yyjpcx 发表于 2006-2-5 01:38:02

用WinDbg动态脱Reflector

用WinDbg动态脱Reflector

Bi11
4 Feb 2006

我才知道WinDbg+SOS能调托管程序。。。无敌。。。

举个例子吧,脱Reflector玩玩,最新的4.2.0.0。
精华7里henryouly的《研读Reflector的保护原理心得》文中已经说了原理。简单说就是先解压,然后用Assembly.Load(byte[])加载。这次我们的任务是动态将这个要加载的byte[]给dump出来。

用WinDbg加载Reflector
Microsoft (R) Windows DebuggerVersion 6.6.0003.5
...

在加载mscorjit.dll时设异常,执行
0:000> sxe ld:mscorjit.dll
0:000> g
...
ModLoad: 79430000 7947d000   C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\MSCORJIT.DLL
eax=00000000 ebx=00000000 ecx=00f60000 edx=7c92eb94 esi=00000000 edi=00000000
eip=7c92eb94 esp=0012e99c ebp=0012ea90 iopl=0         nv up ei ng nz ac po nc
cs=001bss=0023ds=0023es=0023fs=003bgs=0000             efl=00000296
ntdll!KiFastSystemCallRet:
7c92eb94 c3               ret

载入sos.dll (WinDbg的插件,就在%windir%\Microsoft.NET\Framework\v1.1.4322\下。如果不能加载,请先设PATH环境变量)
0:000> .load sos

找Assembly.Load的MethodDesc
0:000> !name2ee mscorlib.dll System.Reflection.Assembly.Load
Loaded Son of Strike data table version 5 from "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll"
...
-----------------------
MethodDesc: 79ba35a8
Name: Class System.Reflection.Assembly System.Reflection.Assembly.Load(SZArray UI1)
-----------------------

给这个MethodDesc的m_CodeOrIL上加个断点(等RV添入)
0:000> ba w4 79ba35a8+4
0:000> g
Breakpoint 0 hit
...

RV应该添入了,设个断点
0:000> bp poi(79ba35a8+4)
0:000> g
Breakpoint 1 hit
eax=79a3bea8 ebx=01283de0 ecx=02447a68 edx=00b4568c esi=01285f54 edi=01285f30
eip=79a3bea8 esp=0012f644 ebp=0012f674 iopl=0         nv up ei pl nz na po nc
cs=001bss=0023ds=0023es=0023fs=003bgs=0000             efl=00000206
mscorlib_79990000+0xabea8:
79a3bea8 50               push    eax

看看堆栈,没问题~
0:000> !clrstack
Thread 0
ESP       EIP   
0012f64479a3bea8 Class System.Reflection.Assembly System.Reflection.Assembly.Load(SZArray UI1)
0012f64800f702d7 Void Reflector.Application..ctor(Class Reflector.IWindowManager)
0012f67c00f70090 Void Reflector.Application.ᐁ()
0012f9b0791d94bc
0012fa94791d94bc

看看堆栈里的objects
0:000> !dumpstackobjects
ESP/REGObject   Name
ebx      01283de0 Reflector.Application
ecx      02447a68 System.Byte[]
esi      01285f54 ᐄ
edi      01285f30 System.IO.MemoryStream
0012f64c 01283de0 Reflector.Application
0012f654 01284dec System.IO.__UnmanagedMemoryStream
0012f660 01283de0 Reflector.Application

我们找到了她的地址:2447a68,看看:
0:000> d 02447a68
02447a683c 2c b6 00 00 00 0e 00-4d 5a 00 00 05 00 00 00<,......MZ......
02447a7804 00 00 00 ff ff 00 00-80 00 00 00 00 00 00 00................
02447a8840 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00@...............
02447a9800 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00................
02447aa800 00 00 00 80 00 00 00-0e 1f e8 00 00 5a 83 c2.............Z..
02447ab80d b4 09 cd 21 b8 01 4c-cd 21 54 68 69 73 20 70....!..L.!This p
02447ac872 6f 67 72 61 6d 20 63-61 6e 6e 6f 74 20 62 65rogram cannot be
02447ad820 72 75 6e 20 69 6e 20-44 4f 53 20 6d 6f 64 65   run in DOS mode

换只眼看看
0:000> dd 02447a68
02447a6800b62c3c 000e0000 00005a4d 00000005
02447a7800000004 0000ffff 00000080 00000000
02447a8800000040 00000000 00000000 00000000
02447a9800000000 00000000 00000000 00000000
02447aa800000000 00000080 00e81f0e c2835a00
02447ab8cd09b40d 4c01b821 685421cd 70207369
02447ac872676f72 63206d61 6f6e6e61 65622074
02447ad86e757220 206e6920 20534f44 65646f6d

用LordPE把0x2447a70开始,0xe0000大小的内存Dump到文件。改个exe,peid查看入口,_CorDllMain,是dll文件。那就再把文件名改成dll。

拖到Reflector,正常,收工。初次玩WinDbg,有出丑的地方还请指正~

顺便提一下,4.2的Reflector混淆用的都是不可显示的Unicode,出来一个个框框,太有创意了。


主要参考资料:

在托管代码中设置断点(WINDBG)
http://blog.joycode.com/gangp/articles/20417.aspx

用WinDbg探索CLR世界 跟踪方法的 JIT 过程
http://www.blogcn.com/User8/flier_lu/blog/1678453.html

SOS - Son of Strike
%???%\SDK\v1.1\Tool Developers Guide\Samples\sos\SOS.htm
页: [1]
查看完整版本: 用WinDbg动态脱Reflector