求一个API Hook的完整代码例子,可以用一个单独的API作为例子,不用微软的deturs.

解决方案 »

  1.   

    http://www.vckbase.com/code/listcode.asp?mclsid=13&sclsid=1309
      

  2.   

    to zfive5(醉马不肖):
    我要的不是对windows消息的hook ,而是对API函数调用的hook 。
      

  3.   

    有关API HOOK方面的一些浅释  作者 TopLevel 
    关键字 API HOOK
    原作者姓名 TopLevel介绍
    本文粗略的介绍了有关API HOOK方面的一些原理,附有源代码,希望能给大家带来帮助。读者评分 3 评分次数 1 正文
    Creator        :    TopLevel 
    Create Date    :    2003-5-12API HOOK(API钩子)的目的:    一看到Hook这个字眼,首先我们的脑海里浮现的就是“钩子”两词。对于“钩子”两词,看起来不是那么陌生。反正,对于我来说,至少和它还算个脸熟吧。 :P
    不过你对它即使脸生,也没关系。因为在这里我们所指的Hook绝对不同于我们所熟悉的系统钩子。虽然意义不同,但有一点,就是它们目的是一样的 :拦截“控制权”(不知道,意思表达的对不对,要是对的话,就鼓鼓掌)。说白了,就是让系统执行某项动作之前,首先按照我们的意图执行,然后,再继续执行系统默认的动作。(附注:做“贼”要让别人不知道,那才叫“贼”。 ·#¥—…*·# ^_^ )
    长话短说,在这里的所谓的API HOOK就是指的就是 :系统函数接口的钩子。也就是说,当系统函数进行调用时,首先进入我们指定的函数,然后再执行系统的函数。API HOOK(API钩子)的原理:    其实,这里边的可以采用多种方法实现我们想要的功能。在这里可以就以Jmp方法的为例进行说明。Jmp方法实现简单且一目明了,很容易理解。
        其实Jmp有好几种二进制指令,我们这里是用的0xE9,汇编格式为下:     Jmp XXXX      // 其中XXXX为距离当前指令的偏移。我们知道,系统函数都是以DLL封装起来的,应用程序应用到系统函数时,应首先把该DLL加载到当前的进程空间中,调用的系统函数的入口地址,可以通过GetProcAddress函数进行获取。当系统函数进行调用的时候,首先把所必要的信息保存下来(包括参数和返回地址,等一些别的信息),然后就跳转到函数的入口地址,继续执行。其实函数地址,就是系统函数“可执行代码”的开始地址。那么怎么才能让函数首先执行我们的函数呢?呵呵,应该明白了吧,把开始的那段可执行代码替换为我们自己定制的一小段可执行代码,这样系统函数调用时,不就按我们的意图乖乖行事了吗?其实,就这么简单。Very very简单。 :P
    大话说出去了,可仔细一想,并没那么简单。哎,急性子没办法,“江山易改,本性难移”。一个兄弟问 : “Top, 看你愁眉不展的,谁又把砖头当鲜花仍你了?”
    Top         : “我!·#·%¥·#—(¥,”
    Top心想     : “小样,不就是要干的神不知,鬼不觉的吗?不就是,不让它弹出那些可恶的带小红叉叉的对话框吗?还治不了它,K,不混了。”要想“神不知,鬼不觉“就要做到下面最基本的两点:
        1.    把进行拦截的函数原形定义的格式和即将拦截的系统函数原形一致。也就是说,参数和返回值要一致。有且只有这样,才能使我们的拦截操作,对当前进程的健壮性,有最大程度的保障。
        2.    保持对系统函数的继续调用。如果没这一点,“神不知,鬼不觉“不仅人不相信,恐怕连鬼也不相信。比如:你拦截了MessageBox这个函数,结果你处理完自己的事情(MyMessageBox),也没继续进行系统函数的处理(MessageBox)一拍屁股,就走了,洋洋自得的样子。殊不知,用户在那傻眼,他(她)很郁闷,怎么对话框它怎么就不见了呢?一定是中木马了。哈哈,你的拦截不成功,连菜菜鸟都算不上的,都知道出问题了。这让我想起一个的广告语:”地球人都知道“。要想不让它弹出长得不好看的带小红叉叉的对话框,呵呵。就需要SEH(Structure Exception Handle)方面的知识了,本人很菜,略知一二,考虑一般不会出现这种情况,就不打算把得砖头的本钱压在这里了。不过这方面的知识,很重要的。嘻嘻。废话说了这么多,呵呵。该说些实际的了。下面我们就具体讲一下我们该怎么样定制我们的二进制代码,好让它跳到我们的函数中去。我们的做法是:把系统函数的入口地方的内容替换为一条Jmp指令,目的就是跳到我们的函数进行执行。而Jmp后面要求的是相对偏移,也就是我们的函数入口地址到系统函数入口地址之间的差异,再减去我们这条指令的大小。用公式表达如下:
    int nDelta = UserFunAddr – SysFunAddr - (我们定制的这条指令的大小);
    Jmp nDleta;也就是说:如果我们已经挂钩好了系统函数。那么当系统进行系统调用时,首先就碰到我们的Jmp XXXX指令,而这条指令作用就是跳到我们的函数中去执行。记住挂钩系统函数时,必须(强调的说法)把我们要替换的内容保存下来,切记,切记。如果不明白,再想想刚才所说的 2。保持对系统函数的继续调用。保存这部分内容就是为了恢复系统函数入口地址的内容,让系统函数得以继续调用。
    我们采用的总体流程可概括如下:à 保存系统函数入口 - 进入我们的函数 - 恢复系统函数入口 - 可以做一些我们想做的操作 - 调用系统函数 - 挂接系统函数 - 保存系统函数入口 à …图例如下:
        
    未挂接:
    挂接后:
    XXXX = 我的函数入口指针(地址)- 系统函数入口指针(地址)- sizeof (Jmp XXXX指令的大小);API HOOK(API钩子)的应用:   屏幕取词,游戏外挂,数据包的抓取等。   具体代码如下(只演示了本进程内的API HOOK).版权所有 @ 2002~2006 TopLevel Studio All Rights Reserved (如有转载,劳告知一声)正文完附件:
    说明 Raw.gif
    说明 Modify.gif
    说明 ApiHookTest.zip 
    http://www.vchelp.net/ASP/ibr_upload/578.zip
      

  4.   

    截获Windows系统内部的API调用http://www.copathway.com:9191/vchelp/file2002_2/apihook.rar
      

  5.   

    to  Skt32(Skt32) :
    你贴的这片文章我看过,但是好像这种解决方案不是很好,特别是在多线程下不是很适合。