系統要調用一個函數,是不是先將函數頭部載入,接著就是函數的參數信息,以及函數中所調用的功能,最后是函數尾部信息?
我想知道的是系統調用一個函數的具体過程?函數結构的定義?以及用C語言模擬的具体方法!謝謝!
我想知道的是系統調用一個函數的具体過程?函數結构的定義?以及用C語言模擬的具体方法!謝謝!
解决方案 »
- 各位前辈解答一下,关于com聚合的问题。
- 用IWebBrowser2 的get_HWND 得到IE的窗口句柄后,用::SendMessage(hIE,WM_CLOSE,0,0); 怎么没有任何反应?
- 如何屏蔽掉关闭命令
- 在CRebar上放置了CButton控件,怎么才能使用它。(我为IDR_MAINFRAME连接了一个类CMyDialog)
- ->【抛砖引玉,总结一下这些命令的用法】<-
- 如何改变propertypage的标题?
- 阅读*.pdf文档时,想用金山词霸,怎么弄。 急!!!!!!!
- COM客户端如何将HMENU或HWND等句柄传递给COM的组件,如何描述IDL文件以及实现文件,谢谢
- 有关Ftp的Port命令一问?
- ado连接SQLServer时m_pRecordset->Open("SELECT * FROM dbo.test", 。。。。。。不能显示出对话框
- 刚刚那位朋友?
- 请教大家关于数据集访问的几个问题
不同的 Calling Conventions(我不知道汉语怎么翻译)压出栈的顺序是不一样的。对stdcall方式来说是这样的:
函数:int MyProc(int a, int b);
调用:MyProc(2, 3);
被编译成:
push 3
push 2
call MyProc
堆栈的恢复工作是由MyProc来做的。
push 3
push 2
call MyProc
add esp, 8 // 恢复栈
//typedef struct _APF_HOOK_FUNCTION_HEAD {
BYTE bPush_EBP;
WORD wMov_EBP_ESP; _APF_HOOK_FUNCTION_HEAD() {
bPush_EBP = INSTR_PUSH_EBP;
wMov_EBP_ESP = INSTR_MOV_EBP_ESP;
};}APF_HOOK_FUNCTION_HEAD, * PAPF_HOOK_FUNCTION_HEAD;//
// 构造 push dword ptr [ebp + xxh] 指令
//typedef struct _APF_HOOK_FUNCTION_PUSH_PARAMETER {
WORD wPush_Dword_Ptr;
BYTE bOffset; _APF_HOOK_FUNCTION_PUSH_PARAMETER() {
wPush_Dword_Ptr = INSTR_PUSH_DWORD_PTR;
}} APF_HOOK_FUNCTION_PUSH_PARAMETER, * PAPF_HOOK_FUNCTION_PUSH_PARAMETER;//
// 調用原來那一部分的代碼
//typedef struct _APF_HOOK_CALL {
BYTE bPushLong;
DWORD dwConstant;
BYTE bMov_EAX_DWORD;
DWORD dwAddress;
WORD wCall_EAX;
_APF_HOOK_CALL() {
bPushLong = INSTR_PUSH_LONG;
bMov_EAX_DWORD = INSTR_MOV_EAX_DWORD;
wCall_EAX = INSTR_CALL_EAX;
}
} APF_HOOK_CALL, * PAPF_HOOK_CALL;
//
// 函數的返回部分
//typedef struct _APF_HOOK_FUNCTION_TAIL { WORD wMov_ESP_EBP;
BYTE bPop_EBP;
BYTE bRet;
WORD wAdjustSize; _APF_HOOK_FUNCTION_TAIL() {
wMov_ESP_EBP = INSTR_MOV_ESP_EBP;
bPop_EBP = INSTR_POP_EBP;
bRet = INSTR_RETN;
};}APF_HOOK_FUNCTION_TAIL, * PAPF_HOOK_FUNCTION_TAIL;
各位請看看上面的代碼,我也是在看別人的代碼!
上面是hook另外的函數時所定義的一些結构!然后在程序中和所要hook的函數交換地址以及參數等.
它是怎樣按照這些步驟來實現的阿!能不能詳細說一下上面這段代碼定義的方式!
#define INSTR_PUSH_EBP ( ( BYTE )0x55 )
#define INSTR_MOV_EBP_ESP ( ( WORD )0xEC8B )
#define INSTR_MOV_ESP_EBP ( ( WORD )0xE58B )
#define INSTR_POP_EBP ( ( BYTE )0x5D )
#define INSTR_RETN ( ( BYTE )0xC2 )
#define INSTR_MOV_EAX_DWORD ( ( BYTE )0xB8 )
#define INSTR_PUSH_LONG ( ( BYTE )0x68 )
#define INSTR_CALL_EAX ( ( WORD )0xD0FF )
#define INSTR_PUSH_DWORD_PTR ( ( WORD )0x75FF )
push ebp
mov ebp, espAPF_HOOK_FUNCTION_PUSH_PARAMETER 就是将栈中bOffset处的参数入栈
push doword ptr[ebp + bOffset]APF_HOOK_CALL 压入常量,调用函数
push dwConstant
mov eax, dwAddress // Address应该是相对于模块加载首部的地址
call eaxAPF_HOOK_FUNCTION_TAIL
mov esp, ebp
pop ebp
ret wAdjustSize那些宏的定义值就是用到的某些指令编译后的二进制值。
1.栈中"bOffset处"怎么樣得到,是否根据參數個數所計算出來的偏移值
2.ret wAdjustSize一句中"wAdjustSize"代表了什么,這個一般又該怎樣得到
3.象那些宏定義的机器碼(應該是這樣吧),如果這樣直接抄上去的話,它在內存里面可否正常運作,是不是就象那种純粹的單片机一樣只要把机器碼直接寫到內存的相應地址就可以了,拿
typedef struct _APF_HOOK_FUNCTION_TAIL { WORD wMov_ESP_EBP;
BYTE bPop_EBP;
BYTE bRet;
WORD wAdjustSize; _APF_HOOK_FUNCTION_TAIL() {
wMov_ESP_EBP = INSTR_MOV_ESP_EBP;
bPop_EBP = INSTR_POP_EBP;
bRet = INSTR_RETN;
};}APF_HOOK_FUNCTION_TAIL, * PAPF_HOOK_FUNCTION_TAIL;
這個來說,把這個結構寫入內存后,它上面定義的那些參數怎么一下子都沒有了,只剩下這些類似的匯編代碼:
mov esp, ebp
pop ebp
ret wAdjustSize
是不是衹要象這樣就可以了啊!為什么???
_APF_HOOK_FUNCTION_TAIL() {
wMov_ESP_EBP = INSTR_MOV_ESP_EBP;
bPop_EBP = INSTR_POP_EBP;
bRet = INSTR_RETN;
};
來計算參數偏移地址,一般從最后一個參數開始,往前計算( BYTE )( ( i + 1 ) * STACK_ELEMENT_SIZE );
2.wAdjustSize代表調用返回的地址大小,由參數個數*STACK_ELEMENT_SIZE 計算出來, 然后ret wAdjustSize,
3.在聲明參數的時候就相當于給其分配了內存,然后接下來就相當于往內存中寫入..比如WORD wMov_ESP_EBP;wMov_ESP_EBP=.......