前几天在本站看到一篇《api hook实战》的文章,把里面的例子测试了一下,发现只能截获本例子进程的,如何能够实现系统当前所有进程都生效的API HOOK?
如果有相关例子更好!
非常感谢!

解决方案 »

  1.   

    解决的我也给一百分。
    http://www.csdn.net/expert/topic/1079/1079128.xml?temp=.9226343
      

  2.   

    have you seen codeguru example "HIJACK", it is a global API hook example.(maybe you should change some code)
    http://codeguru.earthweb.com/dll/Hijack.html
      

  3.   

    以前CSDN上有过另一个HookApi的办法, 我贴在下面, 看完后请大家帮忙回答这样的问题:
      为什么必须有一个Dll才行呢? 我曾试图将Dll和测试程序中的诸函数写到同一个程序中, 发现只是在这一个程序中HookApi起作用, 其它的MessageBox照旧, 这是什么原因呢? 难道User32.dll在内存中不仅有一个实例? 我查看内存发现在我的程序中MessageBoxA的入口处被修改了, 而在别的程序中仍是原来的, 这让我不明所以.
      请各位不吝键盘, up有分.
    这么多高手在这里,哎,小弟愿意向各位高手学习 
      Api拦截并不是一个新的技术,很多商业软件都采用这种技术。对windows的Api函数的拦截,不外乎两种方法,第一种是Mr. Jeffrey Richter 的修改exe文件的模块输入节,种方法,很安全,但很复杂,而且有些exe文件,没有Dll的输入符号的列表,有可能出现拦截不到的情况。第二种方法就是常用的JMP XXX的方法,虽然很古老,却很简单实用。 
        本文一介绍第二种方法在Win2k下的使用。第二种方法,Win98/me 下因为进入Ring0级的方法很多,有LDT,IDT,Vxd等方法,很容易在内存中动态修改代码,但在Win2k下,这些方法都不能用,写WDM太过复杂,表面上看来很难实现, 
    其实不然。Win2k为我们提供了一个强大的内存Api操作函数---VirtualProtectEx,WriteProcessMemeory,ReadProcessMemeory,有了它们我们就能在内存中动态修改代码了,其原型为: 
            BOOL VirtualProtectEx( 
                                  HANDLE hProcess,    // 要修改内存的进程句柄 
                                  LPVOID lpAddress,    // 要修改内存的起始地址 
                                  DWORD dwSize,        // 修改内存的字节 
                                  DWORD flNewProtect,  // 修改后的内存属性 
                                  PDWORD lpflOldProtect  // 修改前的内存属性的地址 
                                    ); 
            BOOL WriteProcessMemory( 
                                  HANDLE hProcess,  // 要写进程的句柄 
                                  LPVOID lpBaseAddress,  // 写内存的起始地址 
                                  LPVOID lpBuffer,  // 写入数据的地址 
                                  DWORD nSize,      // 要写的字节数 
                                  LPDWORD lpNumberOfBytesWritten  // 实际写入的子节数 
                                  ); 
          BOOL ReadProcessMemory( 
                                  HANDLE hProcess,  // 要读进程的句柄 
                                  LPCVOID lpBaseAddress,  // 读内存的起始地址 
                                  LPVOID lpBuffer,  // 读入数据的地址 
                                  DWORD nSize,      // 要读入的字节数 
                                  LPDWORD lpNumberOfBytesRead    // 实际读入的子节数 
                                    ); 
    具体的参数请参看MSDN帮助。在Win2k下因为Dll和所属进程在同一地址空间,这点又和Win9x/me存在所有进程存在共享的地址空间不同, 
    因此,必须通过钩子函数和远程注入进程的方法,现以一个简单采用钩子函数对MessageBoxA进行拦截例子来说明: 
    其中Dll文件为: 
              HHOOK g_hHook; 
              HINSTANCE g_hinstDll; 
              FARPROC pfMessageBoxA; 
              int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); 
              BYTE OldMessageBoxACode[5],NewMessageBoxACode[5]; 
              HMODULE hModule ; 
              DWORD dwIdOld,dwIdNew; 
              BOOL bHook=false; 
              void HookOn(); 
              void HookOff(); 
              BOOL init(); 
    LRESULT WINAPI MousHook(int nCode,WPARAM wParam,LPARAM lParam); 
    BOOL APIENTRY DllMain( HANDLE hModule, 
                          DWORD  ul_reason_for_call, 
                          LPVOID lpReserved 
                        ) 

        switch (ul_reason_for_call) 
        { 
            case DLL_PROCESS_ATTACH: 
                if(!init()) 
                { 
                              MessageBoxA(NULL,"Init","ERROR",MB_OK); 
                              return(false); 
                } 
            case DLL_THREAD_ATTACH: 
            case DLL_THREAD_DETACH: 
            case DLL_PROCESS_DETACH: 
                          if(bHook) UnintallHook();  
                        break; 
        } 
        return TRUE; 

    LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数 

        
        return(CallNextHookEx(g_hHook,nCode,wParam,lParam)); 

    HOOKAPI2_API BOOL InstallHook()//输出安装空的钩子函数 
    {  
      g_hinstDll=LoadLibrary("HookApi2.dll"); 
      g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0); 
      if (!g_hHook) 
      { 
            MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK); 
            return(false); 
      } 
      
              
      return(true); 

    HOOKAPI2_API BOOL UninstallHook()//输出御在钩子函数 

      
        return(UnhookWindowsHookEx(g_hHook)); 
    } BOOL init()//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令 

        hModule=LoadLibrary("user32.dll"); 
        pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA"); 
        if(pfMessageBoxA==NULL) 
          return false; 
        _asm 
        { 
            lea edi,OldMessageBoxACode 
            mov esi,pfMessageBoxA 
            cld 
            movsd 
            movsb 
        } 
        NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令 
        _asm 
        { 
            lea eax,MyMessageBoxA 
            mov ebx,pfMessageBoxA 
            sub eax,ebx 
            sub eax,5 
            mov dword ptr [NewMessageBoxACode+1],eax 
        } 
        dwIdNew=GetCurrentProcessId(); //得到所属进程的ID 
        dwIdOld=dwIdNew; 
        HookOn();//开始拦截 
        return(true); 
    } int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType )//首先关闭拦截,然后才能调用被拦截的Api 函数 
    {  
        int nReturn=0; 
        HookOff(); 
        nReturn=MessageBoxA(hWnd,"Hook",lpCaption,uType); 
        HookOn(); 
        return(nReturn); 

    void HookOn() 

        HANDLE hProc; 
        dwIdOld=dwIdNew; 
        hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄 
        VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写 
        WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA 
        VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性 
        bHook=true; 

    void HookOff()//将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA 

        HANDLE hProc; 
        dwIdOld=dwIdNew; 
        hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld); 
        VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld); 
        WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0); 
        VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld); 
        bHook=false; 

    //测试文件: 
    int APIENTRY WinMain(HINSTANCE hInstance, 
                        HINSTANCE hPrevInstance, 
                        LPSTR    lpCmdLine, 
                        int      nCmdShow) 

        
        if(!InstallHook()) 
        { 
            MessageBoxA(NULL,"Hook Error!","Hook",MB_OK); 
            return 1; 
        } 
        MessageBoxA(NULL,"TEST","TEST",MB_OK);//可以看见Test变成了Hook,也可以在其他进程中看见 
        if(!UninstallHook()) 
        { 
            MessageBoxA(NULL,"Uninstall Error!","Hook",MB_OK); 
            return 1; 
        } 
        return 0; 
    }
      大概啊。因为只有dll函数材能注入其它进程德空间,你的和序不可能注入其它进程德空间吧。  可是在我的那个合二为一的程序中是起作用的呀,只是在别的程序中不行。
    另外,在我的程序中看起来的确是将代码注入到User32.dll中了,为什么rujor(rujor)说“你的和序不可能注入其它进程德空间吧”呢?dll和我的程序有什么区别呢?  一般是进程内hook在程序内,进程外hook要做成动态库。
      

  4.   

    这种dll注入技术,只有在其他程序中有消息队列时,也就是调用了USER32函数创建了窗口后,你的hook dll才会被加载到这个程序的地址空间中去。
      

  5.   

    see the links below :http://www.codeproject.com/dll/apihijack.asphttp://www.rohitab.com/discuss/topic.cgi?forum=1&topic=8
      

  6.   

    http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_20294215.html
    ....so many sites u can find via www.google.com...just use key of "hook api" ...Enjoy !
      

  7.   

    所谓必须用DLL的原因,我看到过解释,原话记不清了。
    反正就是这个意思:
    win32里与win16不同,所有内存(也可能是线程)都是独立(局部)的,相互之间不能影响。幸好DLL可以被不同的程序共同使用,所以微软用这个方法弥补了这个全局共享的问题。关于全局API HOOK的程序,我曾经做了一个,您可以下载:
    ftp://pub:[email protected]/Hook和hotKey.rar
    ftp://pub:[email protected]/Hook和hotKey源码.rar运行软件之前,请先看一下使用说明.
      

  8.   

    HOHO,问HOOK问题的人还真多。
    我这个菜鸟也就研究了一个星期,做了个程序,拿着这个程序到处卖分,真是不好意思。
    不用给我分了!
      

  9.   

    你可能没单独做成dll,所以只能hook自己。
      

  10.   

    我做成了单独的dll然后在应用程序中调用了这个dll,只有我这个应用程序调用TextOut时才会被hook到,而其他的应用程序不管怎么调用都TextOut函数都不能被截获我试过用微软的detours来处理,发现detours中的一个例子traceapi,也是只能截获调用traceapi.dll的应用程序中使用的api函数。不知道为何!nevergrief(孤独骑士):
    你的这个例子是Hook的API函数吗?
      

  11.   

    nevergrief(孤独骑士):
    我想实现的是对api函数的hook,不是对键盘和鼠标的hook:)谢谢!!
      

  12.   

    做成dll,SetHookEx的最后一个参数为0就可以了!
      

  13.   

    浅谈API HOOK技术(一)
    APIHook一直是使大家感兴趣的话题。屏幕取词,内码转化,屏幕翻译,中文平台等等都涉及到了此项技术。有很多文章涉及到了这项技术,但都闪烁其词不肯明明白白的公布。我仅在这里公布以下我用Delphi制作APIHook的一些心得。 
    通常的APIHOOK有这样几种方法: 
    1、自己写一个动态链接库,里面定义自己写的想取代系统的API。把这个动态链接库映射到2G以上的系统动态链接库所在空间,把系统动态链接库中的该API的指向修改指向自己的函数。这种方法的好处就是可以取代系统中运行全部程序的该API。但他有个局限,就是只适用于Win9x。(原因是NT中动态链接库不是共享的,每个进程都有自己的一份动态链接库在内存中的映射) 
    2、自己写一个动态链接库,里面定义自己写得象替代系统的API。把这个动态链接库映射到进程的空间里。将该进程对API的调用指向自己写的动态链接库。这种方法的好处是可以选择性的替代哪个进程的API。而且适用于所有的Windows*作系统。 
    这里我选用的是第二种方法。 
    第二种方法需要先了解一点PE文件格式的知识。 
    首先是一个实模式的的DOS文件头,是为了保持和DOS的兼容。 
    接着是一个DOS的代理模块。你在纯DOS先运行Win32的可执行文件,看看是不是也执行了,只是显示的的是一行信息大意是说该Windows程序不能在DOS实模式下运行。 
    然后才是真正意义上的Windows可执行文件的文件头。它的具体位置不是每次都固定的。是由文件偏移$3C决定的。我们要用到的就是它。 
    如果我们在程序中调用了一个MessageBoxA函数那么它的实现过程是这样的。他先调用在本进程中的MessageBoxA函数然后才跳到动态链接库的MessageBoxA的入口点。即: 
    call messageBoxA(0040106c) 
    jmp dword ptr [_jmp_MessageBoxA@16(00425294)] 
    其中00425294的内容存储的就是就是MessageBoxA函数的入口地址。如果我们做一下手脚,那么...... 
    那就开始吧! 
    我们需要定义两个结构 
    type 
    PImage_Import_Entry = ^Image_Import_Entry; 
    Image_Import_Entry = record 
    Characteristics: DWORD; 
    TimeDateStamp: DWORD; 
    MajorVersion: Word; 
    MinorVersion: Word; 
    Name: DWORD; 
    LookupTable: DWORD; 
    end; 
    type 
    TImportCode = packed record 
    JumpInstruction: Word; file: //定义跳转指令jmp 
    AddressOfPointerToFunction: ^Pointer; file: //定义要跳转到的函数 
    end; 
    PImportCode = ^TImportCode; 
    然后是确定函数的地址。 
    function LocateFunctionAddress(Code: Pointer): Pointer; 
    var 
    func: PImportCode; 
    begin 
    Result := Code; 
    if Code = nil then exit; 
    try 
    func := code; 
    if (func.JumpInstruction = $25FF) then 
    begin 
    Result := func.AddressOfPointerToFunction^; 
    end; 
    except 
    Result := nil; 
    end; 
    end; 
    参数Code是函数在进程中的指针,即那条Jmp XXX的指令。$25FF就是跳转指令的机器码。 
    再下一篇我会讲如何替换下那个XXX的内容,让他跳到你想去的地方。
      

  14.   

    浅谈API HOOK技术(二)
    ) 
    在这里我将要实现转跳。有人说修改内存内容要进入Ring 0 才可以。可是Windows本身提供了一个写内存的指令WriteProcessMemory。有了这把利器,我们几乎无所不能。如游戏的修改等在这里我们只谈APIHOOK。 
    function RepointFunction(OldFunc, NewFunc: Pointer): Integer; 
    var 
    IsDone: TList; 
    function RepointAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer; 
    var 
    Dos: PImageDosHeader; 
    NT: PImageNTHeaders; 
    ImportDesc: PImage_Import_Entry; 
    RVA: DWORD; 
    Func: ^Pointer; 
    DLL: string; 
    f: Pointer; 
    written: DWORD; 
    begin 
    Result := 0; 
    Dos := Pointer(hModule); 
    if IsDone.IndexOf(Dos) >= 0 then exit; 
    IsDone.Add(Dos); OldFunc := LocateFunctionAddress(OldFunc); if IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then exit; 
    if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit; 
    NT := Pointer(Integer(Dos) + dos._lfanew); RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] 
    .VirtualAddress; if RVA = 0 then exit; 
    ImportDesc := pointer(integer(Dos) + RVA); 
    while (ImportDesc^.Name <> 0) do 
    begin 
    DLL := PChar(Integer(Dos) + ImportDesc^.Name); 
    RepointAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc); 
    Func := Pointer(Integer(DOS) + ImportDesc.LookupTable); 
    while Func^ <> nil do 
    begin 
    f := LocateFunctionAddress(Func^); 
    if f = OldFunc then 
    begin 
    WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written); 
    if Written > 0 then Inc(Result); 
    end; 
    Inc(Func); 
    end; 
    Inc(ImportDesc); 
    end; 
    end; begin 
    IsDone := TList.Create; 
    try 
    Result := RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc); 
    finally 
    IsDone.Free; 
    end; 
    end; 
    有了这两个函数我们几乎可以更改任何API函数。 
    我们可以先写一个DLL文件。我这里以修改Text相关函数为例: 
    先定义几个函数: 
    type 
    TTextOutA = function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall; 
    TTextOutW = function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall; 
    TTextOut = function(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall; 
    TDrawTextA = function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall; 
    TDrawTextW = function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall; 
    TDrawText = function(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall; 
    var 
    OldTextOutA: TTextOutA; 
    OldTextOutW: TTextOutW; 
    OldTextOut: TTextOut; 
    OldDrawTextA: TDrawTextA; 
    OldDrawTextW: TDrawTextW; 
    OldDrawText: TDrawText; 
    ...... 
    function MyTextOutA(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall; 
    begin 
    OldTextOutA(DC, X, Y, 'ABC', length('ABC')); 
    end; function MyTextOutW(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall; 
    begin 
    OldTextOutW(DC, X, Y, 'ABC', length('ABC')); 
    end; function MyTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall; 
    begin 
    OldTextOut(DC, X, Y, 'ABC', length('ABC')); 
    end; function MyDrawTextA(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall; 
    begin 
    OldDrawTextA(hDC, 'ABC', length('ABC'), lpRect, uFormat); 
    end; function MyDrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall; 
    begin 
    OldDrawTextW(hDC, 'ABC', length('ABC'), lpRect, uFormat); 
    end; function MyDrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall; 
    begin 
    OldDrawText(hDC, 'ABC', length('ABC'), lpRect, uFormat); 
    end; 调用时我们要把原来的函数地址保存下来: 
    if @OldTextOutA = nil then 
    @OldTextOutA := LocateFunctionAddress(@TextOutA); 
    if @OldTextOutW = nil then 
    @OldTextOutW := LocateFunctionAddress(@TextOutW); 
    if @OldTextOut = nil then 
    @OldTextOut := LocateFunctionAddress(@TextOut); 
    if @OldDrawTextA = nil then 
    @OldDrawTextA := LocateFunctionAddress(@DrawTextA); 
    if @OldDrawTextW = nil then 
    @OldDrawTextW := LocateFunctionAddress(@DrawTextW); 
    if @OldDrawText = nil then 
    @OldDrawText := LocateFunctionAddress(@DrawText); 
    然后很顺其自然的用自己的函数替换掉原来的函数 
    RepointFunction(@OldTextOutA, @MyTextOutA); 
    RepointFunction(@OldTextOutW, @MyTextOutW); 
    RepointFunction(@OldTextOut, @MyTextOut); 
    RepointFunction(@OldDrawTextA, @MyDrawTextA); 
    RepointFunction(@OldDrawTextW, @MyDrawTextW); 
    RepointFunction(@OldDrawText, @MyDrawText); 
    在结束时不要忘记恢复原来函数的入口,要不然你会死得很难看哟!好了我们在写一个Demo程序。你会说怎么文字没有变成ABC呀?是呀,你要刷新一下才行。最小化然后在最大化。看看变了没有。 
    要不然你就写代码刷新一下好了。至于去拦截其他进程的API那就用SetWindowsHookEx写一个其他的钩子将DLL映射进去就行了,我就不再浪费口水了。 
    掌握了该方法你几乎无所不能。你可以修改其它程序。你可以拦截Createwindow等窗口函数改变其他程序的窗口形状、你还可以入侵其它的程序,你还可以......嘿嘿。干了坏事别招出我来就行了。 
    我还写了个例子,请在CSDN上下载。 
      

  15.   

    他这个例子也是只能HOOK本进程的api。
    “至于去拦截其他进程的API那就用SetWindowsHookEx写一个其他的钩子将DLL映射进去就行了,我就不再浪费口水了”
    如他所说,我想做的就是如何将钩子dll映射到当前的所有进程的地址空间中,应该如何实现?谢谢nevergrief(孤独骑士),再想想办法,等问题解决了单独开帖子给你分,谢谢!
      

  16.   

    I have built "hijack" example before,it can hook all process.have you read already?
      

  17.   

    我来csdn是为了学习,不是要分,兄弟不要来这套客套话。我不懂API HOOK,正想学习学习,看看这个,我觉得好像是全局的。
    http://www.csdn.net/develop/article/12/12283.shtm另外,不知您是否对打印有研究?小弟正着急呢,帮忙看看:
    http://www.vckbase.com/bbs2/viewtopic2.asp?id=85982
      

  18.   

    /*-> ForceLib.hThis is a small header file to make the usage of ForceLibrary.dll easier
    with C/C++.
    Just include this file and you can start using the functions.  by yoda*/#ifndef __ForceLibraryHeader__
      #define __ForceLibraryHeader__// the dll prototypes
    typedef DWORD (WINAPI* fForceLibrary)(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
    typedef BOOL  (WINAPI* fTrapEntry)(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
    typedef BOOL  (WINAPI* fForceLibraryDBG)(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
    typedef DWORD (WINAPI* fPerformCleanup)(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);// functions
    BOOL  LoadFL();
    DWORD ForceLibrary(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
    BOOL  TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
    BOOL  ForceLibraryDBG(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
    DWORD PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);// constants
    const CHAR*   szDllName         = "ForceLibrary.dll";
    const PSTR    szFunctNameFL     = "ForceLibrary";
    const PSTR    szFunctNameTE     = "TrapEntry";
    const PSTR    szFunctNameFLDBG  = "ForceLibraryDBG";
    const PSTR    szFunctNamePC     = "PerformCleanup";const CHAR*   szError           = "ERROR";
    const DWORD   dwMsgFlags        = MB_ICONERROR | MB_TASKMODAL;
    const CHAR*   szDllNotFound     = "ForceLibrary.dll wasn't found !";
    const CHAR*   szGetProcError    = "Error during Dll initialization !";// variables
    fForceLibrary     _ForceLibrary;
    fTrapEntry        _TrapEntry;
    fForceLibraryDBG  _ForceLibraryDBG;
    fPerformCleanup   _PerformCleanup;HANDLE   hFL = 0;
    BOOL LoadFL()
    {
    hFL = LoadLibrary(szDllName);
    if (!hFL)
    {
    MessageBox(0,szDllNotFound,szError,dwMsgFlags);
    return FALSE;
    }
    _ForceLibrary = (fForceLibrary)GetProcAddress((HMODULE)hFL,szFunctNameFL);
    _TrapEntry = (fTrapEntry)GetProcAddress((HMODULE)hFL,szFunctNameTE);
    _ForceLibraryDBG = (fForceLibraryDBG)GetProcAddress((HMODULE)hFL,szFunctNameFLDBG);
    _PerformCleanup = (fPerformCleanup)GetProcAddress((HMODULE)hFL,szFunctNamePC); if (!_ForceLibrary ||
    !_TrapEntry ||
    !_ForceLibraryDBG || 
    !_PerformCleanup)
    {
    MessageBox(0,szGetProcError,szDllName,dwMsgFlags);
    return FALSE;
    }
    return TRUE;
    }
    BOOL TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
    {
    if (!hFL)
    if (!LoadFL())
    return FALSE;
    return _TrapEntry(dwEntryPoint,pPI);
    }BOOL  ForceLibraryDBG(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
    {
    if (!hFL)
    if (!LoadFL())
    return FALSE;
    return _ForceLibraryDBG(szTargetLib,dwEntryPoint,pPI);
    }DWORD PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
    {
    if (!hFL)
    if (!LoadFL())
    return 0;
    return _PerformCleanup(dwEntryPoint,pPI);
    }  #endif
      

  19.   

    //////
    /////                        -=[ ForceLibrary.dll ]=-
    ////                                by yoda/f2f
    ///                                version: 1.2
    //
    //     You are able to use *parts* of this source code in your own programs 
    //     if you mention my name.
    //     Please report any bugs/comments/suggestions to [email protected]
    //     Have fun.
    //#include <windows.h>
    #include <tlhelp32.h>
    #include <stddef.h>
    #include "th32.h"#pragma pack(1) // very important !// this code structs load the dll
    typedef struct
    {
        //BYTE  Int3;    
    BYTE  PushOpc;           // 0x68     = push (dword)
    DWORD PushAddr;          // address of dll name
    BYTE  CallOpc;           // 0xE8     = call (dword)
    DWORD CallAddr;          // address of LoadLibraryAPI
    WORD  jmp_$;             // 0xEBFE   = jmp eip
    char  LibPath[MAX_PATH]; // path of the dll to load
    } sLibLoadCode;typedef struct
    {
        //BYTE  Int3;    
    BYTE  PushOpc;           // 0x68     = push (dword)
    DWORD PushAddr;          // address of dll name
    BYTE  CallOpc;           // 0xE8     = call (dword)
    DWORD CallAddr;          // address of LoadLibraryAPI
    BYTE  RetOpc;            // 0xC2     = ret (word)
    WORD  RetValue;          // return number
    char  LibPath[MAX_PATH]; // path of the dll to load
    } sLibLoadCodeNT;typedef struct
    {
    BYTE  PushOpc;      // 0x68 = push (dword)
    DWORD PushAddr;     // address of dll name
    BYTE  CallOpc;      // 0xE8 = call (dword)
    DWORD CallAddr;     // address of LoadLibraryAPI
    BYTE  Int3;         // end of code
    char  LibPath[256]; // path of the dll to load
    } sLibLoadCodeDBG;typedef struct
    {
    DWORD  dwImageBase;
    DWORD  dwSizeOfImage;
    DWORD  dwEntryPointVA;
    } sProcessPEInfo;typedef DWORD (WINAPI* _CodeEntry)(PVOID);// the functions
    BOOL   InitCodeStruct(sLibLoadCode *LibLoaderCode,
    sLibLoadCodeNT *LibLoaderCodeNT,
    CHAR* szTargetLib,
    DWORD dwCodeStart);
    BOOL   InitCodeStructDBG(sLibLoadCodeDBG &LibLoaderCode,CHAR* szTargetLib,DWORD dwCodeStart);
    DWORD  GetProcessEntryPoint(DWORD PID);
    BOOL   ForceLibrary95(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
    BOOL   ForceLibraryNT(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo);
    extern "C" BOOL WINAPI TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
    extern "C" BOOL WINAPI ForceLibraryDBG(CHAR* szTargetLib,DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);
    extern "C" DWORD WINAPI PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI);// constants
    const DWORD                     LOADCODESIZEDBG   = sizeof(sLibLoadCodeDBG);
    const DWORD                     HEADER_SIZE       = 0x2000;
    const BYTE                      Int3              = 0xCC;// global variables
    sLibLoadCodeDBG           LibLoadCodeDBG;
    DWORD                     dwLibBase;
    DWORD                     dwCodeStart,dwCodeEnd,dwBytesWritten,dwBytesRead;
    CONTEXT                   TestRegs;VOID*                     pCodeEntry;
    DWORD                     dwOldProt,dwNewProt;
    CONTEXT                   Regs,InitRegs;
    BYTE                      bOrgEntry;DWORD ForceLibrary(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo)
    {
     DWORD dwWinVer = GetVersion();  // get the highest bit
     dwWinVer = dwWinVer >> 31; if (!dwWinVer)
     if (ForceLibraryNT(szLibraryPath,pProcInfo))
     return dwLibBase;
     else
     return 0;
    else
     if (ForceLibrary95(szLibraryPath,pProcInfo))
     return dwLibBase;
     else
     return 0;
    }BOOL InitCodeStruct(sLibLoadCode *LibLoaderCode,
    sLibLoadCodeNT *LibLoaderCodeNT,
    CHAR* szTargetLib,
    DWORD dwCodeStart)
    {
    DWORD dwLoadLibApiAddr; dwLoadLibApiAddr = (DWORD)GetProcAddress(
    GetModuleHandle("kernel32.dll"),
    "LoadLibraryA");
    if (!dwLoadLibApiAddr)
    return FALSE;

    if (LibLoaderCode)
    {
            //LibLoaderCode->Int3             = Int3;
    LibLoaderCode->PushOpc          = 0x68;
    LibLoaderCode->CallOpc          = 0xE8;
    LibLoaderCode->CallAddr         = dwLoadLibApiAddr - dwCodeStart - 
                                  offsetof(sLibLoadCode,jmp_$);
    strcpy(LibLoaderCode->LibPath,szTargetLib);
    LibLoaderCode->PushAddr         = dwCodeStart + offsetof(sLibLoadCode,LibPath);
    LibLoaderCode->jmp_$            = 0xFEEB;
    }
    else
    {
            //LibLoaderCodeNT->Int3           = Int3;
    LibLoaderCodeNT->PushOpc        = 0x68;
    LibLoaderCodeNT->CallOpc        = 0xE8;
    LibLoaderCodeNT->CallAddr       = dwLoadLibApiAddr - dwCodeStart - 
                                  offsetof(sLibLoadCodeNT, RetOpc);
    strcpy(LibLoaderCodeNT->LibPath,szTargetLib);
    LibLoaderCodeNT->PushAddr       = dwCodeStart + offsetof(sLibLoadCodeNT, LibPath);
    LibLoaderCodeNT->RetOpc         = 0xC2;
    LibLoaderCodeNT->RetValue       = 0x0004;
    }
    return TRUE;
    }BOOL InitCodeStructDBG(sLibLoadCodeDBG &LibLoaderCode,CHAR* szTargetLib,DWORD dwCodeStart)
    {
    DWORD dwLoadLibApiAddr; LibLoaderCode.Int3 = Int3;
    LibLoaderCode.PushOpc = 0x68;
    LibLoaderCode.CallOpc = 0xE8;
    dwLoadLibApiAddr = (DWORD)GetProcAddress(
    GetModuleHandle("kernel32.dll"),
    "LoadLibraryA");
    if (!dwLoadLibApiAddr)
    return FALSE;
    LibLoaderCode.CallAddr = dwLoadLibApiAddr - dwCodeStart - offsetof(sLibLoadCodeDBG,Int3);
    strcpy(LibLoaderCode.LibPath,szTargetLib);
    LibLoaderCode.PushAddr = dwCodeStart + offsetof(sLibLoadCodeDBG,LibPath);
    return TRUE;
    }// returns...
    // 0 - error
    DWORD GetProcessEntryPoint(DWORD PID)
    {
    HANDLE          hSnap;
    MODULEENTRY32   ModuleInfo;
    PROCESSENTRY32  ProcInfo;
    sProcessPEInfo  ProcPEInfo;
    CHAR            ProcPath[256];
    DWORD           dwMemSize,dwPEHeaderAddr;
    VOID*           pHeader;
    HANDLE          hProc; // get ToolHelp32 addresses
    if (!GetTh32())
    return FALSE; // I - get the process filename
    hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if (hSnap == INVALID_HANDLE_VALUE)
    return 0; // init the ProcInfo struct
    ZeroMemory(&ProcInfo,sizeof(ProcInfo));
    ProcInfo.dwSize = sizeof(ProcInfo); // find the to the PID corresponding file path
    _Process32First(hSnap,&ProcInfo);
    ProcPath[0] = 0;
    while (_Process32Next(hSnap,&ProcInfo))
    if (ProcInfo.th32ProcessID == PID)
    strcpy((LPTSTR)&ProcPath,ProcInfo.szExeFile);
    CloseHandle(hSnap);
    if (ProcPath[0] == 0)
    return 0; // II - find the ImageBase/SizeOfImage
    hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,PID);
    if (hSnap == INVALID_HANDLE_VALUE)
    return 0; // init the ModuleInfo and the ProcPEInfo struct
    ZeroMemory(&ModuleInfo,sizeof(ModuleInfo));
    ModuleInfo.dwSize = sizeof(ModuleInfo);
    ZeroMemory(&ProcPEInfo,sizeof(ProcPEInfo)); _Module32First(hSnap,&ModuleInfo);
    if (stricmp((LPCTSTR)&ModuleInfo.szExePath,(LPCTSTR)&ProcPath) == 0)
    {
    ProcPEInfo.dwImageBase = (DWORD)ModuleInfo.modBaseAddr;
    ProcPEInfo.dwSizeOfImage = ModuleInfo.modBaseSize;
    }
    while (_Module32Next(hSnap,&ModuleInfo))
    {
    if (stricmp((LPCTSTR)&ModuleInfo.szExePath,(LPCTSTR)&ProcPath) == 0)
    {
    ProcPEInfo.dwImageBase = (DWORD)ModuleInfo.modBaseAddr;
    ProcPEInfo.dwSizeOfImage = ModuleInfo.modBaseSize;
    }
    }
      

  20.   

    CloseHandle(hSnap);
    if (ProcPEInfo.dwImageBase == 0)
    return 0; // get the EntryPoint
    if (ProcPEInfo.dwSizeOfImage < HEADER_SIZE)
    dwMemSize = ProcPEInfo.dwSizeOfImage;
    else
    dwMemSize = HEADER_SIZE;
    if (!(hProc = OpenProcess(PROCESS_VM_READ,FALSE,PID)))
    return 0;
    if (!(pHeader = GlobalAlloc(GMEM_FIXED,dwMemSize)))
    return 0;
    if (!ReadProcessMemory(
    hProc,
    (PVOID)ProcPEInfo.dwImageBase,
    pHeader,
    dwMemSize,
    &dwBytesRead))
    {
    GlobalFree(pHeader);
    return 0;
    }
    if (((PIMAGE_DOS_HEADER)pHeader)->e_magic != IMAGE_DOS_SIGNATURE)
    {
    GlobalFree(pHeader);
    return 0;
    }
    dwPEHeaderAddr = ((PIMAGE_DOS_HEADER)pHeader)->e_lfanew;
    if (((PIMAGE_NT_HEADERS)(dwPEHeaderAddr + (DWORD)pHeader))->Signature !=
    IMAGE_NT_SIGNATURE)
    {
    GlobalFree(pHeader);
    return 0;
    }
    ProcPEInfo.dwEntryPointVA = ((PIMAGE_NT_HEADERS)(dwPEHeaderAddr + (DWORD)pHeader))->OptionalHeader \
    .AddressOfEntryPoint + ProcPEInfo.dwImageBase;
    GlobalFree(pHeader);
    return ProcPEInfo.dwEntryPointVA;
    }BOOL ForceLibrary95(char* szLibraryPath, PROCESS_INFORMATION* pProcInfo)
    {
    DWORD            dwEntryPoint,dwEWRProt;
    sLibLoadCode     LibLoadCode; InitRegs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
    if (!GetThreadContext(pProcInfo->hThread,&InitRegs))
    return FALSE;
    if (!(dwEntryPoint = GetProcessEntryPoint(pProcInfo->dwProcessId)))
    return FALSE; // init the LibLoadCode struct
    if (!InitCodeStruct(&LibLoadCode, NULL, szLibraryPath, dwEntryPoint))
    return FALSE; // save the code at the EntryPoint
    pCodeEntry = GlobalAlloc(GMEM_FIXED, sizeof(LibLoadCode));
    if (!pCodeEntry)
    return FALSE;
    VirtualProtectEx(
    pProcInfo->hProcess,
    (VOID*)dwEntryPoint,
    sizeof(LibLoadCode),
    PAGE_EXECUTE_READWRITE,
    &dwOldProt);
    if (!ReadProcessMemory(
    pProcInfo->hProcess,
    (VOID*)dwEntryPoint,
    pCodeEntry,
    sizeof(LibLoadCode),
    &dwBytesRead))
    {
    GlobalFree(pCodeEntry);
    return FALSE;
    }

    // write the loader code to the EntryPoint
    if (!WriteProcessMemory(
    pProcInfo->hProcess,
    (VOID*)dwEntryPoint,
    &LibLoadCode,
    sizeof(LibLoadCode),
    &dwBytesWritten))
    {
    GlobalFree(pCodeEntry);
    return FALSE;
    } // execute the copied code
    Regs = InitRegs;
    Regs.Eip = dwEntryPoint;
    ResumeThread(pProcInfo->hThread); // wait until the thread finishes
    dwCodeEnd = dwEntryPoint + offsetof(sLibLoadCode,jmp_$);
    TestRegs.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
    do
    {
    Sleep(50);
    GetThreadContext(pProcInfo->hThread,&TestRegs);
    } while (TestRegs.Eip != dwCodeEnd);
    dwLibBase = TestRegs.Eax; // suspend the thread and restore all !
    SuspendThread(pProcInfo->hThread);
    if (!WriteProcessMemory(
    pProcInfo->hProcess,
    (VOID*)dwEntryPoint,
    pCodeEntry,
    sizeof(LibLoadCode),
    &dwBytesWritten))
    {
    GlobalFree(pCodeEntry);
    return FALSE;
    }
    GlobalFree(pCodeEntry);
    VirtualProtectEx(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    sizeof(LibLoadCode),
    dwOldProt,
    &dwEWRProt);
    InitRegs.Eip = dwEntryPoint;
    if (!SetThreadContext(pProcInfo->hThread,&InitRegs))
    return FALSE;
    return TRUE;
    }BOOL ForceLibraryNT(CHAR* szLibraryPath,PROCESS_INFORMATION* pProcInfo)
    {
    sLibLoadCodeNT  LibLoadCode;
    DWORD           dwRemoteThreadID;
    HANDLE          hRemoteThread;
    _CodeEntry      CodeEntry;    
    // import NT only stuff manually
    HMODULE kernel = GetModuleHandle("kernel32.dll"); typedef LPVOID (WINAPI*VirtualAllocExFunc)(
    HANDLE hProcess,          // process to allocate memory
    LPVOID lpAddress,         // desired starting address 
    SIZE_T dwSize,            // size of region to allocate
    DWORD flAllocationType,   // type of allocation
    DWORD flProtect           // type of access protection
    );
    VirtualAllocExFunc VirtualAllocExPtr = (VirtualAllocExFunc)GetProcAddress(kernel,"VirtualAllocEx"); typedef BOOL (WINAPI*VirtualFreeExFunc)(
    HANDLE hProcess,   // handle to process
    LPVOID lpAddress,  // starting address of memory region
    SIZE_T dwSize,     // size of memory region
    DWORD dwFreeType   // operation type
    );
    VirtualFreeExFunc VirtualFreeExPtr = (VirtualFreeExFunc)GetProcAddress(kernel,"VirtualFreeEx"); if(!VirtualFreeExPtr || !VirtualAllocExPtr)
    {
    MessageBox(0,"couldnt import virtualallocex",0,0);
    ExitProcess(1);
    } // get some mem in the target's process memory
    dwCodeStart = (DWORD)VirtualAllocExPtr(
    pProcInfo->hProcess,
    NULL,
    sizeof(LibLoadCode),
    MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);
    if (!dwCodeStart)
    return FALSE; // init the LibLoadCode struct
    if (!InitCodeStruct(0, &LibLoadCode, szLibraryPath, dwCodeStart))
    {
    VirtualFreeExPtr(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    sizeof(LibLoadCode),
    MEM_DECOMMIT);
    return FALSE;
    } // copy the code into the allocated mem
    if (!WriteProcessMemory(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    &LibLoadCode,
    sizeof(LibLoadCode),
    &dwBytesWritten))
    {
    VirtualFreeExPtr(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    sizeof(LibLoadCode),
    MEM_DECOMMIT);
    return FALSE;
    } // execute it
    CodeEntry = (_CodeEntry)dwCodeStart;
    if (!(hRemoteThread = CreateRemoteThread(
    pProcInfo->hProcess,
    NULL,
    0,
    CodeEntry,
    NULL,
    0,
    &dwRemoteThreadID)))
    {
    VirtualFreeExPtr(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    sizeof(LibLoadCode),
    MEM_DECOMMIT);
    return FALSE;
    }
      

  21.   

    // wait until the thread finishes
    WaitForSingleObject(hRemoteThread, INFINITE);
    if (!GetExitCodeThread(hRemoteThread, &dwLibBase))
    {
    VirtualFreeExPtr(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    sizeof(LibLoadCode),
    MEM_DECOMMIT);
    return FALSE;
    } // clean up
    VirtualFreeExPtr(
    pProcInfo->hProcess,
    (VOID*)dwCodeStart,
    sizeof(LibLoadCode),
    MEM_DECOMMIT);
    CloseHandle(hRemoteThread); if (dwLibBase)
    return TRUE;
    else
    return FALSE;
    }extern "C" BOOL WINAPI TrapEntry(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
    {
    // simply set a 0CCh at the EntryPoint
    VirtualProtectEx(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    1,
    PAGE_EXECUTE_READWRITE,
    &dwOldProt);
    if (!ReadProcessMemory(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    (VOID*)&bOrgEntry,
    1,
    &dwBytesRead))
    return FALSE;
    if (!WriteProcessMemory(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    (VOID*)&Int3,
    1,
    &dwBytesWritten))
    return FALSE;
    VirtualProtectEx(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    1,
    dwOldProt,
    &dwNewProt);
    return TRUE;
    }extern "C" BOOL WINAPI ForceLibraryDBG(CHAR* szTargetLib,
       DWORD dwEntryPoint,
       PROCESS_INFORMATION *pPI)
    {
    // save the regs
    Regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
    if (!GetThreadContext(pPI->hThread,&Regs))
    return FALSE;
    Regs.Eip = dwEntryPoint;
    InitRegs = Regs; // init the LibLoadCodeDBG struct
    if (!InitCodeStructDBG(LibLoadCodeDBG,szTargetLib,dwEntryPoint))
    return FALSE; VirtualProtectEx(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    LOADCODESIZEDBG,
    PAGE_EXECUTE_READWRITE,
    &dwOldProt); // restore the EntryPoint-byte
    if (!WriteProcessMemory(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    &bOrgEntry,
    1,
    &dwBytesWritten))
    return FALSE; // save the code at the EntryPoint
    pCodeEntry = GlobalAlloc(GMEM_FIXED,LOADCODESIZEDBG);
    if (!pCodeEntry)
    return FALSE;
    if (!ReadProcessMemory(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    pCodeEntry,
    LOADCODESIZEDBG,
    &dwBytesRead))
    {
    GlobalFree(pCodeEntry);
    return FALSE;
    }

    // write the loader code to the EntryPoint and restore protection of the code page
    if (!WriteProcessMemory(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    &LibLoadCodeDBG,
    LOADCODESIZEDBG,
    &dwBytesWritten))
    {
    GlobalFree(pCodeEntry);
    return FALSE;
    } // prepare the execution of the copied code
    SetThreadContext(pPI->hThread,&Regs);
    return TRUE;
    }extern "C" DWORD WINAPI PerformCleanup(DWORD dwEntryPoint,PROCESS_INFORMATION *pPI)
    {
    // grab the result of the "LoadLibraryA" call
    GetThreadContext(pPI->hThread,&Regs);
    dwLibBase = Regs.Eax; // restore all !
    if (!WriteProcessMemory(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    pCodeEntry,
    LOADCODESIZEDBG,
    &dwBytesWritten))
    {
    GlobalFree(pCodeEntry);
    return 0;
    }
    GlobalFree(pCodeEntry);
    VirtualProtectEx(
    pPI->hProcess,
    (VOID*)dwEntryPoint,
    LOADCODESIZEDBG,
    dwOldProt,
    &dwNewProt);
    if (!SetThreadContext(pPI->hThread,&InitRegs))
    return 0;
    return dwLibBase;
    }
      

  22.   

    #ifndef __TH32_h__
    #define __TH32_h__#include <windows.h>
    #include <tlhelp32.h>// ToolHelp32 function prototypes
    typedef HANDLE (WINAPI* fCreateToolhelp32Snapshot)
    (
      DWORD dwFlags,       
      DWORD th32ProcessID  
    );typedef BOOL (WINAPI* fProcess32First)
    (
      HANDLE hSnapshot,      
      LPPROCESSENTRY32 lppe  
    );
     
    typedef BOOL (WINAPI* fProcess32Next)
    (
      HANDLE hSnapshot,      
      LPPROCESSENTRY32 lppe  
    );typedef BOOL (WINAPI* fModule32First)
    (
      HANDLE hSnapshot,     
      LPMODULEENTRY32 lpme  
    );
     
    typedef BOOL (WINAPI* fModule32Next)
    (
      HANDLE hSnapshot,     
      LPMODULEENTRY32 lpme  
    );extern fCreateToolhelp32Snapshot    _CreateToolhelp32Snapshot;
    extern fProcess32First              _Process32First;
    extern fProcess32Next               _Process32Next;
    extern fModule32First               _Module32First;
    extern fModule32Next                _Module32Next;BOOL GetTh32();#endif
    //anotherfile//
    // TH32.c: loads dynamically the ToolHelp32 API's because they
    //         aren't available on NT4 ! Much thanks goes to ELiCZ
    //         for putting my attention on that fact.
    //#include "th32.h"
    #pragma pack(1) // very important !// global variables
    fCreateToolhelp32Snapshot    _CreateToolhelp32Snapshot;
    fProcess32First              _Process32First;
    fProcess32Next               _Process32Next;
    fModule32First               _Module32First;
    fModule32Next                _Module32Next;BOOL GetTh32()
    {
    HINSTANCE hKrnl; // get kernel32 base
    hKrnl = LoadLibrary("Kernel32.dll");
    if (!hKrnl)
    return FALSE; // get th32 addresses
    _CreateToolhelp32Snapshot = (fCreateToolhelp32Snapshot)GetProcAddress(
    hKrnl, "CreateToolhelp32Snapshot");
    _Process32First = (fProcess32First)GetProcAddress(hKrnl, "Process32First");
    _Process32Next = (fProcess32Next)GetProcAddress(hKrnl, "Process32Next");
    _Module32First = (fModule32First)GetProcAddress(hKrnl, "Module32First");
    _Module32Next  = (fModule32Next)GetProcAddress(hKrnl, "Module32Next"); if (!_CreateToolhelp32Snapshot ||
    !_Process32First ||
    !_Process32Next ||
    !_Module32First ||
    !_Module32Next)
    return FALSE;

    return TRUE;
    }
      

  23.   

    #include <windows.h>
    #include "stdio.h"
    #include "ForceLib.h"#pragma pack(1) // very important !HINSTANCE mainInstance;bool fileExists(const char* filename)
    {
    WIN32_FIND_DATA finddata;
    HANDLE handle = FindFirstFile(filename,&finddata);
    return (handle!=INVALID_HANDLE_VALUE);
    }//#define OGC_DEBUG
    #undef OGC_DEBUG//==============================================================================
    bool promptForFile( char* retFile, const char* tip, char* filter, char* title, bool save, HWND hWnd )
    {
                  OPENFILENAME ofn;
                  memset(&ofn, 0, sizeof(OPENFILENAME));
                  ofn.lStructSize = sizeof(OPENFILENAME);
                  ofn.hwndOwner = hWnd;
                  ofn.hInstance = mainInstance;
                  ofn.nFilterIndex = 1;
                  ofn.lpstrFile = retFile;
                  ofn.nMaxFile = 256;
                  ofn.lpstrInitialDir = tip;
                  //====
                  ofn.lpstrFilter = filter;
                  ofn.lpstrTitle  = title;              strcpy( retFile, tip );              bool status;
                  if( save )
                  {
                      ofn.Flags = OFN_OVERWRITEPROMPT;
                      status =  (GetSaveFileName(&ofn)!=0);
                  } else
                  {
                      ofn.Flags = OFN_FILEMUSTEXIST;
                      status = (GetOpenFileName(&ofn)!=0);
                  }
                  return status;
    }STARTUPINFO          SI;
    PROCESS_INFORMATION  PI;//==================================================================================
    bool isApplogAlreadyDisabled()
    {
    HKEY  l_hKey;
        DWORD l_UseProfile;
        DWORD l_dwBufLen = 4;    DWORD l_ret = RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    "Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Defrag\\AppStartParams",
    0,KEY_QUERY_VALUE, &l_hKey);
    if(l_ret!=ERROR_SUCCESS) { RegCloseKey(l_hKey); return false; } l_ret = RegQueryValueEx(l_hKey,"UseProfile",NULL,NULL,(LPBYTE)&l_UseProfile,&l_dwBufLen);
    if(l_ret!=ERROR_SUCCESS) { RegCloseKey(l_hKey); return false; } RegCloseKey(l_hKey);
    return (l_UseProfile==0);
    }//==================================================================================
    bool isOnWindowsDrive(char* file)
    {
    // check for windows drive = hl drive
    char windir[400];
    GetWindowsDirectory(windir,390);
    if( file[1]==':' && windir[1]==':' && tolower(file[0])==tolower(windir[0]) ) return true;
    else return false;
    }//==================================================================================
    void unHideApplog()
    {
    char applogdir[400];
    GetWindowsDirectory(applogdir,390);
    strcat(applogdir,"\\Applog");
    SetFileAttributes( applogdir, FILE_ATTRIBUTE_NORMAL );
    }////==================================================================================
    //void ErrorExit(char* text)
    //{
    // MessageBox(0,text,0,0);
    // ExitProcess(1);
    //}
    //
    ////==================================================================================
    //void disableApplog()
    //{
    //    HKEY hk; 
    // 
    //    if (RegCreateKey(
    //     HKEY_LOCAL_MACHINE, 
    //            "Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Defrag\\AppStartParams",&hk
    // ) != ERROR_SUCCESS )
    // {
    // ErrorExit("Registry access error. 1");
    // }
    //
    // DWORD NewValue = 0;
    // if (RegSetValueEx(hk,"UseProfile",0,REG_DWORD,(BYTE*)&NewValue,4) != ERROR_SUCCESS)
    // {
    // ErrorExit("Registry access error. 2");
    // }
    //}////==================================================================================
    //void cleanupApplog()
    //{
    // WIN32_FIND_DATA findData;
    // HANDLE hFindFile;
    // char* fileName = findData.cFileName;
    //
    // char searchPattern[400];
    // GetWindowsDirectory(searchPattern,390);
    // strcat(searchPattern,"\\Applog\\*.*");
    //
    // hFindFile = FindFirstFile( searchPattern, &findData );
    // if( hFindFile == INVALID_HANDLE_VALUE){ return; }
    // do{
    // if(strcmp(fileName,".") && strcmp(fileName,".."))
    // {
    // char fullname[400];
    // strcpy(fullname,searchPattern);
    // strcpy(fullname + strlen(fullname)-3,fileName);
    // DeleteFile(fullname);
    // }
    // } while( FindNextFile(hFindFile,&findData) );
    //}////==================================================================================
    void applogFix()
    {
    // check for NT
    bool IsNT = ((HIWORD(::GetVersion()) & 0x8000) == 0); 
    #ifdef OGC_DEBUG
    IsNT = false;
    #endif
    if(IsNT) return; // make it easier for users to find applog
    unHideApplog();//    if(!isApplogAlreadyDisabled())
    // {
    // DWORD ret = MessageBox( 0,
    // "OGC Hook has detected that you are running\n"
    // "Windows 98 or Windows ME, and have Half-Life installed\n"
    // "on the same drive as your Operating System.\n"
    // "In order to avoid server side detection by scanning\n"
    // "for applog files, OGC Hook can disable the Applog Feature.\n"
    // "\nDo you want to disable Applog? (required)"
    // ,
    // "[OGC] Applog Disabling",
    // MB_YESNO|MB_ICONQUESTION
    // );
    // if( ret != IDYES  )
    // {
    // MessageBox(0,
    // "You've chosen to leave Applog enabled.\n"
    // "If you want to uninstall OGC Hook, you \n"
    // "might want to browse to your WINDOWS\\Applog\n"
    // "folder and delete OGC related files manually\n\n"
    // "OGC Hook will now quit!\n"
    // , "[OGC] Info", MB_OK );
    // ExitProcess(0);
    // }
    //
    // // deleting a few files can take ages in win9x. inform the user.
    // MessageBox(0,"OGC Hook will now disable Applog"
    // " file creation,\nand cleanup the WINDOWS\\Applog folder\n"
    // "This may take some time"     , "[OGC] Info",MB_OK);
    //
    // disableApplog();
    // cleanupApplog();
    //
    // MessageBox(0,"OGC Hook is done with Applog \n"
    // "cleanup. Half-Life will now be startetd.",
    // "[OGC] Info",MB_OK);
    // }
    // else
    // {
    // cleanupApplog();
    // }
    }//==================================================================================
      

  24.   

    void removeTrailingCRLF(char* a)
    {
    while(a[strlen(a)-1]=='\x0D' || a[strlen(a)-1]=='\x0A' ) a[strlen(a)-1]=0;
    }
    //==================================================================================
    int WINAPI WinMain(HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       LPSTR lpCmdLine,
       int nShowCmd)
    {
    mainInstance = hInstance; // setup 
    char hookEXE  [400] = ""; // "c:\\program files\\ogc hook\\notepad.exe"
    char hookDLL  [400] = ""; // "c:\\program files\\ogc hook\\notepad.dll"
    char hookINI  [400] = ""; // "c:\\program files\\ogc hook\\notepad.ini"
    char hlCmdLine[400] = "";
    char hlEXE    [400] = "";

    GetModuleFileName(0,hookEXE,390); 
    int  len = strlen(hookEXE);
    strcpy(hookDLL,hookEXE); 
    strcpy(hookINI,hookEXE); 
    hookDLL[len-3]='d';hookDLL[len-2]='l';hookDLL[len-1]='l';
    hookINI[len-3]='i';hookINI[len-2]='n';hookINI[len-1]='i'; // file check
    #ifndef OGC_DEBUG
    if( !fileExists(hookDLL) ) {
    MessageBox(0,hookDLL,"DLL NOT FOUND",MB_ICONERROR|MB_TOPMOST);
    return 1;
    }
    #endif // try to get hl path out of the ini
    bool success = false;
    do{
    FILE* file = fopen(hookINI,"r");
    if(file)
    {
    fgets(hlEXE    ,390,file);hlEXE[398]=0;     removeTrailingCRLF(hlEXE);
    fclose(file);
    } if(!fileExists(hlEXE))
    {
    MessageBox(0,"Please point me to your HL/CS executable,\nhl.exe or cstrike.exe","[OGC] Request",MB_ICONEXCLAMATION);
    bool ok = promptForFile( hlEXE, "c:\\sierra\\half-life\\hl.exe",
    "hl.exe or cstrike.exe\0hl.exe;cstrike.exe\0",
    "Show me your HL/CS Directory", false, 0);
    if(!ok) { return 0; }

    file = fopen(hookINI,"w");
    if(file)
    {
    fprintf(file,"%s\x0D\x0A",hlEXE);
    fclose(file);
    } else {
    MessageBox(0,hookINI,"write error",0); 
    break;
    }
    if(fileExists(hlEXE)) success = true;
    }
    else
    {
    success = true;
    } } while(!success); if( !strcmpi(hlEXE,hookEXE) )
    {
    MessageBox(0,"cannot start myself","Error",MB_ICONEXCLAMATION);
    DeleteFile(hookINI);
    return 1;
    } // disable applog for win9x
    #ifndef OGC_DEBUG
    if( isOnWindowsDrive(hlEXE) ) applogFix();
    #else
    applogFix();
    #endif

    // command line
    if(!strstr(lpCmdLine,"-game")) strcpy(hlCmdLine," -game cstrike ");
    strcat(hlCmdLine,lpCmdLine); // start the shit !
    ZeroMemory(&SI,sizeof(STARTUPINFO));
    ZeroMemory(&PI,sizeof(PROCESS_INFORMATION));
    SI.cb = sizeof(STARTUPINFO); // set the right directory:
    char hlDir[400];
    strcpy(hlDir,hlEXE);
    char* pos = hlDir+strlen(hlDir);
    while(pos>=hlDir && *pos!='\\') --pos;
    *pos = 0;
    char* hlBaseFileName = pos+1;
    SetCurrentDirectory(hlDir);

    if (!CreateProcess(hlBaseFileName,hlCmdLine,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&SI,&PI))
    {
    MessageBox(0,"Cannot create the Halflife Process!","[OGC] Error",MB_ICONERROR|MB_TOPMOST);
    return -1;
    }

    // call the dll function
    if (!ForceLibrary(hookDLL,&PI))
    {
    MessageBox(0,"Injection failed.","[OGC] Error",MB_ICONERROR|MB_TOPMOST);
    TerminateProcess(PI.hProcess,-1);
    return -1;
    } // let the main thread run
    ResumeThread(PI.hThread);
    // WaitForSingleObject(PI.hProcess,INFINITE); // clean up
    CloseHandle(PI.hProcess);
    CloseHandle(PI.hThread);
    return 0;
    }
    这个例子是把dll,inject 到某个进程中去的功能希望能有帮助,对了这个是cs的做弊器,各位不会不知道吧。
      

  25.   

    各位,不要在帖子上贴源码了,请直接把整个工程上传到
    ftp://pub:[email protected]
    好吗?同时加上几句简单的程序使用说明,谢谢!
      

  26.   

    nevergrief(孤独骑士) :
    呵呵,只是表示一下感激之情,还有你的热情:) 绝对没有别的意思!kingzai() :
    我也试过这个例子,可是我调试的时候确跳不到MyExtTextOutW函数中,而用softice加断点则能够在有程序调用ExtTextOutW时跳出:(
    请指点!
      

  27.   

    nevergrief(孤独骑士):
    真不好意思,我没做过打印:(
      

  28.   

    <marquee> HOHO,祝大家学习使用API Hook愉快!!!</marquee>
      

  29.   

    麻烦你老兄把能够使用的例子上传到我的ftp上去,好不好?这样大家都可以下载使用,谢谢了!!!
      

  30.   

    我好像知道原因了,用上面所说的几种方法都可以实现api hook,但是如果想做到全局hook就需要把我们的hook dll注入到系统的每个进程中,这样就能够hook所有的api了。同时需要监视新建的进程,建立新进程后就立刻将dll注入到新进程中,这样就ok了。
    我认为理论上是这样的,等我试试先:)
      

  31.   

    发言的人已经很多了,下面这两个例子非常,
    你可以参考,对你有用:
    http://www.codeproject.com/useritems/syswidehook9x.asp
    http://www.codeproject.com/system/hooksys.asp
      

  32.   

    简单来说,全局钩子程序必须是dll,这样可以对系统完成“注入”这样其他程序通过系统来调用时就是你的进程了,而不是原来的进程。
      

  33.   

    同样.请大家看看这篇文档
    http://www.csdn.net/develop/Read_Article.asp?Id=15119
    要hook其他进程,注入dll是必须的了..那么该采用哪种方法呢???
    是全局hook 还是 远程线程呢...
    就像上面的那篇文章..
    是用全局hook 动态连接库作的dll.但在win2k中,我还是无法hook其他进程..
    那么到底是什么原因呢????