本帖最后由 solly 于 2024-3-9 10:54 编辑
这是一个分段解密的壳,看程序节信息,只有0x00401000~0x00402000之间是可执行,所以在先在0x00401200, 0x00401400, 0x00401800, 0x00401A00 下4个硬件写入断点,然后执行crackme,最终前面3个会断下来,最后一个没有断下来,表示没有用到,所以确定解密过程在 0x00401800~00401A00之间结束,在这个区间内继续下3个硬件断点再来一次:如 0x00401880, 0x00401900, 0x00401980,最后又是前2个断下来了,再就是在 0x00401900~0x00401980内下断点了,可以看到这个区间后面都是0了,应该是代码段要结束了,所以在最后一个非0字节下一个断点吧,然后执行,断在如下处:
[Asm] 纯文本查看 复制代码 004093F0 | C00A 03 | ROR BYTE PTR DS:[EDX],3 |
004093F3 | 87DD | XCHG EBP,EBX |
004093F5 | 56 | PUSH ESI |
然后F7一路逢call必进,到下面这里:
[Asm] 纯文本查看 复制代码 0040958D | 40 | INC EAX |
0040958E | 60 | PUSHAD |
0040958F | 56 | PUSH ESI |
00409590 | 83EC FC | SUB ESP,FFFFFFFC |
00409593 | 83C4 20 | ADD ESP,20 |
00409596 | 48 | DEC EAX |
00409597 | 83C2 01 | ADD EDX,1 |
0040959A | 83C1 FF | ADD ECX,FFFFFFFF |
0040959D | 75 8B | JNE unpackme4.40952A |
这里是恢复 IAT 了,一个循环,EAX++,ECX--,在下面下断点:
[Asm] 纯文本查看 复制代码 0040959F | 68 2386F7DA | PUSH DAF78623 |
F9执行。断下后又是一路F7,来到这里:
[Asm] 纯文本查看 复制代码 00409676 | 40 | INC EAX |
00409677 | 48 | DEC EAX |
00409678 | 83C4 20 | ADD ESP,20 |
0040967B | 48 | DEC EAX |
0040967C | C00A 04 | ROR BYTE PTR DS:[EDX],4 |
0040967F | E8 01000000 | CALL unpackme4.409685 |
00409684 | 5B | POP EBX |
00409685 | E8 00000000 | CALL unpackme4.40968A | call $0
0040968A | C70424 2B1BEB32 | MOV DWORD PTR SS:[ESP],32EB1B2B | [esp]:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
00409691 | 81C0 92CD3C56 | ADD EAX,563CCD92 |
00409697 | 81E8 92CD3C56 | SUB EAX,563CCD92 |
0040969D | 83EC FC | SUB ESP,FFFFFFFC |
004096A0 | 83EC FC | SUB ESP,FFFFFFFC |
004096A3 | 83C2 01 | ADD EDX,1 |
004096A6 | 83C1 FF | ADD ECX,FFFFFFFF |
004096A9 | 0F85 74FFFFFF | JNE unpackme4.409623 |
004096AF | 68 F864F7B8 | PUSH B8F764F8 |
又是一个循环,EAX++,ECX--,又在循环后下面F2断点,F9执行,断下后又是一路F7,逢call必进,来到这里:
[Asm] 纯文本查看 复制代码 004097F0 | C70424 2DC2EB67 | MOV DWORD PTR SS:[ESP],67EBC22D | [esp]:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
004097F7 | 83EC FC | SUB ESP,FFFFFFFC |
004097FA | 4B | DEC EBX |
004097FB | 81EA 38A9741A | SUB EDX,1A74A938 |
00409801 | 83EA FF | SUB EDX,FFFFFFFF |
00409804 | 83C1 FF | ADD ECX,FFFFFFFF |
00409807 | 85C9 | TEST ECX,ECX |
00409809 | 0F85 36FFFFFF | JNE unpackme4.409745 |
0040980F | 57 | PUSH EDI |
00409810 | 56 | PUSH ESI |
00409811 | E8 D8000000 | CALL unpackme4.4098EE |
00409816 | A1 58214000 | MOV EAX,DWORD PTR DS:[402158] |
0040981B | C3 | RET |
0040981C | 90 | NOP |
最后一个循环了吧,在循环后面(0x0040980F)下 F2 断点,F9执行,断下后,F7进入 call 0x004098EE:
[Asm] 纯文本查看 复制代码 004098EE | 5E | POP ESI |
004098EF | BF 00104000 | MOV EDI,<unpackme4.EntryPoint> | edi:EntryPoint
004098F4 | B9 36000000 | MOV ECX,36 | 36:'6'
004098F9 | F3:A5 | REP MOVSD |
004098FB | 5E | POP ESI |
004098FC | 5F | POP EDI | edi:EntryPoint
这里进行壳的入口代码恢复为crackme的原始代码。F8一路执行,来到这里:
[Asm] 纯文本查看 复制代码 0040990F | 3E:8B45 0C | MOV EAX,DWORD PTR DS:[EBP+C] |
00409913 | 05 00004000 | ADD EAX,unpackme4.400000 |
00409918 | 50 | PUSH EAX |
00409919 | FFD7 | CALL EDI |
0040991B | 83EC 04 | SUB ESP,4 |
0040991E | 50 | PUSH EAX |
0040991F | 33DB | XOR EBX,EBX |
00409921 | 8B45 00 | MOV EAX,DWORD PTR SS:[EBP] |
00409924 | 8B8418 00004000 | MOV EAX,DWORD PTR DS:[EAX+EBX+400000] |
0040992B | A9 00000080 | TEST EAX,80000000 |
00409930 | 74 07 | JE unpackme4.409939 |
00409932 | 25 FFFF0000 | AND EAX,FFFF |
00409937 | EB 09 | JMP unpackme4.409942 |
00409939 | 85C0 | TEST EAX,EAX |
0040993B | 74 1D | JE unpackme4.40995A |
0040993D | 05 02004000 | ADD EAX,unpackme4.400002 |
00409942 | 894424 04 | MOV DWORD PTR SS:[ESP+4],EAX |
00409946 | FFD6 | CALL ESI |
00409948 | 83EC 08 | SUB ESP,8 |
0040994B | 8B4D 10 | MOV ECX,DWORD PTR SS:[EBP+10] |
0040994E | 898419 00004000 | MOV DWORD PTR DS:[ECX+EBX+400000],EAX |
00409955 | 83C3 04 | ADD EBX,4 |
00409958 | EB C7 | JMP unpackme4.409921 |
0040995A | 83C4 08 | ADD ESP,8 |
0040995D | 83C5 14 | ADD EBP,14 |
00409960 | 837D 10 00 | CMP DWORD PTR SS:[EBP+10],0 |
00409964 | 75 A9 | JNE unpackme4.40990F |
这里是加载DLL的导出函数的入口地址了。在大循环后面(0x00409966)下 F2 断点,F9执行,再一路 F7 来到这里:
[Asm] 纯文本查看 复制代码 00409995 | EB 05 | JMP unpackme4.40999C |
00409997 | 41 | INC ECX | ecx:"姍@"
00409998 | F6F9 | IDIV CL |
0040999A | 2F | DAS |
0040999B | 55 | PUSH EBP |
0040999C | 83EC FC | SUB ESP,FFFFFFFC |
0040999F | 83EC E0 | SUB ESP,FFFFFFE0 |
004099A2 | C3 | RET |
一路F8, ret 后到这里:
[Asm] 纯文本查看 复制代码 0040998A | 60 | PUSHAD |
0040998B | E8 05000000 | CALL unpackme4.409995 |
00409990 | 83B40D 6A18EB05 41 | XOR DWORD PTR SS:[EBP+ECX+5EB186A],41 |
然后还是一路 F7 ,ret 和call几次后,就会到这里:
[Asm] 纯文本查看 复制代码 00407000 | 0F31 | RDTSC |
00407002 | 33C9 | XOR ECX,ECX |
00407004 | 03C8 | ADD ECX,EAX |
00407006 | EB 58 | JMP unpackme4.407060 |
这里是时钟反调试,后面还有一个 RDTSC 。还是一路 F7 到这里:
[Asm] 纯文本查看 复制代码 00407060 | 0F31 | RDTSC |
00407062 | 2BC1 | SUB EAX,ECX |
00407064 | 3D FF0F0000 | CMP EAX,FFF |
00407069 | 0F83 A3000000 | JAE unpackme4.407112 |
0040706F | E9 84000000 | JMP unpackme4.4070F8 |
这里的 JAE跳转是反调试用的,不能跳转,下面的那个 JMP 才是正确的线路。执行这个 JMP 0x004070F8,来到这里:
[Asm] 纯文本查看 复制代码 004070F8 | B8 00174000 | MOV EAX,unpackme4.401700 |
004070FD | 33F6 | XOR ESI,ESI | esi:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
004070FF | 33DB | XOR EBX,EBX |
00407101 | 8A1C06 | MOV BL,BYTE PTR DS:[ESI+EAX] |
00407104 | 80EB FF | SUB BL,FF |
00407107 | 881C06 | MOV BYTE PTR DS:[ESI+EAX],BL |
0040710A | 46 | INC ESI | esi:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users"
0040710B | 83FE 32 | CMP ESI,32 | esi:&L"ALLUSERSPROFILE=C:\\Documents and Settings\\All Users", 32:'2'
0040710E | 75 F1 | JNE unpackme4.407101 |
00407110 | FFE0 | JMP EAX |
就可以看到 OEP 了。执行最后那条指令:
[Asm] 纯文本查看 复制代码 00407110 | FFE0 | JMP EAX |
你就到 OEP 去了。
另外,delphi 和 VB 的入口也很好找的,特征都很明显。
|