Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1504234
  • 博文数量: 228
  • 博客积分: 1698
  • 博客等级: 上尉
  • 技术积分: 3241
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-24 21:49
个人简介

Linux

文章分类

全部博文(228)

文章存档

2017年(1)

2016年(43)

2015年(102)

2014年(44)

2013年(5)

2012年(30)

2011年(3)

分类: LINUX

2014-07-23 16:18:25

Interfaces

DECAF提供了许多事件-驱动接口使分析更容易一些。提供了两种类型的接口,第一种是在特定的事件点插入跟踪代码,第二种是作为命令工具获取Guest系统信息或读取Guest系统的内存。
1. 回调接口
为了更好的理解这些接口,对QEMU的基础了解是很必要的,看一查看qemu获取更多的信息。
1.1 回调类型
1). VMI callback
在shared/vmi_callback.h中定义,如下:

点击(此处)折叠或打开

  1. typedef enum {
  2.   VMI_CREATEPROC_CB = 0,// 进程结构创建时被调用
  3.   VMI_REMOVEPROC_CB,    // 销毁进程时调用
  4.   VMI_LOADMODULE_CB,    // 加载dll或者模块时调用
  5.   VMI_REMOVEMODULE_CB,  // 卸载dll或者模块时调用
  6.   VMI_LOADMAINMODULE_CB,// 进程开始运行时调用
  7.   VMI_PROCESSBEGIN_CB = VMI_LOADMAINMODULE_CB, //alias
  8.   VMI_LAST_CB, //place holder for the last position, no other uses.
  9. } VMI_callback_type_t;
2) Instruction callback
在shared/DECAF_callback_common.h中被定义,这类回调在指令级别进行。

点击(此处)折叠或打开

  1. typedef enum {
  2.         DECAF_BLOCK_BEGIN_CB = 0,    // 在块开始时被调用
  3.         DECAF_BLOCK_END_CB,          // 在块结束时被调用
  4.         DECAF_INSN_BEGIN_CB,         // 在指令被执行之前调用
  5.         DECAF_INSN_END_CB,           // 在指令被执行之后调用
  6.         DECAF_MEM_READ_CB,           // 在内存被读取时调用
  7.         DECAF_MEM_WRITE_CB,          // 在内存被写时调用
  8.         DECAF_EIP_CHECK_CB,
  9.         DECAF_KEYSTROKE_CB,          // 击键行为被产生时调用
  10.         DECAF_NIC_REC_CB,            // 网卡收到包时调用
  11.         DECAF_NIC_SEND_CB,           // 网卡发送包时调用
  12.         DECAF_OPCODE_RANGE_CB,
  13.         DECAF_TLB_EXEC_CB,
  14.         DECAF_READ_TAINTMEM_CB,
  15.         DECAF_WRITE_TAINTMEM_CB,
  16.         DECAF_LAST_CB, //place holder for the last position, no other uses.
  17. } DECAF_callback_type_t;
3). Mem read/write callback
在shared/DECAF_callback_common.h中被定义
DECAF_MEM_READ_CB,发生了内存读取操作时被调用
DECAF_MEM_WRITE_CB,发生了内存写操作时被调用

4)Keystroke callback
在shared/DECAF_callback_common.h中被定义
DECAF_KEYSTROKE_CB,当系统从ps2 driver读取击键操作时被调用

5)EIP check callback
DECAF_EIP_CHECK_CB,适用于所有的函数调用,在跳转到EIP指定的函数前被调用。当指定了某些污染源时,用于检查EIP是否被污染。如果被污染,则意味着exploit的发生。


6)network callback
DECAF_NIC_REC_CB,当网卡收到数据时被调用

DECAF_NIC_SEND_CB,当网卡发送数据时被调用

目前DECAF对网络回调的实现是基于NE2000网卡的,所以当插件中用到网络回调时,需要在启动DECAF时指定 “-device ne2k_pci,netdev=mynet”来使用NE2000网卡。

1.2 回调注册和注销函数
为了使用以上的回调,首先需要注册回调函数。在卸载插件之前,需要确保回调函数已经被注销了。否则可能会导致意向不到的问题。
可以使用下面代码注册/注销VMI callback:


点击(此处)折叠或打开

  1. DECAF_Handle VMI_register_callback(procmod_callback_type_t cb_type,
  2.                 procmod_callback_func_t cb_func,
  3.                 int *cb_cond
  4.                 );

  5. int VMI_unregister_callback(procmod_callback_type_t cb_type, DECAF_Handle handle);
注册和注销其他的回调类型,需要使用下面的代码:

点击(此处)折叠或打开

  1. DECAF_Handle DECAF_register_callback(
  2.                 DECAF_callback_type_t cb_type,
  3.                 DECAF_callback_func_t cb_func,
  4.                 int *cb_cond
  5.                 );

  6. int DECAF_unregister_callback(DECAF_callback_type_t cb_type, DECAF_Handle handle);
对于块开始/结束的回调,为了获取更好的性能需要使用下面的接口:

点击(此处)折叠或打开

  1. DECAF_Handle DECAF_registerOptimizedBlockBeginCallback(
  2.     DECAF_callback_func_t cb_func,
  3.     int *cb_cond,
  4.     gva_t addr,
  5.     OCB_t type);

  6. DECAF_Handle DECAF_registerOptimizedBlockEndCallback(
  7.     DECAF_callback_func_t cb_func,
  8.     int *cb_cond,
  9.     gva_t from,
  10.     gva_t to);

  11. int DECAF_unregisterOptimizedBlockBeginCallback(DECAF_Handle handle);

  12. int DECAF_unregisterOptimizedBlockEndCallback(DECAF_Handle handle);
1.3 API Hook Interfaces
DECAF提供了接口来获取guest os的任意API,可以在DECAF/shared/hookapi.h看到详细的描述:

点击(此处)折叠或打开

  1. uintptr_t hookapi_hook_function_byname(const char *mod,const char *func,int is_global,target_ulong cr3,hook_proc_t fnhook,void *opaque,uint32_t sizeof_opaque);

  2. void hookapi_remove_hook(uintptr_t handle);

  3. uintptr_t hookapi_hook_return(target_ulong pc,hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque);

  4. uintptr_t hookapi_hook_function(int is_global, target_ulong pc, target_ulong cr3, hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque );
2. Utils
正如在sample_plugins看到的,你注册了DECAF_INSN_BEGIN_CB 回调,但是在你的my_insn_begin_callback函数中能完成那些事情呢?utils接口可以帮助你获取关于guest os更多的信息。可以在DECAF/shared/DECAF_main.c/h或者DECAF/shared/vmi.h/vmi_c_wrapper.h中找到这些定义。
1)Utils for read/write memory from/to guest OS
点击(此处)折叠或打开
  1. /*given a virtual address of guest os, get the corresponded physical address */
  2.   gpa_t DECAF_get_phys_addr(CPUState* env, gva_t addr);

  3.   DECAF_errno_t DECAF_memory_rw(CPUState* env, uint32_t addr, void *buf, int len,int is_write);

  4.   DECAF_errno_t DECAF_memory_rw_with_cr3(CPUState* env, target_ulong cr3,gva_t addr, void *buf, int len, int is_write);

  5.   DECAF_errno_t DECAF_read_mem(CPUState* env, gva_t vaddr, int len, void *buf);

  6.   DECAF_errno_t DECAF_write_mem(CPUState* env, gva_t vaddr, int len, void *buf);

  7.   DECAF_errno_t DECAF_read_mem_with_cr3(CPUState* env, target_ulong cr3,gva_t vaddr, int len, void *buf);

  8.   DECAF_errno_t DECAF_write_mem_with_cr3(CPUState* env, target_ulong cr3,gva_t vaddr, int len, void *buf);

  9.   DECAF_get_page_access(CPUState* env, gva_t addr);
2)Utils for get OS-level semantics
VMI的组件是使用C++开发的,你可以在插件中使用vim.h中的C++接口,如果进行C/C++混合编程的话。当然,也可以使用vmi_c_wrapper.h中导出的C接口。
C++接口,如下:

点击(此处)折叠或打开

  1. module * VMI_find_module_by_pc(target_ulong pc, target_ulong pgd, target_ulong *base);

  2. module * VMI_find_module_by_name(const char *name, target_ulong pgd, target_ulong *base);

  3. module * VMI_find_module_by_base(target_ulong pgd, uint32_t base);

  4. process * VMI_find_process_by_pid(uint32_t pid);

  5. process * VMI_find_process_by_pgd(uint32_t pgd);

  6. process* VMI_find_process_by_name(char *name);
C接口

点击(此处)折叠或打开

  1. /// @ingroup semantics
  2. /// locate the module that a given instruction belongs to
  3. /// @param eip virtual address of a given instruction
  4. /// @param cr3 memory space id: physical address of page table
  5. /// @param proc process name (output argument)
  6. /// @param tm return tmodinfo_t structure
  7. extern int VMI_locate_module_c(gva_t eip, gva_t cr3, char proc[],tmodinfo_t *tm);

  8. //extern int checkcr3(uint32_t cr3, uint32_t eip, uint32_t tracepid, char *name,
  9.   // int len, uint32_t * offset);

  10. extern int VMI_locate_module_byname_c(const char *name, uint32_t pid,tmodinfo_t * tm);

  11. extern int VMI_find_cr3_by_pid_c(uint32_t pid);

  12. extern int VMI_find_pid_by_cr3_c(uint32_t cr3);

  13. extern int VMI_find_pid_by_name_c(char* proc_name);

  14. /// @ingroup semantics
  15. /// find process given a memory space id
  16. /// @param cr3 memory space id: physical address of page table
  17. /// @param proc process name (output argument)
  18. /// @param pid process pid (output argument)
  19. /// @return number of modules in this process
  20. extern int VMI_find_process_by_cr3_c(uint32_t cr3, char proc_name[], size_t len, uint32_t *pid);
  21. /* find process name and CR3 using the PID as search key */
  22. extern int VMI_find_process_by_pid_c(uint32_t pid, char proc_name[], size_t len, uint32_t *cr3);

  23. extern int VMI_get_proc_modules_c(uint32_t pid, uint32_t mod_no, tmodinfo_t *buf);

  24. extern int VMI_get_all_processes_count_c(void);
  25. /* Create array with info about all processes running in system
  26.     */
  27. extern int VMI_find_all_processes_info_c(size_t num_proc, procinfo_t *arr);

  28. //Aravind - added to get the number of loaded modules for the process. This is needed to create the memory required by get_proc_modules
  29. extern int VMI_get_loaded_modules_count_c(uint32_t pid);
  30. //end - Aravind

  31. /// @ingroup semantics
  32. /// @return the current thread id. If for some reason, this operation
  33. /// is not successful, the return value is set to -1.
  34. /// This function only works in Windows XP for Now.
  35. extern int VMI_get_current_tid_c(CPUState* env);

  36. //0 unknown 1 windows 2 linux
  37. extern int VMI_get_guest_version_c(void);







阅读(2222) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~