Hook技术2 内存中修改模块开头代码为跳转语句

来源:互联网 发布:小米note网络制式指令 编辑:程序博客网 时间:2024/05/16 15:22
 
 分类: Hook技术心得2008-08-31 19:50 241人阅读 评论(0) 收藏 举报

这种霸道的技术,一般不推荐使用,除非无奈之下,不妨可以试试。

原理也很简单,要导入一个Dll,把它在内存中的代码,前几代改为

JUMP 我的函数地址

然后,在我的里,再把他的几行代码改回去,把我自己的事做完之后,再调用它,也可以不调用。最后它返回后,又将它的前几行代码改为JUMP。

原理非常简单:

下面给出一个封装好的类:

//////////////////////////////////////////////////////////

// ULHook.h

 

#ifndef __ULHOOK_H__

#define __ULHOOK_H__

 

#include <windows.h>

 

class CULHook

{

public:

     CULHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook);

     ~CULHook();

     // 取消挂钩

     void Unhook();

     // 重新挂钩

     void Rehook();

protected:

     PROC m_pfnOrig;                 // 目标API函数的地址

     BYTE m_btNewBytes[8];       // 新构建的个字节

     BYTE m_btOldBytes[8];       // 原来个字节

     HMODULE m_hModule;

};

 

#endif // __ULHOOK_H__

 

///////////////////////////////////////////

// ULHook.cpp文件

 

 

#include "ULHook.h"

 

 

CULHook::CULHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook)

{

 

     // jmp eax == 0xFF, 0xE0

     // 生成新的执行代码

     BYTE btNewBytes[8] = { 0xB8, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xE0, 0x00 };

     memcpy(m_btNewBytes, btNewBytes, 8);

     *(DWORD *)(m_btNewBytes + 1) = (DWORD)pfnHook;

 

     // 加载指定模块,取得API函数地址

     m_hModule = ::LoadLibrary(pszModName);

     if(m_hModule == NULL)

     {

         m_pfnOrig = NULL;

         return;

     }

     m_pfnOrig = ::GetProcAddress(m_hModule, pszFuncName);

 

 

     // 修改原API函数执行代码的前个字节,使它跳向我们的函数

     if(m_pfnOrig != NULL)

     {

         DWORD dwOldProtect;

         MEMORY_BASIC_INFORMATION    mbi;

         ::VirtualQuery( m_pfnOrig, &mbi, sizeof(mbi) );

         ::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);

 

         // 保存原来的执行代码

         memcpy(m_btOldBytes, m_pfnOrig, 8);

         // 写入新的执行代码

         ::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,

                            m_btNewBytes, sizeof(DWORD)*2, NULL);

    

         ::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);

     }

}

 

CULHook::~CULHook()

{

     Unhook();

     if(m_hModule != NULL)

         ::FreeLibrary(m_hModule);

}

 

void CULHook::Unhook()

{

     if(m_pfnOrig != NULL)

     {

         DWORD dwOldProtect;

         MEMORY_BASIC_INFORMATION    mbi;

         ::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));

         ::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);

 

         // 写入原来的执行代码

         ::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,

                            m_btOldBytes, sizeof(DWORD)*2, NULL);

    

         ::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);

     }

}

 

void CULHook::Rehook()

{

     // 修改原API函数执行代码的前个字节,使它跳向我们的函数

     if(m_pfnOrig != NULL)

     {

         DWORD dwOldProtect;

         MEMORY_BASIC_INFORMATION    mbi;

         ::VirtualQuery( m_pfnOrig, &mbi, sizeof(mbi) );

         ::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);

 

         // 写入新的执行代码

         ::WriteProcessMemory(::GetCurrentProcess(), (void *)m_pfnOrig,

                            m_btNewBytes, sizeof(DWORD)*2, NULL);

    

         ::VirtualProtect(m_pfnOrig, 8, mbi.Protect, 0);

     }

}

原创粉丝点击