Thread: VMP vm
View Single Post
  #2  
Old 08-17-2013, 13:40
Conquest Conquest is offline
Friend
 
Join Date: Jan 2013
Location: 0x484F4D45
Posts: 125
Rept. Given: 46
Rept. Rcvd 29 Times in 17 Posts
Thanks Given: 33
Thanks Rcvd at 60 Times in 29 Posts
Conquest Reputation: 29
Next i will provide an example from a real vmp executable. I will include all the said info for the vm as well as you will see what is a handler in really is.

I will attach a windowsxp sp3 notepad(5.1.2600.5512) packed with vmp with minimal protection features so that you can run it inside olly even if u dont have enough protection enabled to hide from vmp

Upon entering the vm you will land on the oep at 01194550 which is an immediate jump. you will see lots of these jumpings in vmp to make the cracker puzzled. but i wont go details about how it works or how to unpack it etc.

Once you are at the ep of the vmp sfx section you need to start tracing/stepping in . most of the codes you see either total crap codes or simple fix-ups

After the jump there is a


Code:
011934FA    68 4BA69DC4     PUSH 0xC49DA64B
this pushed value will decide the start and other parameters for the vm. It is the initialization key fo rthis particular vm instance.

now step/trace till 01199AAB where our interesting codes will start.

Code:
01199AA3    8B7424 34                                        MOV ESI,DWORD PTR SS:[ESP+0x34]
01199AA7    83C4 04                                          ADD ESP,0x4
01199AAA    9C                                              PUSHFD
01199AAB    F7DE                                            NEG ESI
01199AAD    9C                                              PUSHFD
01199AAE    9C                                              PUSHFD
01199AAF    81C6 8EA584C3                                    ADD ESI,0xC384A58E
01199AB5    0FB6FA                                          MOVZX EDI,DL
01199AB8    F7DE                                            NEG ESI
01199ABA    F7D7                                            NOT EDI
01199ABC    C1ED 06                                          SHR EBP,0x6
01199ABF    66:0FCD                                          BSWAP BP
This is a interesting part of the code since it will decide the start of the virtual machine p- codes. lots of junks are there but if you follow it properly only 3 instructions are useful. I have pointed out them -

Code:
01199AAB    F7DE                                            NEG ESI

01199AAF    81C6 8EA584C3                                    ADD ESI,0xC384A58E

01199AB8    F7DE                                            NEG ESI
This is the vm init. after the last NEG ESI if you follow Address pointed by ESI(which here on 1st run is 0x011900BD) you will see the vm p-codes. Here is something very interesting- load the binary in IDA and you will some assemblies at the address 011900BD . Dont get fooled by it. Its not normal/ordinary x86 assemblies and trying to run it will just cause the app to malfunction. Later we will see that the pcode-reader may not start reading the table at that particular address at all. what i mean will make sense a bit later.

Now start tracing again and you will reach at 01198836. this is another very important function. it can be called as p-code reader.

Code:
01198831    0375 00                                          ADD ESI,DWORD PTR SS:[EBP]
01198834    F6D0                                            NOT AL

>>>01198836    8A46 FF                                          MOV AL,BYTE PTR DS:[ESI-0x1] <<<

01198839    66:0FBAE9 0E                                    BTS CX,0xE
0119883E    FEC5                                            INC CH
01198840    8D89 5410092E                                    LEA ECX,DWORD PTR DS:[ECX+0x2E091054]
If you havent got puzzled yet, you will see the value at esi is 0x011900BD. Interesting enough the asembly reads 1 less the address i.e. 011900Bc . So the p-codes indeed started at 011900Bc.

Now the pcode stays altered which needs to be changed for main-vm handler to be used(much like polymorphism in c++).
Now keep stepping and you will find these following codes which alters the value in eax(al)
Code:
01198846    28D8                                            SUB AL,BL
01198850    34 BA                                            XOR AL,0xBA
01199693    FEC8                                            DEC AL
011995E4    34 26                                            XOR AL,0x26
Just notice the value in eax(al) . its the decoded value for main vm handler to point ot the appropriate vm-pcode- handlers. Always remember that since there is 0~255 possible p- codes there for there can exist 256 sub-vmhandlers for them(they dont though). In simpler words for every vmed code you retrieve there is a vm handler for it. some time 2 or more p-codes point to same vm-pcode-handler
Step again and now you will see the main vm handler-
Code:
01199609    8B0C85 888F1901                                  MOV ECX,DWORD PTR DS:[EAX*4+0x1198F88]
it points to vm handler dynamically i.e. as value of eax changes the total value pointed by assembly changes as well. Once again its another table as well. The base of the table is 0x1198F88 . if you look at that position in hex dump you will find the table. it just fetches the appropriate member from the table depending on the value of eax.
Code:
 for instance if eax=0, 0x1198F88+0x4=0x1198F88 that is the 1st member of the table For eax=20 it will fetch the 20th member from the table.
If you arent aware, vmprotect can find the code alternation made on unpacked clients as well as running client . There exists similar v-table for that hash calculation as well(Raham Knows more). But i dont have much details of that at the moment(Its vmed and i dont have a 'un-virtualizer).
Now the vm handler is obfuscated. If you look at it , it doesnt even point to anything at all. Now if you step you will find this-
Code:
0119A8F0    81C1 B9C48277                                    ADD ECX,0x7782C4B9
Now it points to the proper handler address. We need a jump to this so they do a clever trick- push it and use retn. but before they enter another round of junk codes and fix ups. Finally you will see a retn imm which will jump to the vm subhandler. here it will be this-
Code:
0119AA7B    C2 3400                                          RETN 0x34
step in and you are inside the vm subhandler.What it will do is to carry out the particular instruction which was replaced by the vm pcode

I will not get into the details of how handlers work. But just to let you know though the handlers are replace of some assembly instructions ,they are not replica of the instruction. The do several jobs including fetching the values doing the maths etc all in one handler.

Vm Return-
At the end of vm execution the main vm handler points to the vm_retn address. This particular function has several jobs to do. First of all, it restores all the registers including the flags and points to the proper ip. Finding the proper vm retn handler isnt trivial rather it stays un-executed till the vm reads the vm_retn pcode.
You can keep stepping till the handler jumps to something weird but to cut to the chase put a hwbp on the following
Code:
011993C1 >  66:0FBAE0 0E                                    BT AX,0xE
most of the codes you will find while stepping is not of our importance so i will just point out the register restores
Code:
011993E2    58                                              POP EAX

011993EF    5B                                              POP EBX

0119898D    8B4C24 04                                        MOV ECX,DWORD PTR SS:[ESP+0x4]

0119899A    8B6C24 08                                        MOV EBP,DWORD PTR SS:[ESP+0x8]

011989A1    8B5424 0C                                        MOV EDX,DWORD PTR SS:[ESP+0xC]

011989AD    8B7424 10                                        MOV ESI,DWORD PTR SS:[ESP+0x10]

011994F2    8B7C24 1C                                        MOV EDI,DWORD PTR SS:[ESP+0x1C]

011989B9    9D                                              POPFD
here is one interesting thing which i have found based on 3 different vm samples. Although the p-code mappings change and things like push-pop orders, the vm-pcode handlers remains same for all vms. what does this mean? remember the cpuid feature of vmprotect. Though while using lcf-at scripts you encounter with lots of cpuids via the log, the true resides inside a vm handler. if you look at it properly, the handler is same for all versions(they are full of garbage assemblies to hide that fact). same with other handlers. all are same. just the p-code mappings for them changes.

So till now i have tried to sum up what i have found and its missing a lot of things which i have yet to figure out properly. This includes the initial vm stack and the meaning of the stack values, as well as method of stack based calculations

---------------------------------------------------
Target-
---------------------------------------------------
http://hostr.co/eU7V47XQ2jkN
---------------------------------------------------
password- tuts4you

On last note- if you find any inconsistency in the paper, don be hesitated to point them out. The only reason of writing this paper is to share the knowledge which i have and unless others share their experience its not complete
Reply With Quote
The Following 5 Users Gave Reputation+1 to Conquest For This Useful Post:
ahmadmansoor (08-18-2013), besoeso (08-17-2013), niculaita (08-17-2013), softgate (08-17-2013), user1 (08-17-2013)
The Following 2 Users Say Thank You to Conquest For This Useful Post:
abhi93696 (03-30-2017), Antitrack (01-24-2018)