Log in

View Full Version : VMProtect, Part 0: Basics


OpenRCE_RolfRolles
August 7th, 2008, 04:50
VMProtect ("http://www.vmprotect.ru/") is a virtualization protector. Like other protections in the genre, among others ReWolf's x86 Virtualizer ("http://www.openrce.org/blog/view/847/x86_Virtualizer_-_source_code") and CodeVirtualizer ("http://www.oreans.com/codevirtualizer.php"), it works by disassembling the x86 bytecode of the target executable and compiling it into a proprietary, polymorphic bytecode which is executed in a custom interpreter at run-time. This is unlike the traditional notions of packing, in which the x86 bytecode is simply encrypted and/or compressed: with virtualization, the original x86 bytecode in the protected areas is gone, never to be seen again. Or so the idea goes.

If you've never looked at VMProtect before, I encourage you to take a five-minute look in IDA (here's ("http://www.tuts4you.com/download.php?view.1601") a sample packed binary). As far as VMs go, it is particularly skeletal and easily comprehended. The difficulty lies in recreating working x86 bytecode from the VM bytecode. Here's a two-minute analysis of its dispatcher.

Code:
push edi ; push all registers
push ecx
push edx
push esi
push ebp
push ebx
push eax
push edx
pushf
push 0 ; imagebase fixup
mov esi, [esp+8+arg_0] ; esi = pointer to VM bytecode
mov ebp, esp ; ebp = VM's "stack" pointer
sub esp, 0C0h
mov edi, esp ; edi = "scratch" data area

VM__FOLLOW__Update:
add esi, [ebp+0]

VM__FOLLOW__Regular:
mov al, [esi] ; read a byte from EIP
movzx eax, al
sub esi, -1 ; increment EIP
jmp ds:VM__HandlerTable[eax*4] ; execute instruction handler


A feature worth discussing is the "scratch space", referenced by the register edi throughout the dispatch loop. This is a 16-dword-sized area on the stack where VMProtect saves the registers upon entering the VM, modifies them throughout the course of a basic block, and from whence it restores the registers upon exit. For each basic block protected by the VM, the layout of the registers in the scratch space can potentially be different.

Here's a disassembly of some instruction handlers. Notice that A) VMProtect is a stack machine and that B) each handler -- though consisting of scant few instructions -- performs several tasks, e.g. popping several values, performing multiple operations, pushing one or more values.

Code:
#00: x = [EIP-1] & 0x3C; y = popd; [edi+x] = y

.text:00427251 and al, 3Ch ; al = instruction number
.text:00427254 mov edx, [ebp+0] ; grab a dword off the stack
.text:00427257 add ebp, 4 ; pop the stack
.text:0042725A mov [edi+eax], edx ; store the dword in the scratch space

#01: x = [EIP-1] & 0x3C; y = [edi+x]; pushd y

.vmp0:0046B0EB and al, 3Ch ; al = instruction number
.vmp0:0046B0EE mov edx, [edi+eax] ; grab a dword out of the scratch space
.vmp0:0046B0F1 sub ebp, 4 ; subtract 4 from the stack pointer
.vmp0:0046B0F4 mov [ebp+0], edx ; push the dword onto the stack

#02: x = popw, y = popw, z = x + y, pushw z, pushf

.text:004271FB mov ax, [ebp+0] ; pop a word off the stack
.text:004271FF sub ebp, 2
.text:00427202 add [ebp+4], ax ; add it to another word on the stack
.text:00427206 pushf
.text:00427207 pop dword ptr [ebp+0] ; push the flags

#03: x = [EIP++]; w = popw; [edi+x] = Byte(w)

.vmp0:0046B02A movzx eax, byte ptr [esi] ; read a byte from EIP
.vmp0:0046B02D mov dx, [ebp+0] ; pop a word off the stack
.vmp0:0046B031 inc esi ; EIP++
.vmp0:0046B032 add ebp, 2 ; adjust stack pointer
.vmp0:0046B035 mov [edi+eax], dl ; write a byte into the scratch area

#04: x = popd, y = popw, z = x << y, pushd z, pushf

.vmp0:0046B095 mov eax, [ebp+0] ; pop a dword off the stack
.vmp0:0046B098 mov cl, [ebp+4] ; pop a word off the stack
.vmp0:0046B09B sub ebp, 2
.vmp0:0046B09E shr eax, cl ; shr the dword by the word
.vmp0:0046B0A0 mov [ebp+4], eax ; push the result
.vmp0:0046B0A3 pushf
.vmp0:0046B0A4 pop dword ptr [ebp+0] ; push the flags

#05: x = popd, pushd ss:[x]

.vmp0:0046B5F7 mov eax, [ebp+0] ; pop a dword off the stack
.vmp0:0046B5FA mov eax, ss:[eax] ; read a dword from ss
.vmp0:0046B5FD mov [ebp+0], eax ; push that dword


https://www.openrce.org/blog/view/1238/VMProtect,_Part_0:__Basics

evaluator
August 7th, 2008, 05:47
hey, was there need for discover VMProtect!?
i mean, how many SOFTWARE you found protected with it?

RolfRolles
August 7th, 2008, 08:10
I'm interested in it because of malware analysis, not cracking. There's enough of it in malware to justify the time expenditure.

evaluator
August 7th, 2008, 10:51
thanks for replay!

my Q was not about cracking interest, it was about unpacker_work;

that is surprise! so VMProtect used in malware!?
can you point exactly to that ones? are they protected by DEMO vers

blabberer
August 7th, 2008, 14:38
well there are many craps protected by virtualwhatever available you can check one that was recently posted by naides in malware analysis forum that uses oreans's product
handler #77 in that exe executes LoadLibrary etc

its vm aware so be careful



005019D7 2C 35 SUB AL, 35
005019D9 04 F4 ADD AL, 0F4
005019DB 00D0 ADD AL, DL
005019DD 2C F4 SUB AL, 0F4
005019DF 04 35 ADD AL, 35
005019E1 5A POP EDX ; 0012FFF0
005019E2 30C3 XOR BL, AL
005019E4 0FB6C0 MOVZX EAX, AL
005019E7 <looper> FF2487 JMP NEAR DWORD PTR DS:[EDI+EAX*4]



004FC2D2 <jumptablebase> F6EF45C8 ÈEïö
004FC2D6 <jt1> 0052CD04 ÍR. DiskInte.0052CD04
004FC2DA <jt2> 004F61BD ½aO. DiskInte.004F61BD
004FC2DE <jt3> FFFF9E7C |žÿÿ
004FC2E2 <jt4> 00000001 ...
004FC2E6 <jt5> FFFFFFFF ÿÿÿÿ
004FC2EA <jt6> 7C809B77 w›€| kernel32.CloseHandle
004FC2EE <jt7> 00000213 ..
004FC2F2 <jt8> 00000002 ...
004FC2F6 <jt9> 00000001 ...
004FC2FA <jt10> 00000004 ...
004FC2FE <jt11> F6EF45C8 ÈEïö
004FC302 <jt12> 00000000 ....
004FC306 <jt13> 00000000 ....
004FC30A <jt14> 00000000 ....
004FC30E <jt15> 00000000 ....
004FC312 <jt16> 00000000 ....
004FC316 <jt17> 00502F2E ./P. DiskInte.00502F2E


[here is the complete handler sequence for that #

[CODE]
004FFFDD FF77 38 PUSH DWORD PTR DS:[EDI+38]
004FFFE0 812C24 4D17CD7A SUB DWORD PTR SS:[ESP], 7ACD174D
004FFFE7 59 POP ECX
004FFFE8 52 PUSH EDX
004FFFE9 57 PUSH EDI ; <DiskInte.jumptablebase>
004FFFEA 53 PUSH EBX
004FFFEB 68 1E34415E PUSH 5E41341E
004FFFF0 5B POP EBX
004FFFF1 43 INC EBX
004FFFF2 ^ E9 B9E6FFFF JMP DiskInte.004FE6B0

004FE6B0 81C3 0E430EF3 ADD EBX, F30E430E
004FE6B6 89DF MOV EDI, EBX
004FE6B8 5B POP EBX
004FE6B9 4F DEC EDI ; <DiskInte.jumptablebase>
004FE6BA 4F DEC EDI ; <DiskInte.jumptablebase>
004FE6BB 81F7 6258946F XOR EDI, 6F945862
004FE6C1 81C7 2C42431B ADD EDI, 1B43422C
004FE6C7 53 PUSH EBX
004FE6C8 BB 3B29B545 MOV EBX, 45B5293B
004FE6CD 29DF SUB EDI, EBX
004FE6CF 5B POP EBX
004FE6D0 89FA MOV EDX, EDI ; <DiskInte.jumptablebase>
004FE6D2 5F POP EDI ; <DiskInte.jumptablebase>
004FE6D3 F7D2 NOT EDX
004FE6D5 C1E2 08 SHL EDX, 8
004FE6D8 68 08610000 PUSH 6108
004FE6DD E9 DE210000 JMP DiskInte.005008C0

005008C0 891C24 MOV DWORD PTR SS:[ESP], EBX
005008C3 BB FF675D60 MOV EBX, 605D67FF
005008C8 31DA XOR EDX, EBX
005008CA 5B POP EBX
005008CB 50 PUSH EAX
005008CC 53 PUSH EBX
005008CD BB 27729B27 MOV EBX, 279B7227
005008D2 4B DEC EBX
005008D3 81E3 6913C834 AND EBX, 34C81369
005008D9 55 PUSH EBP
005008DA E9 CA050000 JMP DiskInte.00500EA9

00500EA9 BD 591FEE6C MOV EBP, 6CEE1F59
00500EAE E9 28090000 JMP DiskInte.005017DB


005017DB 81ED 5EC04A21 SUB EBP, 214AC05E
005017E1 31EB XOR EBX, EBP
005017E3 5D POP EBP
005017E4 89D8 MOV EAX, EBX
005017E6 5B POP EBX
005017E7 E9 B35B0000 JMP DiskInte.0050739F

0050739F 51 PUSH ECX
005073A0 ^ E9 377DFFFF JMP DiskInte.004FF0DC

004FF0DC B9 9828C556 MOV ECX, 56C52898
004FF0E1 81E9 C7D78800 SUB ECX, 88D7C7
004FF0E7 E9 E61A0000 JMP DiskInte.00500BD2

00500BD2 09C8 OR EAX, ECX
00500BD4 59 POP ECX
00500BD5 C1E0 04 SHL EAX, 4
00500BD8 2D 7E6D3889 SUB EAX, 89386D7E
00500BDD E9 15390000 JMP DiskInte.005044F7

005044F7 81C2 0A3E4C29 ADD EDX, 294C3E0A
005044FD 01C2 ADD EDX, EAX

005088D6 81EA 0A3E4C29 SUB EDX, 294C3E0A
005088DC 58 POP EAX
005088DD 81EA E4EBDAE6 SUB EDX, E6DAEBE4
005088E3 01D1 ADD ECX, EDX
005088E5 5A POP EDX
005088E6 68 D1770000 PUSH 77D1
005088EB 893C24 MOV DWORD PTR SS:[ESP], EDI ; <DiskInte.jumptablebase>
005088EE FF3424 PUSH DWORD PTR SS:[ESP]
005088F1 5A POP EDX
005088F2 55 PUSH EBP
005088F3 54 PUSH ESP
005088F4 ^ E9 6990FFFF JMP DiskInte.00501962

00501962 5D POP EBP
00501963 57 PUSH EDI ; <DiskInte.jumptablebase>
00501964 ^ E9 40B0FFFF JMP DiskInte.004FC9A9

004FC9A9 BF 28375724 MOV EDI, 24573728
004FC9AE C1EF 08 SHR EDI, 8
004FC9B1 81CF A00BA966 OR EDI, 66A90BA0
004FC9B7 81F7 DF3E491B XOR EDI, 1B493EDF
004FC9BD E9 6FA20000 JMP DiskInte.00506C31

00506C31 47 INC EDI ; <DiskInte.jumptablebase>
00506C32 81F7 6D61E47D XOR EDI, 7DE4616D
00506C38 ^ E9 8A81FFFF JMP DiskInte.004FEDC7

004FEDC7 01FD ADD EBP, EDI ; <DiskInte.jumptablebase>
004FEDC9 5F POP EDI ; <DiskInte.jumptablebase>
004FEDCA 81ED 04000000 SUB EBP, 4
004FEDD0 872C24 XCHG DWORD PTR SS:[ESP], EBP
004FEDD3 5C POP ESP
004FEDD4 ^ E9 DEDFFFFF JMP DiskInte.004FCDB7

004FCDB7 890C24 MOV DWORD PTR SS:[ESP], ECX
004FCDBA 83EC 04 SUB ESP, 4
004FCDBD 892424 MOV DWORD PTR SS:[ESP], ESP
004FCDC0 810424 04000000 ADD DWORD PTR SS:[ESP], 4
004FCDC7 59 POP ECX
004FCDC8 81C1 04000000 ADD ECX, 4
004FCDCE 52 PUSH EDX
004FCDCF BA 04000000 MOV EDX, 4
004FCDD4 01D1 ADD ECX, EDX
004FCDD6 5A POP EDX
004FCDD7 870C24 XCHG DWORD PTR SS:[ESP], ECX
004FCDDA 5C POP ESP
004FCDDB 09C9 OR ECX, ECX
004FCDDD 0F84 8C7A0000 JE DiskInte.0050486F <--- this always had jumped

0050486F C742 30 AF0CB55>MOV DWORD PTR DS:[EDX+30], 5CB50CAF
00504876 E9 963D0000 JMP DiskInte.00508611

00508611 816A 30 03736D0>SUB DWORD PTR DS:[EDX+30], 6D7303
00508618 FF72 30 PUSH DWORD PTR DS:[EDX+30]
0050861B 53 PUSH EBX
0050861C BB 01000000 MOV EBX, 1
00508621 816C24 04 B95B6>SUB DWORD PTR SS:[ESP+4], 57685BB9
00508629 295C24 04 SUB DWORD PTR SS:[ESP+4], EBX
0050862D 814424 04 B95B6>ADD DWORD PTR SS:[ESP+4], 57685BB9
00508635 5B POP EBX
00508636 8F42 30 POP DWORD PTR DS:[EDX+30]
00508639 50 PUSH EAX
0050863A B8 753C6E19 MOV EAX, 196E3C75
0050863F ^ E9 35FCFFFF JMP DiskInte.00508279

00508279 55 PUSH EBP
0050827A BD 0D0BB94B MOV EBP, 4BB90B0D
0050827F ^ E9 DC84FFFF JMP DiskInte.00500760

00500760 F7DD NEG EBP
00500762 ^ E9 8BE9FFFF JMP DiskInte.004FF0F2

004FF0F2 81E5 91649742 AND EBP, 42976491
004FF0F8 81C5 E53D4A2A ADD EBP, 2A4A3DE5
004FF0FE 81CD 3429005F OR EBP, 5F002934
004FF104 81C5 1943657D ADD EBP, 7D654319
004FF10A 81F5 31E16CEC XOR EBP, EC6CE131
004FF110 29E8 SUB EAX, EBP
004FF112 5D POP EBP
004FF113 0942 30 OR DWORD PTR DS:[EDX+30], EAX
004FF116 58 POP EAX
004FF117 68 D35B0000 PUSH 5BD3
004FF11C 893424 MOV DWORD PTR SS:[ESP], ESI ; DiskInte.0052F503
004FF11F E9 1C780000 JMP DiskInte.00506940

00506940 BE 2E45242C MOV ESI, 2C24452E
00506945 ^ E9 A7EAFFFF JMP DiskInte.005053F1

005053F1 F7D6 NOT ESI ; DiskInte.0052F503
005053F3 E9 71360000 JMP DiskInte.00508A69

00508A69 D1E6 SHL ESI, 1
00508A6B 81EE 12329B7D SUB ESI, 7D9B3212
00508A71 68 794B0000 PUSH 4B79
00508A76 892C24 MOV DWORD PTR SS:[ESP], EBP
00508A79 BD 217F5560 MOV EBP, 60557F21
00508A7E 21EE AND ESI, EBP
00508A80 5D POP EBP
00508A81 ^ E9 EF3EFFFF JMP DiskInte.004FC975

004FC975 81F6 4A156800 XOR ESI, 68154A
004FC97B 2172 30 AND DWORD PTR DS:[EDX+30], ESI ; DiskInte.0052F503
004FC97E E9 16240000 JMP DiskInte.004FED99

004FED99 8B3424 MOV ESI, DWORD PTR SS:[ESP]
004FED9C 83C4 04 ADD ESP, 4
004FED9F 816A 30 0A14540>SUB DWORD PTR DS:[EDX+30], DiskInte.0054140A
004FEDA6 61 POPAD
004FEDA7 9D POPFD
004FEDA8 C3 RETN <--- will go to system dll calls like loadlib,closehandle etc




rolf if this disassembly snippet is similar to vmprotect can you try unobfuscate it ? i mean bring out the original sequence of x86 opcodes

evaluator
August 8th, 2008, 01:08
we are talking exactly about VMProtect;
VM_code of oreans" is it's subject, i see it there..

my main thought is: MALWARE using VM will NOT achieve any greats!
malware must use "malicious" API, so that's all you need to detect;

WriteProcessMemory2otherProcess = MALWARE/Virus
basta!

other is VMcode in normal program, where it tries to hide IMPORTANT code from you..

evilcry
August 8th, 2008, 01:25
Great work RolfRolles!!!

I was always looking for good VMProtect material, truly important pieces of
malware uses it, especially Rootkit Vectors as Srizbi

Regards,
Giuseppe Bonfa'

evaluator
August 8th, 2008, 09:48
blabberer,

as i seen, that is 90% LOADER code released in VM-code in Themida!

STUPIDEST action even..
.. in loaders history>>;D

NeOXOeN
August 8th, 2008, 17:38
Great work RolfRolles as alwasy :P

evaluator: stop typing bs..thx

evaluator
August 9th, 2008, 00:40
evilcry, i failed to find Srizbi for dld..

evilcry
August 9th, 2008, 04:05
you can download some sample of Srizbi from OffensiveComputing,
here some link:

http://www.offensivecomputing.net/?q=ocsearch&ocq=1ddb3ac06f25db07cd512bd4634b5397
http://www.offensivecomputing.net/download.php?id=1323179076&auth=01b31cc6a7ab09ddb2e88fc2af4df682

and here some other MD5 hash to push in OC's search engine:

Quote:

c6c14c466b681dbf424c7d187c101b50
772b1a32e372110a0e9d6f1e61ca6d25
6f934af71d05165b55143a00d1ff9e90
9d293d8d48b88a4a428ef238838d60ab
57aca884c232ca4dec72bf278589c778
c048fc3c849151071ddef5fb91e189c4
7380fff6f78c14baf8080f7edb73701d




Regards,
Evilcry

evaluator
August 9th, 2008, 16:26
i played liittle with it, dumped DRV, but too many (3?) VM there, 1 virtualized loader, after then should be virtualized INIT..

but look here, is this sure VMprotect from http://www.vmprotect.ru ?

evilcry
August 10th, 2008, 02:32
Quote:

but look here, is this sure VMprotect from http://www.vmprotect.ru ?


Yes, I think is 1.6x or 1.5x Version but surely RolfRolles knows better its characteristics

evaluator
August 10th, 2008, 06:53
strange, i dlded last VMprotect & its code looks as written in first post!
in this driver is other code.. (full version VMcode?)

BTW, unpacked driver.. what now!? ~ ; D

evaluator
August 10th, 2008, 10:39
ya, i just traced demo_protected example from included "examples", cool~
opcodes are different on new compile, .. good work done by author, BTW!

now, as i understand, virus was protected by full version,
where this main VMinterpreter_code was junked_mutated, VM_opcodes crypted;

but while tracing demo e.g. clean VM_interpreter, i guess:
mainly, there is NO single VM_opcode for some real instruction.
even more, there done fake calculations-comparisions-junkVMcode!

so, all this greatly works against one_automated solution.

wugui
September 1st, 2008, 06:00
it is a demo version of vmprotect,not a release version.