攔截API(修改函數地址方法)

來源:互聯網
上載者:User

#include <windows.h>
#include <stdio.h>
#include <stddef.h>
#include <atlbase.h>
#include <ImageHlp.h>
#pragma comment(lib, "ImageHlp.lib")

#define HookExceptionNo 5

BOOL Init();

BOOL SysVer = true;
HMODULE g_hModule;
DWORD dwIdOld, dwIdNew;
//###############################################################
/* begin 這是攔截API所需要的代碼*/
typedef struct
{
    FARPROC funcaddr;
    BYTE    olddata[5];
    BYTE    newdata[5];
}HOOKSTRUCT;
HOOKSTRUCT MessageA_API;

void Ring0WriteMemory(void *dst, void *src, int copySize)
{
    BYTE IDTR_1[6];
    DWORD OldExceptionHook;
    __asm
    {
        JMP __Continue
   
        Ring0Proc:

        PUSHAD
       
        MOV AX,30h     // 定義一個系統層級的資料區段選擇子
       
        MOV BX,DS      // 儲存原DS與ES
        MOV DX,ES
       
        MOV DS,AX      // 修改DS與ES
        MOV ES,AX
       
        REP MOVSB      // 插入指令
       
        MOV DS,BX      // 複原DS與ES
        MOV ES,DX

        POPAD
       
        IRETD          //返回
   
        __Continue:
       
       
        SIDT FWORD PTR IDTR_1                    // 修改中斷門
        MOV EAX,DWORD PTR IDTR_1+02h
        ADD EAX,HookExceptionNo*08h+04h
        CLI
       
       
        MOV ECX,DWORD PTR [EAX]                  // 儲存原異常處理常式入口
        MOV CX,WORD PTR [EAX-04h]
        MOV OldExceptionHook,ECX
       
        LEA EBX,Ring0Proc                        // 指定新入口 
        MOV WORD PTR [EAX-04h],BX
        SHR EBX,10h
        MOV WORD PTR[EAX+02h],BX
       
        PUSHAD                                   // 配置參數
        MOV EDI,dst
        MOV ESI,src
        MOV ECX,copySize
       
        INT HookExceptionNo                      // 啟用Ring0代碼
        POPAD
       
        MOV ECX,OldExceptionHook                 // 複原入口
        MOV WORD PTR[EAX-04h],CX
        SHR ECX,10h
        MOV WORD PTR[EAX+02h],CX
       
        STI
    }    
}

 void HookOnOne(HOOKSTRUCT *hookfunc)
{
 if(SysVer)
 {
  HANDLE hProc;
  dwIdOld = dwIdNew;
  hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwIdOld);
  VirtualProtectEx(hProc, hookfunc->funcaddr, 5, PAGE_READWRITE,&dwIdOld);
  WriteProcessMemory(hProc, hookfunc->funcaddr, hookfunc->newdata, 5, 0);
  VirtualProtectEx(hProc, hookfunc->funcaddr, 5, dwIdOld, &dwIdOld);
 }
 else
 {
  Ring0WriteMemory(hookfunc->funcaddr, hookfunc->newdata, sizeof(hookfunc->newdata));
 }
}
//---------------------------------------------------------------------------
void HookOffOne(HOOKSTRUCT *hookfunc)
{
 if(SysVer)
 {
  HANDLE hProc;
  dwIdOld = dwIdNew;
  hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwIdOld);
  VirtualProtectEx(hProc, hookfunc->funcaddr,5, PAGE_READWRITE, &dwIdOld);
  WriteProcessMemory(hProc, hookfunc->funcaddr, hookfunc->olddata, 5, 0);
  VirtualProtectEx(hProc, hookfunc->funcaddr, 5, dwIdOld, &dwIdOld);
 }
 else
 {
  Ring0WriteMemory(hookfunc->funcaddr, hookfunc->olddata, sizeof(hookfunc->olddata));
 }
}

//擷取被攔截函數資訊
 BOOL hookapi(char *dllname, char *procname, DWORD myfuncaddr, HOOKSTRUCT *hookfunc)
{
    g_hModule = LoadLibrary(dllname);
    hookfunc->funcaddr = GetProcAddress(g_hModule, procname);
    if(hookfunc->funcaddr == NULL)
 {
  MessageBox(NULL, "擷取原函數地址失敗", "error", MB_OK);
        return false;
 }
 
    memcpy(hookfunc->olddata, hookfunc->funcaddr, 5);
    hookfunc->newdata[0] = 0xe9;
    DWORD jmpaddr = myfuncaddr - (DWORD)hookfunc->funcaddr - 5;
    memcpy(&hookfunc->newdata[1], &jmpaddr, 5);
    return true;
}

int WINAPI MyMessageBoxA(HWND hWnd,
      LPCTSTR lpText,
      LPCTSTR lpCaption,
      UINT uType)
{
 int runt;
 HookOffOne(&api_MessageBoxA);
 runt = ::MessageBoxA(hWnd, "攔截成功", lpCaption, uType);
 HookOnOne(&api_MessageBoxA);

 return runt;
}

BOOL Init()                                                                                                                                                                         {
 hookapi("user32.dll", "MessageBoxA", (DWORD)MyMessageBoxA, &api_MessageBoxA);   

HookOnOne(&api_MessageBoxA);                        

}

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved)
{
 OSVERSIONINFO verinfo;
 verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 switch (ul_reason_for_call)
    {
 case DLL_PROCESS_ATTACH:
  dwIdNew = GetCurrentProcessId();
  GetVersionEx(&verinfo);
  if(verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
   SysVer = TRUE;
  else
   SysVer = FALSE;

    return Init() ;
  break;
 case DLL_PROCESS_DETACH:
  if(g_hModule != NULL)
   FreeLibrary(g_hModule);
  break;
 }
    return TRUE;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.