HOOK(易语⾔⾼级部分)Hook
API_HOOK核⼼代码
这⾥时绝对跳转 FF,同进程不⽤修改内存属性?
没有修改内存属性,照样可⾏
HOOK同进程MessageBoxA
未HOOK前 MessageBoxA
HOOK后 MessageBoxA
我们正好把这7个字节改了.
mov eax,0x401A5F
jmp eax
调用子程序的例子类_InlineHook
这个类⽐先那个类要⾼级点,还可以调⽤原函数,和远程进程
整体思路
这个就是利⽤相对跳转。E9
修改被hook代码,执⾏相对跳转 到我们的代码,我们的代码也可通过私有_新函数地址继续执⾏原先代码,也可不执⾏。
下图中的jmp是是跳到我们的函数
这⾥是私有_新函数地址 保留的代码,从图中看可以继续跳到原先代码执⾏.
关于堆内存
例如建⽴⼀个⽂本变量A,你⽤HEAPALLOC申请内存,赋值给A后,当A进⾏下⼀次重新赋值时会⾃动调⽤HEAPFREE来释放之前的堆内存,易语⾔对⽂本、字节集等变量在堆上赋值时会⾃动调⽤HEAPFREE清空之前的堆内存,所以你不⽤管这个变量的堆内存,不管这个变量赋值多少次,在下次赋值时都会进⾏这个操作,所以不会有内存泄露。
关于函数参数
例如易语⾔在调⽤含⾃定义结构体的API时会先在堆上申请内存然后将⾃定义结构体转为字节集,然后再传⼊字节集的地址进栈⾥再调⽤这个API,调⽤完后再对着这个结构体将字节集的数据⼀个个填写进去。
还有⼀个更明显的例⼦就是易语⾔调⽤⼦程序时如果⽤的是“XXX⼦程序()”的形式来调⽤(我想⼤部分都是这样),那么当⼦程序⾥有⽂本、字节集、数组、⾃定义结构体之类的参数时,那么传⼊进栈⾥的是指针的指针,对于⽂本和字节集参数来说传⼊的就是“取变量地址()”⽽⾮“取变量数据地址”,⽤“&”取到的⼦程序地址并不是真正的⼦程序地址,⽽只是⼀个外壳地址,这个外壳地址在平时是不起作⽤的(你可以在OD⾥对这个地址下断,调⽤⼦程序时会发现OD根本不会断下来),⼀般是在做回调函数的时候才会起作⽤,例如APIHOOK的时候就会⽤到“&”取到得⼦程序外壳地址做回调函数,这个外壳的作⽤就是将传⼊的数据------数据的指针
变为指针的指针。
这也就解释了,因为多了⼀层中间指针
第⼀次eax 取的是中间指针,第⼆次取得才是实际地址,具体过程如下
主要在图中标记第⼆步骤
关于JMP
0xFF JMP 远跳 eax取值
0xE8 CALL 后⾯的四个字节是地址
0xE9 JMP 后⾯的四个字节是偏移 RVA = ⽬标地址-(指令所在地址+指令长度) 0xEB JMP 后⾯的⼆个字节是偏移 负数补码 ⽐如F9是EIP向前移动7个字节
"减⼀取反"和"取反加⼀"等价
已知补码求源码也可取反 + 1,分正数和负数,负数的补码= 正数 取反 + 1
补码的补码是原码
总结
HOOK 很好很强⼤.