Virtual Machine Loop Start
...
...
...
--> Decode VM Instruction's
...
--> Execute the Decoded VM Instruction's
...
...
--> Check Special Conditions
...
...
...
Virtual Machine Loop End
struct TVMContext {
int Register_IOType, // 通用寄存器,能持有I/O方向
int Register_IO, //
int Register_IOAddress, //通用寄存器,能寻址内存引用的地址
int Register_IOCount, // 通用寄存器,能字节传输传递
int GenericRegisters[12], // 其它的通用寄存器
int *Registers, //指向寄存器区域
int VM_ESP , // 虚拟堆栈指针
int VM_EIP , //虚拟指令指针
int VMEIP_Saved_Prior_InstrExec, // 操持跟踪当前执行的指令IP
TVMFLAGS VM_EFLAGS, // VM标志
int InstructionCounter, //指令数
int InitCode,
int MemorySize,
void* ProgramMemoryAddr,
int Original_ESP,
int StackMemorySize,
void* StackMemoryAddr,
int MachineControl, // 保持跟踪虚拟机状态
int VM_ResumeExec // 虚拟机的一种异常处理器
}
struct TInstructionBuffer{
int Length, // 指令长度
int InstructionData, // 通过查表传递
char InstrType,
//char Fillers1[3], //如果结构对齐 为1
int Operand_Size,
char InstructionParamsCount,
//char Fillers2[3], //如果结构对齐为 1
SubInstr ParamDest,
SubInstr paramSrc,
SubInstr ParamThird,
SubInstr *WorkSubField // 指向 SubInstr 参数 (类似于“Registers[]”所做的)
};
Opcode = *RealEIP;
MachineCheck = (*OpcodeProc[(char)Opcode])(&InstBuff,&VMContext); // VM dispatcher
我们可以看到下面的IDA 代码片断:
Execute_VM_Opcode: ; CODE XREF: _main+13D#j
.text:004021B8 0D4 mov edx, [esp+0D4h+VMInstructionBuff_VM_Opcode]
.text:004021BF 0D4 lea eax, [esp+0D4h+VM_Context] ; Load Effective Address
.text:004021C3 0D4 lea ecx, [esp+0D4h+VM_InstructionBuff_Body_Ptr] ; Load Effective Address
.text:004021CA 0D4 and edx, 0FFh ; VM Opcode is 1 byte only
.text:004021D0 0D4 push eax ; VM Context
.text:004021D1 0D8 push ecx ; VM Instr Ptr
.text:004021D2 0DC call VM_Opcode_Table[edx*4] ; Indirect Call Near Procedure
.text:004021D2
.text:004021D9 0DC add esp, 8 ; Add
.text:004021DC 0D4 test eax, eax ; Logical Compare
.text:004021DE 0D4 jz VM_Loop_Head_Default ; Jump if Zero (ZF=1)
.data:00407430 VM_Opcode_Table dd offset VM_MOV ; DATA XREF: _main+162#r
.data:00407434 dd offset VM_Multiple_op2
.data:00407438 dd offset VM_Multiple_op2
.data:0040743C dd offset VM_Multiple_op2
.data:00407440 dd offset VM_Multiple_op2
.data:00407444 dd offset VM_Multiple_op2
.data:00407448 dd offset VM_PUSH
.data:0040744C dd offset VM_POP
.data:00407450 dd offset VM_JMP
.data:00407454 dd offset VM_CALL
... ...
; int __cdecl VM_NOP(int Param1,int Param2)
.text:00401F80 VM_NOP proc near ; CODE XREF: _main+162#p
.text:00401F80 ; DATA XREF: .data:0040746C#o ...
.text:00401F80
.text:00401F80 Param1 = dword ptr 4
.text:00401F80 Param2 = dword ptr 8
.text:00401F80
.text:00401F80 000 mov ecx, [esp+Param1]
.text:00401F84 000 mov eax, [esp+Param2]
.text:00401F88 000 mov edx, [ecx]
.text:00401F8A 000 mov ecx, [eax+Param2.Something]
.text:00401F8D 000 add ecx, edx ; Add
.text:00401F8F 000 mov [eax+Param2.Something], ecx
.text:00401F92 000 xor eax, eax ; Logical Exclusive OR
.text:00401F94 000 retn ; Return Near from Procedure
.text:00401F94
.text:00401F94 VM_NOP endp
case 2: // XOR
switch(DecodedInstr->OperandSize) {
case 1: VMValueEval = (char)VMValueSrc ^ (char)VMValueThird; break;
case 2: VMValueEval = (word)VMValueSrc ^ (word)VMValueThird;break;
case 4: VMValueEval = VMValueSrc ^ VMValueThird;
}
VM_XOR_case_multi_3: ; CODE XREF: VM_Multiple_op2+70#j
.text:00402336 ; DATA XREF: .text:004026E8#o
.text:00402336 014 mov eax, [ebx_is_InstrBuf+VM_InstrBuffer.Operand_Size]
.text:00402339 014 dec eax ; Decrement by 1
.text:0040233A 014 jz short loc_40236E ; Jump if Zero (ZF=1)
.text:0040233A
.text:0040233C 014 dec eax ; Decrement by 1
.text:0040233D 014 jz short loc_402355 ; Jump if Zero (ZF=1)
.text:0040233D
.text:0040233F 014 sub eax, 2 ; Integer Subtraction
.text:00402342 014 jnz Finalize_Instruction_end_of_case_0Ch ; Jump if Not Zero (ZF=0)
.text:00402342
.text:00402348 014 mov eax, [esp+14h+Hold_34h_param]
.text:0040234C 014 mov esi, edi_is_Param_24h
.text:0040234E 014 xor esi, eax ; Logical Exclusive OR
.text:00402350 014 jmp Finalize_Instruction_end_of_case_0Ch ; Jump
.text:00402350
.text:00402355 ; ---------------------------------------------------------------------------
.text:00402355
.text:00402355 loc_402355: ; CODE XREF: VM_Multiple_op2+12D#j
.text:00402355 014 mov esi, [esp+14h+Hold_34h_param]
.text:00402359 014 mov ecx, edi_is_Param_24h
.text:0040235B 014 and esi, 0FFFFh ; Logical AND
.text:00402361 014 and ecx, 0FFFFh ; Logical AND
.text:00402367 014 xor esi, ecx ; Logical Exclusive OR
.text:00402369 014 jmp Finalize_Instruction_end_of_case_0Ch ; Jump
.text:00402369
.text:0040236E ; ---------------------------------------------------------------------------
.text:0040236E
.text:0040236E loc_40236E: ; CODE XREF: VM_Multiple_op2+12A#j
.text:0040236E 014 mov esi, [esp+14h+Hold_34h_param]
.text:00402372 014 mov edx, edi_is_Param_24h
.text:00402374 014 and esi, 0FFh ; Logical AND
.text:0040237A 014 and edx, 0FFh ; Logical AND
.text:00402380 014 xor esi, edx ; Logical Exclusive OR
.text:00402382 014 jmp Finalize_Instruction_end_of_case_0Ch ; Jump
.text:00402196 0D4 mov eax, [esp+0D4h+RealVMAddr__and_decoded_VMEIP]
.text:0040219A 0D4 lea ecx, [esp+0D4h+VM_InstructionBuff_Body_Ptr]
.text:004021A1 0D4 push eax
.text:004021A2 0D8 push ecx
.text:004021A3 0DC call VMInstructionDecoder ; Call Procedure
.text:004021A3
.text:004021A8 0DC add esp, 8 ; Add
.text:004021AB 0D4 test eax, eax ; Logical Compare
.text:004021AD 0D4 jnz short Execute_VM_Opcode ; Jump if Not Zero (ZF=0)
if (!MachineCheck) {
MachineCheck = VMInstructionDecoder(&InstBuff,RealEIP);
if (!MachineCheck) // check for opposite behavior...
bool VMAddress2Real(TVMContext *VMContext,int VMAddress,int *RealAddr) { // .text:004011D0
if( RANGE(VMAddress,VMContext->InitCode,VMContext->MemorySize) ) {
*RealAddr = (VM_Address-VMContext->InitCode)+VMContext->ProgramMemoryAddr;
return 1;
}
if( RANGE(VMAddress,VMContext->Original_ESP,VMContext->StackMemorySize) ) {
*RealAddr = (VM_Address-VMContext->Original_ESP)+VMContext->StackMemoryAddr;
return 1;
}
VMContext->MachineControl = mcWrongAddress;
return 0;
}
// :00401F60 VM_ALLOW_IO
int __cdecl VM_ALLOW_IO(TVMContext* VMContext, TInstructionBuffer* DecodedInstr) {
VMContext->MachineControl = mcInputOutput;
NextInstr(VMContext,DecodedInstr);
// very ugly: for having IO you must force a MachineControl check, as if error were in.
return 1;
}
:00401F60 VM_ALLOW_IO proc near ; CODE XREF: _main+162#p
.text:00401F60 ; DATA XREF: .data:0040752C#o
.text:00401F60
.text:00401F60 arg_0 = dword ptr 4
.text:00401F60 arg_4 = dword ptr 8
.text:00401F60
.text:00401F60 000 mov eax, [esp+arg_4]
.text:00401F64 000 mov ecx, [esp+arg_0]
.text:00401F68 000 mov [eax+VM_Context.maybe_MachineControl], mcInputOutput
.text:00401F6F 000 mov edx, [ecx]
.text:00401F71 000 mov ecx, [eax+VM_Context.VM_EIP]
.text:00401F74 000 add ecx, edx ; Add
.text:00401F76 000 mov [eax+VM_Context.VM_EIP], ecx
.text:00401F79 000 mov eax, 1
.text:00401F7E 000 retn ; Return Near from Procedure
.text:00401F7E
.text:00401F7E VM_ALLOW_IO endp
.text:004021E4 0D4 cmp [esp+0D4h+Ctx_var_54_zeroed_on_loop_head_R70_MachineControl], edi_mcInputOutput ; Compare Two Operands
.text:004021EB 0D4 jnz VM_MachineErrCheck_OrEndOfVM ; jump to test if we need NOT to read/write output!
.text:004021EB
.text:004021F1 0D4 lea edx, [esp+0D4h+VM_Context] ; Load Effective Address
.text:004021F5 0D4 push edx ; VM_Context_Ptr
.text:004021F6 0D8 call CheckForInputOutput ; Call Procedure
if (MachineCheck && VMContext.maybe_MachineControl==c2) { // VM loop end. c2==mcInputOutput
CheckForInputOutput(&VMContext);
continue;
int __cdecl VM_RET(TVMContext* VMContext, TInstructionBuffer* DecodedInstr) {
int VMValue;
Read_VMMemory_To(VMContext->VM_ESP, &VMValue);
VMContext->VM_ESP-=4;
VMContext->VM_EIP = VMValue;
}
.text:00401EC0 VM_RET proc near ; CODE XREF: _main+162#p
.text:00401EC0 ; DATA XREF: .data:0040745C#o
.text:00401EC0
.text:00401EC0 VMCOntext_Ptr = dword ptr 0Ch
.text:00401EC0
.text:00401EC0 000 push esi
.text:00401EC1 004 mov esi, [esp+VMCOntext_Ptr]
.text:00401EC5 004 push esi ; vm_context_ptr
.text:00401EC6 008 lea eax, [esp+4+VMCOntext_Ptr] ; Load Effective Address
.text:00401ECA 008 mov ecx, [esi+VM_Context.VM_ESP]
.text:00401ECD 008 push 4 ; AddressDataSize
.text:00401ECF 00C push eax ; Write_VMValue_in_LE_At
.text:00401ED0 010 push ecx ; VMAddress
.text:00401ED1 014 call Read_VMMemory_To ; was Set_RealAddress_To
.text:00401ED1
.text:00401ED6 014 add esp, 10h ; Add
.text:00401ED9 004 test eax, eax ; Logical Compare
.text:00401EDB 004 jnz short loc_401EE4 ; Jump if Not Zero (ZF=0)
.text:00401EDB
.text:00401EDD 004 mov eax, 1
.text:00401EE2 004 pop esi
.text:00401EE3 000 retn ; Return Near from Procedure
.text:00401EE3
.text:00401EE4 ; ---------------------------------------------------------------------------
.text:00401EE4
.text:00401EE4 loc_401EE4: ; CODE XREF: VM_RET+1B#j
.text:00401EE4 004 mov eax, [esi+VM_Context.VM_ESP]
.text:00401EE7 004 mov edx, [esp+VMCOntext_Ptr]
.text:00401EEB 004 add eax, -4 ; Add
.text:00401EEE 004 mov [esi+VM_Context.VM_EIP], edx
.text:00401EF1 004 mov [esi+VM_Context.VM_ESP], eax
.text:00401EF4 004 xor eax, eax ; Logical Exclusive OR
.text:00401EF6 004 pop esi
.text:00401EF7 000 retn ; Return Near from Procedure
.text:00401EF7
.text:00401EF7 VM_RET endp
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!
上传的附件: