3.hook到达的位置是 00401561 50 push eax
于是乎,首次调用api的路线变成了
原生:调用api->查表DLL是否在表中存在,不存在则LoadlLibrary->查表该api地址是否在表中存在,不存在则GetProcAddress->返回api地址->jmp api
优化后:首次调用api->查表DLL是否在表中存在,不存在则LoadlLibrary->查表该api地址是否在表中存在,不存在则GetProcAddress->返回api地址->修改调用方机器码,改为 call api
优化后:第二次及以上调用api->call api
下图为:易语言静态编译原生调用api,会有一个api编号,然后call(这个call包含了上面说的所有过程)[attach]1383953[/attach]
下图为:优化后的调用api,编号填充为多字节NOP,然后直接call api
[attach]1383954[/attach]
优点:速度显著提升
缺点:加密壳通常都会保护api,或者VM掉调用方的代码,或者VM掉支持库接口位置代码,这些情况都会导致不能用,并且由于会动态修改内存代码,不能通过CRC校验,会损失一部分安全性。
总结:原理相当于是,省掉了每次调用api查表的时间,改为通过地址直达调用api。缺点是加载DLL后地址不能变,如果DLL被重载之类的,则崩溃。并且不能加壳。