1、怎么调试Hook到X进程的动态库D。
(1)用WINDBG.exe调试X进程,此时动态库D还没有进驻X进程。
(2)用Hook工具把动态库D Hook到进程X里。
(3)注意要在D动态库需要中断的地方插入以下代码:
__asm
{
int 3
}
(4) 当Hook成功后,D动态库运行到INT 3处时,WINDBG.exe会自动定位到动态库D中断的代码处。
2、汇编注意的问题:
(1)在__declspec(naked)声明的函数中,要注意不要定义局部变量,否则会打乱ebp堆栈,导致程序出
现错乱。原因是:进入裸函数后,系统会根据局部变量的大小,调整EBP值。但在进入裸函数后没有把
ESP的值赋给EBP,所以EBP应该是上一层函数的入口ESP,此时操作EBP就会影响到上一层函数的堆栈,甚
至更上层的堆栈。
注:EBP的用途,EBP寄存器是用来保存函数的堆栈起始点,从EBP到当前ESP之间的堆栈就是当前函数所
分配的局部变量(不考虑嵌入汇编)。所以当调用CALL指令后,系统会把ESP减1,此时往堆栈写入函数返回地址EIP,然后,一般编译器产生的函数还会调用“Push EBP”指令把上一层函数压进栈,再把当前的ESP赋给EBP,也就是说当前函数EBP向高地址方向的前两个DWORD值分别是上个函数的EBP,函数返回EIP。
既然不能用局部变量,以下几种内存空间可以代替:
a、全局变量
b、寄存器,但注意要先进栈保护好寄存器原有的值。
c、利用当前ESP,但要处理的好,否则容易出错。
(2)如下表达式,
__asm
{
mov [dwParam], eax
}
经编译后产生的汇编代码如下:
mov dword ptr[dwParm], eax
表示把eax的值赋给指针dwParam,并不能赋给dwParam指向的空间。
(3)Hook到API后需要往上寻找CallStack,此时需要用到EBP寄存器,同时为了避免异常,
需要不断地检测:在回溯的时候是否碰到Call指令,否则将是不正确的回溯。那此时需要知道
Call指令的一些编码格式,以便识别Call指令。参见“Call指令详解”。