【实例下载】点击此处下载(或鼠标右键另存为)
【原文链接】http://bbs.pediy.com/showthread.php?s=&threadid=359
[part 1]
幻影之旅
by forgot/uS
转载保持完整
00420000 > /EB 20 jmp short Try.00420022
00420002 |0000 add byte ptr ds:[eax], al
00420004 |40 inc eax
00420005 |0000 add byte ptr ds:[eax], al
00420007 |0040 00 add byte ptr ds:[eax], al
0042000A |0000 add byte ptr ds:[eax], al
0042000C |0000 add byte ptr ds:[eax], al
0042000E |0000 add byte ptr ds:[eax], al
00420010 |0000 add byte ptr ds:[eax], al
00420012 |0200 add al, byte ptr ds:[eax]
00420014 |0B00 or eax, dword ptr ds:[eax]
00420016 |0000 add byte ptr ds:[eax], al
00420018 |0230 add dh, byte ptr ds:[eax]
0042001A |0000 add byte ptr ds:[eax], al
0042001C |0000 add byte ptr ds:[eax], al
0042001E |0000 add byte ptr ds:[eax], al
00420020 |0000 add byte ptr ds:[eax], al
00420022 \9C pushfd ; 保存标志
00420023 55 push ebp ; 保存寄存器
00420024 57 push edi
00420025 56 push esi
00420026 52 push edx
00420027 51 push ecx
00420028 53 push ebx
00420029 9C pushfd
0042002A E8 00000000 call Try.0042002F ; 取delta
0042002F 5D pop ebp
00420030 81ED FC584000 sub ebp, Try.004058FC
00420040 50 push eax ; 保存eax
00420058 8B85 F1344200 mov eax, dword ptr ss:[ebp+4234F1]
00420063 83F8 00 cmp eax, 0 ; DLL 重入?
0042007D 0F85 33030000 jnz Try.004203B6 ; 第二次进入,无需解压缩,直接跳去执行
0042008D B8 C7D70100 mov eax, 1D7C7
00420097 83C0 10 add eax, 10 ; 计算所需长度
0042009F 6A 04 push 4
004200A1 68 00100000 push 1000
004200A6 50 push eax ; 所需长度
004200A7 6A 00 push 0
004200A9 FF95 B93D4200 call dword ptr ss:[ebp+423DB9] ; 分配内存, VirtualAlloc
004200DC 8BF0 mov esi, eax ; esi -> 分配的内存
00420110 8D9D 835C4000 lea ebx, dword ptr ss:[ebp+405C83] ; ebx -> 被压缩的数据
0042011B 50 push eax ; 目的地
0042011C 53 push ebx ; 数据来源
0042011D E8 15010000 call Try.00420237 ; APLib解码, depack
00420127 83C4 08 add esp, 8 ; 平衡堆栈
00420134 56 push esi ; 保存内存首地址
0042013A 8BC8 mov ecx, eax ; 数据长度
00420141 8DBD 835C4000 lea edi, dword ptr ss:[ebp+405C83] ; 目的地
0042014C F3:A4 rep movsb ; 传送数据
0042017B 5E pop esi ; 恢复内存首地址
004201D6 68 00800000 push 8000
004201DB 6A 00 push 0
004201DD 56 push esi
004201DE FF95 B53D4200 call dword ptr ss:[ebp+423DB5] ; 释放申请的内存, VirtualFree
; * forgot : 干吗不在内存里执行……成了固定地址, 让偶们有机会.哈
00420216 E9 9B010000 jmp Try.004203B6 ; 跳向解压缩后的数据
004203B6 90 nop
004203CD 58 pop eax ; 恢复上边保存的eax
004203D3 EB 43 jmp short Try.00420418 ; 下边放的是一些函数名与其DLL名,跳过他们
---------------------------------------------------------------------------
004203D5 6B 65 72 6E 65 6C 33 32 2E 64 6C 6C 00 53 6C 65 kernel32.dll.Sle
004203E5 65 70 00 47 65 74 54 69 63 6B 43 6F 75 6E 74 00 ep.GetTickCount.
004203F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00420405 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00420415 00 00 00 ...
---------------------------------------------------------------------------
; * forgot: 这一段真无聊
00420418 60 pushad ; 保存寄存器
00420419 83BD CA5C4000 0>cmp dword ptr ss:[ebp+405CCA], 0 ; Sleep 地址
00420420 75 2C jnz short Try.0042044E ; 非零表示已经取得, 不再执行这一段
00420422 8D85 A25C4000 lea eax, dword ptr ss:[ebp+405CA2] ; eax -> "kernel32.dll"
00420428 50 push eax ; push FileName
00420429 FF95 C13D4200 call dword ptr ss:[ebp+423DC1] ; 载入动态链接库, LoadLibraryA
0042042F 8DB5 AF5C4000 lea esi, dword ptr ss:[ebp+405CAF] ; esi -> "Sleep"
00420435 56 push esi ; ProcNameOrOrdinal = "Sleep"
00420436 50 push eax ; hModule = 77E40000 (kernel32)
00420437 FF95 C53D4200 call dword ptr ss:[ebp+423DC5] ; 取Sleep地址, GetProcAddress
0042043D 8985 CA5C4000 mov dword ptr ss:[ebp+405CCA], eax ; 存入Sleep地址, 隐式链接
00420443 68 F4010000 push 1F4 ; 500 ms
00420448 FF95 CA5C4000 call dword ptr ss:[ebp+405CCA] ; 调用 Sleep 延时
0042044E 61 popad ; 恢复寄存器
00420498 8985 F5344200 mov dword ptr ss:[ebp+4234F5], eax ; 这是啥玩艺?十里香-_-;;
004204A8 BE 5C344200 mov esi, Try.0042345C ; esi -> 指向一个OSVERSIONINFO结构
004204B2 03F5 add esi, ebp
; * D.Boy真奇怪, lea esi, 0042345C[ebp] 不行吗?很多都这么写,请大虾们不吝赐教.
004204E1 C706 94000000 mov dword ptr ds:[esi], 94h ; sizeof OSVERSIONINFO
004204EC 56 push esi
004204ED FF95 BD3D4200 call dword ptr ss:[ebp+423DBD] ; 取系统版本.GetVersionExA
004204F8 837E 10 02 cmp dword ptr ds:[esi+10], 2 ; Windows 98 系列? 这里有个if...else...endif结构
004204FC 75 13 jnz short Try.00420511
00420503 C685 F0344200 0>mov byte ptr ss:[ebp+4234F0], 1 ; 设置 NT 标记
0042050F /EB 39 jmp short Try.0042054A
00420511 90 nop
00420516 C685 F0344200 0>mov byte ptr ss:[ebp+4234F0], 0 ; 清零 NT 标记
0042054A 90 nop
00420559 8D85 CF5C4000 lea eax, dword ptr ss:[ebp+405CCF] ; eax -> 上边的一小段Buffer,就是刚才放 Sleep 等的地方
004205A9 80BD F0344200 0>cmp byte ptr ss:[ebp+4234F0], 1 ; 某个标记
004205B0 0F85 114C0000 jnz Try.004251C7
004205D2 E8 D40D0000 call Try.004213AB ; 取函数地址
{
004213AB 90 nop
004213D8 60 pushad
004213DE BB 04714000 mov ebx, Try.00407104
004213E8 03DD add ebx, ebp
; * forgot : 又来了-_-;;
00421433 807B 08 00 cmp byte ptr ds:[ebx+8], 0 ; "ntdll.dll"存在?
00421464 /0F84 5D030000 je Try.004217C7 ; 跳过
0042149C 8BC3 mov eax, ebx ; eax = ebx
004214CB 83C0 08 add eax, 8 ; eax -> "ntdll.dll"
004214D3 50 push eax
004214D4 FF95 C13D4200 call dword ptr ss:[ebp+423DC1] ; kernel32.LoadLibraryA
; * 载入"NTDLL.DLL"动态链接库, 我觉得是Bug,应该先GetModuleHandleA才对,有些默认都映射了.
00421507 8985 FC704000 mov dword ptr ss:[ebp+4070FC], eax ; 写入 NTDLL 基地址
0042153A 83F8 00 cmp eax, 0 ; 获得 NTDLL 模块了?
0042153D 75 46 jnz short Try.00421585 ; Good...走人
00421544 C785 00714000 0>mov dword ptr ss:[ebp+407100], 0 ; 设置失败标记
00421553 E9 6F020000 jmp Try.004217C7
00421585 90 nop
004215A1 8B33 mov esi, dword ptr ds:[ebx] ; Try.00407150
004215A8 8B7B 04 mov edi, dword ptr ds:[ebx+4] ; Try.0040719F
004215B0 03F5 add esi, ebp ; 指向 dll函数 名表
004215B7 03FD add edi, ebp ; 指向 函数地址表
004215EC 803E 00 cmp byte ptr ds:[esi], 0
004215EF 75 58 jnz short Try.00421649 ; 处理完了吗?
004215F6 83C3 08 add ebx, 8
004215FE 803B 00 cmp byte ptr ds:[ebx], 0 ; NULL?
00421601 74 1F je short Try.00421622
0042161A 43 inc ebx
00421620 EB DC jmp short Try.004215FE
00421622 90 nop
0042167B 56 push esi ; 函数名
0042167C FFB5 FC704000 push dword ptr ss:[ebp+4070FC] ; NTDLL
00421682 FF95 C53D4200 call dword ptr ss:[ebp+423DC5] ; kernel32.GetProcAddress
0042169F 83F8 00 cmp eax, 0
004216A2 75 30 jnz short Try.004216D4
004216A9 C785 00714000 0>mov dword ptr ss:[ebp+407100], 0
004216CA /E9 F8000000 jmp Try.004217C7
00421701 8907 mov dword ptr ds:[edi], eax ; 写入地址
00421730 83C7 04 add edi, 4 ; 下一个地址
0042173D 803E 00 cmp byte ptr ds:[esi], 0 ; NULL?
00421740 74 31 je short Try.00421773
00421759 46 inc esi
00421771 EB CA jmp short Try.0042173D
0042178A 46 inc esi ; 上边到达NULL,这里跳过NULL
004217B8 E9 18FEFFFF jmp Try.004215D5 ; 循环处理 -> 004215EC
; * 所有要处理的函数:
---------------------------------------------------------------------------
00421883 52 74 6C 49 6E 69 74 55 6E 69 63 6F 64 65 53 74 RtlInitUnicodeSt
00421893 72 69 6E 67 00 5A 77 4F 70 65 6E 53 65 63 74 69 ring.ZwOpenSecti
004218A3 6F 6E 00 5A 77 55 6E 6D 61 70 56 69 65 77 4F 66 on.ZwUnmapViewOf
004218B3 53 65 63 74 69 6F 6E 00 5A 77 4D 61 70 56 69 65 Section.ZwMapVie
004218C3 77 4F 66 53 65 63 74 69 6F 6E 00 00 00 00 00 F8 wOfSection.....
004218D3 41 F9 77 00 00 00 00 00 00 00 00 00 00 00 00 00 A鵺.............
004218E3 00 00 00 52 65 6C 65 61 73 65 4D 75 74 65 78 00 ...ReleaseMutex.
004218F3 43 72 65 61 74 65 4D 75 74 65 78 41 00 44 65 6C CreateMutexA.Del
00421903 65 74 65 46 69 6C 65 41 00 44 65 76 69 63 65 49 eteFileA.DeviceI
00421913 6F 43 6F 6E 74 72 6F 6C 00 47 65 74 4C 61 73 74 oControl.GetLast
00421923 45 72 72 6F 72 00 47 65 74 53 79 73 74 65 6D 44 Error.GetSystemD
00421933 69 72 65 63 74 6F 72 79 41 00 43 72 65 61 74 65 irectoryA.Create
00421943 46 69 6C 65 41 00 57 72 69 74 65 46 69 6C 65 00 FileA.WriteFile.
00421953 43 6C 6F 73 65 48 61 6E 64 6C 65 00 00 00 00 00 CloseHandle.....
00421963 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00421973 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00421983 00 00 00 00 00 00 00 00 53 74 61 72 74 53 65 72 ........StartSer
00421993 76 69 63 65 41 00 44 65 6C 65 74 65 53 65 72 76 viceA.DeleteServ
004219A3 69 63 65 00 4F 70 65 6E 53 43 4D 61 6E 61 67 65 ice.OpenSCManage
004219B3 72 41 00 43 72 65 61 74 65 53 65 72 76 69 63 65 rA.CreateService
004219C3 41 00 4F 70 65 6E 53 65 72 76 69 63 65 41 00 43 A.OpenServiceA.C
004219D3 6F 6E 74 72 6F 6C 53 65 72 76 69 63 65 00 43 6C ontrolService.Cl
004219E3 6F 73 65 53 65 72 76 69 63 65 48 61 6E 64 6C 65 oseServiceHandle
004219F3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00421A03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00421A13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00421A23 00 .
---------------------------------------------------------------------------
0042167B 56 push esi
0042167C FFB5 FC704000 push dword ptr ss:[ebp+4070FC]
00421682 FF95 C53D4200 call dword ptr ss:[ebp+423DC5] ; kernel32.GetProcAddress, 最后一个函数
0042169F 83F8 00 cmp eax, 0 ; 失败?
004216A2 75 30 jnz short Try.004216D4
004216A9 C785 00714000 0>mov dword ptr ss:[ebp+407100], 0 ; 失败标记
004216CA /E9 F8000000 jmp Try.004217C7
00421701 8907 mov dword ptr ds:[edi], eax ; 写入地址
00421730 83C7 04 add edi, 4
0042173D 803E 00 cmp byte ptr ds:[esi], 0
00421740 74 31 je short Try.00421773
00421759 46 inc esi
00421771 ^\EB CA jmp short Try.0042173D ; 循环到遇到NULL
0042178A 46 inc esi ; 跳过NULL,指向下一个函数
; * forgot :一大堆取函数地址,不说了
004217CC 61 popad ; 终于结束了
004217E4 8B85 00714000 mov eax, dword ptr ss:[ebp+407100] ; 设置返回值
00421801 C3 ret
}
004205E1 8D85 2E6C4000 lea eax, dword ptr ss:[ebp+406C2E] ; 告诉我们要干坏事了;-), 互斥体名称
---------------------------------------------------------------------------
00421361 4C 6F 61 64 69 6E 67 44 42 50 45 00 00 00 00 00 LoadingDBPE.....
00421371 43 64 73 79 73 00 5C 5C 2E 5C 44 62 70 65 44 65 Cdsys.\\.\DbpeDe
00421381 76 69 63 65 30 00 00 00 00 00 00 00 00 00 00 00 vice0...........
00421391 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
004213A1 00 00 00 00 00 00 00 00 00 00 ..........
---------------------------------------------------------------------------
00420614 50 push eax
00420615 6A 01 push 1
00420617 6A 00 push 0
00420619 FF95 34724000 call dword ptr ss:[ebp+407234] ; 呵呵,创建互斥体,kernel32.CreateMutexA
00420636 83F8 00 cmp eax, 0
00420666 /0F84 CB490000 je Try.00425037 ; 大概装载过了,跳过装载吧
0042069E 8985 2A6C4000 mov dword ptr ss:[ebp+406C2A], eax ; 保存互斥体
004206E8 FF95 40724000 call dword ptr ss:[ebp+407240] ; ntdll.RtlGetLastWin32Error
00420705 3D B7000000 cmp eax, 0B7 ; 忘记是啥了
0042070A 0F85 9B000000 jnz Try.004207AB
0042073D FFB5 2A6C4000 push dword ptr ss:[ebp+406C2A]
00420743 FF95 50724000 call dword ptr ss:[ebp+407250] ; 我没到这里,猜想是CloseHandle
0042074E C785 2A6C4000 0>mov dword ptr ss:[ebp+406C2A], 0 ; 互斥体清零
00420785 B8 00000000 mov eax, 0 ; 返回 FALSE
0042078F /E9 A3480000 jmp Try.00425037
004207AB 90 nop
004207B5 83BD 706C4000 0>cmp dword ptr ss:[ebp+406C70], 0
004207BC 75 5C jnz short Try.0042081A