想申个精,这是我昨天写了一晚上写的虚拟机,模拟了一个调用MessageBox的过程。实现的指令不算多。支持立即数和[]这种取地址的方式。大家直接看程序吧。
对不起,10分钟前发布的版本有点问题,这个已经解决了masm32直接编译ml /c /coff 链接的时候link /subsystem:windows /section:.text,RWE 完全可以运行: )
.586
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data
chCaption db 'Message', 0
chText db 'oh yeah!', 0
chUser32 db 'user32.dll', 0
chSrc db 0h, 08h ;这条相当于x86的push 0
dd 0h
db 7h, 0C0h ;相当于x86的mov eax, chCaption
dd chCaption
db 0h, 00h ;相当于x86的push chText
db 0h, 08h
dd chText
db 0h, 08h ;相当于x86的push 0
dd 0h
db 2h, 08h ;call MessageBox
dd 77d507eah
db 3h, 0h ;rent虚拟机退出
.code
opcode dd ?
start:
call here
here:
pop ebx
mov eax, here
sub ebx, eax
lea eax, [chSrc + ebx]
mov opcode, eax
;指定opcode
invoke LoadLibrary, offset chUser32
push eax
push esp
push ebp
push esi
push edi
push ebx
push ecx
push edx
pushfd
mov esi, opcode
lea edi, [esp + 20h]
lea ebp, [ASM + ebx]
jmp Dispatch
db 0CCh
VNOT:
pop eax
not dword ptr[eax]
pushfd
pop [edi - 20h]
jmp Dispatch
VNEG:
pop eax
neg dword ptr[eax]
pushfd
pop [edi - 20h]
jmp Dispatch
VJMP:
pop eax
add esi, [eax]
jmp Dispatch
VCALL:
pop ecx
mov ecx, [ecx]
call ecx
mov [edi], eax
jmp Dispatch
db 0CCh
;以上是初始化工作,从这开始进入分配器
Dispatch:
xor eax, eax ;reset eax
mov al, [esi]
inc esi
mov edx, [ebp + 4*eax] ;reset edx
mov al, [esi]
inc esi
test al, 80h ;;;比较单双操作数
jnz Double
test al, 40h ;这里开始是对单操作数指令的处理
jnz SingalAddr
cmp al, 08h
jz ImmiValue
lea ecx, [edi + 4*eax] ;push eax
push ecx ;操作寄存器
jmp edx
ImmiValue:
push esi ;push immi
add esi, 4
jmp edx
SingalAddr:
cmp al, 08h
jz ImmiAddr
mov ecx, [edi + 4*eax] ;push [eax]
push ecx ;操作寄存器中的地址
jmp edx
ImmiAddr:
mov eax, [esi] ;push [immi]
push eax
add esi, 4
jmp edx
Double: ;这里开始是对双操作数指令的处理
xor ecx, ecx
and al, 7Fh
test al, 40h
jnz HaveImmi
and al, 40h
mov cl, [esi]
inc esi
test cl, 80h
jnz FValue
lea eax, [edi + 4*eax] ;mov eax, ecx
push eax
lea ecx, [edi + 4*ecx]
push ecx
jmp edx
FValue:
test cl, 40h ;mov eax, [ecx]
jnz BValue
lea eax, [edi + 4*eax]
push eax
mov ecx, [edi + 4*ecx]
push ecx
jmp edx
BValue:
mov eax, [edi + 4*eax] ;mov [eax], ecx
push eax
mov ecx, [edi + 4*ecx]
push ecx
jmp edx
HaveImmi:
and al, 0BFh
test al, 20h
jnz HaveAddr
lea ecx, [edi + 4*eax]
push ecx ;mov eax, immi
push esi
add esi, 4
jmp edx
HaveAddr:
test al, 10h
jnz ImmiBValue
and al, 0Fh ;mov eax, [immi]
lea ecx, [edi + 4*eax]
push ecx
push [esi]
add esi, 4
jmp edx
ImmiBValue:
and al, 0EFh ;mov [eax], immi
mov ecx, [edi + 4*eax]
push ecx
push esi
add esi, 4
jmp edx
jmp edx
db 0CCh ;以上都是分配器程序
VMOV:
pop eax
pop ecx
mov eax, [eax]
mov [ecx], eax
jmp Dispatch
VLEA:
pop eax
pop ecx
mov [ecx], eax
jmp Dispatch
VRETN:
mov al, [esi]
lea esp, [edi + 8h]
mov edx, [esp - 4]
lea esp, [esp + eax]
jmp edx
VPUSH:
pop eax
push [eax]
jmp Dispatch
VPOP:
pop eax
pop [eax]
jmp Dispatch
VADD:
pop eax
pop ecx
add [ecx], eax
jmp Dispatch
VSUB:
pop eax
pop ecx
sub [ecx], eax
jmp Dispatch
ASM dd VPUSH
dd VPOP
dd VCALL
dd VRETN
dd VJMP
dd VNOT
dd VNEG
dd VMOV
dd VLEA
dd VADD
dd VSUB
end start
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!