在之前的日志中,我提到过,我发现每个API的代码之间,都有5个字接的空白。所以,我忽然想到,我可以利用这5个字节进行新的API Hook,进而实现API被Hook以后还能执行原来的指令。
其实,我觉得很多时候Hook一个API后,我们就没有必要去执行原来的代码了,因为我们要用新的过程来取代原来的API。可是,有的时候我们需要的仅仅是监视一下这个API的执行,或者只修改一下它的返回值而已,不希望它的过程被覆盖掉。这样,就产生了我这样的一个想法。
这个方法,原理就是在API过程的最后,函数返回之前,跳转到我构造的指令中。在我的指令里,先保存了一下API的返回值,以便我们可以自己选择返回API原来的值或者自己定制的值。然后把传递进来的参数重新压栈,接着再用call指令调用我们自己的过程,然后返回。
只是这个方法,有一个缺点,就是每个API的后面必须要有5字节的空白和只有一处返回指令。
其实并不需要5个字节的空白。因为返回指令一般都是1字节或3字节的,而跳转指令都是5字接的。所以,只要有4字节或2字接的空白就足够了,具体要看API的返回指令而定了。
值得欣慰的是,大部分的API都满足这条件。自己写的DLL暂时不支持此法的Hook,以后再研究一下还有没其他方法。
思路其实都很清晰的,过程我也写得很简单。稍微会点ASM和VB的人估计看我这代码都没困难的吧。
废话不说了,现在就放上代码吧。
frmMain.frm
modMain.bas
完整工程下载:
其实,我觉得很多时候Hook一个API后,我们就没有必要去执行原来的代码了,因为我们要用新的过程来取代原来的API。可是,有的时候我们需要的仅仅是监视一下这个API的执行,或者只修改一下它的返回值而已,不希望它的过程被覆盖掉。这样,就产生了我这样的一个想法。
这个方法,原理就是在API过程的最后,函数返回之前,跳转到我构造的指令中。在我的指令里,先保存了一下API的返回值,以便我们可以自己选择返回API原来的值或者自己定制的值。然后把传递进来的参数重新压栈,接着再用call指令调用我们自己的过程,然后返回。
只是这个方法,有一个缺点,就是每个API的后面必须要有5字节的空白和只有一处返回指令。
其实并不需要5个字节的空白。因为返回指令一般都是1字节或3字节的,而跳转指令都是5字接的。所以,只要有4字节或2字接的空白就足够了,具体要看API的返回指令而定了。
值得欣慰的是,大部分的API都满足这条件。自己写的DLL暂时不支持此法的Hook,以后再研究一下还有没其他方法。
思路其实都很清晰的,过程我也写得很简单。稍微会点ASM和VB的人估计看我这代码都没困难的吧。
废话不说了,现在就放上代码吧。
frmMain.frm
modMain.bas
完整工程下载:


2008/08/16 22:10 ..by
下载文件 (已下载 3 次)







主要是给dwReturn这个数组加个注释,怕有的人看不明白。
例如你的API有4个参数,你在声明的时候就把上限设为4就可以了。
从下标0开始,依次为:原API返回值、第一个参数、第二个参数、第三个参数、第四个参数。
应该都很好理解的。
还有就是Form_Unload的时候,还原一下API Hook,避免调试的模式下会产生不能为Read的错误。程序编译后是不会有这样错误的。
代码作了些修改,也改正了一些小地方的错误。记住千万不要使用过程声明中的参数,自己在过程体中重新声明参数变量,然后像例子中那样手动恢复变量好了。
等我再找时间研究下为啥会出这样的错~!