| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3691 人关注过本帖, 1 人收藏
标题:APIHook是不是只能hook到系统函数呢?
只看楼主 加入收藏
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
结帖率:79.17%
收藏(1)
已结贴  问题点数:20 回复次数:12 
APIHook是不是只能hook到系统函数呢?
我使用以下函数
程序代码:
void AddStub(unsigned *func, unsigned *func_stub)
{
    //stubFuncAddr[MAX_STUB] [2] = func_stub;                 // 函 数 func将被进行打桩测试
    SetFuncAddr(func, func_stub);

    //-------------HOOK 部 分
    HMODULE hMod = GetModuleHandle(NULL);
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod;
    PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
    PIMAGE_OPTIONAL_HEADER pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);
    PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + \
                                                 pOptHeader->DataDirectory[1].VirtualAddress);
  


    while(pImportDescriptor->FirstThunk)
    {
        char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);
        //printf(" 函 数模块:%s\n",dllname);
              


        PIMAGE_THUNK_DATA 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);
          


            //printf("%4d:  ",no);
            //printf("%30s",funname);
            //printf("%8x\n",lpAddr);
            //printf("%8x\n",*lpAddr);
            // 修 改内存的部分
            if((*lpAddr) == (unsigned)func)
            {
                // 修 改内存页的属性
                DWORD dwOLD;
                MEMORY_BASIC_INFORMATION  mbi;
                VirtualQuery(lpAddr,&mbi,sizeof(mbi));
                VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
                // 写 内存
                WriteProcessMemory(GetCurrentProcess(), lpAddr, &func_stub, sizeof(DWORD), NULL);
                // 恢 复内存页的属性
                VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
            }
            //---------
            no++;
            pThunkData++;
        }
      


        pImportDescriptor++;
    }
}

发现程序只能hook到系统dll中的API函数,而不能hook自己定义的函数,这是hook的限制吗?
搜索更多相关主题的帖子: 系统 函数 APIHook hook 
2010-08-02 23:05
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:5 
看了一下楼主的HOOK方式,只是采用了替换导入表象目地址的方式进行HOOK。你的自定义函数并不在导入表中,
所以无法HOOK。

BTW:
这种HOOK方式局限性也比较大,对动态加载的DLL无效。




举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-03 08:54
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 2楼 东海一鱼
版主,您能否给个例子怎么hook上自定义的函数呢?麻烦您了

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-03 23:14
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:15 
写得不好,请多指教。
程序代码:
/////////////////////////////////////////////////////////////////////////////////////
//                    HOOKAPI DEMO PROGRAM
//文件名:HOOKTEST.C
//
//描述: 演示WINNT下HOOK系统API过程及方法
//
//作者:东海一鱼
//
//时间: 2010.7.22        
//
//使用编译器: VC2003
//
//使用第三方库: NULL
//
//
//Bug、修复纪录:
//          1、2010.8.4 增加HOOK私有函数代码(被hook函数名TestFn,hook函数名MyHookFn2)                    
////////////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

#define FLATJMPCODE_LENGTH 5            //x86 平坦内存模式下,绝对跳转指令长度

//我的新API函数
int __stdcall MyHookFn(HWND hwnd,char* sztext,char* szTitle,int stly)
{
    const char* szHookTxt = "原函数已被HOOK!";        
   
    return MessageBoxEx(hwnd,szHookTxt,szTitle,stly,0);   //调用另外的API
}

//我的新私有桩函数
void MyHookFn2(char* szTxt)
{
    char* pBuf = (char*)malloc(strlen(szTxt) + sizeof(char*) * 32);

    __try
    {
        sprintf(pBuf,"%s - %s\n",szTxt," 原函数已被HOOK!");
        printf("%s\n",pBuf);
    }
    __finally
    {
        free(pBuf);
    }
}

//HOOK函数
BOOL HookApi(LPVOID ApiFun,LPVOID HookFun)
{
    BOOL    IsSuccess = FALSE;
    DWORD   TempProtectVar;              //临时保护属性变量
    MEMORY_BASIC_INFORMATION MemInfo;    //内存分页属性信息
   
    VirtualQuery(ApiFun,&MemInfo,sizeof(MEMORY_BASIC_INFORMATION));  

    if(VirtualProtect(MemInfo.BaseAddress,MemInfo.RegionSize,
        PAGE_READWRITE,&MemInfo.Protect))                            //修改页面为可写
    {
        *(BYTE*)ApiFun = 0xe9;                                      
        *(DWORD*)((BYTE*)ApiFun + 1) = (DWORD)HookFun - (DWORD)ApiFun - FLATJMPCODE_LENGTH;
       
        VirtualProtect(MemInfo.BaseAddress,MemInfo.RegionSize,
            MemInfo.Protect,&TempProtectVar);                               //改回原属性
       
        IsSuccess = TRUE;
    }
   
    return IsSuccess;
}

//私有测试函数
void TestFn(char* szTitle)
{
    printf("%s",szTitle);
}

int main(int argc,char** argv)
{
    HMODULE hDll;
    LPVOID  OldFun;
   
    hDll = GetModuleHandle("User32.dll");
    OldFun = GetProcAddress(hDll,"MessageBoxA");  //要HOOK的API函数
   
    if(OldFun)
    {
        if(HookApi(OldFun,MyHookFn))  //如果HOOK成功
            MessageBoxA(0,"call Api MessageBox","Is Hookd?",MB_OK); //调用原API,测试HOOK
        if(HookApi(TestFn,MyHookFn2))
            TestFn("Private Function Hook Test");  //调用私有函数,测试HOOK
    }
   
    if(hDll)
        FreeLibrary(hDll);
   
    return 0;
}


举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-04 10:35
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 2楼 东海一鱼
刚才看了下您的代码,确实可以hook普通的自定义函数。
但是我还是有个疑问,您之前说自定义函数并不在导入表,那么自定义的函数在哪里呢?

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-04 23:46
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
我晕,函数入口点就是一符号地址而已。没有跳转表的话,就在代码节中啊。

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-05 12:21
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 6楼 东海一鱼
谢谢您的指教,我理解下您的话,您看下是否正确:

1) 只有声明外部可以使用的函数才在导入表中列出各相应的符号地址
2) 不管是否声明外部使用,函数实现体均会在代码段中存在

不知道是否这样?

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-05 22:25
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
是的,确切的说。只有链接PE动态库(DLL)才有导入表(实际上就是一个函数跳转表)这个概念。它是进程加载器
根据DLL加载地址动态填写的。静态链接的库没有这个东东。


举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-05 22:31
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 8楼 东海一鱼
是的,静态链接库在连接阶段连接到最终的可执行程序中了,范围地址也已经固定死了

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-05 23:28
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 4楼 东海一鱼
该实现好像也不能打桩类成员函数
程序代码:
class TestClass {
public:
    void classFn(void) { printf("classFn\n"); }
} classTmp;

void classFn_stub(void) { printf("classFn_stub\n"); }

int main(int argc,char** argv)
{
    HMODULE hDll;
    LPVOID  OldFun;
   

    hDll = GetModuleHandle("User32.dll");
    OldFun = GetProcAddress(hDll,"MessageBoxA");  //要HOOK的API函数
   

    if(OldFun)
    {
        if(HookApi( classTmp.classFn , classFn_stub))
            TestFn("class Function Hook Test");  //调用私有函数,测试HOOK
    }
   

    if(hDll)
        FreeLibrary(hDll);
   

    return 0;
}

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-06 02:02
快速回复:APIHook是不是只能hook到系统函数呢?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.064947 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved