首页
社区
课程
招聘
[求助]IATHOOK DLL注入DEBUG成功并出现效果。Realse钩成功但是没出效果。
发表于: 2013-11-18 15:01 4999

[求助]IATHOOK DLL注入DEBUG成功并出现效果。Realse钩成功但是没出效果。

2013-11-18 15:01
4999
下面是我DLL注入代码

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
#include <windows.h>
#include <stdio.h>
 
//定义函数原型
typedef int (WINAPI *PFNMESSAGEBOX)(HWND hWnd,  LPCTSTR lpText,  LPCTSTR lpCaption,  UINT uType);
//保存原始的MessageBox地址,注意这里
PROC g_orgProc = (PROC)MessageBox;
 
int WINAPI MyMessageBox(HWND hWnd,  LPCTSTR lpText,  LPCTSTR lpCaption,  UINT uType)
{
    printf("%x",(DWORD)MyMessageBox);
    printf("123");
    return ((PFNMESSAGEBOX)g_orgProc)(hWnd, "mymessagebox1111", "成功", uType);
}
 
//=========================================
// 函数名: EnableDebugPrivilege
// 输   入: bEnable(BOOL) - 提升:TRUE, 恢复:FALSE
// 输   出: BOOL - 成功:TRUE, 失败:FALSE
// 功   能: 提升/恢复权限
//=========================================
bool EnableDebugPriv(const char * name)
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID luid;
    //打开进程令牌环
    if(!OpenProcessToken(GetCurrentProcess(),//取得句柄的令牌 OpenProcessToken()函数
        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
        &hToken) )
    {
        printf("OpenProcessToken error./n");
        return FALSE;
    }
    //获得进程本地唯一ID
    if(!LookupPrivilegeValue(NULL,name,&luid) )//一个权限对应的LUID值
    {
        printf("LookupPrivilege error!/n");
        return FALSE;
    }
 
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    tp.Privileges[0].Luid = luid;
    //调整权限
    if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL) )//调用AdjustTokenPrivileges对这个访问令牌进行修改
    {
        printf("AdjustTokenPrivileges error!/n");
        return FALSE;
    }
 
    return TRUE;
}
 
 
void SetHook()
{
    HMODULE hModule = ::GetModuleHandleA(NULL);
    IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hModule;
    IMAGE_OPTIONAL_HEADER* pOpNtHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hModule + pDosHeader->e_lfanew + 24); //这里加24
    IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModule + pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
 
    BOOL bFindDll = FALSE;
    while (pImportDesc->FirstThunk)
    {
        char* pszDllName = (char*)((BYTE*)hModule + pImportDesc->Name);
        printf("模块名称:%s\n", pszDllName);
 
        if (stricmp(pszDllName, "user32.dll") == 0)//如果是user32.dll
        {
            bFindDll = TRUE;
            break;
        }
        pImportDesc++; 
    }
 
    if (bFindDll)
    {
        DWORD n = 0;
        //一个IMAGE_THUNK_DATA就是一个导入函数
        IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hModule + pImportDesc->OriginalFirstThunk);
        while (pThunk->u1.Function)
        {
            //取得函数名称
            char* pszFuncName = (char*)((BYTE*)hModule+pThunk->u1.AddressOfData+2); //函数名前面有两个..
            printf("function name:%-25s,  ", pszFuncName);
            //在这里是比较的函数名称
            if (stricmp(pszFuncName, "MessageBoxA") == 0)
            {
                //取得函数地址
                PDWORD lpAddr = (DWORD*)((BYTE*)hModule + pImportDesc->FirstThunk) + n; //从第一个函数的地址,以后每次+4字节
                //在这里是比较的函数地址
                printf("addrss:%X\n", lpAddr);
                DWORD* lpNewProc = (DWORD*)MyMessageBox;
                DWORD OldProtect = 0;
                DWORD NewProtect = 0;
 
                VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &OldProtect);    //将指定内存设为可读写
                if (!WriteProcessMemory(GetCurrentProcess(), lpAddr, &lpNewProc, sizeof(DWORD), NULL))
                {
                    printf("写入失败!\n");
                    return;
                }
                VirtualProtect(lpAddr, sizeof(DWORD), OldProtect, &NewProtect ); 
                printf("成功写入!\n");
                return;
 
            }          
            n++; //每次增加一个DWORD
        }
        printf("\n");      
    }
}
 
/*
int main(int argc, char* argv[])
{
    ::MessageBoxA(NULL, "before hook", "", MB_OK);
    EnableDebugPriv(SE_DEBUG_NAME);
    SetHook();
    ::MessageBoxA(NULL, "AFTERE hook", "", MB_OK);
    return 0;
}*/
         
 
BOOL WINAPI DllMain( HMODULE hInstance,
                    DWORD fdwReason,
                    LPVOID lp)
{
 
 
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox(NULL, "DLL加载成功!", NULL, MB_OK);
        if (!EnableDebugPriv(SE_DEBUG_NAME))
        {
            MessageBox(NULL, "提权失败!", NULL, MB_OK);
        }
        MessageBox(NULL, "提权成功!", NULL, MB_OK);
        MessageBox(NULL, "提权成功!11111", NULL, MB_OK);
        SetHook();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}


下面是我的测试DEMO。当这个DEMO 是DEBUG模式下编译的情况下成功出现效果。当时Realse情况下是不成功的!不解!
如果需要权限的话。我已经加了提权代码了。
两外Realse情况下,用XT观察了下,也是正确勾住了函数的。但是确没出现效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "stdio.h"
#include "windows.h"
 
int main()
{
    printf("test---\n");
    while(1)
    {
        getchar();
        MessageBoxA(NULL, "原来的", "原来的", 0);
    }
    return 0;
}

[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

收藏
免费
支持
分享
最新回复 (3)
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
自己解决了,造福后人。分析如下:

00401000 > $  56            push esi
00401001   .  57            push edi
00401002   .  68 F4204000   push TestDemo.004020F4                   ; /format = "test---
"
00401007   .  FF15 A4204000 call dword ptr ds:[<&MSVCR90.printf>]    ; \printf
0040100D   .  8B35 A0204000 mov esi,dword ptr ds:[<&MSVCR90.getchar>>;  MSVCR90.getchar
00401013   .  8B3D AC204000 mov edi,dword ptr ds:[<&USER32.MessageBo>;  USER32.MessageBoxA
00401019   .  83C4 04       add esp,4
0040101C   .  8D6424 00     lea esp,dword ptr ss:[esp]
00401020   >  FFD6          call esi                                 ;  程序刚开始是断在这里,但是MessageBoxA地址已经保存在EDI
00401022   .  6A 00         push 0
00401024   .  68 00214000   push TestDemo.00402100
00401029   .  68 00214000   push TestDemo.00402100
0040102E   .  6A 00         push 0
00401030   .  FFD7          call edi                                 ;  这里CALL  MessageBoxA并不通过IAT了,直接CALL地址
00401032 > .^ EB EC         jmp short TestDemo.00401020
00401034 > .  3B0D 00304000 cmp ecx,dword ptr ds:[__security_cookie]
0040103A   .  75 02         jnz short TestDemo.0040103E
0040103C   .  F3:           prefix rep:
0040103D   .  C3            retn

事实就是RELEASE版本,编译的时候对程序进行了,优化。将MessageBoxA函数地址放与一个固定寄存器中,因此下面每次CALL的时候都是 CALL 寄存器而不是通过IAT表查找函数。当然这只是因为这个程序太简单了~
2013-11-18 15:51
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
就算是Release版为了优化事先把API的地址放在了寄存器里,这个API的地址也是从IAT从取到的啊,所以IAT HOOK应该还是能钩住的才对

00401013   .  8B3D AC204000 mov edi,dword ptr ds:[<&USER32.MessageBo>;  USER32.MessageBoxA
2013-11-18 20:58
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
IAT Hook不靠谱,如果只是想简单快速的实现API Hook可以用Hot Patching
2013-11-19 11:01
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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