首页
社区
课程
招聘
2
一个HOOK后遗症问题
发表于: 2022-6-16 17:05 7386

一个HOOK后遗症问题

2022-6-16 17:05
7386

菜鸟贴,请各位指教!
图片描述

 

上面是我的c++代码,我对加密与解密里面的代码进行了修改,想通过替换掉kernel32中的VirtualAlloc的内部调用的kernel32._impVirtualAllocEx,来跳转到自定义的LPVOID WINAPI DetourVirtualAllocEx中。
汇编如下:
ff 25 9413e875 jmp kernel32._imp
VirtualAllocEx
然后跳过原来的那个kernel32._imp__VirtualAllocEx(不去执行了)。就是直接替换掉。
我按照右边的代码去执行之后,产生了栈的检测错误:
图片描述
经过调试,当我正常调用VirtualAlloc的时候,在内部函数中的返回是retn10:
图片描述
而我自己写的HOOK函数中,最后的ret是14:
图片描述
多pop了4个byte,
图片描述
后来我用x32dbg进行补丁处理,把这个地方改成retn 10就没问题了。
图片描述
图片描述
图片描述
为什么会这样呢?我的理解是如果按照WINAPI的调用约定,应该是被调函数内部做栈平衡,怎么vs2010生成出来的,就多pop了4个byte呢?


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
赞赏记录
参与人
雪币
留言
时间
shinratensei
为你点赞~
2022-7-15 11:17
伟叔叔
为你点赞~
2022-7-15 11:10
最新回复 (19)
雪    币: 341
活跃值: (1020)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2

:)

最后于 2022-6-16 18:10 被fatcateatrat编辑 ,原因:
2022-6-16 18:08
0
雪    币: 202
活跃值: (1442)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
发样本,没看懂你的意思
2022-6-16 18:10
0
雪    币: 6129
活跃值: (4941)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
像这样的错误 有两个可能性,第一个是你的Detour函数 调用约定声明不对,第二个 用release编译
2022-6-16 20:48
0
雪    币: 1197
活跃值: (4008)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
5
你这里出现了VirtualAlloc和VirtualAllocEx,是不是哪里搞混了
2022-6-16 21:08
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
戒烟 发样本,没看懂你的意思
所有的代码都贴在最上面了。。
2022-6-17 08:23
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
yeyeshun 你这里出现了VirtualAlloc和VirtualAllocEx,是不是哪里搞混了
没有混的。。。
2022-6-17 08:24
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
黑洛 像这样的错误 有两个可能性,第一个是你的Detour函数 调用约定声明不对,第二个 用release编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/////////////////////////////////////////////////////////////////
//         第13章  Hook技术 《加密与解密(第四版)》           //
//                                                             //
//         Author: achillis(黑月教主)                          //
//         Blog  : http://www.cnblogs.com/achillis/            //
//         QQ    : 344132161                                   //
//         Email : achillis@126.com                            //
//         转载请保留作者信息                                  //
//         (c)  看雪学院 http://www.kanxue.com 2000-2018              //
/////////////////////////////////////////////////////////////////
 
//本程序的功能是对VirtualAlloc函数进行call Hook
 
#include <windows.h>
#include <stdio.h>
#include <CONIO.H>
 
ULONG g_PointerToRawData = 0 ;
ULONG g_RawOffset = 0 ;
 
LPVOID GetAddress(char *,char *);
LPVOID WINAPI DetourVirtualAllocEx(
    HANDLE hProcess,  // process within which to allocate memory
    LPVOID lpAddress, // desired starting address of allocation
    DWORD dwSize,     // size, in bytes, of region to allocate
    DWORD flAllocationType,    // type of allocation
    DWORD flProtect   // type of access protection
    );
BOOL Inline_InstallHook(void);
BOOL Inline_UnInstallHook();
VOID TestHook();
 
int main(int argc, char* argv[])
{
    TestHook();
    Inline_InstallHook();
    TestHook();
    //Inline_UnInstallHook();
    printf"yes i am ok\n" );
    getchar();
    return 0;
}
 
VOID TestHook()
{
    LPVOID lpAddr = VirtualAlloc(NULL,0x1000,MEM_COMMIT,PAGE_READWRITE);
}
 
LPVOID WINAPI DetourVirtualAllocEx(
    HANDLE hProcess,  // process within which to allocate memory
    LPVOID lpAddress, // desired starting address of allocation
    SIZE_T dwSize,     // size, in bytes, of region to allocate
    DWORD flAllocationType,                            // type of allocation
    DWORD flProtect   // type of access protection
    )
{    LPVOID lpAddr = NULL ;
    printf("[DetourVirtualAllocEx] VirtualAllocEx called.\n");
    lpAddr = VirtualAllocEx(hProcess,lpAddress,dwSize,flAllocationType,flProtect);
    printf("[DetourVirtualAllocEx] Alloced Buffer = 0x%X\n",lpAddr);
    return lpAddr;
}
 
DWORD G_OldAddress = 0;
DWORD G_NewAddress = 0;
 
/*
7C809AF1 >  8BFF                 mov edi,edi
7C809AF3    55                   push ebp
7C809AF4    8BEC                 mov ebp,esp
7C809AF6    FF75 14              push dword ptr ss:[ebp+14]
7C809AF9    FF75 10              push dword ptr ss:[ebp+10]
7C809AFC    FF75 0C              push dword ptr ss:[ebp+C]
7C809AFF    FF75 08              push dword ptr ss:[ebp+8]
7C809B02    6A FF                push -1
7C809B04    E8 09000000          call kernel32.VirtualAllocEx
7C809B09    5D                   pop ebp
7C809B0A    C2 1000              retn 10
*/
BOOL Inline_InstallHook()
{
    HMODULE hModule_ = LoadLibraryA( "kernel32.dll" ); 
    //准备Hook
    BOOL bFound = FALSE;
    BOOL bResult = FALSE ;
    ULONG addrTemp = 0 ;
    ULONG addrTargetFun = (ULONG)GetAddress("kernel32.dll","VirtualAllocEx");
    PBYTE pFun = (PBYTE)GetAddress("kernel32.dll","VirtualAlloc");
    PBYTE pBase = pFun;
    int i = 0 ;
    for (i=0;i<0x30;i++,pFun++)
    {
        // 7C809B04    E8 09000000          call kernel32.VirtualAllocEx
        // 9413e875       ff 25 9413e875        jmp  kernel32._imp__VirtualAllocEx
        // ssj 2022.6.16
        // 这里的思想是搜索kernel32.dll中的VirtualAlloc,他会jmp去调用kernel32._imp__VirtualAllocEx
        // 在这个vs2010里面,我们找到jmp指令的值是ff,25,修改里面的地址为自定义的函数。
        if (pFun[0] == 0xff && pFun[1] == 0x25)
        {
            union{
                byte bb_[4];
                DWORD address_;
            };
            bb_[0] = pFun[2];
            bb_[1] = pFun[3];
            bb_[2] = pFun[4];
            bb_[3] = pFun[5];
 
            G_OldAddress = address_;
 
            DWORD *jmpAddress_ = reinterpret_cast<DWORD*>( G_OldAddress );
 
            MEMORY_BASIC_INFORMATION mbInfor_;
            VirtualQuery( jmpAddress_, &mbInfor_, sizeof( mbInfor_ ) );
 
            SIZE_T wwww;
 
            addrTemp = (LONG)DetourVirtualAllocEx;
            G_NewAddress = addrTemp;
 
            DWORD oldProtect_;
            VirtualProtect( mbInfor_.BaseAddress, mbInfor_.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect_ );
            bResult = WriteProcessMemory( GetCurrentProcess( ), jmpAddress_, &addrTemp, sizeof(LONG), &wwww);
            VirtualProtect( mbInfor_.BaseAddress, mbInfor_.RegionSize, oldProtect_, nullptr );
 
            int aa = 0;
            bResult = FALSE;
 
            break;
 
            //addrTemp = (ULONG)pFun + 5 + *(LONG*)(pFun+1);
            //if (addrTemp == addrTargetFun) //判断call的目标地址是不是VirtualAllocEx
            //{
            //    bResult = TRUE;
            //    break;
            //}
        }
    }
     
    if (bResult)
    {
        //开始Hook
        g_PointerToRawData = (ULONG)pFun + 1 ;
        g_RawOffset = *(LONG*)(pFun+1) ;
        addrTemp = (LONG)DetourVirtualAllocEx - (LONG)pFun - 5 ;
        bResult = WriteProcessMemory(GetCurrentProcess(),pFun+1,&addrTemp,sizeof(LONG),NULL);
    }
 
    return bResult;
}
 
 
BOOL Inline_UnInstallHook()
{
    DWORD addrTemp = g_RawOffset ;
    return WriteProcessMemory(GetCurrentProcess(),(LPVOID)g_PointerToRawData,&addrTemp,sizeof(LONG),NULL);
}
 
 
//获取指定模块中指定API的地址
LPVOID GetAddress(char *dllname,char *funname)
{
    HMODULE hMod=0;
    if (hMod=GetModuleHandle(dllname))
    {
        return GetProcAddress(hMod,funname);
    
    else
    {
        hMod=LoadLibrary(dllname);
        return GetProcAddress(hMod,funname);
    }
     
}
2022-6-17 08:34
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
yeyeshun 你这里出现了VirtualAlloc和VirtualAllocEx,是不是哪里搞混了

我编译成release版本也是

2022-6-17 08:38
0
雪    币: 364
活跃值: (2011)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
VirtualAlloc   4个参数 ret 10h     VirtualAllocEx 5个参数 ret 14h
2022-6-17 09:25
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
LPVOID WINAPI DetourVirtualAllocEx(
    HANDLE hProcess,  // process within which to allocate memory
    LPVOID lpAddress, // desired starting address of allocation
    SIZE_T dwSize,     // size, in bytes, of region to allocate
    DWORD flAllocationType,                            // type of allocation
    DWORD flProtect   // type of access protection
    )
{    LPVOID lpAddr = NULL ;
    printf("[DetourVirtualAllocEx] VirtualAllocEx called.\n");
    lpAddr = VirtualAllocEx(hProcess,lpAddress,dwSize,flAllocationType,flProtect);
    printf("[DetourVirtualAllocEx] Alloced Buffer = 0x%X\n",lpAddr);
    return lpAddr;
}
 我这里定义的也是5个参数呢。。
2022-6-17 11:32
0
雪    币: 8715
活跃值: (8619)
能力值: ( LV13,RANK:570 )
在线值:
发帖
回帖
粉丝
12
黑月教主是那位写易语言C编译器的大佬嘛
2022-6-17 11:57
0
雪    币: 11039
活跃值: (5256)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
addrTargetFun是VirtualAllocEx,pFun却是VirtualAlloc,用VirtualAllocEx hook VirtualAlloc?
2022-6-17 13:05
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
superlover addrTargetFun是VirtualAllocEx,pFun却是VirtualAlloc,用VirtualAllocEx hook VirtualAlloc?
我是用DetourVirtualAllocEx来hook掉VirtualAllocEx
2022-6-17 14:40
0
雪    币: 3162
活跃值: (1319)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
15

刚看了下,新系统里面有stub存在,有可能是你get VirtualAlloc的时候,取的是VirtualAllocStub,然后在里面搜索ff 25 的时候,搜索出来的还是 VirtualAlloc。 

 你可以把你get出来的地址,u一下看下汇编代码

1
2
3
4
5
6
7
KERNEL32!VirtualAllocStub:
75855ed0 8bff            mov     edi,edi
75855ed2 55              push    ebp
75855ed3 8bec            mov     ebp,esp
75855ed5 5d              pop     ebp
75855ed6 ff2510138c75    jmp     dword ptr [KERNEL32!_imp__VirtualAlloc (758c1310)]
75855edc cc              int     3


2022-6-17 15:46
0
雪    币: 7698
活跃值: (4486)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
hello,hook LPVOID WINAPI DetourVirtualAllocEx(    HANDLE hProcess,  // process within which to allocate memor ...

正是因为你定义的是5个参数,所以RENT 14啊,RENT 10的virtualalloc函数,这个函数只有4个参数,这不是很明白的吗。另外我WIN7系统kernel32.virtualalloc函数内部通过JMP跳转的到的是kernelbase.virtualalloc而不是kernel32.virtualallocex,所以通过替换JMP后面的数值的话替换的是kernelbase.virtualalloc,这个函数同样只有4个参数,需要RENT 10才能正常运行

最后于 2022-6-17 20:52 被htpidk编辑 ,原因:
2022-6-17 20:24
0
雪    币: 1197
活跃值: (4008)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
17
zhouws 刚看了下,新系统里面有stub存在,有可能是你get VirtualAlloc的时候,取的是VirtualAllocStub,然后在里面搜索ff 25 的时候,搜索出来的还是 VirtualAlloc ...
我觉得你说的靠谱
2022-6-17 22:11
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18

你说的是对的,这个jmp到kernelbase的VirtualAlloc了,不是我认为的VirtualAllocEx(5个参数)。而kernelbase的VirtualAlloc中的参数是4个。所以问题出现了。非常感谢大家!


2022-6-18 08:40
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
htpidk hello,hook LPVOID WINAPI DetourVirtualAllocEx( &nbsp; &nbsp;HAN ...
你说的是对的
2022-6-18 08:41
0
雪    币: 335
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
htpidk hello,hook LPVOID WINAPI DetourVirtualAllocEx( &nbsp; &nbsp;HAN ...

把第一个参数去掉就ok了。。。

2022-6-18 08:44
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册