第一次分析,纯超级菜鸟帖,还有好多地方不明白,希望和我一样的菜鸟共同学习。
00401000 > FC CLD
00401001 FC CLD
00401002 FC CLD
00401003 90 NOP
00401004 - E9 BDBA0000 JMP NOTEPAD.0040CAC6 ; 跨段跳转到外壳处
00401009 - E3 D5 JECXZ SHORT NOTEPAD.00400FE0
0040100B 04 4F ADD AL,4F
开始就跨段跳到外壳部分。
0040CAC6 66:83ED 00 SUB BP,0
0040CACA 86E4 XCHG AH,AH
0040CACC 80CC 00 OR AH,0
0040CACF 51 PUSH ECX
0040CAD0 9C PUSHFD
0040CAD1 59 POP ECX
0040CAD2 F6C5 01 TEST CH,1
0040CAD5 - 75 FE JNZ SHORT NOTEPAD.0040CAD5
0040CAD7 59 POP ECX
0040CAD8 90 NOP
0040CAD9 FC CLD
0040CADA 90 NOP
0040CADB FC CLD
0040CADC E8 0B000000 CALL NOTEPAD.0040CAEC ; F7单步,可能是变形JUMP。F8会跑飞
0040CAE1 FC CLD
0040CBFB FC CLD
0040CBFC FC CLD
0040CBFD FC CLD
0040CBFE 85D2 TEST EDX,EDX ; 一路F7,这里EDX是字节数,似乎在解码。
0040CC00 ^ 0F85 5BFFFFFF JNZ NOTEPAD.0040CB61 ; 40CC07开始存放解压出的东东
0040CC06 60 PUSHAD
40CC06处F4,解压完毕,
0040CC06 60 PUSHAD
0040CC07 BE 00104000 MOV ESI,NOTEPAD.<模块入口点>
0040CC0C B8 2B11D2BB MOV EAX,BBD2112B
0040CC11 8906 MOV DWORD PTR DS:[ESI],EAX
0040CC13 B8 5C78BCDF MOV EAX,DFBC785C
0040CC18 8946 04 MOV DWORD PTR DS:[ESI+4],EAX
0040CC1B B8 4466A1BB MOV EAX,BBA16644
0040CC20 8946 08 MOV DWORD PTR DS:[ESI+8],EAX
0040CC23 B8 4F74A4D2 MOV EAX,D2A4744F
0040CC28 8946 0C MOV DWORD PTR DS:[ESI+C],EAX
0040CC2B B8 4874D2BB MOV EAX,BBD27448
0040CC30 8946 10 MOV DWORD PTR DS:[ESI+10],EAX
0040CC33 B8 6464A69B MOV EAX,9BA66464
0040CC38 8946 14 MOV DWORD PTR DS:[ESI+14],EAX
0040CC3B B8 4477F2E9 MOV EAX,E9F27744
0040CC40 8946 18 MOV DWORD PTR DS:[ESI+18],EAX ; 硬编码4010000开始的28个字节 不知道什么意思?
0040CC43 61 POPAD
这部分不太理解,在40CC07处是解压的壳代码,然后执行壳代码,为什么要在401000开始的地方填这些内容呢?
0040CC44 E8 00000000 CALL NOTEPAD.0040CC49
0040CC49 5D POP EBP
0040CC4A 81ED 05104000 SUB EBP,NOTEPAD.00401005 ; 典型代码 获取定位信息 EBP放修正值
0040CC50 8CC9 MOV CX,CS
0040CC52 32C9 XOR CL,CL
0040CC54 E3 02 JECXZ SHORT NOTEPAD.0040CC58
0040CC56 EB 0D JMP SHORT NOTEPAD.0040CC65
0040CC58 64:67:A1 3000 MOV EAX,DWORD PTR FS:[30] ; 获取PEB结构地址。
0040CC5D 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX+2]
0040CC61 0AC0 OR AL,AL
0040CC63 74 08 JE SHORT NOTEPAD.0040CC6D
0040CC65 64:67:8B36 2000 MOV ESI,DWORD PTR FS:[20]
0040CC6B EB 02 JMP SHORT NOTEPAD.0040CC6F
0040CC6D 33F6 XOR ESI,ESI
0040CC6F 8D85 49104000 LEA EAX,DWORD PTR SS:[EBP+401049]
0040CC75 50 PUSH EAX
0040CC76 64:FF36 PUSH DWORD PTR FS:[ESI] ; 构造SEH结构
0040CC79 8BC4 MOV EAX,ESP
0040CC7B 64:8906 MOV DWORD PTR FS:[ESI],EAX ; 异常处理地址40CC8D 我们先CTRL+G去那儿下个断点
0040CC7E EB 1C JMP SHORT NOTEPAD.0040CC9C
0040CC80 50 PUSH EAX
0040CC81 45 INC EBP
0040CC82 6E OUTS DX,BYTE PTR ES:[EDI] ; I/O 命令
0040CC83 6372 79 ARPL WORD PTR DS:[EDX+79],SI
0040CC86 70 74 JO SHORT NOTEPAD.0040CCFC
0040CC88 2076 34 AND BYTE PTR DS:[ESI+34],DH
0040CC8B 2E:308B 6424086>XOR BYTE PTR CS:[EBX+64082464],CL
0040CC92 67:8F06 0000 POP DWORD PTR DS:[0]
0040CC97 83C4 04 ADD ESP,4
0040CC9A EB 0E JMP SHORT NOTEPAD.0040CCAA
0040CC9C 33C0 XOR EAX,EAX
0040CC9E 8618 XCHG BYTE PTR DS:[EAX],BL ; 构造读0地址异常,我们直接F9运行,会中断在40CC8D
这段很简单,通过SEH来到40CC8D,是个很单纯的防F8的吧。
来到40CCAA
0040CCAA E8 00000000 CALL NOTEPAD.0040CCAF ; 又是个典型的定位
0040CCAF 5D POP EBP
0040CCB0 81ED 6B104000 SUB EBP,NOTEPAD.0040106B
0040CCB6 8D85 93104000 LEA EAX,DWORD PTR SS:[EBP+401093]
0040CCBC 50 PUSH EAX
0040CCBD 64:67:FF36 0000 PUSH DWORD PTR FS:[0]
0040CCC3 8BC4 MOV EAX,ESP
0040CCC5 64:67:A3 0000 MOV DWORD PTR FS:[0],EAX ; 又是个SEH。去40CCD7下个断
0040CCCA 9C PUSHFD
又是个SEH,来到40CCD7
0040CCD7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
0040CCDB 8B00 MOV EAX,DWORD PTR DS:[EAX]
0040CCDD 3D 04000080 CMP EAX,80000004
0040CCE2 74 06 JE SHORT NOTEPAD.0040CCEA
0040CCE4 4B DEC EBX
0040CCE5 65:72 61 JB SHORT NOTEPAD.0040CD49 ; 多余的前缀
0040CCE8 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0040CCE9 61 POPAD
0040CCEA EB 02 JMP SHORT NOTEPAD.0040CCEE
0040CCEC 49 DEC ECX
0040CCED BE 609CBE00 MOV ESI,0BE9C60
0040CCF2 1040 00 ADC BYTE PTR DS:[EAX],AL
0040CCF5 8BFE MOV EDI,ESI
0040CCF7 B9 00100000 MOV ECX,1000
0040CCFC BB 2B11D2BB MOV EBX,BBD2112B
0040CD01 AD LODS DWORD PTR DS:[ESI]
0040CD02 33C3 XOR EAX,EBX
0040CD04 AB STOS DWORD PTR ES:[EDI]
0040CD05 ^ E2 FA LOOPD SHORT NOTEPAD.0040CD01 ; 终于开始解码了 401000开始的1000字节
0040CD07 9D POPFD
0040CD08 61 POPAD
0040CD09 EB 02 JMP SHORT NOTEPAD.0040CD0D
0040CD0B 49 DEC ECX
0040CD0C BE 609CBE00 MOV ESI,0BE9C60
0040CD11 50 PUSH EAX
0040CD12 40 INC EAX
0040CD13 008B FEB90004 ADD BYTE PTR DS:[EBX+400B9FE],CL
0040CD19 0000 ADD BYTE PTR DS:[EAX],AL
0040CD1B BB 2B11D2BB MOV EBX,BBD2112B
0040CD20 AD LODS DWORD PTR DS:[ESI]
0040CD21 33C3 XOR EAX,EBX
0040CD23 AB STOS DWORD PTR ES:[EDI]
0040CD24 ^ E2 FA LOOPD SHORT NOTEPAD.0040CD20 ; 开始解码405000开始的400字节
0040CD26 9D POPFD
0040CD27 61 POPAD
0040CD28 BD CC104000 MOV EBP,NOTEPAD.004010CC ; 夸张。。。直接就跨段跳到OEP
0040CD2D FFE5 JMP EBP
这样。。。居然就完了。
跳到壳代码
解压壳
填401000处28个字节
构造两个SEH
开始解码2个区段
输入表好象根本没处理。
总之 这个壳超简单。
到OEP后,用OD自带插件DUMP下来 不用修复输入表,只需要用LOADPE重建PE就可以了。
如果用其他工具DUMP,还需要用IMPORTREC修复输入表 然后再重建PE。
2个SEH DUMP以后的区段混乱,估计是这个壳的特点吧。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)