|
本帖最后由 破解狼人 于 2010-10-31 23:08 编辑
TMD的RISC VM一共有6个段
1。双opcode决定handle所用的第一opcode指向的一张表,如:
003A0000 00 00 3B 00 0C 00 3B 00 18 00 3B 00 24 00 3B 00
003A0010 30 00 3B 00 3C 00 3B 00 48 00 3B 00 54 00 3B 00
003A0020 60 00 3B 00 6C 00 3B 00 78 00 3B 00 84 00 3B 00
003A0030 90 00 3B 00 9C 00 3B 00 A8 00 3B 00 B4 00 3B 00
003A0040 C0 00 3B 00 CC 00 3B 00 D8 00 3B 00 E4 00 3B 00
003A0050 F0 00 3B 00 FC 00 3B 00 08 01 3B 00 14 01 3B 00
003A0060 20 01 3B 00 2C 01 3B 00 38 01 3B 00 44 01 3B 00
003A0070 50 01 3B 00 5C 01 3B 00 68 01 3B 00 74 01 3B 00
003A0080 80 01 3B 00 8C 01 3B 00 98 01 3B 00 A4 01 3B 00
003A0090 B0 01 3B 00 BC 01 3B 00 C8 01 3B 00 D4 01 3B 00
003A00A0 E0 01 3B 00 EC 01 3B 00 F8 01 3B 00 04 02 3B 00
003A00B0 10 02 3B 00 1C 02 3B 00 28 02 3B 00 34 02 3B 00
003A00C0 40 02 3B 00 4C 02 3B 00 58 02 3B 00 64 02 3B 00
003A00D0 70 02 3B 00 7C 02 3B 00 88 02 3B 00 94 02 3B 00
003A00E0 A0 02 3B 00 AC 02 3B 00 B8 02 3B 00 C4 02 3B 00
003A00F0 D0 02 3B 00 DC 02 3B 00 E8 02 3B 00 F4 02 3B 00
2。双opcode决定handle所用的第二opcode指向的一张表,如:
003B0000 00 00 00 00 A4 17 4B 01 5D 5F 58 01 A0 41 48 01
003B0010 1F BD 48 01 DE 61 4F 01 B7 38 4B 01 69 5E 48 01
003B0020 5C 27 47 01 F9 82 52 01 2B EB 50 01 00 00 00 00
003B0030 03 B8 55 01 A7 D8 51 01 55 7C 4C 01 00 00 00 00
003B0040 00 00 00 00 2F 32 51 01 B2 1F 49 01 73 C2 46 01
003B0050 C5 1E 4F 01 C8 9D 4D 01 00 00 00 00 CD 09 50 01
003B0060 64 B9 4C 01 07 38 49 01 C1 77 53 01 55 25 4D 01
003B0070 BB CD 49 01 88 FA 54 01 FF 5E 51 01 42 EF 52 01
003B0080 07 3B 4C 01 1C 5C 51 01 B2 AF 53 01 9E 82 58 01
003B0090 F8 18 47 01 0D BA 4E 01 70 C9 4C 01 00 00 00 00
003B00A0 B4 7D 4F 01 9E 6A 51 01 9D 2A 55 01 00 00 00 00
003B00B0 4A 67 4A 01 00 00 00 00 BE 8D 56 01 04 55 46 01
003B00C0 B7 9E 4A 01 C0 A1 50 01 B5 A9 56 01 00 00 45 01
003B00D0 27 69 53 01 B1 61 56 01 8E 81 51 01 7C 11 54 01
003B00E0 5A 16 58 01 3C 31 4B 01 41 E7 56 01 2B EF 54 01
003B00F0 00 00 00 00 9C D2 49 01 B2 75 52 01 43 36 57 01
所以双opcode决定handle如下:
如果opcode1为10,opcode2为4,那么003A0000 + 10 = 3A0010,查表得003B0030,003B0030 + 4 = 003B0034,查表得0151D8A7,所以决定的handle的地址就是0151D8A7
3。单opcode决定handle所用的opcode指向的一张表,如:
003C0000 00 00 45 01 30 D6 51 01 E4 90 48 01 B8 71 47 01
003C0010 64 B9 4C 01 83 42 57 01 9D 2A 55 01 73 C2 46 01
003C0020 91 8B 45 01 B7 9E 4A 01 C8 9D 4D 01 5A 9D 57 01
003C0030 0D 4B 56 01 B4 CC 57 01 BB 8E 4F 01 07 3B 4C 01
003C0040 B7 C8 4D 01 1F 64 4A 01 CF 33 4B 01 B2 1F 49 01
003C0050 5A 16 58 01 8C E6 47 01 9E 2A 47 01 DA EA 54 01
003C0060 E2 E9 4B 01 18 82 47 01 D3 80 48 01 5D 5F 58 01
003C0070 B6 55 47 01 55 25 4D 01 A2 C8 4D 01 B8 C9 45 01
003C0080 B5 92 56 01 CD 09 50 01 74 29 53 01 BA FF 4B 01
003C0090 2F 32 51 01 C0 CE 4F 01 B9 BF 58 01 2F C6 58 01
003C00A0 F7 BE 50 01 3C 31 4B 01 CA 9C 4A 01 B8 06 46 01
003C00B0 2B EF 54 01 70 C9 4C 01 44 42 46 01 DF 13 59 01
003C00C0 85 1D 51 01 69 5E 48 01 DC 95 55 01 A0 3C 59 01
003C00D0 F0 28 4B 01 88 FA 54 01 BE 8D 56 01 8E 81 51 01
003C00E0 08 3B 45 01 EE 86 52 01 C5 B3 4A 01 D7 15 4F 01
003C00F0 C1 5F 51 01 C5 1E 4F 01 4A EC 59 01 00 00 00 00
这张表只需要一个opcode就可以决定handle,如果opcode为10,那么查表得003C0000 + 10 = 003C0010,为014CB964,即为handle地址
4。 VMContext段,这个段放置VM执行需要的一些数据,如eax~edi这8个寄存器等等其他数据
5。 VM的栈
6。 VM的代码段
几个概念:
handle:具体执行的VM指令集,如VM_mov,VM_or等等。
pcode_data:执行某一条handle时,需要的操作数等等数据所放的地方。
dispatcher:TMD的VM中没有dispatcher,是通过每条handle中计算出下一条handle地址和pcode_data地址,直接跳过去。
下面我们只分析Themida2065.exe主程序中其中某一个handle的代码,在分析前,首先需要能看懂代码乱序,代码变形等等,还要对VM的大致结构有一定的了解。
我们取其中的一句pcode,我这里加载TMLicense.dat加载的区段是0x3670000,在0x3670000中下硬件访问断点,然后运行,一开始没有停在VM中,继续F9,直到停在VM中
这时候栈如下:
00391FF0 6479DB2D
00391FF4 03670000
00391FF8 00000000
00391FFC 00000000
因为这时候停在某一句handle的中间,我们让他运行到下一句的handle的最开始,在run trace的command is one of里加上jmp esi,然后CTRL+F11
停下来了。因为handle太长,这里我们记录run trace,再按一次CTRL + F11,这样就把这句handle所执行的语句全部记录下来了。下面就开始分析了。
先介绍可能用到的几个内存地址数据
edi指向VM_Context段
esi指向pcode_data的地址
VM_Context.5DC-----pCode_data_addr
VM_Context.490-----Key1 解码pCode_data中操作数的key
VM_Context.544-----Key2 解码下一条pCode_data地址的key
除了进入VM的第一条指令的opcode地址是1字节指向,其他的opcode都需要2字节指向
VM_Context.434-----Key3 解码下一条opCode2字节的key
VM_Context.37C-----Key4 解码下一条opCode字节的key
VM_Context.550-----OpCode_2byte_table1的地址,就是上面的那个3A0000
VM_Context.62C-----OpCode2(offset)
VM_Context.47C-----OpCode1(offset)
下条指令的handle: [OpCode_2byte_table1 + OpCode1] -> xxx
[xxx+ OpCode2] -> yyy
其他的在用到的地方再讲
----------------------------------------------开始讲解-----------------------------------------
Address Thread Command ; Registers and comments
//初始化esi为pCode_data_addr
0157163E Main push dword ptr [edi+0x5DC] //edi+0x5DC的地址存放的是pCode_data_addr ; ESP=00391FF4
01571644 Main jmp 0151EF85
0151EF85 Main mov esi, dword ptr [esp] //esi指向了pCode_data_addr ; ESI=00BE2A50
这里有点代码变形,实际上处理的就是add esp, 4
//push ebx
0151EF88 Main push 0x4621 ; ESP=00391FF0
0151EF8D Main mov dword ptr [esp], ebx
0151EF90 Main jmp 014D21A5
//ebx为push dword ptr [edi+0x5DC]前的esp地址
014D21A5 Main mov ebx, esp ; EBX=00391FF0
014D21A7 Main add ebx, 0x4 ; EBX=00391FF4
014D21AD Main add ebx, 0x4 ; EBX=00391FF8
014D21B3 Main push ebx ; ESP=00391FEC
//mov ebx, [esp+0x4]
014D21B4 Main push dword ptr [esp+0x4] ; ESP=00391FE8
014D21B8 Main pop ebx ; EBX=411D51F8, ESP=00391FEC
//把push dword ptr [edi+0x5DC]前的esp地址弹到栈顶
014D21B9 Main pop dword ptr [esp] ; ESP=00391FF0
//平衡堆栈
014D21BC Main pop esp ; ESP=00391FF8
014D21BD Main push eax ; ESP=00391FF4
014D21BE Main jmp 01472EB1
//这里实际上是mov ebx, 3
//mov ebx, 0x48155F8C
01472EB1 Main push 0x48155F8C ; ESP=00391FF0
01472EB6 Main pop ebx ; EBX=48155F8C, ESP=00391FF4
01472EB7 Main or ebx, 0x19E94E2D ; EBX=59FD5FAD
01472EBD Main jmp 014D87AE
014D87AE Main inc ebx ; EBX=59FD5FAE
014D87AF Main push eax ; ESP=00391FF0
014D87B0 Main mov eax, 0x59FD5FAD ; EAX=59FD5FAD
014D87B5 Main xor ebx, eax ; FL=P, EBX=00000003
014D87B7 Main pop eax ; EAX=00000008, ESP=00391FF4
内容太长了,发不了,祥细下载附件好了……
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|