拦截API(修改函数地址方法)

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值