偶写的API Hook类

使用陷阱式Hook,  原理是把要Hook的API所在位置改成jmp newfunc, 这里的newfunc是用来代替此API的函数. 在newfunc中只要恢复被改的内存再调用原API就成了

使用方法:

建立DLL,使用系统级空Hook用于进入其它进程,

WINBASEAPI HANDLE WINAPI NewCreateFileA(
    LPCSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile
    )
{
 hook->Lock();   // 因为陷阱式Hook是不可重入的,so用临界区来防止重入
    hook->HookOff();   //恢复原CreateFileA地址的头五字节
    HANDLE Result=CreateFileA(lpFileName,dwDesiredAccess,dwShareMode,
      lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,
      hTemplateFile);
    SendMessage(hwnd,WM_USER,HOOK_CREATEFILEA,0);   //Hook到了,想做什么呢?
    hook->HookOn();  //干完还得继续Hook地
 hook->Unlock();   // 退出临界区
    return Result;
}

在DllEntryPoint里建立Hook:

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    if(reason==DLL_PROCESS_ATTACH)
    {
        h_inst=hinst;
        hook=new CHookClass("kernel32.dll","CreateFileA",NewCreateFileA);  
        hook->HookOn();
    }
    else if(reason==DLL_PROCESS_DETACH)
    {
        delete hook;
    }
 return 1;
}

//系统级空Hook,这里用了WH_GETMESSAGE,用其它的也行:

LRESULT CALLBACK GetMsgProc(int code,WPARAM wPar,LPARAM lPar)
{
 return CallNextHookEx(MessageHook, code, wPar, lPar);    //什么也不做,只是为了进入其它进程
}

extern "C" void __declspec(dllexport) __stdcall StartHook(HWND hWnd)
{
   if(MessageHook==0)
   {
      hwnd=hWnd;
      MessageHook=SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, h_inst, 0);
   }
}
extern "C" void __declspec(dllexport) __stdcall StopHook()
{
   if(MessageHook!=0)
   {
     UnhookWindowsHookEx(MessageHook);
     MessageHook=0;
   }
}

注意这里面的hwnd,MessageHook要使用共享段,怎么用不在此文章范围内,网上也是一找一大把的

//

#ifndef _HOOKCLASSH_
#define _HOOKCLASSH_

#include <windows.h>
//---------------------------------------------------------------

class CHookClass{
    CHookClass(const CHookClass&);
    CHookClass &operator=(const CHookClass&);        //不准拷贝和赋值

    #pragma pack(push,1)
    struct TJmpCode{
  char Jmp;
        DWORD Ptr;
    };
    #pragma pack(pop)
public:
 /* LibName: DLL 文件名 */
    /* FuncName: 目标函数名 */
    /* NewFuncPtr: 用于替换的函数指针 */
 CHookClass(const char *LibName, const char *FuncName, void *NewFuncPtr);
 ~CHookClass();

 void HookOn();   // 开启 API Hook
    void HookOff();  // 关闭 API Hook

    void Lock();     // 进入临界区
    void Unlock();   // 退出临界区

    bool IsHooked(){
     // 取Hook状态
     return _IsHooked;
    }
private:
    TJmpCode _OrgCode;      // 原代码
    TJmpCode _NewCode;      // 新代码 jmp FuncPtr
   
    void *_TagFuncPtr;   // 目标函数指针
    HANDLE _CurProcess;  // 当前进程
    bool _IsHooked;       // 显示是否被Hook了

    CRITICAL_SECTION _cs;   // 临界区
};

//---------------------------------------------------------------
CHookClass::CHookClass(const char *LibName, const char *FuncName, void *NewFuncPtr)
 :_TagFuncPtr(NULL),_IsHooked(false),_CurProcess(0)
{
 HMODULE hModule=LoadLibrary(LibName);
 _TagFuncPtr=GetProcAddress(hModule, FuncName);
 if(_TagFuncPtr==NULL) throw(-1);

    CopyMemory(&_OrgCode,_TagFuncPtr,5);       // 保存原函数前五字节

    _NewCode.Jmp=0xe9;  //jmp

    _NewCode.Ptr=DWORD(NewFuncPtr)-DWORD(_TagFuncPtr)-5; // 新的五字节为 jmp NewFuncPtr

 _CurProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE, GetCurrentProcessId()); // 以特权方式打开当前进程

 InitializeCriticalSection(&_cs);

}

CHookClass::~CHookClass()
{
 if(_IsHooked) HookOff();
    DeleteCriticalSection(&_cs);
}

void CHookClass::HookOn()
{
 // !开启 API Hook
    if(!_IsHooked)
    {
        DWORD dwOldProtect;
        VirtualProtectEx(_CurProcess, _TagFuncPtr, 5, PAGE_READWRITE, &dwOldProtect);  // 更改内存属性
        WriteProcessMemory(_CurProcess, _TagFuncPtr, &_NewCode, 5, NULL); // 将_TagFuncPtr的前5个字节改为JMP NewFuncPtr
        VirtualProtectEx(_CurProcess, _TagFuncPtr, 5, dwOldProtect, &dwOldProtect);
        _IsHooked=true;
    }
}
void CHookClass::HookOff()
{
 // !关闭 API Hook
    if(_IsHooked)
    {
        DWORD dwOldProtect;
        VirtualProtectEx(_CurProcess, _TagFuncPtr, 5, PAGE_READWRITE, &dwOldProtect);
        WriteProcessMemory(_CurProcess, _TagFuncPtr, &_OrgCode, 5, NULL); // 恢复_TagFuncPtr的前5个字节
        VirtualProtectEx(_CurProcess, _TagFuncPtr, 5, dwOldProtect, &dwOldProtect);
        _IsHooked=false;
    }
}

void CHookClass::Lock()     // 进入临界区
{
 EnterCriticalSection(&_cs);
}
void CHookClass::Unlock()   // 退出临界区
{
 LeaveCriticalSection(&_cs);
}
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值