会员申请 ID:丶看海个人邮箱:weidandann@163.com
原创技术文章:
Armadillo V4.X CopyMem-II脱壳
设置OllyDbg忽略所有其它异常选项。用IsDebug插件去掉OllyDbg的调试器标志。
1 寻找OEP+解码Dump
载入程序
0182C243 >/$ 55 PUSH EBP
0182C244 |. 8BEC MOV EBP,ESP
0182C246 |. 6A FF PUSH -1
0182C248 |. 68 405F8501 PUSH Cam.01855F40
0182C24D |. 68 80BF8201 PUSH Cam.0182BF80 ; SE 处理程序安装
0182C252 |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
0182C258 |. 50 PUSH EAX
0182C259 |. 64:8925 00000>MOV DWORD PTR FS:[0],ESP
0182C260 |. 83EC 58 SUB ESP,58
0182C263 |. 53 PUSH EBX
0182C264 |. 56 PUSH ESI
0182C265 |. 57 PUSH EDI
0182C266 |. 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
下断BP WaitForDebugEvent
中断后取消断点,看堆栈:
0012DC8C 0181C386 /CALL 到 WaitForDebugEvent 来自 Cam.0181C380
0012DC90 0012ED7C |pDebugEvent = 0012ED7C
0012DC94 000003E8 \Timeout = 1000. ms
0012DC98 7C930738 ntdll.7C930738
在数据窗口定位到0012CD90处,准备看OEP值
现在去代码窗口Ctrl+G:0181c386
Ctrl+F在当前位置下搜索命令:or eax,0FFFFFFF8
找到第一处在0181c956处,在其上cmp dword ptr ss:[ebp-A34],0处设置断点。
0181C90A > \83BD CCF5FFFF>CMP DWORD PTR SS:[EBP-A34],0 //下断,Shift+F9中断下来 把[ebp-A34]=[0012CD7C]=000001B7清0
0181C911 . 0F8C A8020000 JL Cam.0181CBBF
0181C917 . 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34]
0181C91D . 3B0D D4738501 CMP ECX,DWORD PTR DS:[18573D4] //注意[18573D4]
0181C923 0F8D 96020000 JGE Cam.0181CBBF //解码结束后跳转0181CBBF 在0181CBBF处下断
0181C929 . 8B95 40F6FFFF MOV EDX,DWORD PTR SS:[EBP-9C0]
0181C92F . 81E2 FF000000 AND EDX,0FF
0181C935 . 85D2 TEST EDX,EDX
0181C937 . 0F84 AD000000 JE Cam.0181C9EA
0181C93D . 6A 00 PUSH 0
0181C93F . 8BB5 CCF5FFFF MOV ESI,DWORD PTR SS:[EBP-A34]
0181C945 . C1E6 04 SHL ESI,4
0181C948 . 8B85 CCF5FFFF MOV EAX,DWORD PTR SS:[EBP-A34]
0181C94E . 25 07000080 AND EAX,80000007
0181C953 . 79 05 JNS SHORT Cam.0181C95A
0181C955 . 48 DEC EAX
0181C956 . 83C8 F8 OR EAX,FFFFFFF8 //找到这里
0181C959 . 40 INC EAX
0181C95A > 33C9 XOR ECX,ECX
0181C95C . 8A88 BC4D8501 MOV CL,BYTE PTR DS:[EAX+1854DBC]
0181C962 . 8B95 CCF5FFFF MOV EDX,DWORD PTR SS:[EBP-A34]
0181C968 . 81E2 07000080 AND EDX,80000007
0181C96E . 79 05 JNS SHORT Cam.0181C975
0181C970 . 4A DEC EDX
0181C971 . 83CA F8 OR EDX,FFFFFFF8
0181C974 . 42 INC EDX
0181C975 > 33C0 XOR EAX,EAX
0181C977 . 8A82 BD4D8501 MOV AL,BYTE PTR DS:[EDX+1854DBD]
0181C97D . 8B3C8D 840385>MOV EDI,DWORD PTR DS:[ECX*4+1850384]
0181C984 . 333C85 840385>XOR EDI,DWORD PTR DS:[EAX*4+1850384]
0181C98B . 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34]
0181C991 . 81E1 07000080 AND ECX,80000007
0181C997 . 79 05 JNS SHORT Cam.0181C99E
0181C999 . 49 DEC ECX
0181C99A . 83C9 F8 OR ECX,FFFFFFF8
0181C99D . 41 INC ECX
0181C99E > 33D2 XOR EDX,EDX
0181C9A0 . 8A91 BE4D8501 MOV DL,BYTE PTR DS:[ECX+1854DBE]
0181C9A6 . 333C95 840385>XOR EDI,DWORD PTR DS:[EDX*4+1850384]
0181C9AD . 8B85 CCF5FFFF MOV EAX,DWORD PTR SS:[EBP-A34]
0181C9B3 . 99 CDQ
0181C9B4 . B9 1C000000 MOV ECX,1C
0181C9B9 . F7F9 IDIV ECX
0181C9BB . 8BCA MOV ECX,EDX
0181C9BD . D3EF SHR EDI,CL
0181C9BF . 83E7 0F AND EDI,0F
0181C9C2 . 03F7 ADD ESI,EDI
0181C9C4 . 8B15 B8738501 MOV EDX,DWORD PTR DS:[18573B8]
0181C9CA . 8D04B2 LEA EAX,DWORD PTR DS:[EDX+ESI*4]
0181C9CD . 50 PUSH EAX
0181C9CE . 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34]
0181C9D4 . 51 PUSH ECX
0181C9D5 . E8 68210000 CALL Cam.0181EB42
0181C9DA . 83C4 0C ADD ESP,0C
0181C9DD 25 FF000000 AND EAX,0FF //这里Patch
0181C9E2 85C0 TEST EAX,EAX
0181C9E4 0F84 D5010000 JE Cam.0181CBBF
0181C9EA 837D D8 00 CMP DWORD PTR SS:[EBP-28],0
0181C9EE 75 27 JNZ SHORT Cam.0181CA17
0181C9F0 8B15 04048501 MOV EDX,DWORD PTR DS:[1850404]
0181C9F6 . 3315 D8038501 XOR EDX,DWORD PTR DS:[18503D8]
找到PATCH的地方0181C9DD处,
Patch代码:
0181C9DD FF85 CCF5FFFF INC DWORD PTR SS:[EBP-0A34]
0181C9E3 C705 D8738501>MOV DWORD PTR DS:[18573D4+4],1
0181C9ED ^ E9 18FFFFFF JMP 0181C90A
下断BP WriteProcessMemory,shift+f9
中断在上面BP WriteProcessMemory断点处。看数据窗口:
0012ED7C 01 00 00 00 AC 02 00 00 F0 03 00 00 01 00 00 80 .ʬ.ϰ. 耀
0012ED8C 00 00 00 00 00 00 00 00 70 08 77 00 02 00 00 00 ....ࡰw .
0012ED9C 00 00 00 00 70 08 77 00 70 08 77 00 64 2D FA F3 ..ࡰwࡰwⵤ
0012EDAC 00 00 00 00 60 2D FA F3 00 00 00 00 00 00 00 00 ..ⵠ....
0012EDBC 13 00 00 00 F6 85 56 00 64 2D FA F3 F1 2F 4E 80 .藶Vⵤ⿱聎
0012EDCC 00 00 00 00 70 08 77 00 01 00 00 00 01 00 00 00 ..ࡰw . .
0012EDDC 01 6A 94 7C 00 00 00 00 00 00 00 00 00 00 00 00 樁粔......
很明显可以看到OEP=00770870
取消WriteProcessMemory处断点,继续Shift+F9,中断在0181CBBF 处
此时子进程代码已经解开,运行LordPE,完全Dump出子进程
到此,打开Dump的程序,发现出现错误,那肯定是输入表没的搞定了
二、搞定输入表
再次载入主程序
下断:BP DebugActiveProcess 中断后看堆栈:
0012DC90 0181C1DA /CALL 到 DebugActiveProcess 来自 Cam.0181C1D4
0012DC94 0000016C \ProcessId = 16C
0012DC98 7C930738 ntdll.7C930738
新开一个OllyDbg,附加进程ID 16C的子进程
F9,再F12,会暂停在EP处
0182C243 >- EB FE JMP SHORT Cam.<模块入口点>
0182C245 EC IN AL,DX ; I/O 命令
0182C246 6A FF PUSH -1
0182C248 68 405F8501 PUSH Cam.01855F40
0182C24D 68 80BF8201 PUSH Cam.0182BF80 ; SE 处理程序安装
0182C252 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0182C258 50 PUSH EAX
0182C259 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0182C260 83EC 58 SUB ESP,58
0182C263 53 PUSH EBX
0182C264 56 PUSH ESI
0182C265 57 PUSH EDI
0182C266 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
0182C269 FF15 88018501 CALL DWORD PTR DS:[<&KERNEL32.GetVersion>; kernel32.GetVersion
0182C26F 33D2 XOR EDX,EDX
0182C243 >- EB FE JMP SHORT Cam.<模块入口点>
//子进程在EP处死循环 恢复原来EP处的代码:55 8B
就这这样了
0182C243 > 55 PUSH EBP
0182C244 8BEC MOV EBP,ESP
0182C246 6A FF PUSH -1
0182C248 68 405F8501 PUSH Cam.01855F40
0182C24D 68 80BF8201 PUSH Cam.0182BF80 ; SE 处理程序安装
0182C252 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0182C258 50 PUSH EAX
0182C259 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
下断BP OpenMutexA Shift+F9,中断后看堆栈:
0012F798 01817DB8 /CALL 到 OpenMutexA 来自 Cam.01817DB2
0012F79C 001F0001 |Access = 1F0001
0012F7A0 00000000 |Inheritable = FALSE
0012F7A4 0012FDD8 \MutexName = "16C::DA3428C337"
0012F7A8 0012D6B8
0012F7AC 00000000
一看就知道当然是为了切换成单进程,
在CPU窗口中 Ctrl+G:401000 键入以下代码:
00401000 60 PUSHAD
00401001 9C PUSHFD
00401002 68 D8FD1200 PUSH 12FDD8 ; ★ 堆栈里看到的值
00401007 33C0 XOR EAX,EAX
00401009 50 PUSH EAX
0040100A 50 PUSH EAX
0040100B E8 08A6A577 CALL kernel32.CreateMutexA
00401010 9D POPFD
00401011 61 POPAD
00401012 - E9 D012A677 JMP kernel32.OpenMutexA
00401017 90 NOP
二进制:
60 9C 68 D8 FD 12 00 33 C0 50 50 E8 2F DB 40 7C 9D 61 E9 04 DC 40 7C 90
在 401000 处点鼠标右键 "此处为新 EIP",F9运行,再次中断在OpenMutexA处,此时Ctrl+G:401000 撤销刚才的修改的代码,使代码还原。OK,父进程分离完毕!清除 OpenMutexA 断点.
下断:HE GetModuleHandleA Shift+F9,注意看堆栈:
0012EE64 5D175394 /CALL 到 GetModuleHandleA 来自 5D17538E
0012EE68 5D1753E0 \pModule = "kernel32.dll"
0012EE6C 5D1E2B38
Shift+F9
0012EF24 77F45BB0 /CALL 到 GetModuleHandleA 来自 SHLWAPI.77F45BAA
0012EF28 77F44FF4 \pModule = "KERNEL32.DLL"
0012EF2C 00000001
Shift+F9
0012F73C 01816EF3 /CALL 到 GetModuleHandleA 来自 Cam.01816EED
0012F740 00000000 \pModule = NULL
0012F744 0012F750
Shift+F9
00129528 02486DF3 /CALL 到 GetModuleHandleA 来自 02486DED
0012952C 0249BC1C \pModule = "kernel32.dll"
00129530 0249CEC4 ASCII "VirtualAlloc"
00129534 0249FA98
Shift+F9
00129528 02486E10 /CALL 到 GetModuleHandleA 来自 02486E0A
0012952C 0249BC1C \pModule = "kernel32.dll"
00129530 0249CEB8 ASCII "VirtualFree"
00129534 0249FA98
Shift+F9
0012928C 02475CE1 /CALL 到 GetModuleHandleA 来自 02475CDB
00129290 001293DC \pModule = "kernel32.dll" 返回的时机到了 Alt+F9
00129294 00000000
到这里,正是返回的时候,取消GetModuleHandleA处断点,Alt+F9返回
02475CE1 8B0D AC404A02 MOV ECX,DWORD PTR DS:[24A40AC] //返回这里
02475CE7 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
02475CEA A1 AC404A02 MOV EAX,DWORD PTR DS:[24A40AC]
02475CEF 391C06 CMP DWORD PTR DS:[ESI+EAX],EBX
02475CF2 75 16 JNZ SHORT 02475D0A
02475CF4 8D85 B4FEFFFF LEA EAX,DWORD PTR SS:[EBP-14C]
02475CFA 50 PUSH EAX
02475CFB FF15 BC624902 CALL DWORD PTR DS:[24962BC] ; kernel32.LoadLibraryA
02475D01 8B0D AC404A02 MOV ECX,DWORD PTR DS:[24A40AC]
02475D07 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
02475D0A A1 AC404A02 MOV EAX,DWORD PTR DS:[24A40AC]
02475D0F 391C06 CMP DWORD PTR DS:[ESI+EAX],EBX
02475D12 0F84 2F010000 JE 02475E47 //Magic Jump! 修改为:jmp 02475E47
02475D18 33C9 XOR ECX,ECX
02475D1A 8B07 MOV EAX,DWORD PTR DS:[EDI]
02475D1C 3918 CMP DWORD PTR DS:[EAX],EBX
02475D1E 74 06 JE SHORT 02475D26
02475D20 41 INC ECX
02475D21 83C0 0C ADD EAX,0C
02475D24 ^ EB F6 JMP SHORT 02475D1C
02475D26 8BD9 MOV EBX,ECX
02475D28 C1E3 02 SHL EBX,2
02475D2B 53 PUSH EBX
02475D2C E8 63F20100 CALL 02494F94 ; JMP 到 msvcrt.??2@YAPAXI@Z
02475D31 8B0D A4404A02 MOV ECX,DWORD PTR DS:[24A40A4]
ARM CopyMem-II在处理输入表的时候还有时间校验,不处理的话会导致某些函数被加密
下断:BP GetTickCount 中断后取消断点返回
7C8092AC > BA 0000FE7F MOV EDX,7FFE0000 断在这里,取消断点后alt+f9返回
7C8092B1 8B02 MOV EAX,DWORD PTR DS:[EDX]
7C8092B3 F762 04 MUL DWORD PTR DS:[EDX+4]
7C8092B6 0FACD0 18 SHRD EAX,EDX,18
7C8092BA C3 RETN
7C8092BB 90 NOP
7C8092BC 90 NOP
返回到这里
0248C009 8985 A4D4FFFF MOV DWORD PTR SS:[EBP-2B5C],EAX ; Cam.006342A3
0248C00F 6A 01 PUSH 1
0248C011 58 POP EAX
0248C012 85C0 TEST EAX,EAX
0248C014 0F84 A8030000 JE 0248C3C2
0248C01A 8B85 84D9FFFF MOV EAX,DWORD PTR SS:[EBP-267C]
0248C020 66:8B00 MOV AX,WORD PTR DS:[EAX]
0248C023 66:8985 64C2FFF>MOV WORD PTR SS:[EBP-3D9C],AX
0248C02A 8B85 84D9FFFF MOV EAX,DWORD PTR SS:[EBP-267C]
0248C030 40 INC EAX
下面还有一处GetTickCount取时间 往下看,找到这里
0248C38B 33C0 XOR EAX,EAX
0248C38D E9 22140000 JMP 0248D7B4
0248C392 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
0248C398 3B85 64D9FFFF CMP EAX,DWORD PTR SS:[EBP-269C]
0248C39E 73 1D JNB SHORT 0248C3BD
0248C3A0 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
0248C3A6 8B8D 68CAFFFF MOV ECX,DWORD PTR SS:[EBP-3598]
0248C3AC 8908 MOV DWORD PTR DS:[EAX],ECX //函数写入。在这里可以看见输入表函数开始地址005D7208
0248C3AE 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
0248C3B4 83C0 04 ADD EAX,4
0248C3B7 8985 10D9FFFF MOV DWORD PTR SS:[EBP-26F0],EAX
0248C3BD ^ E9 4DFCFFFF JMP 0248C00F
0248C3C2 FF15 7C624902 CALL DWORD PTR DS:[249627C] ; kernel32.GetTickCount
0248C3C8 2B85 A4D4FFFF SUB EAX,DWORD PTR SS:[EBP-2B5C]
0248C3CE 8B8D A8D4FFFF MOV ECX,DWORD PTR SS:[EBP-2B58]
0248C3D4 6BC9 32 IMUL ECX,ECX,32
0248C3D7 81C1 D0070000 ADD ECX,7D0
0248C3DD 3BC1 CMP EAX,ECX //时间校验
0248C3DF 76 07 JBE SHORT 0248C3E8 //修改为:JMP 0248C3E8
0248C3E1 C685 34D9FFFF 0>MOV BYTE PTR SS:[EBP-26CC],1
0248C3E8 83BD E4D7FFFF 0>CMP DWORD PTR SS:[EBP-281C],0
0248C3EF 0F85 8A000000 JNZ 0248C47F
0248C3F5 0FB685 94D4FFFF MOVZX EAX,BYTE PTR SS:[EBP-2B6C]
0248C3FC 85C0 TEST EAX,EAX
0248C3FE 74 7F JE SHORT 0248C47F
0248C400 6A 00 PUSH 0
0248C402 8B85 98D4FFFF MOV EAX,DWORD PTR SS:[EBP-2B68]
0248C408 C1E0 02 SHL EAX,2
0248C40B 50 PUSH EAX
0248C40C 8B85 0CD8FFFF MOV EAX,DWORD PTR SS:[EBP-27F4]
0248C412 0385 90D4FFFF ADD EAX,DWORD PTR SS:[EBP-2B70]
0248C418 50 PUSH EAX
0248C419 E8 131E0000 CALL 0248E231
0248C41E 83C4 0C ADD ESP,0C
0248C421 8B85 98D4FFFF MOV EAX,DWORD PTR SS:[EBP-2B68]
0248C427 C1E0 02 SHL EAX,2
0248C42A 50 PUSH EAX
0248C42B FFB5 6CD9FFFF PUSH DWORD PTR SS:[EBP-2694]
0248C431 8B85 0CD8FFFF MOV EAX,DWORD PTR SS:[EBP-27F4]
0248C437 0385 90D4FFFF ADD EAX,DWORD PTR SS:[EBP-2B70]
0248C43D 50 PUSH EAX
0248C43E E8 4B8B0000 CALL 02494F8E ; JMP 到 msvcrt.memcpy
0248C443 83C4 0C ADD ESP,0C
0248C446 6A 01 PUSH 1
0248C448 8B85 98D4FFFF MOV EAX,DWORD PTR SS:[EBP-2B68]
0248C44E C1E0 02 SHL EAX,2
0248C451 50 PUSH EAX
0248C452 8B85 0CD8FFFF MOV EAX,DWORD PTR SS:[EBP-27F4]
0248C458 0385 90D4FFFF ADD EAX,DWORD PTR SS:[EBP-2B70]
0248C45E 50 PUSH EAX
0248C45F E8 CD1D0000 CALL 0248E231
0248C464 83C4 0C ADD ESP,0C
0248C467 8B85 6CD9FFFF MOV EAX,DWORD PTR SS:[EBP-2694]
0248C46D 8985 A4ABFFFF MOV DWORD PTR SS:[EBP+FFFFABA4],EAX
0248C473 FFB5 A4ABFFFF PUSH DWORD PTR SS:[EBP+FFFFABA4]
0248C479 E8 0A8B0000 CALL 02494F88 ; JMP 到 msvcrt.??3@YAXPAX@Z
0248C47E 59 POP ECX
0248C47F ^ E9 30F7FFFF JMP 0248BBB4
0248C484 8B85 F0D7FFFF MOV EAX,DWORD PTR SS:[EBP-2810] //这里下断,中断后输入表处理完毕
在0248C3AC 8908 MOV DWORD PTR DS:[EAX],ECX 处下断,就可以看到第一次函数写入的地址013d547c
在命令框中输入D 013d547c,在数据窗口中查看属性中选长型,地址。取消013d547c处的断点,shift+f9程序中断在0248C484处,到此输入表处理完毕,在数据窗口中找出输入表的开始地址及大小
运行ImportREC,选择这个进程。填入RVA=FD4F2C、Size=00002000,Get Import剪切掉无效函数,修改OEP RVA= 00370870,FixDump,正常运行!
希望H大可以批准通过,真心想来贵论坛学习
|