模拟器Nebula的脱壳和保护研究 (5千字)
标题:模拟器Nebula的脱壳和保护研究软件:Nebula
版本:2.21
下载网站:www.hotbest.com
破解者: 火翼[CCG]
组织 : [CCG] (China Cracking Group)
使用软件: trw2000+HexWorkshop+OllyDbg
这个软件的保护确实很好玩,很折磨人。
直接用trw2000加载后会无法执行(后来发现出错的原因不是那个异常而是因
为没装Directx 8.0 造成读取DirectInput设备出错),用OllyDbg载入
执行到:
0712D0BA 0F0B UD2 //触发异常,会跳到异常处理
//程序
0712D0BC E8 2BD2648B CALL 9277A2EC
0712D0C1 028B 20648F02 ADD CL,BYTE PTR DS:[EBX+28F6420]
0712D0C7 58 POP EAX
0712D0C8 5D POP EBP
0712D0C9 C3 RETN
0712D0CA 9A 8B95E723 4000 CALL FAR 0040:23E7958B ; 远距呼叫 FAR
0712D0D1 E8 F9000000 CALL nebula.0712D1CF
0712D0D6 E8 01000000 CALL nebula.0712D0DC
0712D0DB C783 C404BB27 44>MOV DWORD PTR DS:[EBX+27BB04C4],6A001E44
0712D0E5 04 68 ADD AL,68
0712D0E7 0030 ADD BYTE PTR DS:[EAX],DH
结束异常处理后,会返回
0712D0BD 2BD2 SUB EDX,EDX
0712D0BF 64:8B02 MOV EAX,DWORD PTR FS:[EDX]
0712D0C2 8B20 MOV ESP,DWORD PTR DS:[EAX]
0712D0C4 64:8F02 POP DWORD PTR FS:[EDX]
0712D0C7 58 POP EAX
0712D0C8 5D POP EBP
0712D0C9 C3 RETN
比较后会发现,这一段会把堆栈返回异常前,另外把ECX置为
7120bd
只要这样改便可跳过异常
0712D0BA EB 01 JMP SHORT nebula.0712D0BD
.
.
.
0712D0BF B9 BDD01207 MOV ECX,nebula.0712D0BD
继续跟
跳出一个复杂的循环后
会到达
0712D1BE 2B7C24 28 SUB EDI,DWORD PTR SS:[ESP+28]
0712D1C2 897C24 1C MOV DWORD PTR SS:[ESP+1C],EDI
0712D1C6 61 POPAD
0712D1C7 C3 RETN //跳到712D11A
然后执行到
0712D120 83C4 04 ADD ESP,4
0712D123 5A POP EDX
0712D124 5E POP ESI
0712D125 0E PUSH CS
0712D126 56 PUSH ESI
0712D127 CB RETF //跳到071d0000
按F7跟到071d0000
执行到
071D0029 C1 ??? ; 未知命令
071D002A F1 ??? ;未知命令
会无法继续
只要把这两句改为NOP就可以了过去了
循环会在
071D035F 6A 3D PUSH 3D
071D0361 59 POP ECX
071D0362 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
071D0364 C3 RETN //跳到712D001
跳回712d001处
之后是个小循环
只要在
0712D03D C3 RETN
设断,按几次F9,观察esp指向为
0012FFC0 004E355C nebula.004E355C
0012FFC4 77E614C7 返回到 kernel32.77E614C7
0012FFC8 0012D51C
004e355c处就是OEP
用trw2000载入程序
G 4E355C
Pedump或者Makepe就可以了
总结
程序的入口点在import段,执行时会完成还原import表和
解压程序的过程。
有一次循环是还原import表引用的函数名称
代码如下
0712D083 8A07 MOV AL,BYTE PTR DS:[EDI]
0712D085 32C2 XOR AL,DL
0712D087 32C6 XOR AL,DH
0712D089 D2C0 ROL AL,CL
0712D08B 02C1 ADD AL,CL
0712D08D 02C5 ADD AL,CH
0712D08F 02C2 ADD AL,DL
0712D091 02C6 ADD AL,DH
0712D093 D2C8 ROR AL,CL
0712D095 2AC1 SUB AL,CL
0712D097 2AC5 SUB AL,CH
0712D099 F6D0 NOT AL
0712D09B 2AC2 SUB AL,DL
0712D09D 2AC6 SUB AL,DH
0712D09F D2C0 ROL AL,CL
0712D0A1 D2C8 ROR AL,CL
0712D0A3 32C1 XOR AL,CL
0712D0A5 F6D0 NOT AL
0712D0A7 32C5 XOR AL,CH
0712D0A9 D3C2 ROL EDX,CL
0712D0AB 8807 MOV BYTE PTR DS:[EDI],AL
0712D0AD 47 INC EDI
0712D0AE 49 DEC ECX
0712D0AF ^75 D2 JNZ SHORT nebula.0712D083
开始地址为712d229
结束地址为71c5018
还有一次循环是用这还原出的名字
在申请的一块内存中构建一段代码(就是071D0000处)
这一段代码会把import表对应的地址建好
另外还要注意
代码很多地方都用call代替jmp
不能用F8跳过去,ret时也要注意esp指向的地址
问题:
1)
程序只能在98下运行,XP下dump之后修复引入表不成功。
2)
dump出来的程序有110M大,有100多M是00
但我PE结构还学的不透,修正总是失败,还好,可以再用
别的压缩工具再压一下
修正
1)文件大小修正
仔细研究了一下段的结构和加载时的内存映射关系,发现修正文件确实很简单。
只要保持虚拟地址和大小不变,改变段的实际大小和在文件中的启始地质就可以了去掉没
用的0了。makepe产生的文件有100多M,其中最大的短是124000开始的,这段的内容在1DA900后
就全是0了,1da900-124000=B6900,这段的实际大小我取B8000,124000+B8000=1DC000
然后用16进制文件工具打开脱壳后的文件,删除1DC000到下一段开始的地址之间的0,这里是
6D23000,所以删除1DC000-6D22FFF之间的所有字节,然后修正剩下段在文件中的启始地址,后面
所有段在文件中的启始地址都要减去6B47000(6D23000-1DC000)
修正后文件大小为2.5M
2)XP下无法运行的修正
98下去壳的文件无法在XP下执行,点击会弹出无法找到TlsAllocInternal
这个函数对应的XP下函数为TlsAlloc,改过后执行会出现runtime错误,只好
手工修正引入表,原加壳程序的IAT填写由程序本身完成,经过比较发现在XP
下运行98下生成的去壳文件时系统分配的IAT和XP下运行原加壳程序的IAT有5
处不同
原程序运行时生成IAT
77E5A6F0 ;CloseHandle
77E5569E ;GlobalAlloc
77E5E595 ;kernel32.FreeEnvironmentStringsW
77E5DE7E ;kernel32.LCMapStringW
77E5E0C8 ;kernel32.GetStringTypeW
在XP下运行98下脱壳程序生成的IAT
77E4DB14 ;FindCloseChangeNotification
77E5A682 ;LocalAlloc
77E51660 ;kernel32.FreeEnvironmentStringsA
77E5D995 ;kernel32.LCMapStringA
77E548CE ;kernel32.GetStringTypeA
这些不同是因为98和XP系统对程序的引入表中的函数名作了不同的解释,而Trw2000
在makepe时只是根据IAT重新建立了import表,这就造成了程序无法直接在XP下运行。
把98下脱壳文件的引入表里的函数名称改为对应的原程序IAT运算中使用的函数就
可以修正在XP下不能执行的问题。
另外如果使用ProcDump来Dump文件就不会出现文件很大的问题,但引入表要自己修正
到此,Nebula已完美脱壳。
