<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      Windows 2000下Api函數的攔截區分

      [摘要]簡介:   Api攔截并不是一個新的技術,很多商業軟件都采用這種技術。對windows的Api函數的攔截,不外乎兩種方法,第一種是Mr. Jeffrey Richter 的修改exe文件的模塊輸入節,種方法,很安全,但很復雜,而且有些exe文件,沒有Dll的輸入符號的列表,有可能出現攔截不到的情況...
      簡介:

        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;



      日韩精品一区二区三区高清