Interfaces
DECAF提供了许多事件-驱动接口使分析更容易一些。提供了两种类型的接口,第一种是在特定的事件点插入跟踪代码,第二种是作为命令工具获取Guest系统信息或读取Guest系统的内存。
1. 回调接口
为了更好的理解这些接口,对QEMU的基础了解是很必要的,看一查看qemu获取更多的信息。
1.1 回调类型
1). VMI callback
在shared/vmi_callback.h中定义,如下:
-
typedef enum {
-
VMI_CREATEPROC_CB = 0,// 进程结构创建时被调用
-
VMI_REMOVEPROC_CB, // 销毁进程时调用
-
VMI_LOADMODULE_CB, // 加载dll或者模块时调用
-
VMI_REMOVEMODULE_CB, // 卸载dll或者模块时调用
-
VMI_LOADMAINMODULE_CB,// 进程开始运行时调用
-
VMI_PROCESSBEGIN_CB = VMI_LOADMAINMODULE_CB, //alias
-
VMI_LAST_CB, //place holder for the last position, no other uses.
-
} VMI_callback_type_t;
2) Instruction callback
在shared/DECAF_callback_common.h中被定义,这类回调在指令级别进行。
-
typedef enum {
-
DECAF_BLOCK_BEGIN_CB = 0, // 在块开始时被调用
-
DECAF_BLOCK_END_CB, // 在块结束时被调用
-
DECAF_INSN_BEGIN_CB, // 在指令被执行之前调用
-
DECAF_INSN_END_CB, // 在指令被执行之后调用
-
DECAF_MEM_READ_CB, // 在内存被读取时调用
-
DECAF_MEM_WRITE_CB, // 在内存被写时调用
-
DECAF_EIP_CHECK_CB,
-
DECAF_KEYSTROKE_CB, // 击键行为被产生时调用
-
DECAF_NIC_REC_CB, // 网卡收到包时调用
-
DECAF_NIC_SEND_CB, // 网卡发送包时调用
-
DECAF_OPCODE_RANGE_CB,
-
DECAF_TLB_EXEC_CB,
-
DECAF_READ_TAINTMEM_CB,
-
DECAF_WRITE_TAINTMEM_CB,
-
DECAF_LAST_CB, //place holder for the last position, no other uses.
-
} 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:
-
DECAF_Handle VMI_register_callback(procmod_callback_type_t cb_type,
-
procmod_callback_func_t cb_func,
-
int *cb_cond
-
);
-
-
int VMI_unregister_callback(procmod_callback_type_t cb_type, DECAF_Handle handle);
注册和注销其他的回调类型,需要使用下面的代码:
-
DECAF_Handle DECAF_register_callback(
-
DECAF_callback_type_t cb_type,
-
DECAF_callback_func_t cb_func,
-
int *cb_cond
-
);
-
-
int DECAF_unregister_callback(DECAF_callback_type_t cb_type, DECAF_Handle handle);
对于块开始/结束的回调,为了获取更好的性能需要使用下面的接口:
-
DECAF_Handle DECAF_registerOptimizedBlockBeginCallback(
-
DECAF_callback_func_t cb_func,
-
int *cb_cond,
-
gva_t addr,
-
OCB_t type);
-
-
DECAF_Handle DECAF_registerOptimizedBlockEndCallback(
-
DECAF_callback_func_t cb_func,
-
int *cb_cond,
-
gva_t from,
-
gva_t to);
-
-
int DECAF_unregisterOptimizedBlockBeginCallback(DECAF_Handle handle);
-
-
int DECAF_unregisterOptimizedBlockEndCallback(DECAF_Handle handle);
1.3 API Hook Interfaces
DECAF提供了接口来获取guest os的任意API,可以在DECAF/shared/hookapi.h看到详细的描述:
-
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);
-
-
void hookapi_remove_hook(uintptr_t handle);
-
-
uintptr_t hookapi_hook_return(target_ulong pc,hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque);
-
-
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
点击(此处)折叠或打开
-
/*given a virtual address of guest os, get the corresponded physical address */
-
gpa_t DECAF_get_phys_addr(CPUState* env, gva_t addr);
-
-
DECAF_errno_t DECAF_memory_rw(CPUState* env, uint32_t addr, void *buf, int len,int is_write);
-
-
DECAF_errno_t DECAF_memory_rw_with_cr3(CPUState* env, target_ulong cr3,gva_t addr, void *buf, int len, int is_write);
-
-
DECAF_errno_t DECAF_read_mem(CPUState* env, gva_t vaddr, int len, void *buf);
-
-
DECAF_errno_t DECAF_write_mem(CPUState* env, gva_t vaddr, int len, void *buf);
-
-
DECAF_errno_t DECAF_read_mem_with_cr3(CPUState* env, target_ulong cr3,gva_t vaddr, int len, void *buf);
-
-
DECAF_errno_t DECAF_write_mem_with_cr3(CPUState* env, target_ulong cr3,gva_t vaddr, int len, void *buf);
-
-
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++接口,如下:
-
module * VMI_find_module_by_pc(target_ulong pc, target_ulong pgd, target_ulong *base);
-
-
module * VMI_find_module_by_name(const char *name, target_ulong pgd, target_ulong *base);
-
-
module * VMI_find_module_by_base(target_ulong pgd, uint32_t base);
-
-
process * VMI_find_process_by_pid(uint32_t pid);
-
-
process * VMI_find_process_by_pgd(uint32_t pgd);
-
-
process* VMI_find_process_by_name(char *name);
C接口
-
/// @ingroup semantics
-
/// locate the module that a given instruction belongs to
-
/// @param eip virtual address of a given instruction
-
/// @param cr3 memory space id: physical address of page table
-
/// @param proc process name (output argument)
-
/// @param tm return tmodinfo_t structure
-
extern int VMI_locate_module_c(gva_t eip, gva_t cr3, char proc[],tmodinfo_t *tm);
-
-
//extern int checkcr3(uint32_t cr3, uint32_t eip, uint32_t tracepid, char *name,
-
// int len, uint32_t * offset);
-
-
extern int VMI_locate_module_byname_c(const char *name, uint32_t pid,tmodinfo_t * tm);
-
-
extern int VMI_find_cr3_by_pid_c(uint32_t pid);
-
-
extern int VMI_find_pid_by_cr3_c(uint32_t cr3);
-
-
extern int VMI_find_pid_by_name_c(char* proc_name);
-
-
/// @ingroup semantics
-
/// find process given a memory space id
-
/// @param cr3 memory space id: physical address of page table
-
/// @param proc process name (output argument)
-
/// @param pid process pid (output argument)
-
/// @return number of modules in this process
-
extern int VMI_find_process_by_cr3_c(uint32_t cr3, char proc_name[], size_t len, uint32_t *pid);
-
/* find process name and CR3 using the PID as search key */
-
extern int VMI_find_process_by_pid_c(uint32_t pid, char proc_name[], size_t len, uint32_t *cr3);
-
-
extern int VMI_get_proc_modules_c(uint32_t pid, uint32_t mod_no, tmodinfo_t *buf);
-
-
extern int VMI_get_all_processes_count_c(void);
-
/* Create array with info about all processes running in system
-
*/
-
extern int VMI_find_all_processes_info_c(size_t num_proc, procinfo_t *arr);
-
-
//Aravind - added to get the number of loaded modules for the process. This is needed to create the memory required by get_proc_modules
-
extern int VMI_get_loaded_modules_count_c(uint32_t pid);
-
//end - Aravind
-
-
/// @ingroup semantics
-
/// @return the current thread id. If for some reason, this operation
-
/// is not successful, the return value is set to -1.
-
/// This function only works in Windows XP for Now.
-
extern int VMI_get_current_tid_c(CPUState* env);
-
-
//0 unknown 1 windows 2 linux
-
extern int VMI_get_guest_version_c(void);
阅读(2222) | 评论(0) | 转发(0) |