0rp
September 30th, 2007, 07:59
since yates needs a proper explanation about the secu vm, here it goes:
each secu title has 256 opcodes. an opcode is a block containing upto 512 instructions (maybe more, doesnt matter). most opcodes are obfuscated.
an opcode consists of serveral parts: param decryption, real deal, goto next opcode, so it looks like
game -> opcode (aka vmenter) -> opcode -> opcode -> .... -> opcode (aka vmexit) -> game
there are several types of how the vm is used. most games use only the socalled boring mode, wich means the vm does nothing but link two gamecode parts together (why 99% of all games use just this easy to defeat mode?)
a more fun type is where the vm actually does some game related stuff (why is this feature like never used btw?). gamedevs have to use this feature with sdk macros i guess (enlight me please)
heres a small log:
in this log, opcode 95 leaves the vm and jumps to code at 472507cc
472507cc is generated code, that the vm before that vm has generated. the code at 472507cc:
its obvious that this generated code has only one purpose: generate (or decrypt) a buf.
this is the encrypted buf:
as you can see, the values in this buf are written by the vm i pasted above:
and whats the decrypted version of this buf?
so, this super hidden generated code just gets the cpuid of the current process and stores its value in a vmreg
each secu title has 256 opcodes. an opcode is a block containing upto 512 instructions (maybe more, doesnt matter). most opcodes are obfuscated.
an opcode consists of serveral parts: param decryption, real deal, goto next opcode, so it looks like
game -> opcode (aka vmenter) -> opcode -> opcode -> .... -> opcode (aka vmexit) -> game
there are several types of how the vm is used. most games use only the socalled boring mode, wich means the vm does nothing but link two gamecode parts together (why 99% of all games use just this easy to defeat mode?)
a more fun type is where the vm actually does some game related stuff (why is this feature like never used btw?). gamedevs have to use this feature with sdk macros i guess (enlight me please)
heres a small log:
Code:
0046 mov reg_0068, 007e28fc reg_0068 = 00000000
000d add reg_0068, [reg_03a4] reg_0068 = 007e28fc, reg_03a4 = 00400000, [00400000] = 00905a4d
00ad mov reg_0068, [reg_0068] reg_0068 = 00be28fc, reg_0068 = 00be28fc, [00be28fc] = 7b414fb1
00bb mov reg_0054, 007f6edc reg_0054 = 00000000
000d add reg_0054, [reg_03a4] reg_0054 = 007f6edc, reg_03a4 = 00400000, [00400000] = 00905a4d
00ad mov reg_0054, [reg_0054] reg_0054 = 00bf6edc, reg_0054 = 00bf6edc, [00bf6edc] = 00f00971
0099 mov reg_0050, [reg_0054] reg_0050 = 00000000, reg_0054 = 00f00971, [00f00971] = 000001be
0077 add reg_0054, 00000004 reg_0054 = 00f00971
0086 mov reg_0058, reg_001c reg_0058 = 00000000, reg_001c = 0022c950
0077 add reg_0058, 00000024 reg_0058 = 0022c950
0077 add reg_0058, 00000008 reg_0058 = 0022c974
0099 mov reg_0058, [reg_0058] reg_0058 = 0022c97c, reg_0058 = 0022c97c, [0022c97c] = 00ed45c5
0089 mov reg_005c, 00000000 reg_005c = 00000000
00da mov reg_0320, 00cceec0 reg_0320 = 00000001
0046 mov reg_03c8, 0424448b reg_03c8 = 00000000
00c8 mov reg_03cc, 08244c8b reg_03cc = 00000000
007c mov reg_03d0, 0004c969 reg_03d0 = 00000000
0065 mov reg_03d4, 30800000 reg_03d4 = 00000000
00c7 mov reg_03d8, fae240eb reg_03d8 = 00000000
0065 mov reg_03dc, 505a5958 reg_03dc = 00000000
0046 mov reg_03e0, 9090c351 reg_03e0 = 00000000
00d9 mov reg_00c8, e8cb5060 reg_00c8 = 00000001
00bb mov reg_00cc, 2c6aebeb reg_00cc = 00000000
00ee mov reg_00d0, ebebebef reg_00d0 = 00000000
007c mov reg_00d4, 92e4151b reg_00d4 = 00000000
0032 mov reg_00d8, ebd46be2 reg_00d8 = 00000000
0089 mov reg_00dc, 12957b18 reg_00dc = 00000000
0065 mov reg_00e0, ea531900 reg_00e0 = 00000000
0087 mov reg_00e4, b8ebebeb reg_00e4 = 00000000
0087 mov reg_00e8, 34ce49e4 reg_00e8 = 00000000
0046 mov reg_00ec, b0141414 reg_00ec = 00000000
00c8 mov reg_00f0, e8c36862 reg_00f0 = 00000000
00c8 mov reg_00f4, 7b28ebeb reg_00f4 = 00000000
0032 mov reg_00fc, 0000000c reg_00fc = 00000000
0094 mov reg_0100, [reg_0058] reg_0100 = 00000000, reg_0058 = 00ed45c5, [00ed45c5] = d6640055
0077 add reg_0100, 000000c8 reg_0100 = 47250404
0000 unk
0000 unk
00b6 mov reg_0100, reg_0014 reg_0100 = 472504cc, reg_0014 = 47250404
0077 add reg_0100, 000003c8 reg_0100 = 47250404
0095 jmp 472507cc
in this log, opcode 95 leaves the vm and jumps to code at 472507cc
472507cc is generated code, that the vm before that vm has generated. the code at 472507cc:
Code:
472507cc 8b 44 24 04 mov eax, [esp+4]
472507d0 8b 4c 24 08 mov ecx, [esp+8]
472507d4 69 c9 04 00 00 00 imul ecx, ecx, 00000004
472507da 80 30 eb xor [eax], eb
472507dd 40 inc eax
472507de e2 fa loop 472507da
472507e0 58 pop eax
472507e1 59 pop ecx
472507e2 5a pop edx
472507e3 50 push eax
472507e4 51 push ecx
472507e5 c3 ret
its obvious that this generated code has only one purpose: generate (or decrypt) a buf.
this is the encrypted buf:
Code:
e8cb5060 2c6aebeb ebebebef 92e4151b
ebd46be2 12957b18 ea531900 b8ebebeb
34ce49e4 b0141414 e8c36862 7b28ebeb
as you can see, the values in this buf are written by the vm i pasted above:
Code:
00d9 mov reg_00c8, e8cb5060 reg_00c8 = 00000001
00bb mov reg_00cc, 2c6aebeb reg_00cc = 00000000
00ee mov reg_00d0, ebebebef reg_00d0 = 00000000
and whats the decrypted version of this buf?
Code:
472504cc 8b bb 20 03 00 00 mov edi, [ebx+320]
472504d2 81 c7 04 00 00 00 add edi, 00000004
472504d8 f0 fe 0f lock dec [edi]
472504db 79 09 jns 472504e6
472504dd 80 3f 00 cmp [edi], 00
472504e0 f3 90 pause
472504e2 7e f9 jle 472504dd
472504e4 eb f2 jmp 472504d8
472504e6 b8 01 00 00 00 mov eax, 00000001
472504eb 53 push ebx
472504ec 0f a2 cpuid
472504ee 25 df ff ff ff and eax, ffffffdf
472504f3 5b pop ebx
472504f4 89 83 28 03 00 00 mov [ebx+328], eax
472504fa c3 ret
so, this super hidden generated code just gets the cpuid of the current process and stores its value in a vmreg