VMCrackME 参见
http://bbs.pediy.com/showthread.php?t=40854
这个VM的具体分析可以参见cyclotron大牛的分析
//VM.H
#ifndef _VM_H_
#define _VM_H_
#include <windows.h>
typedef struct _VMDATA
{
DWORD STACK[64];//堆栈
DWORD ESP;
DWORD EAX;
DWORD EBX;
DWORD ECX;
DWORD EDX;
DWORD ESI;
DWORD EDI;
DWORD EIP;
PBYTE OEP;
PBYTE CODE;
PDWORD DATA;
PBYTE PARAM;
PBYTE PARAM1;
BOOL SFLAG;//符号标志
BOOL ZFLAG;//零标志
} VMDATA,*PVMDATA;
void Execute(PBYTE vmcode,PDWORD vmdata,PBYTE vmparam,PBYTE vmparam1);
#endif _VM_H_
//VM.cpp
#include "VM.h"
#include <stdio.h>
void Vmpushbyte_vmcode(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->EAX=0;
vm_data->EAX=*vm_data->CODE;
vm_data->ESP++;
vm_data->STACK[vm_data->ESP]=vm_data->EAX;
printf("push %0X \n",vm_data->EAX);
}
void Vmpushbyte_vmdata(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->EAX=vm_data->DATA[*(vm_data->CODE)];
vm_data->ESP++;
vm_data->STACK[vm_data->ESP]=vm_data->EAX;
printf("push (%X) Data[%X]\n",vm_data->EAX,*(vm_data->CODE));
}
void Vmpopbyte_vmdata(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->DATA[*(vm_data->CODE)]=vm_data->EAX;
vm_data->ESP--;
printf("pop (%X) Data[%X]\n",vm_data->EAX,*(vm_data->CODE));
}
void VmAdd(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->ESP--;
vm_data->STACK[vm_data->ESP]=vm_data->STACK[vm_data->ESP]+vm_data->EAX;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->ZFLAG=(vm_data->EAX==0);
vm_data->SFLAG=vm_data->EAX<0;
printf("Add %0X \n",vm_data->EAX);
}
void VmSub(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->ESP--;
vm_data->STACK[vm_data->ESP]=vm_data->EAX-vm_data->STACK[vm_data->ESP];
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->ZFLAG=(vm_data->EAX==0);
vm_data->SFLAG=vm_data->EAX & 0x80000000;
printf("Sub:%0X\n",vm_data->EAX);
}
void VmExit(PVMDATA vm_data)
{
return ;
}
void Vmpush_vmeax(PVMDATA vm_data)
{
vm_data->ESP++;
vm_data->STACK[vm_data->ESP]=vm_data->EAX;
printf("Mov [ESP],EAX(%X)\n",vm_data->EAX);
}
void VmMul(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP] ;
vm_data->ESP--;
vm_data->STACK[vm_data->ESP] =vm_data->EAX*vm_data->STACK[vm_data->ESP] ;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->ZFLAG=(vm_data->EAX==0);
vm_data->SFLAG=((vm_data->EAX & 0x80000000)!=0);
printf("Mul :R=%X\n",vm_data->EAX);
}
void VmDiv(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP] ;
vm_data->ESP--;
vm_data->STACK[vm_data->ESP] =vm_data->EAX / vm_data->STACK[vm_data->ESP] ;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
vm_data->ZFLAG=(vm_data->EAX==0);
vm_data->SFLAG=vm_data->EAX<0;
printf("Div:R=%X\n",vm_data->EAX);
}
void VmAnd(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP] ;
vm_data->ESP--;
vm_data->STACK[vm_data->ESP] =vm_data->EAX & vm_data->STACK[vm_data->ESP] ;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
}
void VmOr(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP] ;
vm_data->ESP--;
vm_data->STACK[vm_data->ESP] =vm_data->EAX | vm_data->STACK[vm_data->ESP] ;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
}
void VmXor(PVMDATA vm_data)
{
vm_data->EAX=vm_data->STACK[vm_data->ESP] ;
vm_data->ESP--;
vm_data->STACK[vm_data->ESP] =vm_data->EAX ^ vm_data->STACK[vm_data->ESP] ;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
}
void Vmpop_vmeax(PVMDATA vm_data)
{
vm_data->ESP--;
vm_data->EAX=vm_data->STACK[vm_data->ESP] ;
printf("MOV EAX,[ESP](%X)\n",vm_data->EAX);
}
void Vmpushbyte_vmparam(PVMDATA vm_data)
{
vm_data->EAX=0;
vm_data->EAX=vm_data->PARAM[vm_data->ECX];
vm_data->ECX++;
vm_data->ESP++;
vm_data->STACK[vm_data->ESP] =vm_data->EAX;
printf("push (%X) Param[%X]:%0X \n",vm_data->EAX,vm_data->ECX);
}
void Vmpopbyte_vmparam1(PVMDATA vm_data)
{
vm_data->PARAM1[vm_data->EDX]=LOBYTE(vm_data->EAX);
vm_data->ESP--;
vm_data->EAX=vm_data->STACK[vm_data->ESP];
printf("pop (%X) Param[%X]:%0X \n",vm_data->EAX,vm_data->EDX);
vm_data->EDX++;
}
void VmJmp(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->ESI= *(vm_data->CODE) <<8 ;
vm_data->CODE++;
vm_data->ESI+vm_data->ESI+ *(vm_data->CODE);
vm_data->CODE=vm_data->OEP+vm_data->ESI;
printf("Jmp Satrt+%0X \n",vm_data->ESI);
}
void VmJz(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->ESI= *(vm_data->CODE) <<8 ;
vm_data->CODE++;
vm_data->ESI=vm_data->ESI+ *(vm_data->CODE);
if (vm_data->ZFLAG)
vm_data->CODE=vm_data->OEP+vm_data->ESI;
}
void VmJnz(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->ESI= *(vm_data->CODE) <<8 ;
vm_data->CODE++;
vm_data->ESI=vm_data->ESI+ *(vm_data->CODE);
if (! vm_data->ZFLAG)
vm_data->CODE=vm_data->OEP+vm_data->ESI;
}
void VmJs(PVMDATA vm_data)
{
vm_data->CODE++;
vm_data->ESI= *(vm_data->CODE) <<8 ;
vm_data->CODE++;
vm_data->ESI=vm_data->ESI+ *(vm_data->CODE);
if ( vm_data->SFLAG)
vm_data->CODE=vm_data->OEP+vm_data->ESI;
}
void Execute(PBYTE vmcode,PDWORD vmdata,PBYTE vmparam,PBYTE vmparam1)
{
VMDATA vm_data;
vm_data.OEP=vmcode;
vm_data.CODE=vmcode;
vm_data.DATA=vmdata;
vm_data.PARAM=vmparam;
vm_data.PARAM1=vmparam1;
vm_data.EAX=0;
vm_data.EBX=0;
vm_data.ECX=0;
vm_data.EDX=0;
vm_data.EDI=0;
vm_data.ESI=0;
vm_data.ESP=0;
vm_data.SFLAG=FALSE;
vm_data.ZFLAG=FALSE;
while (++vm_data.CODE)
{
switch ( *(vm_data.CODE) )
{
case 1:
Vmpushbyte_vmcode(&vm_data);
break;
case 2:
Vmpushbyte_vmdata(&vm_data);
break;
case 3:
Vmpopbyte_vmdata(&vm_data);
break;
case 4:
VmAdd(&vm_data);
break;
case 5:
VmSub(&vm_data);
break;
case 6:
VmExit(&vm_data);
return ;
case 7:
Vmpush_vmeax(&vm_data);
break;
case 8:
VmMul(&vm_data);
break;
case 9:
VmDiv(&vm_data);
break;
case 10:
VmAnd(&vm_data);
break;
case 11:
VmOr(&vm_data);
break;
case 12:
VmXor(&vm_data);
break;
case 13:
Vmpop_vmeax(&vm_data);
break;
case 14:
Vmpushbyte_vmparam(&vm_data);
break;
case 15:
Vmpopbyte_vmparam1(&vm_data);
break;
case 16:
VmJmp(&vm_data);
break;
case 17:
VmJz(&vm_data);
break;
case 18:
VmJnz(&vm_data);
break;
case 19:
VmJs(&vm_data);
default:
break;
}
}
}
//VMUnpack.cpp
#include <stdio.h>
#include "VM.h"
char * name="Name";
char * key="555885661";//"Key";
char msg[]="Wrong";
BYTE Code[]={
0x00, 0x01, 0x01, 0x01, 0x02, 0x08, 0x0E, 0x07, 0x01, 0x00,
0x05, 0x0D, 0x13, 0x00, 0x04, 0x0D, 0x01, 0x7F, 0x04, 0x03,
0x00, 0x06
};
BYTE Code1[]={
0x00, 0x01, 0x30, 0x0E, 0x05, 0x02, 0x02, 0x08, 0x02, 0x01,
0x04, 0x03, 0x01, 0x02, 0x02, 0x01, 0x0A, 0x08, 0x03, 0x02,
0x01, 0x30, 0x0E, 0x07, 0x01, 0x00, 0x05, 0x0D, 0x13, 0x00,
0x03, 0x0D, 0x01, 0xEB, 0x02, 0x01, 0x05, 0x03, 0x01, 0x06
};
BYTE Code2[]={
0x00, 0x01, 0x05, 0x02, 0x01, 0x05, 0x02, 0x00, 0x05, 0x12,
0x00, 0x2A, 0x01, 0x41, 0x01, 0x13, 0x04, 0x0F, 0x01, 0x61,
0x01, 0x11, 0x04, 0x0F, 0x01, 0x61, 0x01, 0x14, 0x04, 0x0F,
0x01, 0x61, 0x01, 0x04, 0x04, 0x0F, 0x01, 0x00, 0x0F, 0x01,
0x40, 0x03, 0x03, 0x06
};
DWORD data[10];
int main()
{
Execute(Code,data,(PBYTE)name,NULL);
printf("Name %0X\n",data[0]);
data[1]=0;
data[2]=1;
Execute(Code1,data,(PBYTE)key,NULL);
printf("key %0X\n",data[1]);
Execute(Code2,data,NULL,(PBYTE)msg);
printf("%X %s\n",data[0],msg);
return 0;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)