--- /dev/null
+\r
+#include "core.h"\r
+\r
+//x86\83G\83~\83\85\83\8c\81[\83^\r
+//\89¼\91z86\83\82\81[\83h\82ð\97\98\97p\82·\82é\82Ì\82ª\93ï\82µ\82»\82¤\82È\82Ì\82Å\81A16bit\83R\81[\83h\82Ì\82Ý\91Î\89\9e\82Å\97Ç\82¢\82©\82ç\81A\r
+//CPU\82Æ\93¯\93\99\82Ì\93®\8dì\82ð\82·\82é\83G\83~\83\85\83\8c\81[\83^\81[\82ð\8dì\82é\81B\r
+//\83\81\83\82\83\8a\82Ö\82Ì\91S\8c \83A\83N\83Z\83X\82ª\89Â\94\\82Å\82 \82é\82±\82Æ\82ª\91O\92ñ\81B\r
+\r
+uchar *Emulator_x86_RegNames[] = {\r
+ "AX",\r
+ "CX",\r
+ "DX",\r
+ "BX",\r
+ "SP",\r
+ "BP",\r
+ "SI",\r
+ "DI"\r
+};\r
+\r
+uchar *Emulator_x86_SRegNames[] = {\r
+ "ES",\r
+ "CS",\r
+ "SS",\r
+ "DS",\r
+ "FS",\r
+ "GS",\r
+ "xx",\r
+ "xx"\r
+};\r
+\r
+uchar *Emulator_x86_ByteRegNames[] = {\r
+ "AL",\r
+ "CL",\r
+ "DL",\r
+ "BL",\r
+ "AH",\r
+ "CH",\r
+ "DH",\r
+ "BH"\r
+};\r
+\r
+void Emulator_x86_Initialize(Emulator_x86_Environment *env)\r
+{\r
+ env->EFLAGS.eflags = 0x00000002;\r
+ env->EIP = 0x0000fff0;\r
+\r
+ env->CR0.cr0 = 0x60000010;\r
+ env->CR2 = 0x00000000;\r
+ env->CR3.cr3 = 0x00000000;\r
+ env->CR4.cr4 = 0x00000000;\r
+\r
+ env->SReg[OPCODE_SREG3_ES].selector = 0x0000;\r
+ env->SReg[OPCODE_SREG3_ES].base = 0x00000000;\r
+ env->SReg[OPCODE_SREG3_ES].limit = 0xffff;\r
+ env->SReg[OPCODE_SREG3_ES].type = AR_PRESENT + AR_TYPE_DATA_RW + AR_TYPE_ACCESSED;\r
+ env->SReg[OPCODE_SREG3_CS] = env->SReg[OPCODE_SREG3_ES];\r
+ env->SReg[OPCODE_SREG3_SS] = env->SReg[OPCODE_SREG3_ES];\r
+ env->SReg[OPCODE_SREG3_DS] = env->SReg[OPCODE_SREG3_ES];\r
+ env->SReg[OPCODE_SREG3_FS] = env->SReg[OPCODE_SREG3_ES];\r
+ env->SReg[OPCODE_SREG3_GS] = env->SReg[OPCODE_SREG3_ES];\r
+\r
+ env->GReg[OPCODE_REG_EAX] = 0x00000000;\r
+ env->GReg[OPCODE_REG_ECX] = 0x00000000;\r
+ env->GReg[OPCODE_REG_EDX] = 0x00000000;\r
+ env->GReg[OPCODE_REG_EBX] = 0x00000000;\r
+ env->GReg[OPCODE_REG_ESP] = 0x00000000;\r
+ env->GReg[OPCODE_REG_EBP] = 0x00000000;\r
+ env->GReg[OPCODE_REG_ESI] = 0x00000000;\r
+ env->GReg[OPCODE_REG_EDI] = 0x00000000;\r
+\r
+ env->GDTR.base = 0x00000000;\r
+ env->GDTR.limit = 0xffff;\r
+\r
+ env->IDTR.base = 0x00000000;\r
+ env->IDTR.limit = 0xffff;\r
+\r
+ env->now_opcode = 0x00;\r
+ env->operation_end = False;\r
+ env->operation_32bit = False;\r
+\r
+ return;\r
+}\r
+\r
+uint Emulator_x86_Execute(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_Put_EmulationInformation(env, "Emulator-x86:EIP=0x%08X ", env->EIP);\r
+\r
+ env->operation_prefix_lock_repeat = OPCODE_PREFIX_NONE;\r
+ env->operation_prefix_segment = OPCODE_SREG3_DS;\r
+ env->operation_prefix_opsize = OPCODE_PREFIX_NONE;\r
+ env->operation_prefix_addrsize = OPCODE_PREFIX_NONE;\r
+\r
+ for(; !env->operation_end; ){\r
+ env->now_opcode = Emulator_x86_FetchCode(env, 1);\r
+ Emulator_x86_Put_EmulationInformation(env, "opcode=0x%02X ", env->now_opcode);\r
+\r
+ if(0x40 <= env->now_opcode && env->now_opcode <= 0x47){ /*INC FullReg*/\r
+ Emulator_x86_Operation_INC_RegOnly(env);\r
+\r
+ } else if(0x48 <= env->now_opcode && env->now_opcode <= 0x4F){ /*DEC FullReg*/\r
+ Emulator_x86_Operation_DEC_RegOnly(env);\r
+\r
+ } else if(0x50 <= env->now_opcode && env->now_opcode <= 0x57){ /*PUSH FullReg*/\r
+ Emulator_x86_Operation_PUSH_RegOnly(env);\r
+\r
+ } else if(0x58 <= env->now_opcode && env->now_opcode <= 0x5F){ /*POP FullReg*/\r
+ Emulator_x86_Operation_POP_RegOnly(env);\r
+\r
+ } else if(0xB0 <= env->now_opcode && env->now_opcode <= 0xB7){ /*MOV ByteReg*/\r
+ Emulator_x86_Operation_MOV_To_ByteReg(env);\r
+\r
+ } else if(0xB8 <= env->now_opcode && env->now_opcode <= 0xBF){ /*MOV FullSize*/\r
+ Emulator_x86_Operation_MOV_To_Reg_FullSize(env);\r
+\r
+ } else if(env->now_opcode == 0x1B){ /*SBB Gv, Ev*/\r
+ Emulator_x86_Operation_SBB_Gv_Ev(env);\r
+\r
+ } else if(env->now_opcode == 0x1E){ /*PUSH DS*/\r
+ Emulator_x86_Push_SReg_To_Stack(env, OPCODE_SREG3_DS);\r
+ env->operation_end = True;\r
+\r
+ } else if(env->now_opcode == 0x1F){ /*POP DS*/\r
+ Emulator_x86_Pop_SReg_From_Stack(env, OPCODE_SREG3_DS);\r
+ env->operation_end = True;\r
+\r
+ } else if(env->now_opcode == 0x26){ /*ES Prefix*/\r
+ env->operation_prefix_segment = OPCODE_SREG3_ES;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:ES)");\r
+\r
+ } else if(env->now_opcode == 0x2E){ /*CS/BranchNotTaken Prefix*/\r
+ env->operation_prefix_segment = OPCODE_SREG3_CS;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:CS)");\r
+\r
+ } else if(env->now_opcode == 0x31){ /*XOR Eb, Gb*/\r
+ Emulator_x86_Operation_XOR_Eb_Gb(env);\r
+\r
+ } else if(env->now_opcode == 0x36){ /*SS Prefix*/\r
+ env->operation_prefix_segment = OPCODE_SREG3_SS;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:SS)");\r
+\r
+ } else if(env->now_opcode == 0x3B){ /*CMP Gv, Ev*/\r
+ Emulator_x86_Operation_CMP_Gv_Ev(env);\r
+\r
+ } else if(env->now_opcode == 0x3C){ /*CMP AL*/\r
+ Emulator_x86_Operation_CMP_AL(env);\r
+\r
+ } else if(env->now_opcode == 0x3E){ /*DS/BranchTaken Prefix*/\r
+ env->operation_prefix_segment = OPCODE_SREG3_DS;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:DS)");\r
+\r
+ } else if(env->now_opcode == 0x60){ /*PUSHA/PUSHAD*/\r
+ Emulator_x86_Operation_PUSHA(env);\r
+\r
+ } else if(env->now_opcode == 0x61){ /*POPA/POPAD*/\r
+ Emulator_x86_Operation_POPA(env);\r
+\r
+ } else if(env->now_opcode == 0x64){ /*FS Prefix*/\r
+ env->operation_prefix_segment = OPCODE_SREG3_FS;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:FS)");\r
+\r
+ } else if(env->now_opcode == 0x65){ /*GS Prefix*/\r
+ env->operation_prefix_segment = OPCODE_SREG3_GS;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:GS)");\r
+\r
+ } else if(env->now_opcode == 0x66){ /*OperandSize Prefix*/\r
+ env->operation_prefix_opsize = OPCODE_PREFIX_OPERAND_SIZE;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:OperandSize)");\r
+\r
+ } else if(env->now_opcode == 0x67){ /*AddressSize Prefix*/\r
+ env->operation_prefix_addrsize = OPCODE_PREFIX_ADDRESS_SIZE;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:AddressSize)");\r
+\r
+ } else if(env->now_opcode == 0x6A){ /*AddressSize Prefix*/\r
+ Emulator_x86_Operation_PUSH_Ib(env);\r
+\r
+ } else if(env->now_opcode == 0x74){ /*JE rel8*/\r
+ Emulator_x86_Operation_Jcc_JE_rel8(env);\r
+\r
+ } else if(env->now_opcode == 0x75){ /*JE rel8*/\r
+ Emulator_x86_Operation_Jcc_JNE_rel8(env);\r
+\r
+ } else if(env->now_opcode == 0x89){ /*MOV Ev, Gv*/\r
+ Emulator_x86_Operation_MOV_Ev_Gv(env);\r
+\r
+ } else if(env->now_opcode == 0x8A){ /*MOV Byte*/\r
+ Emulator_x86_Operation_MOV_To_ByteReg_Gb_Eb(env);\r
+\r
+ } else if(env->now_opcode == 0x8D){ /*LEA*/\r
+ Emulator_x86_Operation_LEA(env);\r
+\r
+ } else if(env->now_opcode == 0x8E){ /*MOV SegReg*/\r
+ Emulator_x86_Operation_MOV_To_SegReg(env);\r
+\r
+ } else if(env->now_opcode == 0x8F){ /*POP Ev*/\r
+ Emulator_x86_Operation_POP_Ev(env);\r
+\r
+ } else if(env->now_opcode == 0xA1){ /*MOV eAX, Ov*/\r
+ Emulator_x86_Operation_MOV_eAX_Ov(env);\r
+\r
+ } else if(env->now_opcode == 0xA3){ /*MOV Ov, eAX*/\r
+ Emulator_x86_Operation_MOV_Ov_eAX(env);\r
+\r
+ } else if(env->now_opcode == 0xC3){ /*near RET*/\r
+ Emulator_x86_Operation_RET_Near(env);\r
+\r
+ } else if(env->now_opcode == 0xCD){ /*INT n*/\r
+ Emulator_x86_Operation_INTn(env);\r
+\r
+ } else if(env->now_opcode == 0xE2){ /*LOOP Jv*/\r
+ Emulator_x86_Operation_LOOP_Jv(env);\r
+\r
+ } else if(env->now_opcode == 0xE6){ /*OUT AL*/\r
+ Emulator_x86_Operation_OUT_AL(env);\r
+\r
+ } else if(env->now_opcode == 0xE8){ /*CALL near*/\r
+ Emulator_x86_Operation_CALL_Near_Relative(env);\r
+\r
+ } else if(env->now_opcode == 0xEB){ /*JMP short*/\r
+ Emulator_x86_Operation_JMP_rel8(env);\r
+\r
+ } else if(env->now_opcode == 0xF0){ /*LOCK Prefix*/\r
+ env->operation_prefix_lock_repeat = OPCODE_PREFIX_LOCK;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:LOCK)");\r
+\r
+ } else if(env->now_opcode == 0xF2){ /*REPNE/REPNZ Prefix*/\r
+ env->operation_prefix_lock_repeat = OPCODE_PREFIX_REPNE_REPNZ;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:REPNE/REPNZ)");\r
+\r
+ } else if(env->now_opcode == 0xF3){ /*REP/REPE/REPZ Prefix*/\r
+ env->operation_prefix_lock_repeat = OPCODE_PREFIX_REP_REPE_REPZ;\r
+ Emulator_x86_Put_EmulationInformation(env, "(Prefix:REP/REPE/REPZ)");\r
+\r
+ } else if(env->now_opcode == 0xFB){ /*STI*/\r
+ Emulator_x86_Operation_STI(env);\r
+\r
+ } else if(env->now_opcode == 0xFC){ /*CLD*/\r
+ Emulator_x86_Operation_CLD(env);\r
+\r
+ } else{\r
+ Emulator_x86_Put_EmulationInformation(env, "Unknown OperationCode.\n");\r
+ return 0xFFFFFFFF;\r
+ }\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "\n");\r
+\r
+ env->operation_end = False;\r
+\r
+ return 0;\r
+}\r
+\r
+uint Emulator_x86_Execute_Auto(Emulator_x86_Environment *env)\r
+{\r
+ uint i;\r
+\r
+ for(i = 0; ; i++){\r
+ if(Emulator_x86_Execute(env) == 0xffffffff){\r
+ break;\r
+ }\r
+ }\r
+ return i + 1;\r
+}\r
+\r
+int Emulator_x86_Put_EmulationInformation(Emulator_x86_Environment *env, const uchar format[], ...)\r
+{\r
+ int i;\r
+ uchar s[256];\r
+\r
+ i = vsnprintf(s, sizeof(s), format, (uint *)(&format + 1));\r
+ SerialPort_Send(s);\r
+\r
+ return i;\r
+}\r
+\r
+uint Emulator_x86_FetchCode(Emulator_x86_Environment *env, uint bytes)\r
+{\r
+ uint data;\r
+ uint i;\r
+\r
+ data = 0;\r
+ for(i = 0; i < bytes; i++){\r
+ data |= (*((uchar *)Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_CS, env->EIP)) << (i << 3));\r
+ Emulator_x86_InstructionPointer_Increment(env);\r
+ }\r
+\r
+ return data;\r
+}\r
+\r
+void Emulator_x86_InstructionPointer_Increment(Emulator_x86_Environment *env)\r
+{\r
+ env->EIP++;\r
+ if(!env->operation_32bit){\r
+ env->EIP &= 0x0000ffff;\r
+ }\r
+ return;\r
+}\r
+\r
+uint Emulator_x86_Get_EffectivePhysicalAddress(Emulator_x86_Environment *env, uint sreg, uint offset)\r
+{\r
+ uint addr;\r
+\r
+ addr = 0;\r
+\r
+ if(sreg > 5){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid SReg).");\r
+ return 0;\r
+ }\r
+\r
+ if(env->operation_32bit){ /*32-bit addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit mode is not implemented.");\r
+ } else{ /*16-bit addressing*/\r
+ addr = (env->SReg[sreg].selector << 4) + offset;\r
+ }\r
+ return addr;\r
+}\r
+\r
+uint Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(Emulator_x86_Environment *env, uint mrm)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint offset;\r
+ uint address;\r
+\r
+ modrm.modrm = mrm;\r
+ offset = 0;\r
+ address = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg only*/\r
+ Emulator_x86_Put_EmulationInformation(env, "Not Address, From Register.");\r
+ return 0;\r
+ } else{ /*From MemoryAddress*/\r
+ if(modrm.bit.RM == OPCODE_RM16_ADDR_BX_SI){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EBX, True);\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_ESI, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_ADDR_BX_SI){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EBX, True);\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EDI, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_ADDR_BX_DI){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EBP, True);\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_ESI, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_ADDR_BP_SI){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EBP, True);\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EDI, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_ADDR_SI){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_ESI, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_ADDR_DI){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EDI, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_MOD00_ADDR_DISP16){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EBP, True);\r
+ } else if(modrm.bit.RM == OPCODE_RM16_ADDR_BX){\r
+ offset += Emulator_x86_MoveFromGReg(env, OPCODE_REG_EBX, True);\r
+ }\r
+ if(modrm.bit.Mod == OPCODE_MOD_INDEXONLY){\r
+ if(modrm.bit.RM == OPCODE_RM16_MOD00_ADDR_DISP16){\r
+ offset = Emulator_x86_FetchCode(env, 2);\r
+ }\r
+ } else if(modrm.bit.Mod == OPCODE_MOD_INDEX_AND_DISP_BYTE){\r
+ offset += Emulator_x86_FetchCode(env, 1);\r
+ } else if(modrm.bit.Mod == OPCODE_MOD_INDEX_AND_DISP_FULL){\r
+ offset += Emulator_x86_FetchCode(env, 2);\r
+ }\r
+ offset &= 0x0000ffff;\r
+ address = Emulator_x86_Get_EffectivePhysicalAddress(env, env->operation_prefix_segment, offset);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Address Generated %s:0x%X = [0x%X])", Emulator_x86_SRegNames[env->operation_prefix_segment], offset, address);\r
+ }\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit mode is not implemented.");\r
+ }\r
+\r
+ return address;\r
+}\r
+\r
+void Emulator_x86_MoveToGReg(Emulator_x86_Environment *env, uint reg, uint data, uint fullsize)\r
+{\r
+ if(reg > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid GReg).");\r
+ return;\r
+ }\r
+\r
+ if(fullsize){\r
+ if(env->operation_32bit){ /*DoubleWord*/\r
+ env->GReg[reg] = data;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveToE%s:0x%X)", Emulator_x86_RegNames[reg], data);\r
+ } else{ /*Word*/\r
+ env->GReg[reg] &= 0xffff0000;\r
+ env->GReg[reg] |= 0x0000ffff & data;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveTo%s:0x%X)", Emulator_x86_RegNames[reg], data);\r
+ }\r
+ } else{ /*Byte*/\r
+ if(reg < 4){ /*Low*/\r
+ env->GReg[reg] &= 0xffffff00;\r
+ env->GReg[reg] |= 0x000000ff & data;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveTo%s:0x%X)", Emulator_x86_ByteRegNames[reg], data);\r
+ } else{ /*High*/\r
+ reg -= 4;\r
+ env->GReg[reg] &= 0xffff00ff;\r
+ env->GReg[reg] |= 0x0000ff00 & (data << 8);\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveTo%s:0x%X)", Emulator_x86_ByteRegNames[reg + 4], data);\r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
+uint Emulator_x86_MoveFromGReg(Emulator_x86_Environment *env, uint reg, uint fullsize)\r
+{\r
+ uint data;\r
+\r
+ if(reg > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid GReg).");\r
+ return 0;\r
+ }\r
+\r
+ if(fullsize){\r
+ if(env->operation_32bit){ /*DoubleWord*/\r
+ data = env->GReg[reg];\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveFromE%s:0x%X)", Emulator_x86_RegNames[reg], data);\r
+ } else{ /*Word*/\r
+ data = env->GReg[reg];\r
+ data &= 0x0000ffff;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveFrom%s:0x%X)", Emulator_x86_RegNames[reg], data);\r
+ }\r
+ } else{ /*Byte*/\r
+ if(reg < 4){ /*Low*/\r
+ data = env->GReg[reg];\r
+ data &= 0x000000ff;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveFrom%s:0x%X)", Emulator_x86_ByteRegNames[reg], data);\r
+ } else{ /*High*/\r
+ reg -= 4;\r
+ data = env->GReg[reg];\r
+ data &= 0x0000ff00;\r
+ data = data >> 8;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveFrom%s:0x%X)", Emulator_x86_ByteRegNames[reg + 4], data);\r
+ }\r
+ }\r
+ return data;\r
+}\r
+\r
+void Emulator_x86_MoveToSReg(Emulator_x86_Environment *env, uint sreg, ushort selector)\r
+{\r
+ if(sreg > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid SReg).");\r
+ return;\r
+ }\r
+\r
+ if(env->operation_32bit){ /*32-bit Segmentation*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit mode is not implemented.");\r
+ } else{ /*16-bit Segmentation*/\r
+ env->SReg[sreg].selector = selector;\r
+ Emulator_x86_Put_EmulationInformation(env, "(MoveTo%s:0x%X)", Emulator_x86_SRegNames[sreg], selector);\r
+ }\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Push_Data_To_Stack(Emulator_x86_Environment *env, uint data, uint size_dword)\r
+{\r
+ void *addr;\r
+\r
+ if(env->GReg[OPCODE_REG_ESP] < 4){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(No More Stack).");\r
+ return;\r
+ }\r
+ if(size_dword){ /*DoubleWord*/\r
+ Emulator_x86_MoveToGReg(env, OPCODE_REG_ESP, env->GReg[OPCODE_REG_ESP] - 4, True);\r
+ addr = (void *)Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_SS, env->GReg[OPCODE_REG_ESP]);\r
+ *((uint *)addr) = data;\r
+ } else{ /*Word*/\r
+ Emulator_x86_MoveToGReg(env, OPCODE_REG_ESP, env->GReg[OPCODE_REG_ESP] - 2, True);\r
+ addr = (void *)Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_SS, env->GReg[OPCODE_REG_ESP]);\r
+ *((ushort *)addr) = data;\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "(PushTo[0x%08X]:0x%X)", Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_SS, env->GReg[OPCODE_REG_ESP]), data);\r
+\r
+ return;\r
+}\r
+\r
+uint Emulator_x86_Pop_Data_From_Stack(Emulator_x86_Environment *env, uint size_dword)\r
+{\r
+ uint data;\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "(PopFrom[0x%08X]:", Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_SS, env->GReg[OPCODE_REG_ESP]));\r
+\r
+ if(size_dword){ /*DoubleWord*/\r
+ data = *((uint *)Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_SS, env->GReg[OPCODE_REG_ESP]));\r
+ Emulator_x86_MoveToGReg(env, OPCODE_REG_ESP, env->GReg[OPCODE_REG_ESP] + 4, True);\r
+ } else{ /*Word*/\r
+ data = *((ushort *)Emulator_x86_Get_EffectivePhysicalAddress(env, OPCODE_SREG3_SS, env->GReg[OPCODE_REG_ESP]));\r
+ Emulator_x86_MoveToGReg(env, OPCODE_REG_ESP, env->GReg[OPCODE_REG_ESP] + 2, True);\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "0x%X)", data);\r
+\r
+ return data;\r
+}\r
+\r
+void Emulator_x86_Push_eIP_To_Stack(Emulator_x86_Environment *env)\r
+{\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ env->EIP &= 0x0000ffff;\r
+ Emulator_x86_Push_Data_To_Stack(env, env->EIP, False);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Push IP[0x%X])", env->EIP);\r
+ } else{ /*32-bit*/\r
+ Emulator_x86_Push_Data_To_Stack(env, env->EIP, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Push EIP[0x%X])", env->EIP);\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Pop_eIP_From_Stack(Emulator_x86_Environment *env)\r
+{\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ env->EIP = Emulator_x86_Pop_Data_From_Stack(env, False);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Pop IP[0x%X])", env->EIP);\r
+ } else{ /*32-bit*/\r
+ env->EIP = Emulator_x86_Pop_Data_From_Stack(env, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Pop EIP[0x%X])", env->EIP);\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Push_eFLAGS_To_Stack(Emulator_x86_Environment *env)\r
+{\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ env->EFLAGS.eflags &= 0x0000ffff;\r
+ Emulator_x86_Push_Data_To_Stack(env, env->EFLAGS.eflags, False);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Push FLAGS(0x%X))", env->EFLAGS.eflags);\r
+ } else{ /*32-bit*/\r
+ Emulator_x86_Push_Data_To_Stack(env, env->EIP, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Push EFLAGS(0x%X))", env->EFLAGS.eflags);\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Pop_eFLAGS_From_Stack(Emulator_x86_Environment *env)\r
+{\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ env->EFLAGS.eflags = Emulator_x86_Pop_Data_From_Stack(env, False);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Pop FLAGS(0x%X))", env->EFLAGS.eflags);\r
+ } else{ /*32-bit*/\r
+ env->EFLAGS.eflags = Emulator_x86_Pop_Data_From_Stack(env, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "(Pop EFLAGS(0x%X))", env->EFLAGS.eflags);\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Push_SReg_To_Stack(Emulator_x86_Environment *env, uint sreg)\r
+{\r
+ //16bit/32bit\r
+\r
+ if(sreg > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid SReg).");\r
+ return;\r
+ }\r
+\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ Emulator_x86_Push_Data_To_Stack(env, env->SReg[sreg].selector, False);\r
+ } else{ /*32-bit*/\r
+ Emulator_x86_Push_Data_To_Stack(env, env->SReg[sreg].selector, True);\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "(Push %s(0x%X))", Emulator_x86_SRegNames[sreg], env->SReg[sreg].selector);\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Pop_SReg_From_Stack(Emulator_x86_Environment *env, uint sreg)\r
+{\r
+ //16bit/32bit\r
+\r
+ if(sreg > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid SReg).");\r
+ return;\r
+ }\r
+\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ Emulator_x86_MoveToSReg(env, sreg, Emulator_x86_Pop_Data_From_Stack(env, False));\r
+ } else{ /*32-bit*/\r
+ Emulator_x86_MoveToSReg(env, sreg, Emulator_x86_Pop_Data_From_Stack(env, True));\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "(Pop %s(0x%X))", Emulator_x86_SRegNames[sreg], env->SReg[sreg].selector);\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_To_Reg_FullSize(Emulator_x86_Environment *env)\r
+{\r
+ uint imm;\r
+\r
+ imm = Emulator_x86_FetchCode(env, 2);\r
+\r
+ Emulator_x86_MoveToGReg(env, env->now_opcode - 0xB8, imm, True);\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, 0x%X", Emulator_x86_RegNames[env->now_opcode - 0xB8], imm);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_To_SegReg(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){\r
+ Emulator_x86_MoveToSReg(env, modrm.bit.Reg, Emulator_x86_MoveFromGReg(env, modrm.bit.RM, True));\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, %s", Emulator_x86_SRegNames[modrm.bit.Reg], Emulator_x86_RegNames[modrm.bit.RM]);\r
+ } else{\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ Emulator_x86_MoveToSReg(env, modrm.bit.Reg, *((ushort *)addr));\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, [0x%X]", Emulator_x86_SRegNames[modrm.bit.Reg], addr);\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_To_ByteReg(Emulator_x86_Environment *env)\r
+{\r
+ uchar imm8;\r
+\r
+ imm8 = Emulator_x86_FetchCode(env, 1);\r
+\r
+ Emulator_x86_MoveToGReg(env, env->now_opcode - 0xB0, imm8, False);\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, 0x%X", Emulator_x86_ByteRegNames[env->now_opcode - 0xB0], imm8);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_INTn(Emulator_x86_Environment *env)\r
+{\r
+ //16-bit only\r
+\r
+ uchar intn;\r
+ Emulator_x86_FarPointer *vector;\r
+\r
+ intn = Emulator_x86_FetchCode(env, 1);\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "INT 0x%X", intn);\r
+\r
+ vector = (Emulator_x86_FarPointer *)(intn << 2);\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "[0x%X:0x%X] = [0x%X]", vector->selector, vector->offset, (vector->selector << 4) + vector->offset);\r
+\r
+ Emulator_x86_Push_eFLAGS_To_Stack(env);\r
+ env->EFLAGS.bit.IF = False;\r
+ env->EFLAGS.bit.TF = False;\r
+ env->EFLAGS.bit.AC = False;\r
+ Emulator_x86_Push_SReg_To_Stack(env, OPCODE_SREG3_CS);\r
+ Emulator_x86_Push_eIP_To_Stack(env);\r
+\r
+ Emulator_x86_MoveToSReg(env, OPCODE_SREG3_CS, vector->selector);\r
+ env->EIP = vector->offset;\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_LEA(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint disp;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+\r
+ if(!env->operation_32bit){\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){\r
+ Emulator_x86_Put_EmulationInformation(env, "LEA Invalid.");\r
+ } else{\r
+ disp = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ disp -= (env->SReg[env->operation_prefix_segment].selector << 4);\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.Reg, disp, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "LEA %s, 0x%X", Emulator_x86_RegNames[modrm.bit.Reg], disp);\r
+ }\r
+ } else{\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit mode is not implemented.");\r
+ }\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_CALL_Near_Relative(Emulator_x86_Environment *env)\r
+{\r
+ short relative_addr;\r
+ uchar sign;\r
+\r
+ sign = False;\r
+\r
+ relative_addr = Emulator_x86_FetchCode(env, 2);\r
+\r
+ if(relative_addr < 0){\r
+ sign = True;\r
+ relative_addr = -relative_addr;\r
+ }\r
+\r
+ Emulator_x86_Push_eIP_To_Stack(env);\r
+\r
+ if(sign){\r
+ env->EIP -= (uint)relative_addr;\r
+ } else{\r
+ env->EIP += (uint)relative_addr;\r
+ }\r
+\r
+ if(!env->operation_32bit){\r
+ env->EIP &= 0x0000ffff;\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "near CALL 0x%X", env->EIP);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_PUSHA(Emulator_x86_Environment *env)\r
+{\r
+ uint Temp;\r
+ uint i;\r
+\r
+ Temp = env->GReg[OPCODE_REG_ESP];\r
+\r
+ if(env->operation_32bit){ /*PUSHAD*/\r
+ Emulator_x86_Put_EmulationInformation(env, "PUSHAD");\r
+ for(i = 0; i < 4; i++){\r
+ Emulator_x86_Push_Data_To_Stack(env, Emulator_x86_MoveFromGReg(env, i, True), True);\r
+ }\r
+ Emulator_x86_Push_Data_To_Stack(env, Temp, False);\r
+ for(i = 5; i < 8; i++){\r
+ Emulator_x86_Push_Data_To_Stack(env, Emulator_x86_MoveFromGReg(env, i, True), True);\r
+ }\r
+ } else{ /*PUSHA*/\r
+ Emulator_x86_Put_EmulationInformation(env, "PUSHA");\r
+ for(i = 0; i < 4; i++){\r
+ Emulator_x86_Push_Data_To_Stack(env, Emulator_x86_MoveFromGReg(env, i, True), False);\r
+ }\r
+ Emulator_x86_Push_Data_To_Stack(env, Temp, False);\r
+ for(i = 5; i < 8; i++){\r
+ Emulator_x86_Push_Data_To_Stack(env, Emulator_x86_MoveFromGReg(env, i, True), False);\r
+ }\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_POPA(Emulator_x86_Environment *env)\r
+{\r
+ int i;\r
+\r
+ if(env->operation_32bit){ /*POPAD*/\r
+ Emulator_x86_Put_EmulationInformation(env, "POPAD");\r
+ for(i = 7; i > 4; i--){\r
+ Emulator_x86_MoveToGReg(env, i, Emulator_x86_Pop_Data_From_Stack(env, True), True);\r
+ }\r
+ Emulator_x86_Pop_Data_From_Stack(env, True);\r
+ for(i = 3; i > -1; i--){\r
+ Emulator_x86_MoveToGReg(env, i, Emulator_x86_Pop_Data_From_Stack(env, True), True);\r
+ }\r
+ } else{ /*POPA*/\r
+ Emulator_x86_Put_EmulationInformation(env, "POPA");\r
+ for(i = 7; i > 4; i--){\r
+ Emulator_x86_MoveToGReg(env, i, Emulator_x86_Pop_Data_From_Stack(env, False), True);\r
+ }\r
+ Emulator_x86_Pop_Data_From_Stack(env, False);\r
+ for(i = 3; i > -1; i--){\r
+ Emulator_x86_MoveToGReg(env, i, Emulator_x86_Pop_Data_From_Stack(env, False), True);\r
+ }\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_To_ByteReg_Gb_Eb(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+ addr = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg only*/\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.Reg, Emulator_x86_MoveFromGReg(env, modrm.bit.RM, False), False);\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, %s", Emulator_x86_ByteRegNames[modrm.bit.Reg], Emulator_x86_ByteRegNames[modrm.bit.RM]);\r
+ } else{ /*From MemoryAddress*/\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.Reg, *((uchar *)addr), False);\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, [0x%X]", Emulator_x86_ByteRegNames[modrm.bit.Reg], addr);\r
+ }\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit mode is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_CMP_AL(Emulator_x86_Environment *env)\r
+{\r
+ CPU_EFlags eflags;\r
+ uint imm;\r
+\r
+ imm = Emulator_x86_FetchCode(env, 1);\r
+\r
+ eflags.eflags = asm_Emulator_x86_Get_EFlags_Compare(Emulator_x86_MoveFromGReg(env, OPCODE_REG_BYTE_AL, False), imm);\r
+ env->EFLAGS.bit.CF = eflags.bit.CF;\r
+ env->EFLAGS.bit.PF = eflags.bit.PF;\r
+ env->EFLAGS.bit.AF = eflags.bit.AF;\r
+ env->EFLAGS.bit.ZF = eflags.bit.ZF;\r
+ env->EFLAGS.bit.SF = eflags.bit.SF;\r
+ env->EFLAGS.bit.OF = eflags.bit.OF;\r
+ Emulator_x86_Put_EmulationInformation(env, "CMP AL, 0x%X (CF:%d PF:%d AF:%d ZF:%d SF:%d OF:%d)", imm, env->EFLAGS.bit.CF, env->EFLAGS.bit.PF, env->EFLAGS.bit.AF, env->EFLAGS.bit.ZF, env->EFLAGS.bit.SF, env->EFLAGS.bit.OF);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_Jcc_JE_rel8(Emulator_x86_Environment *env)\r
+{\r
+ char relative_addr;\r
+ uchar sign;\r
+ uint new_eip;\r
+\r
+ sign = False;\r
+ relative_addr = Emulator_x86_FetchCode(env, 1);\r
+ new_eip = env->EIP;\r
+\r
+ if(relative_addr < 0){\r
+ sign = True;\r
+ relative_addr = -relative_addr;\r
+ }\r
+ if(sign){\r
+ new_eip -= (uint)relative_addr;\r
+ } else{\r
+ new_eip += (uint)relative_addr;\r
+ }\r
+\r
+ if(!env->operation_32bit){\r
+ new_eip &= 0x0000ffff;\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "JE 0x%X ", new_eip);\r
+\r
+ if(env->EFLAGS.bit.ZF){\r
+ Emulator_x86_Put_EmulationInformation(env, "Taken.");\r
+ env->EIP = new_eip;\r
+ } else{\r
+ Emulator_x86_Put_EmulationInformation(env, "NotTaken.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_INC_RegOnly(Emulator_x86_Environment *env)\r
+{\r
+ uint operand;\r
+ CPU_EFlags eflags;\r
+\r
+ if((env->now_opcode - 0x40) > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid GReg From OpCode).");\r
+ }\r
+\r
+ operand = Emulator_x86_MoveFromGReg(env, env->now_opcode - 0x40, True);\r
+ Emulator_x86_MoveToGReg(env, env->now_opcode - 0x40, operand + 1, True);\r
+\r
+ eflags.eflags = asm_Emulator_x86_Get_EFlags_Increment(operand);\r
+ env->EFLAGS.bit.PF = eflags.bit.PF;\r
+ env->EFLAGS.bit.AF = eflags.bit.AF;\r
+ env->EFLAGS.bit.ZF = eflags.bit.ZF;\r
+ env->EFLAGS.bit.SF = eflags.bit.SF;\r
+ env->EFLAGS.bit.OF = eflags.bit.OF;\r
+ Emulator_x86_Put_EmulationInformation(env, "INC %s (PF:%d AF:%d ZF:%d SF:%d OF:%d)", Emulator_x86_RegNames[env->now_opcode - 0x40], env->EFLAGS.bit.PF, env->EFLAGS.bit.AF, env->EFLAGS.bit.ZF, env->EFLAGS.bit.SF, env->EFLAGS.bit.OF);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_JMP_rel8(Emulator_x86_Environment *env)\r
+{\r
+ char relative_addr;\r
+ uchar sign;\r
+ uint new_eip;\r
+\r
+ sign = False;\r
+ relative_addr = Emulator_x86_FetchCode(env, 1);\r
+ new_eip = env->EIP;\r
+\r
+ if(relative_addr < 0){\r
+ sign = True;\r
+ relative_addr = -relative_addr;\r
+ }\r
+ if(sign){\r
+ new_eip -= (uint)relative_addr;\r
+ } else{\r
+ new_eip += (uint)relative_addr;\r
+ }\r
+\r
+ if(!env->operation_32bit){\r
+ new_eip &= 0x0000ffff;\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "JMP 0x%X", new_eip);\r
+\r
+ env->EIP = new_eip;\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_RET_Near(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_Pop_eIP_From_Stack(env);\r
+ Emulator_x86_Put_EmulationInformation(env, "near RET to 0x%X", env->EIP);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_PUSH_RegOnly(Emulator_x86_Environment *env)\r
+{\r
+ if((env->now_opcode - 0x50) > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid GReg From OpCode).");\r
+ }\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ Emulator_x86_Put_EmulationInformation(env, "PUSH %s", Emulator_x86_RegNames[env->now_opcode - 0x50]);\r
+ Emulator_x86_Push_Data_To_Stack(env, Emulator_x86_MoveFromGReg(env, env->now_opcode - 0x50, True), False);\r
+ } else{ /*32-bit*/\r
+ Emulator_x86_Put_EmulationInformation(env, "PUSH E%s", Emulator_x86_RegNames[env->now_opcode - 0x50]);\r
+ Emulator_x86_Push_Data_To_Stack(env, Emulator_x86_MoveFromGReg(env, env->now_opcode - 0x50, True), True);\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_XOR_Eb_Gb(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+ CPU_EFlags eflags;\r
+ uint dest_op, source_op;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+ addr = 0;\r
+ dest_op = 0;\r
+ source_op = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ source_op = Emulator_x86_MoveFromGReg(env, modrm.bit.Reg, True);\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg*/\r
+ dest_op = Emulator_x86_MoveFromGReg(env, modrm.bit.RM, True);\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.Reg, dest_op ^ source_op, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "XOR %s, %s", Emulator_x86_RegNames[modrm.bit.RM], Emulator_x86_RegNames[modrm.bit.Reg]);\r
+ } else{ /*MemoryAddress*/\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ dest_op = *((ushort *)addr);\r
+ Emulator_x86_Put_EmulationInformation(env, "XOR [0x%X], %s", addr, Emulator_x86_RegNames[modrm.bit.Reg]);\r
+ *((ushort *)addr) = dest_op ^ source_op;\r
+ }\r
+ eflags.eflags = asm_Emulator_x86_Get_EFlags_XOR(dest_op, source_op);\r
+ env->EFLAGS.bit.CF = False;\r
+ env->EFLAGS.bit.PF = eflags.bit.PF;\r
+ env->EFLAGS.bit.AF = eflags.bit.AF;\r
+ env->EFLAGS.bit.ZF = eflags.bit.ZF;\r
+ env->EFLAGS.bit.SF = eflags.bit.SF;\r
+ env->EFLAGS.bit.OF = False;\r
+ Emulator_x86_Put_EmulationInformation(env, " (CF:%d PF:%d AF:%d ZF:%d SF:%d OF:%d)", env->EFLAGS.bit.CF, env->EFLAGS.bit.PF, env->EFLAGS.bit.AF, env->EFLAGS.bit.ZF, env->EFLAGS.bit.SF, env->EFLAGS.bit.OF);\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_DEC_RegOnly(Emulator_x86_Environment *env)\r
+{\r
+ uint operand;\r
+ CPU_EFlags eflags;\r
+\r
+ if((env->now_opcode - 0x48) > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid GReg From OpCode).");\r
+ }\r
+\r
+ operand = Emulator_x86_MoveFromGReg(env, env->now_opcode - 0x48, True);\r
+ Emulator_x86_MoveToGReg(env, env->now_opcode - 0x48, operand - 1, True);\r
+\r
+ eflags.eflags = asm_Emulator_x86_Get_EFlags_Decrement(operand);\r
+ env->EFLAGS.bit.PF = eflags.bit.PF;\r
+ env->EFLAGS.bit.AF = eflags.bit.AF;\r
+ env->EFLAGS.bit.ZF = eflags.bit.ZF;\r
+ env->EFLAGS.bit.SF = eflags.bit.SF;\r
+ env->EFLAGS.bit.OF = eflags.bit.OF;\r
+ Emulator_x86_Put_EmulationInformation(env, "DEC %s (PF:%d AF:%d ZF:%d SF:%d OF:%d)", Emulator_x86_RegNames[env->now_opcode - 0x48], env->EFLAGS.bit.PF, env->EFLAGS.bit.AF, env->EFLAGS.bit.ZF, env->EFLAGS.bit.SF, env->EFLAGS.bit.OF);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_eAX_Ov(Emulator_x86_Environment *env)\r
+{\r
+ uint offset;\r
+ uint addr;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ offset = Emulator_x86_FetchCode(env, 2);\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress(env, env->operation_prefix_segment, offset);\r
+ Emulator_x86_MoveToGReg(env, OPCODE_REG_EAX, *((ushort *)addr), True);\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV AX, [0x%X]", addr);\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_Ov_eAX(Emulator_x86_Environment *env)\r
+{\r
+ uint offset;\r
+ uint addr;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ offset = Emulator_x86_FetchCode(env, 2);\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress(env, env->operation_prefix_segment, offset);\r
+ *((ushort *)addr) = Emulator_x86_MoveFromGReg(env, OPCODE_REG_EAX, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV [0x%X], AX", addr);\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_OUT_AL(Emulator_x86_Environment *env)\r
+{\r
+ uint port;\r
+\r
+ port = Emulator_x86_FetchCode(env, 1);\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "OUT 0x%X, AL(Not implemented)", port);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_CMP_Gv_Ev(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+ uint op0, op1;\r
+ CPU_EFlags eflags;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+ addr = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ op0 = Emulator_x86_MoveFromGReg(env, modrm.bit.Reg, True);\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg*/\r
+ op1 = Emulator_x86_MoveFromGReg(env, modrm.bit.RM, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "CMP %s, %s", Emulator_x86_RegNames[modrm.bit.Reg], Emulator_x86_RegNames[modrm.bit.RM]);\r
+ } else{ /*MemoryAddress*/\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ op1 = *((ushort *)addr);\r
+ Emulator_x86_Put_EmulationInformation(env, "CMP %s, [0x%X]", Emulator_x86_RegNames[modrm.bit.Reg], addr);\r
+ }\r
+ eflags.eflags = asm_Emulator_x86_Get_EFlags_Compare(op0, op1);\r
+ env->EFLAGS.bit.CF = eflags.bit.CF;\r
+ env->EFLAGS.bit.PF = eflags.bit.PF;\r
+ env->EFLAGS.bit.AF = eflags.bit.AF;\r
+ env->EFLAGS.bit.ZF = eflags.bit.ZF;\r
+ env->EFLAGS.bit.SF = eflags.bit.SF;\r
+ env->EFLAGS.bit.OF = eflags.bit.OF;\r
+ Emulator_x86_Put_EmulationInformation(env, " (CF:%d PF:%d AF:%d ZF:%d SF:%d OF:%d)", env->EFLAGS.bit.CF, env->EFLAGS.bit.PF, env->EFLAGS.bit.AF, env->EFLAGS.bit.ZF, env->EFLAGS.bit.SF, env->EFLAGS.bit.OF);\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_LOOP_Jv(Emulator_x86_Environment *env)\r
+{\r
+ char relative_addr;\r
+ uchar sign;\r
+ uint new_eip;\r
+ uint operand;\r
+\r
+ sign = False;\r
+ relative_addr = Emulator_x86_FetchCode(env, 1);\r
+ new_eip = env->EIP;\r
+\r
+ operand = Emulator_x86_MoveFromGReg(env, OPCODE_REG_ECX, True);\r
+ Emulator_x86_MoveToGReg(env, OPCODE_REG_ECX, operand - 1, True);\r
+\r
+ if(relative_addr < 0){\r
+ sign = True;\r
+ relative_addr = -relative_addr;\r
+ }\r
+ if(sign){\r
+ new_eip -= (uint)relative_addr;\r
+ } else{\r
+ new_eip += (uint)relative_addr;\r
+ }\r
+\r
+ if(!env->operation_32bit){\r
+ new_eip &= 0x0000ffff;\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "LOOP 0x%X", new_eip);\r
+\r
+ if(0 == operand - 1){\r
+ Emulator_x86_Put_EmulationInformation(env, "(NotTaken)");\r
+ } else{\r
+ Emulator_x86_Put_EmulationInformation(env, "(Taken)");\r
+ env->EIP = new_eip;\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_POP_Ev(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+ addr = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg only*/\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.RM, Emulator_x86_Pop_Data_From_Stack(env, False), True);\r
+ Emulator_x86_Put_EmulationInformation(env, "POP %s", Emulator_x86_RegNames[modrm.bit.RM]);\r
+ } else{ /*From MemoryAddress*/\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ *((ushort *)addr) = Emulator_x86_Pop_Data_From_Stack(env, False);\r
+ Emulator_x86_Put_EmulationInformation(env, "POP [0x%X]", addr);\r
+ }\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return; \r
+}\r
+\r
+void Emulator_x86_Operation_POP_RegOnly(Emulator_x86_Environment *env)\r
+{\r
+ if((env->now_opcode - 0x58) > 7){\r
+ Emulator_x86_Put_EmulationInformation(env, "\nEmulator-x86:Internal Error(Invalid GReg From OpCode).");\r
+ }\r
+ if(!env->operation_32bit){ /*16-bit*/\r
+ Emulator_x86_Put_EmulationInformation(env, "POP %s", Emulator_x86_RegNames[env->now_opcode - 0x58]);\r
+ Emulator_x86_MoveToGReg(env, env->now_opcode - 0x58, Emulator_x86_Pop_Data_From_Stack(env, False), True);\r
+ } else{ /*32-bit*/\r
+ Emulator_x86_Put_EmulationInformation(env, "POP E%s", Emulator_x86_RegNames[env->now_opcode - 0x58]);\r
+ Emulator_x86_MoveToGReg(env, env->now_opcode - 0x58, Emulator_x86_Pop_Data_From_Stack(env, True), True);\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_Jcc_JNE_rel8(Emulator_x86_Environment *env)\r
+{\r
+ char relative_addr;\r
+ uchar sign;\r
+ uint new_eip;\r
+\r
+ sign = False;\r
+ relative_addr = Emulator_x86_FetchCode(env, 1);\r
+ new_eip = env->EIP;\r
+\r
+ if(relative_addr < 0){\r
+ sign = True;\r
+ relative_addr = -relative_addr;\r
+ }\r
+ if(sign){\r
+ new_eip -= (uint)relative_addr;\r
+ } else{\r
+ new_eip += (uint)relative_addr;\r
+ }\r
+\r
+ if(!env->operation_32bit){\r
+ new_eip &= 0x0000ffff;\r
+ }\r
+\r
+ Emulator_x86_Put_EmulationInformation(env, "JNE 0x%X ", new_eip);\r
+\r
+ if(!env->EFLAGS.bit.ZF){\r
+ Emulator_x86_Put_EmulationInformation(env, "Taken.");\r
+ env->EIP = new_eip;\r
+ } else{\r
+ Emulator_x86_Put_EmulationInformation(env, "NotTaken.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_STI(Emulator_x86_Environment *env)\r
+{\r
+ env->EFLAGS.bit.IF = True;\r
+ Emulator_x86_Put_EmulationInformation(env, "STI");\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_SBB_Gv_Ev(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+ uint op0, op1;\r
+ CPU_EFlags eflags;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+ addr = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ op0 = Emulator_x86_MoveFromGReg(env, modrm.bit.Reg, True);\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg*/\r
+ op1 = Emulator_x86_MoveFromGReg(env, modrm.bit.RM, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "SBB %s, %s(CF:%d)", Emulator_x86_RegNames[modrm.bit.Reg], Emulator_x86_RegNames[modrm.bit.RM], env->EFLAGS.bit.CF);\r
+ } else{ /*MemoryAddress*/\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ op1 = *((ushort *)addr);\r
+ Emulator_x86_Put_EmulationInformation(env, "SBB %s, [0x%X](CF:%d)", Emulator_x86_RegNames[modrm.bit.Reg], addr, env->EFLAGS.bit.CF);\r
+ }\r
+ eflags.eflags = asm_Emulator_x86_Get_EFlags_Subtract_with_Borrow(&op0, op1, env->EFLAGS.bit.CF);\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.RM, op0, True);\r
+ env->EFLAGS.bit.CF = eflags.bit.CF;\r
+ env->EFLAGS.bit.PF = eflags.bit.PF;\r
+ env->EFLAGS.bit.AF = eflags.bit.AF;\r
+ env->EFLAGS.bit.ZF = eflags.bit.ZF;\r
+ env->EFLAGS.bit.SF = eflags.bit.SF;\r
+ env->EFLAGS.bit.OF = eflags.bit.OF;\r
+ Emulator_x86_Put_EmulationInformation(env, " (CF:%d PF:%d AF:%d ZF:%d SF:%d OF:%d)", env->EFLAGS.bit.CF, env->EFLAGS.bit.PF, env->EFLAGS.bit.AF, env->EFLAGS.bit.ZF, env->EFLAGS.bit.SF, env->EFLAGS.bit.OF);\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_MOV_Ev_Gv(Emulator_x86_Environment *env)\r
+{\r
+ Emulator_x86_OperationCode_ModRM modrm;\r
+ uint addr;\r
+ uint op1;\r
+\r
+ modrm.modrm = Emulator_x86_FetchCode(env, 1);\r
+ addr = 0;\r
+\r
+ if(!env->operation_32bit){ /*16-bit Addressing*/\r
+ op1 = Emulator_x86_MoveFromGReg(env, modrm.bit.Reg, True);\r
+ if(modrm.bit.Mod == OPCODE_MOD_REGISTER){ /*Reg*/\r
+ Emulator_x86_MoveToGReg(env, modrm.bit.RM, op1, True);\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV %s, %s", Emulator_x86_RegNames[modrm.bit.RM], Emulator_x86_RegNames[modrm.bit.Reg]);\r
+ } else{ /*MemoryAddress*/\r
+ addr = Emulator_x86_Get_EffectivePhysicalAddress_FromModRM(env, modrm.modrm);\r
+ *((ushort *)addr) = op1;\r
+ Emulator_x86_Put_EmulationInformation(env, "MOV [0x%X], %s(0x%X)", addr, Emulator_x86_RegNames[modrm.bit.Reg], op1);\r
+ }\r
+ } else{ /*32-bit Addressing*/\r
+ Emulator_x86_Put_EmulationInformation(env, "32-bit addressing is not implemented.");\r
+ }\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_PUSH_Ib(Emulator_x86_Environment *env)\r
+{\r
+ //16bit/32bit?\r
+ uint imm8;\r
+\r
+ imm8 = Emulator_x86_FetchCode(env, 1);\r
+ Emulator_x86_Push_Data_To_Stack(env, imm8, env->operation_32bit);\r
+ Emulator_x86_Put_EmulationInformation(env, "PUSH 0x%X", imm8);\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r
+\r
+void Emulator_x86_Operation_CLD(Emulator_x86_Environment *env)\r
+{\r
+ env->EFLAGS.bit.DF = False;\r
+ Emulator_x86_Put_EmulationInformation(env, "CLD");\r
+\r
+ env->operation_end = True;\r
+\r
+ return;\r
+}\r