Instruction* Neg::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; int preLen = 0; char buf[65]; std::string inst; Instruction* newNeg = 0; Prefix* pre = Prefix::GetPrefix(memLoc); if(pre) { opLoc += preLen = pre->GetLength(); } switch(*opLoc) { case NEG_MOD8: case NEG_MOD16: { unsigned int modrm = (*(opLoc + 1) & 0x38) >> 3; if(modrm == 3) { unsigned int size = (*opLoc == NEG_MOD8 ? 1 : 2); Operand* dst = ModrmOperand::GetModrmOperand (proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "NEG %s", dst->GetDisasm().c_str()); GETINST(preLen + 2 + dst->GetBytecodeLen()); newNeg = new Neg(pre, buf, inst, (int)*opLoc); newNeg->SetOperand(Operand::DST, dst); break; } } } return newNeg; }
Instruction* IDiv::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; int preLen = 0; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); if(pre) { opLoc += preLen = pre->GetLength(); } Instruction* newIDiv = 0; if((*opLoc == IDIV_MOD8 || *opLoc == IDIV_MOD16) && ((unsigned int)((*(opLoc + 1) & 0x38) >> 3) == IDIV_SUB_OPCODE)) { unsigned int size = *opLoc == IDIV_MOD8 ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "IDIV %s", dst->GetDisasm().c_str()); GETINST(preLen + 2 + dst->GetBytecodeLen()); newIDiv = new IDiv(pre, buf, inst, (int)*opLoc); newIDiv->SetOperand(Operand::DST, dst); } return newIDiv; }
Instruction* Mov::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newMov = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case MOV_MOD8_REG8: case MOV_MOD16_REG16: { unsigned int size = (*opLoc == MOV_MOD8_REG8 ? 1 : 2); Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::REG, size); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_REG8_MOD8: case MOV_REG16_MOD16: { unsigned int size = (*opLoc == MOV_REG8_MOD8 ? 1 : 2); Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::REG, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_MOD16_SEGREG: { Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::SEGREG, 2); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, 2); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_SEGREG_MOD16: { Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, 2); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::SEGREG, 2); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_AL_MOFF8: case MOV_AX_MOFF16: { unsigned int size = (*opLoc == MOV_AL_MOFF8 ? 1 : 2); Operand* dst = new RegisterOperand(*opLoc == MOV_AL_MOFF8 ? REG_AL : REG_AX, proc); unsigned int val = (int)*(opLoc + 1); val += ((int)*(opLoc + 2)) << 8; Memory::MemoryOffset tmpMem = opLoc.getNewOffset(val); Operand* src = AddressOperand::GetAddressOperand(proc, tmpMem, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 3); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_MOFF8_AL: case MOV_MOFF16_AX: { unsigned int size = (*opLoc == MOV_MOFF8_AL ? 1 : 2); Operand* src = new RegisterOperand(*opLoc == MOV_MOFF8_AL ? REG_AL : REG_AX, proc); unsigned int val = (int)*(opLoc + 1); val += ((int)*(opLoc + 2)) << 8; Memory::MemoryOffset tmpMem = opLoc.getNewOffset(val); Operand* dst = AddressOperand::GetAddressOperand(proc, tmpMem, size); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 3); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_AL_IMM8: case MOV_CL_IMM8: case MOV_DL_IMM8: case MOV_BL_IMM8: case MOV_AH_IMM8: case MOV_CH_IMM8: case MOV_DH_IMM8: case MOV_BH_IMM8: case MOV_AX_IMM16: case MOV_CX_IMM16: case MOV_DX_IMM16: case MOV_BX_IMM16: case MOV_SP_IMM16: case MOV_BP_IMM16: case MOV_SI_IMM16: case MOV_DI_IMM16: { unsigned int size = 0; Operand* dst = 0; if(*opLoc <= MOV_BL_IMM8) { //The 8 bit omes size = 1; dst = new RegisterOperand((eRegisters)(*opLoc - MOV_AL_IMM8 + REG_AL), proc); } else if(*opLoc <= MOV_BH_IMM8) { size = 1; dst = new RegisterOperand((eRegisters)(*opLoc - MOV_AH_IMM8 + REG_AH), proc); } else { size = 2; dst = new RegisterOperand((eRegisters)(*opLoc - MOV_AX_IMM16), proc); } unsigned int val = (int)*(opLoc + 1 + dst->GetBytecodeLen()); if(size == 2) { val += (int)*(opLoc + 2 + dst->GetBytecodeLen()) << 8; } Operand* src = new ImmediateOperand(val, size, (opLoc + 1 + dst->GetBytecodeLen()).getOffset()); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 1 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); break; } case MOV_MOD8_IMM8: case MOV_MOD16_IMM16: { unsigned int size = (*opLoc == MOV_MOD8_IMM8 ? 1 : 2); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); unsigned int val = (int)*(opLoc + 2 + dst->GetBytecodeLen()); if(size == 2) { val += (int)*(opLoc + 3 + dst->GetBytecodeLen()) << 8; } Operand* src = new ImmediateOperand(val, size, (opLoc + 2 + dst->GetBytecodeLen()).getOffset()); snprintf(buf, 65, "MOV %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newMov = new Mov(pre, buf, inst, (unsigned char)*opLoc); newMov->SetOperand(Operand::SRC, src); newMov->SetOperand(Operand::DST, dst); } break; } return newMov; }
Instruction* Push::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newPush = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case PUSH_MOD16: { if((unsigned int)((*(opLoc + 1) & 0x38) >> 3) != PUSH_SUB_OPCODE) return newPush; Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, 2); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen()); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSH_REG_AX: case PUSH_REG_CX: case PUSH_REG_DX: case PUSH_REG_BX: case PUSH_REG_SP: case PUSH_REG_BP: case PUSH_REG_SI: case PUSH_REG_DI: { Operand* dst = new RegisterOperand((eRegisters)(*opLoc - PUSH_REG_AX + REG_AX), proc); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 1 + dst->GetBytecodeLen()); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSH_IMM8: case PUSH_IMM16: { unsigned int val = *(opLoc + 1); unsigned int size = *opLoc == PUSH_IMM8 ? 1 : 2; if(size == 2) { val += *(opLoc + 2) << 0x8; } else { val += (val >= 0x80) ? 0xFF00 : 0x0000; } Operand* dst = new ImmediateOperand(val, 2, (opLoc + 1).getOffset()); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 1 + size); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSH_CS: case PUSH_SS: case PUSH_DS: case PUSH_ES: { eRegisters reg = REG_CS; if(*opLoc == PUSH_CS) reg = REG_CS; else if(*opLoc == PUSH_DS) reg = REG_DS; else if(*opLoc == PUSH_SS) reg = REG_SS; else if(*opLoc == PUSH_ES) reg = REG_ES; Operand* dst = new RegisterOperand(reg, proc); snprintf(buf, 65, "PUSH %s", dst->GetDisasm().c_str()); GETINST(preSize + 1 + dst->GetBytecodeLen()); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSHF: { Operand* dst = new RegisterOperand(REG_FLAGS, proc); snprintf(buf, 65, "PUSHF"); GETINST(preSize + 1); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); newPush->SetOperand(Operand::DST, dst); break; } case PUSHA: { snprintf(buf, 65, "PUSHA"); GETINST(preSize + 1); newPush = new Push(pre, buf, inst, (unsigned char)*opLoc); } } return newPush; }
Instruction* Or::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; int prefixLen = 0; char buf[65]; int tInt1 = 0; unsigned char modrm = 0; Prefix* prefix = 0; Instruction* newOr = 0; //Build a prefix if possible prefix = Prefix::GetPrefix(memLoc); //Start looking after the prefix if(prefix) { opLoc += prefix->GetLength(); prefixLen += prefix->GetLength(); } std::string inst; //Switch for the different valid opcodes switch(*opLoc) { case OR_AL_IMM8: sprintf(buf, "OR AL, 0x%02X", (int)*(opLoc + 1)); GETINST(prefixLen + 2); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, new ImmediateOperand(*(opLoc + 1), 1,(opLoc + 1).getOffset())); newOr->SetOperand(Operand::DST, new RegisterOperand(REG_AL, proc)); break; case OR_AX_IMM16: tInt1 = (unsigned char)*(opLoc + 1); tInt1 |= (((unsigned char)*(opLoc + 2)) << 8); sprintf(buf, "OR AX, 0x%04X", tInt1); GETINST(prefixLen + 3); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, new ImmediateOperand(tInt1, 2, (opLoc + 1).getOffset())); newOr->SetOperand(Operand::DST, new RegisterOperand(REG_AX, proc)); break; case GRP1_OR_MOD8_IMM8: case GRP1_OR_MOD16_IMM16: case GRP1_OR_MOD16_IMM8: modrm = (*(opLoc + 1) & 0x38) >> 3; if(modrm == 1) { unsigned int immSize = (*opLoc == GRP1_OR_MOD8_IMM8) ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::MOD, immSize); tInt1 = (int)*(opLoc+2+dst->GetBytecodeLen()); if(immSize == 2) { if(*opLoc == GRP1_OR_MOD16_IMM16) { tInt1 += ((int)*(opLoc+3+dst->GetBytecodeLen())) << 8; }else { tInt1 = (tInt1 >= 0x80) ? 0xFF00 + tInt1 : tInt1; } } if(immSize == 1) sprintf(buf, "OR %s, 0x%02X", "", tInt1); else sprintf(buf, "OR %s, 0x%04X", "", tInt1); GETINST(prefixLen + 2 + immSize + dst->GetBytecodeLen() - (*opLoc == GRP1_OR_MOD16_IMM8 ? 1 : 0)); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, new ImmediateOperand(tInt1, immSize, (opLoc + 2 + dst->GetBytecodeLen()).getOffset())); newOr->SetOperand(Operand::DST, dst); } break; case GRP2_OR_MOD8_REG8: case GRP2_OR_MOD16_REG16: { unsigned int size = (*opLoc == GRP2_OR_MOD8_REG8) ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::MOD, size); Operand* src = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::REG, size); sprintf(buf, "OR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(prefixLen + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, src); newOr->SetOperand(Operand::DST, dst); break; } case GRP3_OR_REG8_MOD8: case GRP3_OR_REG16_MOD16: { unsigned int size = *opLoc == GRP3_OR_REG8_MOD8 ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::REG, size); Operand* src = ModrmOperand::GetModrmOperand( proc, opLoc, ModrmOperand::MOD, size); sprintf(buf, "OR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(prefixLen + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newOr = new Or(prefix, buf, inst, (unsigned char)*opLoc); newOr->SetOperand(Operand::SRC, src); newOr->SetOperand(Operand::DST, dst); break; } default: break; } return newOr; }
Instruction* Test::CreateInstruction(Memory::MemoryOffset& memLoc, Processor* proc) { Memory::MemoryOffset opLoc = memLoc; char buf[65]; std::string inst; Prefix* pre = Prefix::GetPrefix(memLoc); unsigned int preSize = 0; Instruction* newTest = 0; if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case TEST_AL_IMM8: case TEST_AX_IMM16: { unsigned int size = (*opLoc == TEST_AL_IMM8 ? 1 : 2); unsigned int val = (int)*(opLoc + 1); if(size == 2) { val += (int)*(opLoc + 2) << 8; } GETINST(preSize + 1 + size); Operand* src = new ImmediateOperand(val, size, (opLoc + 1).getOffset()); Operand* dst = new RegisterOperand(*opLoc == TEST_AL_IMM8 ? REG_AL : REG_AX, proc); snprintf(buf, 65, "TEST %s, %s", size == 1 ? "AL" : "AH", src->GetDisasm().c_str()); newTest = new Test(pre, buf, inst, (unsigned char)*opLoc); newTest->SetOperand(Operand::SRC, src); newTest->SetOperand(Operand::DST, dst); break; } case TEST_MOD8_IMM8: case TEST_MOD16_IMM16: { if((unsigned int)((*(opLoc + 1) & 0x38) >> 3) != TEST_SUB_OPCODE) return 0; unsigned int size = (*opLoc == TEST_MOD8_IMM8 ? 1 : 2); unsigned int val = (int)*(opLoc + 1); if(size == 2) { val += (int)*(opLoc + 2) << 8; } Operand* src = new ImmediateOperand(val, size, (opLoc + 1).getOffset()); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "TEST %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + size + dst->GetBytecodeLen()); newTest = new Test(pre, buf, inst, (unsigned char)*opLoc); newTest->SetOperand(Operand::SRC, src); newTest->SetOperand(Operand::DST, dst); break; } case TEST_MOD8_REG8: case TEST_MOD16_REG16: { unsigned int size = (*opLoc == TEST_MOD8_REG8 ? 1 : 2); Operand* src = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::REG, size); Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); snprintf(buf, 65, "TEST %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); GETINST(preSize + 2 + dst->GetBytecodeLen() + src->GetBytecodeLen()); newTest = new Test(pre, buf, inst, (unsigned char)*opLoc); newTest->SetOperand(Operand::SRC, src); newTest->SetOperand(Operand::DST, dst); break; } } return newTest; }
Instruction* Xor::CreateInstruction(unsigned char* memLoc, Processor* proc) { unsigned char* opLoc = memLoc; unsigned int preSize = 0; char buf[65]; std::string inst; Instruction* newXor = 0; Prefix* pre = Prefix::GetPrefix(memLoc); if(pre) { opLoc += preSize = pre->GetLength(); } switch(*opLoc) { case XOR_AL_IMM8: case XOR_AX_IMM16: { unsigned int size = (*opLoc) == XOR_AL_IMM8 ? 1 : 2; unsigned int val = (int)*(opLoc + 1); if(size == 2) { val += (int)*(opLoc + 2) << 8; } GETINST(preSize + 1 + size); Operand* dst = new RegisterOperand(size == 1 ? REG_AL : REG_AX, proc); Operand* src = new ImmediateOperand(val, size); snprintf(buf, 65, "XOR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); newXor = new Xor(pre, buf, inst, (int)*opLoc); newXor->SetOperand(Operand::SRC, src); newXor->SetOperand(Operand::DST, dst); break; } case XOR_MOD8_IMM8: case XOR_MOD16_IMM16: case XOR_MOD16_IMM8: { if(((*(opLoc + 1) & 0x38) >> 3) != XOR_REG_CONST) break; unsigned int size = *opLoc == XOR_MOD8_IMM8 ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand(proc, opLoc, ModrmOperand::MOD, size); unsigned int val = (int)*(opLoc + 2 +dst->GetBytecodeLen()); if(size == 2) { if(*opLoc == XOR_MOD16_IMM16) val += (int)*(opLoc + 3 + dst->GetBytecodeLen()) << 8; else val += val >= 0x80 ? 0xFF00 : 0x0000; } Operand* src = new ImmediateOperand(val, size); GETINST(preSize + 2 + (*opLoc == XOR_MOD16_IMM8 ? 1 : size) + dst->GetBytecodeLen()); snprintf(buf, 65, "XOR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); newXor = new Xor(pre, buf, inst, (int)*opLoc); newXor->SetOperand(Operand::SRC, src); newXor->SetOperand(Operand::DST, dst); break; } case XOR_MOD8_REG8: case XOR_MOD16_REG16: case XOR_REG8_MOD8: case XOR_REG16_MOD16: { unsigned int size = (*opLoc == XOR_MOD8_REG8 || *opLoc == XOR_REG8_MOD8) ? 1 : 2; Operand* dst = ModrmOperand::GetModrmOperand( proc, opLoc, (*opLoc == XOR_MOD8_REG8 || *opLoc == XOR_MOD16_REG16) ? ModrmOperand::MOD : ModrmOperand::REG, size); Operand* src = ModrmOperand::GetModrmOperand( proc, opLoc, (*opLoc == XOR_REG8_MOD8 || *opLoc == XOR_REG16_MOD16) ? ModrmOperand::MOD : ModrmOperand::REG, size); GETINST(preSize + 2 + src->GetBytecodeLen() + dst->GetBytecodeLen()); snprintf(buf, 65, "XOR %s, %s", dst->GetDisasm().c_str(), src->GetDisasm().c_str()); newXor = new Xor(pre, buf, inst, (int)*opLoc); newXor->SetOperand(Operand::SRC, src); newXor->SetOperand(Operand::DST, dst); break; } } return newXor; }