标题:通过覆盖系统函数的地址来实现HOOK API 中的MessageBoxProxy函数哪里被使用 ...
只看楼主
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
结帖率:79.17%
已结贴  问题点数:15 回复次数:9 
通过覆盖系统函数的地址来实现HOOK API 中的MessageBoxProxy函数哪里被使用了 ?
程序代码:
//
//write by Gxter
//
//通过覆盖系统函数的地址来实现HOOK API
//
#include "stdio.h"
#include "windows.h"
#include "tchar.h"

// "崩溃函数绝对地址"指00401020
BYTE addr_old[8] = {0};
BYTE addr_new[8] = { 0xB8, 0x20, 0x10, 0x40, 0x00, 0xFF, 0xE0, 0x00 }; //第2,3,4,5是需要手工调整的(重要的步骤)
DWORD pfnMsgBox=0; //API函数地址


int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
    int ret = 0;

    DWORD dwOldProtect;
    MEMORY_BASIC_INFORMATION   mbi;
   

    printf("%08x\n", MessageBoxProxy);

    ::VirtualQuery((void *)pfnMsgBox, &mbi, sizeof(mbi));
    ::VirtualProtect((void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);
   

    // 写入原来的执行代码, 恢复
    ::WriteProcessMemory(::GetCurrentProcess(),
        (void *)pfnMsgBox,
        addr_old,
        sizeof(DWORD)*2,
        NULL);
   

    ::VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);
   

    ret=MessageBox(hWnd,"gxter","gxter",uType);
   

    return ret;
}


//----------------------------------------------程序入口
int main()
{
    DWORD dwOldProtect;
    MEMORY_BASIC_INFORMATION   mbi;
   

    MessageBox(NULL,_T("Hook Demo!"),_T("API Hook"),MB_ICONINFORMATION);
    pfnMsgBox=(DWORD)GetProcAddress(GetModuleHandle(_T("user32.dll")),_T("MessageBoxA"));
    printf("api 入口地址: %x\n",pfnMsgBox);
   

   

    VirtualQuery( (void *)pfnMsgBox, &mbi, sizeof(mbi) );
    //修改我们要改的地址的页属性,为可读可写
    VirtualProtect( (void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);
   

    // 保存原来的执行代码
    memcpy(addr_old, (void *)pfnMsgBox, 8);
   

    // 写入新的执行代码
    WriteProcessMemory( GetCurrentProcess(),
        (void *)pfnMsgBox,
        addr_new,
        sizeof(DWORD)*2,
        NULL);
    //修改为原来的属性属性
    VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);
   

    //当调用这个函数的时候就跳到我的函数上面了
    MessageBox(NULL,_T("Hook Demo!"),_T("API Hook"),MB_ICONINFORMATION);
   

   

    getchar();
    return 0;
}
上面的代码好像没有使用函数 MessageBoxProxy ,但是把这个函数去掉,又程序运行错误,不知道为什么 ?
搜索更多相关主题的帖子: HOOK API 函数 系统 地址 
2010-08-08 15:08
yxwsbobo
Rank: 5Rank: 5
等 级:职业侠客
帖 子:345
专家分:306
注 册:2007-10-29
得分:7 
0xB8, 0x20, 0x10, 0x40, 0x00, 0xFF, 0xE0, 0x00

相当于

mov eax,401020
jmp eax


意思是跳到 401020处执行,貌似是要调转到自己的MessageBox执行,此写法是有问题的, 函数地址都是变的,将函数硬编码出来肯定要处问题的

另外不需要修改内存页属性,所以
    DWORD dwOldProtect;
    MEMORY_BASIC_INFORMATION   mbi;

    ::VirtualQuery((void *)pfnMsgBox, &mbi, sizeof(mbi));
    ::VirtualProtect((void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);

 之类的都可以删掉

How are you 怎么是你?
How old are you   怎么老是你?
2010-08-08 15:40
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
得分:7 
回复 楼主 vfdff
作者用了手工编码的方式将MessageBoxProxy的地址放入eax寄存器,并形成相对跳转代码。8个字节只是为了便于操作。每次改变编译方式或更换编译器,都要手工计算这个加载点,这个方法应该是比较笨拙的(希望作者不要介意啊)。

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-08 17:08
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
回复 3楼 东海一鱼
我把函数MessageBoxProxy的名字改成别的好像程序也是好的,这个硬编码地址很奇怪呀,怎么就能刚刚制定到这个函数地址?

但是随便在源代码中增加新的一个函数,这个程序就挂了!

另外,我在MessageBoxProxy函数中把该函数的入口地址打印出来,也不是这个 00401020 呀?!


[ 本帖最后由 vfdff 于 2010-8-8 17:39 编辑 ]

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-08 17:27
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
得分:0 
以下是引用vfdff在2010-8-8 17:27:38的发言:

我把函数MessageBoxProxy的名字改成别的好像程序也是好的,这个硬编码地址很奇怪呀,怎么就能刚刚制定到这个函数地址?

但是随便在源代码中增加新的一个函数,这个程序就挂了!

另外,我在MessageBoxProxy函数中把该函数的入口地址打印出来,也不是这个 00401020 呀?!
   这个硬编码地址很奇怪呀,怎么就能刚刚制定到这个函数地址?

   它可以自己调试打印出来啊。

   但是随便在源代码中增加新的一个函数,这个程序就挂了!

   加入新代码,影响代码生成的布局啊。硬编码无效了,所以要重新计算(观察)。

   另外,我在MessageBoxProxy函数中把该函数的入口地址打印出来,也不是这个 00401020 呀?!

   你打印的是API MessageBox的地址。

   


[ 本帖最后由 东海一鱼 于 2010-8-8 18:04 编辑 ]

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-08 18:03
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
回复 5楼 东海一鱼
很明显 API messageBox 入口地址 77d507ea 和我打印的地址0040100a不一致的!
 单步调试时显示的却真是 00401020 ,怎么和我printf显示的值不一致呢 ?



[ 本帖最后由 vfdff 于 2010-8-8 20:16 编辑 ]

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-08 20:12
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
得分:0 
以下是引用vfdff在2010-8-8 20:12:17的发言:

很明显 API messageBox 入口地址 77d507ea 和我打印的地址0040100a不一致的!
 单步调试时显示的却真是 00401020 ,怎么和我printf显示的值不一致呢 ?
不好意思,图太小,只看到上面的API地址了。
你可以试试把上面的00401020改成0040100a,照样OK。
但是你如果改成Release编译的话,0040100a这个地址就‘挂了’。
原因是:Debug版的每个内部函数还有一个类似于IAT的ILT表。这个0040100a就是指向ILT中的函数地址。

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-09 11:14
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
成Release编译的话,00401020也挂了,需要改成00401000 !


[ 本帖最后由 vfdff 于 2010-8-9 22:54 编辑 ]

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-09 22:51
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
得分:0 
哈,那你何妨给它改成自动获取地址的试试。

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-08-11 17:55
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
得分:0 
是的,只顾问问题,差点把本质的问题给弄丢了
结果大家的指点与自己的实际测试,我知道这个地址并没有什么特别的地方,只是凑上去的而已

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010-08-11 23:07



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-315129-1-1.html




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

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