【转发】GetModuleHandle——windows API 函数

本文介绍如何利用Windows API函数GetModuleHandle获取模块句柄,并演示了一个具体的APIHook实例。通过对自身进程的模块句柄操作,实现了对MessageBoxA函数的拦截与替换。

  VC声明:

       HMODULE GetModuleHandle (LPCTSTR lpModuleName);
  功能说明
  获取一个应用程序或动态链接库的模块句柄
  参数说明
  lpModuleName 模块名称
  返回值
  如执行成功成功,则返回模块句柄。零表示失败。通过GetLastError获得错误信息
  如:
       GetModuleHandle(NULL); //  这将返回自身应用程序句柄

            GetModuleHandle("kernel32");//这将返回kernel32.dll的句柄

       模块句柄实际上就是模块在当前进程空间的装入地址。exe程序装入句柄一般为 0x00400000 。所以GetModuleHandle(NULL); 返回的值为  0x00400000;GetModuleHandle("kernel32");返回值是0x7c800000(这个值正是kernel32.dll中的Image base的值)。下面是使用模块句柄做为指针的例子(下面这个程序片断是我从网上的关于API HOOK的文章http://eyesye.javaeye.com/blog/236389中摘下来):

//----------------------fundll.cpp-----------------------------
//
//write by Gxter
//
//fundll.cpp

#include "windows.h"
#include "process.h"
#include "tlhelp32.h"
#include "stdio.h"

#pragma comment(lib,"th32.lib")

PIMAGE_DOS_HEADER  pDosHeader;
PIMAGE_NT_HEADERS  pNTHeaders;
PIMAGE_OPTIONAL_HEADER   pOptHeader;
PIMAGE_IMPORT_DESCRIPTOR  pImportDescriptor;
PIMAGE_THUNK_DATA         pThunkData;
PIMAGE_IMPORT_BY_NAME     pImportByName;
HMODULE hMod;


// 定义MessageBoxA函数原型
typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);

int * addr = (int *)MessageBoxA;    //保存函数的入口地址
int * myaddr = (int *)MessageBoxProxy;


void ThreadProc(void *param);//线程函数


BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
    if(fdwReason==DLL_PROCESS_ATTACH)    
        _beginthread(ThreadProc,0,NULL);    

    return TRUE;
}


//结束进程的函数

void ThreadProc(void *param)
{
    //------------hook api----------------
    hMod = GetModuleHandle(NULL);

    pDosHeader = (PIMAGE_DOS_HEADER)hMod;
    pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
    pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);

    pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);

    while(pImportDescriptor->FirstThunk)
    {
        char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);

        pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk);

        int no = 1;
        while(pThunkData->u1.Function)
        {
            char * funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2);
            PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) +(no-1);
        
            //修改内存的部分
            if((*lpAddr) == (int)addr)
            {
                //修改内存页的属性
                DWORD dwOLD;
                MEMORY_BASIC_INFORMATION  mbi;
                VirtualQuery(lpAddr,&mbi,sizeof(mbi));
                VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
                
                WriteProcessMemory(GetCurrentProcess(),
                        lpAddr, &myaddr, sizeof(DWORD), NULL);
                //恢复内存页的属性
                VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
            }
            //---------
            no++;
            pThunkData++;
        }

        pImportDescriptor++;
    }
    //-------------------HOOK END-----------------
}

//new messagebox function
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
    return     ((PFNMESSAGEBOX)addr)(NULL, "gxter_test", "gxter_title", 0);
    //这个地方可以写出对这个API函数的处理代码
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值