菜鸟学脱,高手不要见笑
要有专用的OD和脚本配合下才能完成
感谢马哥的指导,终于自己学习搞定了一个Execryptor的壳
一、程序解码
首先装OD设置一下,让其停要系统断点处,载入程序停在了这里
7C921231 C3 RETN
7C921232 8BFF MOV EDI,EDI
7C921234 90 NOP
7C921235 90 NOP
7C921236 90 NOP
7C921237 90 NOP
7C921238 90 NOP
7C921239 > CC INT3
7C92123A C3 RETN
7C92123B 90 NOP
7C92123C 8BFF MOV EDI,EDI
7C92123E 90 NOP
7C92123F 90 NOP
7C921240 90 NOP
7C921241 90 NOP
7C921242 90 NOP
7C921243 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
运行脚本Bypass AntiDBG OEP.txt
中间出现了一次错误提示,不用管,shift+f9通过就行了,一会了就来到了伪OEP处
0095EFD1 E8 D3A2FDFF CALL Ex9000.009392A9
0095EFD6 B1 BB MOV CL,0BB
0095EFD8 C6 ??? ; 未知命令
0095EFD9 D7 XLAT BYTE PTR DS:[EBX+AL]
0095EFDA 25 0930ECE9 AND EAX,E9EC3009
0095EFDF B3 A3 MOV BL,0A3
0095EFE1 0300 ADD EAX,DWORD PTR DS:[EAX]
0095EFE3 E9 45610400 JMP Ex9000.009A512D
0095EFE8 0F89 0D000000 JNS Ex9000.0095EFFB
0095EFEE ^ 0F84 A020FCFF JE Ex9000.00921094
0095EFF4 9C PUSHFD
0095EFF5 57 PUSH EDI
0095EFF6 ^ E9 0060FCFF JMP Ex9000.00924FFB
0095EFFB ^ 0F84 9320FCFF JE Ex9000.00921094
0095F001 9C PUSHFD
0095F002 57 PUSH EDI
0095F003 E9 F5080200 JMP Ex9000.0097F8FD
0095F008 E8 3FE60200 CALL Ex9000.0098D64C
0095F00D 7D 55 JGE SHORT Ex9000.0095F064
这里要记住0095EFD1 E8 D3A2FDFF CALL Ex9000.009392A9这个地址
二、处理IAT
同样要用脚本,ExeCryptor 2.xx IAT Rebuilder v1.1.txt,不过要改才行,将里面的var IATstart
var IATend这两项要改过来,怎样确定IAT,具体可以看大侠们的教程,马哥说过,一般在BBS段下面的那个就是IAT段,
可是,这个软件里面并没有BBS段,呵呵,当然是软件加密者改过了,不要紧,只要用心看,就会发现有这么个段
Memory map, 项目 25
地址=00615000
大小=0003C000 (245760.)
属主=Ex9000 00400000
区段=1zcz1.go
包含=代码
类型=映像 01001002
访问=R
初始访问=RWE
确定他是IAT段后,在数据窗口中来到00615000处,
00615000 0098A8F3 Ex9000.0098A8F3 IATstart
00615004 009CB194 Ex9000.009CB194
00615008 009D450E Ex9000.009D450E
0061500C 0098E863 Ex9000.0098E863
00615010 0099BE5E Ex9000.0099BE5E
00615014 009BCDC6 Ex9000.009BCDC6
00615018 00928A21 Ex9000.00928A21
0061501C 009E3744 Ex9000.009E3744
00615020 009B3892 Ex9000.009B3892
00615024 0097DE15 Ex9000.0097DE15
00615028 009DC667 Ex9000.009DC667
往下看,
00615918 0095B751 Ex9000.0095B751
0061591C 00992216 Ex9000.00992216
00615920 009429EB Ex9000.009429EB
00615924 0098D1D1 Ex9000.0098D1D1
00615928 00999DF2 Ex9000.00999DF2
0061592C 0095BC85 Ex9000.0095BC85
00615930 0095FD67 Ex9000.0095FD67
00615934 0099BB1F Ex9000.0099BB1F
00615938 00954C1B Ex9000.00954C1B
0061593C 00000000
00615940 72F75390 WINSPOOL.ClosePrinter
00615944 72F86673 WINSPOOL.DocumentPropertiesA
00615948 72F83767 WINSPOOL.OpenPrinterA
0061594C 00000000
00615950 76322533 comdlg32.GetFileTitleA
00615954 763300CE comdlg32.CommDlgExtendedError
00615958 76337CD8 comdlg32.GetSaveFileNameA
0061595C 7632311E comdlg32.GetOpenFileNameA
00615960 763447B1 comdlg32.PageSetupDlgA
00615964 763446CD comdlg32.PrintDlgA
00615968 7633C289 comdlg32.ChooseFontA
0061596C 00000000
00615970 769E2A2F ole32.RevokeDragDrop
00615974 769E3D23 ole32.CoLockObjectExternal
00615978 76A78F52 ole32.OleDuplicateData
0061597C 769AF61A ole32.RegisterDragDrop
00615980 76A803F1 ole32.DoDragDrop
00615984 769E2F3B ole32.OleGetClipboard
00615988 769F5F9D ole32.ReadClassStg
0061598C 769FDD7F ole32.ReadFmtUserTypeStg
00615990 769AE53A ole32.CreateBindCtx
00615994 769AD048 ole32.CoTaskMemAlloc
00615998 769C4BED ole32.ReleaseStgMedium
0061599C 769AFAC3 ole32.CoCreateInstance
006159A0 769E3373 ole32.OleUninitialize
006159A4 769AF6DA ole32.OleInitialize
006159A8 769B6410 ole32.CreateStreamOnHGlobal
006159AC 769B2CFD ole32.CoDisconnectObject
006159B0 76A326DC ole32.CoTreatAsClass
006159B4 769BD5D0 ole32.StringFromCLSID
006159B8 76A29FE6 ole32.SetConvertStg
006159BC 769F76AE ole32.WriteFmtUserTypeStg
006159C0 769F5F73 ole32.WriteClassStg
006159C4 76A25D49 ole32.OleRegGetUserType
006159C8 76A03950 ole32.OleSetClipboard
006159CC 769AD02C ole32.CoTaskMemFree
006159D0 76A2A640 ole32.OleIsCurrentClipboard
006159D4 76A2A7F1 ole32.OleFlushClipboard
006159D8 00000000 IATend
确定了这两个地址,将脚本中的改完后就可以运行脚本了
这可能要慢一点,不要紧,慢慢来
三、 确定真正的OEP
通过看了马哥的好多文章,我终于学会了如何确定真正的OEP
在代码窗口中ctrl+g 输入00401000
然后 在此处新建EIP
ctrl+S 输入jmp 0095EFD1找到这里
005B81F5 - E9 D76D3A00 JMP Ex9000.0095EFD1 真正的OEP
005B81FA 033F ADD EDI,DWORD PTR DS:[EDI]
005B81FC 99 CDQ
005B81FD A2 437C3F82 MOV BYTE PTR DS:[823F7C43],AL
005B8202 A6 CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
005B8203 F4 HLT ; 特权命令
005B8204 C6 ??? ; 未知命令
005B8205 0C 40 OR AL,40
005B8207 3D 39725064 CMP EAX,64507239
005B820C 8925 00000000 MOV DWORD PTR DS:[0],ESP
005B8212 83EC 58 SUB ESP,58
005B8215 53 PUSH EBX
005B8216 56 PUSH ESI
005B8217 57 PUSH EDI
呵呵,看到了吧,OEP被改成了JMP Ex9000.0095EFD1 ,不过现在已经可以DUMP了,这里要注意了,要用PETOOLS这个工具DUMP。
DUMP之后,在Import1.6中输入
OEP 005B81F5-00400000=001B81F5
RVA 00615000-00400000=00415000
大小 006159D8-00615000=9d8
FIX之后,保存为DUMPED_
四、修复stolen code
通过看了Isaiah兄的文章,我确定了,这个程序是VC写的
005B81F5 >- E9 D76D3A00 JMP Dumped_.0095EFD1
005B81FA 033F ADD EDI,DWORD PTR DS:[EDI]
005B81FC 99 CDQ
005B81FD A2 437C3F82 MOV BYTE PTR DS:[823F7C43],AL
005B8202 A6 CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
005B8203 F4 HLT ; 特权命令
005B8204 C6 ??? ; 未知命令
005B8205 0C 40 OR AL,40
005B8207 3D 39725064 CMP EAX,64507239
005B820C 8925 00000000 MOV DWORD PTR DS:[0],ESP
005B8212 83EC 58 SUB ESP,58
005B8215 53 PUSH EBX
005B8216 56 PUSH ESI
005B8217 57 PUSH EDI
005B8218 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
005B821B FF15 18536100 CALL DWORD PTR DS:[<&kernel32.GetVersion>; kernel32.GetVersion 这个就是特征
005B8221 33D2 XOR EDX,EDX
005B8223 8AD4 MOV DL,AH
005B8225 8915 B8838000 MOV DWORD PTR DS:[8083B8],EDX
一般的OEP应该是
push ebp
mov ebp,esp
push -1
push imm32
push imm32
...........
这种形式的,现在不知道IMM32到底是多少,现在我们来确定这个IMM32,先要记录下面两个地址
005B82C8 56 PUSH ESI
005B82C9 FF15 B0546100 CALL DWORD PTR DS:[<&kernel32.GetModuleH>; kernel32.GetModuleHandleA
005B82CF 50 PUSH EAX
005B82D0 E8 A7760100 CALL Dumped_.005CF97C
005B82D5 8945 A0 MOV DWORD PTR SS:[EBP-60],EAX
005B82D8 50 PUSH EAX
005B82D9 E8 79EAFFFF CALL Dumped_.005B6D57
005B82DE 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14] 第一处
005B82E1 8B08 MOV ECX,DWORD PTR DS:[EAX]
005B82E3 8B09 MOV ECX,DWORD PTR DS:[ECX]
005B82E5 894D 98 MOV DWORD PTR SS:[EBP-68],ECX
005B82E8 50 PUSH EAX
005B82E9 51 PUSH ECX
005B82EA E8 6C920000 CALL Dumped_.005C155B
005B82EF 59 POP ECX
005B82F0 59 POP ECX
005B82F1 C3 RETN
005B82F2 8B65 E8 MOV ESP,DWORD PTR SS:[EBP-18] 第二处
005b82de
005b82f2
记录下之后,这里我用的是UE打开DUMPED_进行搜索
ff ff ff ff de 82 5b 00 f2 82 5b 00
找到00232a70处用OD打开DUMPED_在数据窗口来到00632a70
00632A70 FF FF FF FF DE 82 5B 00 F2 82 5B 00 00 00 00 00 ???[.?[.....
00632A80 FF FF FF FF B0 95 5B 00 C4 95 5B 00 48 3A 6D 6D ???[.?[.H:mm
00632A90 3A 73 73 00 64 64 64 64 2C 20 4D 4D 4D 4D 20 64 :ss.dddd, MMMM d
00632AA0 64 2C 20 79 79 79 79 00 4D 2F 64 2F 79 79 00 00 d, yyyy.M/d/yy..
00632AB0 50 4D 00 00 41 4D 00 00 44 65 63 65 6D 62 65 72 PM..AM..December
00632AC0 00 00 00 00 4E 6F 76 65 6D 62 65 72 00 00 00 00 ....November....
这就是找到的第一个IMM32
再找第二个
在代码段搜索2进制字串 VC20XC00
005BD884 56 PUSH ESI
005BD885 43 INC EBX
005BD886 3230 XOR DH,BYTE PTR DS:[EAX]
005BD888 58 POP EAX
005BD889 43 INC EBX
005BD88A 3030 XOR BYTE PTR DS:[EAX],DH
005BD88C 55 PUSH EBP
005BD88D 8BEC MOV EBP,ESP
005BD88F 83EC 08 SUB ESP,8
005BD892 53 PUSH EBX
005BD893 56 PUSH ESI
005BD894 57 PUSH EDI
005BD895 55 PUSH EBP
005BD896 FC CLD
005BD897 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]
第二个IMM32就是005BD884
下面就可以修改代码了
005B81F5 >/$ 55 PUSH EBP
005B81F6 |. 8BEC MOV EBP,ESP
005B81F8 |. 6A FF PUSH -1
005B81FA |. 68 702A6300 PUSH 123.00632A70
005B81FF |. 68 84D85B00 PUSH 123.005BD884 ; SE 处理程序安装
005B8204 |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
005B820A |. 50 PUSH EAX
005B820B |. 64:8925 00000>MOV DWORD PTR FS:[0],ESP
005B8212 |. 83EC 58 SUB ESP,58
005B8215 |. 53 PUSH EBX
005B8216 |. 56 PUSH ESI
005B8217 |. 57 PUSH EDI
005B8218 |. 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
005B821B |. FF15 18536100 CALL DWORD PTR DS:[<&kernel32.GetVersion>; kernel32.GetVersion
将OEP的代码都改过来之后,保存文件为123.exe,运行一下,一切正常,
呵呵,终于成功了,通过脱这个壳,又学到了不少的东东,在这里感谢马哥、Isaiah等各位大侠。
由于这个软件是商业软件,故就不往上传了,望见谅。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)