【文章标题】:脱壳手记---themida(1.8.5.5)
【文章作者】: qqmcc
【下载地址】: sayhello.rar
载入OD后,先看看Memory map,看到多了个壳段(图1)
00401000下硬件写入断点
两次shift+f9断在
00618D04 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
这里写入代码段,之后去00401000看看
00401000 55 PUSH EBP
00401001 8BEC MOV EBP,ESP
00401003 51 PUSH ECX
00401004 53 PUSH EBX
00401005 56 PUSH ESI
00401006 57 PUSH EDI
00401007 68 30604000 PUSH 00406030 ; ASCII "hello"
0040100C 6A 65 PUSH 65
0040100E 6A 00 PUSH 0
00401010 90 NOP
00401011 90 NOP 00401012 90 NOP
00401013 90 NOP
00401014 90 NOP
00401015 90 NOP
00401016 8BF0 MOV ESI,EAX
00401018 56 PUSH ESI
00401019 6A 00 PUSH 0
0040101B 90 NOP
0040101C 90 NOP ;下硬件写入断点
0040101D 90 NOP
0040101E 90 NOP
0040101F 90 NOP
00401020 90 NOP
00401021 56 PUSH ESI
00401022 6A 00 PUSH 0
00401024 90 NOP
00401025 90 NOP
00401026 90 NOP
00401027 90 NOP
00401028 90 NOP
00401029 90 NOP
0040102A 8BF0 MOV ESI,EAX
006229DB 8B85 B1250E0A MOV EAX,DWORD PTR SS:[EBP+A0E25B1]
006229E1 2BC7 SUB EAX,EDI
006229E3 83E8 04 SUB EAX,4 ;取得CALL偏移
006229E6 AB STOS DWORD PTR ES:[EDI] ;填充CALL偏移
006229E7 AD LODS DWORD PTR DS:[ESI] ;将[esi]赋值eax
[esi]是一张表见(图2)
006229E8 C746 FC 0000000>MOV DWORD PTR DS:[ESI-4],0 ;清零
006229EF ^ E9 11FFFFFF JMP 00622905 ;这里跳回去看是都还有需要处理的”nop”
00622905 MOV DWORD PTRSS:[EBP+A0E04DD],ESI ;比较[esi]的值
0062290B 83F8 FF CMP EAX,-1 ;比较是否为FFFFFFFF
0062290E 0F85 20000000 JNZ 00622934 ;不是就跳走
00622914 813E DDDDDDDD CMP DWORD PTR DS:[ESI],DDDDDDDD ;比较当前[esi]是否为DDDDDDDD
0062291A 0F85 14000000 JNZ 00622934 ;不是跳走,应为结束标记以控制循环
00622920 C706 00000000 MOV DWORD PTR DS:[ESI],0 ;当前[ESI]填0,
00622926 83C6 04 ADD ESI,4 ;处理下一个[ESI+4]
00622929 89B5 DD040E0A MOV DWORD PTR SS:[EBP+A0E04DD],ESI
0062292F ^ E9 E6F6FFFF JMP 0062201A ;关注这个跳转,新一轮的解码处理
00622934 C1C0 03 ROL EAX,3
00622937 0385 45180E0A ADD EAX,DWORD PTR SS:[EBP+A0E1845]
0062293D 83BD 9D190E0A 0>CMP DWORD PTR SS:[EBP+A0E199D],1
00622944 0F84 9D000000 JE 006229E7
0062294A 813E AAAAAAAA CMP DWORD PTR DS:[ESI],AAAAAAAA
00622950 0F85 12000000 JNZ 00622968
0062201A C785 31110E0A 0>MOV DWORD PTR SS:[EBP+A0E1131],0;;从跳转到这里开始分析
00622024 C785 F5110E0A 0>MOV DWORD PTR SS:[EBP+A0E11F5],0
0062202E 83BD 723F1E0A 0>CMP DWORD PTR SS:[EBP+A1E3F72],0
00622035 0F84 08000000 JE 00622043
0062203B 8D9D 3D2C1D0A LEA EBX,DWORD PTR SS:[EBP+A1D2C3D]
00622041 FFD3 CALL EBX
00622043 FF85 9D120E0A INC DWORD PTR SS:[EBP+A0E129D]
00622049 83BD 9D120E0A 6>CMP DWORD PTR SS:[EBP+A0E129D],64 ;处理的元素大于0x64则进行一次校验
00622050 0F82 62000000 JB 006220B8 ;可以改成jmp忽略校验
00622056 C785 9D120E0A 0>MOV DWORD PTR SS:[EBP+A0E129D],1
00622060 60 PUSHAD
00622061 8DB5 4A401E0A LEA ESI,DWORD PTR SS:[EBP+A1E404A]
00622067 8DBD B55C1E0A LEA EDI,DWORD PTR SS:[EBP+A1E5CB5]
0062206D 2BFE SUB EDI,ESI
0062206F 8BD7 MOV EDX,EDI ;校验数据长度
00622071 8BBD 41150E0A MOV EDI,DWORD PTR SS:[EBP+A0E1541]
00622077 83C9 FF OR ECX,FFFFFFFF ;初始化校验值
0062207A 33C0 XOR EAX,EAX
0062207C 8A06 MOV AL,BYTE PTR DS:[ESI] ;校验数据起始地址
0062207E 32C1 XOR AL,CL
00622080 46 INC ESI
00622081 8B0487 MOV EAX,DWORD PTR DS:[EDI+EAX*4];查校验码表
00622084 C1E9 08 SHR ECX,8
00622087 33C8 XOR ECX,EAX
00622089 4A DEC EDX
0062208A ^ 0F85 EAFFFFFF JNZ 0062207A ;循环检验
00622090 8BC1 MOV EAX,ECX
00622092 F7D0 NOT EAX ;得到最终验证码
00622094 3985 ED090E0A CMP DWORD PTR SS:[EBP+A0E09ED],EAX ;校验比较
006220B8 B9 9CE7F31D MOV ECX,1DF3E79C
006220BD BA C4498C24 MOV EDX,248C49C4
006220C2 AD LODS DWORD PTR DS:[ESI]
006220C3 89B5 DD040E0A MOV DWORD PTR SS:[EBP+A0E04DD],ESI
006220C9 C746 FC 0000000>MOV DWORD PTR DS:[ESI-4],0
006220D0 3D EEEEEEEE CMP EAX,EEEEEEEE
006220D5 0F85 20000000 JNZ 006220FB
006220DB 813E DDDDDDDD CMP DWORD PTR DS:[ESI],DDDDDDDD; EEEEEEEEDDDDDDDD实际上应为表全部处理完毕标识
006220E1 0F85 14000000 JNZ 006220FB
006220E7 C706 00000000 MOV DWORD PTR DS:[ESI],0
006220ED 83C6 04 ADD ESI,4
006220F0 89B5 DD040E0A MOV DWORD PTR SS:[EBP+A0E04DD],ESI
006220F6 E9 F9080000 JMP 006229F4 ;跳出处理循环,到此处后可在代码段下访问断点来到OEP
006220FB 8BD8 MOV EBX,EAX
006220FD 3385 A9050E0A XOR EAX,DWORD PTR SS:[EBP+A0E05A9]
00622103 C1C8 03 ROR EAX,3
00622106 2BC2 SUB EAX,EDX
00622108 C1C0 10 ROL EAX,10
0062210B 33C1 XOR EAX,ECX
0062210D 899D A9050E0A MOV DWORD PTR SS:[EBP+A0E05A9],EBX
00622113 3D 00000100 CMP EAX,10000
00622118 0F83 45000000 JNB 00622163
0062211E 813E BBBBBBBB CMP DWORD PTR DS:[ESI],BBBBBBBB
00622124 0F85 39000000 JNZ 00622163
0062212A C706 00000000 MOV DWORD PTR DS:[ESI],0
00622130 83C6 04 ADD ESI,4
00622133 89B5 DD040E0A MOV DWORD PTR SS:[EBP+A0E04DD],ESI
00622139 8B9D F1230E0A MOV EBX,DWORD PTR SS:[EBP+A0E23F1]
0062213F 8B0B MOV ECX,DWORD PTR DS:[EBX]
00622141 8BD0 MOV EDX,EAX
00622143 60 PUSHAD
00622144 8BC2 MOV EAX,EDX
00622146 2B85 310A0E0A SUB EAX,DWORD PTR SS:[EBP+A0E0A31]
0062214C C1E0 02 SHL EAX,2
0062214F 0385 A1050E0A ADD EAX,DWORD PTR SS:[EBP+A0E05A1]
00622155 96 XCHG EAX,ESI
00622156 AD LODS DWORD PTR DS:[ESI]
00622157 03C1 ADD EAX,ECX
00622159 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX
0062215D 61 POPAD
0062215E E9 7C000000 JMP 006221DF
0062215E E9 7C000000 JMP 006221DF
00622163 51 PUSH ECX
00622164 52 PUSH EDX
00622165 33C9 XOR ECX,ECX
00622167 8B95 2D0B0E0A MOV EDX,DWORD PTR SS:[EBP+A0E0B2D];[esi]表中取得的第一个元素将和[EBP+A0E0B2D]数组的元素一一对比
它是取得原始API的一个KEY
0062216D 3B02 CMP EAX,DWORD PTR DS:[EDX]
0062216F 0F84 38000000 JE sayhello.006221AD ;找到后跳转到后续执行
00622175 83C2 04 ADD EDX,4
00622178 41 INC ECX ;此时的ecx将是[EBP+A0E0B2D]表的数组下标
00622179 3B8D 59040E0A CMP ECX,DWORD PTR SS:[EBP+A0E0459]
0062217F ^ 0F85 E8FFFFFF JNZ sayhello.0062216D
00622185 8DB5 2F3F1E0A LEA ESI,DWORD PTR SS:[EBP+A1E3F2F]
0062218B 8DBD 2D010E0A LEA EDI,DWORD PTR SS:[EBP+A0E012D]
00622191 AC LODS BYTE PTR DS:[ESI]
00622192 84C0 TEST AL,AL
00622194 0F84 06000000 JE sayhello.006221A0
0062219A AA STOS BYTE PTR ES:[EDI]
0062219B ^ E9 F1FFFFFF JMP sayhello.00622191
006221A0 B8 00000000 MOV EAX,0
006221A5 8D8D 734B0E0A LEA ECX,DWORD PTR SS:[EBP+A0E4B73]
006221AB FFE1 JMP ECX
006221AD 898D C9310E0A MOV DWORD PTR SS:[EBP+A0E31C9],ECX
006221B3 5A POP EDX
006221B4 59 POP ECX
006221B5 56 PUSH ESI
006221B6 8B9D F1230E0A MOV EBX,DWORD PTR SS:[EBP+A0E23F1]
006221BC 8B0B MOV ECX,DWORD PTR DS:[EBX]
006221BE 8B85 C9310E0A MOV EAX,DWORD PTR SS:[EBP+A0E31C9]
006221C4 D1E0 SHL EAX,1
006221C6 0385 CD270E0A ADD EAX,DWORD PTR SS:[EBP+A0E27CD]
006221CC 33F6 XOR ESI,ESI
006221CE 96 XCHG EAX,ESI
006221CF 66:AD LODS WORD PTR DS:[ESI]
006221D1 C1E0 02 SHL EAX,2
006221D4 0385 A1050E0A ADD EAX,DWORD PTR SS:[EBP+A0E05A1]
006221DA 96 XCHG EAX,ESI
006221DB AD LODS DWORD PTR DS:[ESI]
006221DC 03C1 ADD EAX,ECX ;到这里eax出现了api地址,
此时我们明白第一个元素解析出API地址
但是经过后面的实验,
这里有时候出现的只是API的字符串
006221DE 5E POP ESI
006221DE 5E POP ESI
006221DF 83BD E5030E0A 0>CMP DWORD PTR SS:[EBP+A0E03E5],1
006221E6 0F84 39000000 JE sayhello.00622225
006221EC 3B8D A1130E0A CMP ECX,DWORD PTR SS:[EBP+A0E13A1]
006221F2 0F84 2D000000 JE sayhello.00622225
006221F8 3B8D 75200E0A CMP ECX,DWORD PTR SS:[EBP+A0E2075]
006221FE 0F84 21000000 JE sayhello.00622225
00622204 3B8D C5080E0A CMP ECX,DWORD PTR SS:[EBP+A0E08C5]
0062220A 0F84 15000000 JE sayhello.00622225
00622210 8D9D 8D541E0A LEA EBX,DWORD PTR SS:[EBP+A1E548D]
00622216 FFD3 CALL EBX
00622218 8BF8 MOV EDI,EAX
0062221A 8985 B1250E0A MOV DWORD PTR SS:[EBP+A0E25B1],EAX
00622220 E9 B4060000 JMP sayhello.006228D9
00622225 8D9D 8D541E0A LEA EBX,DWORD PTR SS:[EBP+A1E548D]
0062222B FFD3 CALL EBX ;经过这个CALL后 ,eax确定为API地址
0062222D 83BD E5030E0A 0>CMP DWORD PTR SS:[EBP+A0E03E5],0
找出之后还会比较是不是指定的几个API
将API代码逻辑上复制到一个新地址,这里是28d0000
0062277E 8D9D D7561E0A LEA EBX,DWORD PTR SS:[EBP+A1E56D7]
00622784 FFD3 CALL EBX
00622786 8D9D BF591E0A LEA EBX,DWORD PTR SS:[EBP+A1E59BF]
0062278C FFD3 CALL EBX
0062278E 0F83 0C000000 JNB sayhello.006227A0
00622794 8385 A50F0E0A 0>ADD DWORD PTR SS:[EBP+A0E0FA5],5
0062279B ^ E9 DEFFFFFF JMP sayhello.0062277E
006227A0 8D9D E8591E0A LEA EBX,DWORD PTR SS:[EBP+A1E59E8]
006227A6 FFD3 CALL EBX
006227A8 0F83 08000000 JNB sayhello.006227B6
006227AE 83C2 04 ADD EDX,4
006227B1 E9 32000000 JMP sayhello.006227E8
006227B6 8D9D 512F1C0A LEA EBX,DWORD PTR SS:[EBP+A1C2F51]
006227BC FFD3 CALL EBX
006227BE 0F83 0B000000 JNB sayhello.006227CF
006227C4 8BB5 A50F0E0A MOV ESI,DWORD PTR SS:[EBP+A0E0FA5]
006227CA E9 80070000 JMP sayhello.00622F4F
006227CF 8B8D A50F0E0A MOV ECX,DWORD PTR SS:[EBP+A0E0FA5]
006227D5 89B5 A50F0E0A MOV DWORD PTR SS:[EBP+A0E0FA5],ESI
006227DB 2BCE SUB ECX,ESI
006227DD F7D9 NEG ECX ;计算出当前API函数的当前指令字节数
006227DF 2BF1 SUB ESI,ECX
006227E1 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
将API原实现代码复制到一个新地址,这里是28c0000
006227E3 ^ E9 96FFFFFF JMP sayhello.0062277E
在28e00000将28D0000代码变形
0062280E 8B85 9D110E0A MOV EAX,DWORD PTR SS:[EBP+A0E119D]
00622814 50 PUSH EAX
00622815 57 PUSH EDI
00622816 8B85 F5000E0A MOV EAX,DWORD PTR SS:[EBP+A0E00F5]
0062281C 50 PUSH EAX
0062281D 8D8D E12C1D0A LEA ECX,DWORD PTR SS:[EBP+A1D2CE1]
00622823 FFD1 CALL ECX ;这个CALL为代码变形并将变形的代码写入新地址
00622825 8BD0 MOV EDX,EAX
006228BD 8D85 73311D0A LEA EAX,DWORD PTR SS:[EBP+A1D3173]
006228C3 FFD0 CALL EAX
006228C5 018D 7D110E0A ADD DWORD PTR SS:[EBP+A0E117D],ECX
006228CB 8BBD B1250E0A MOV EDI,DWORD PTR SS:[EBP+A0E25B1]
006228D1 8BB5 9D110E0A MOV ESI,DWORD PTR SS:[EBP+A0E119D]
006228D7 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
代码复制到[edi],此时EDI即为处理后的”API”地址
006228D9 8BB5 DD040E0A MOV ESI,DWORD PTR SS:[EBP+A0E04DD] ; sayhello.0061A414
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)