use of suite.assembler.Amd64.OpRegControl in project suite by stupidsing.
the class Amd64Assemble method assemble.
public Bytes assemble(long offset, Instruction instruction) {
Encode encode;
switch(instruction.insn) {
case AAA:
encode = assemble(instruction, 0x37);
break;
case ADC:
encode = assembleRmRegImm(instruction, 0x10, 0x80, 2);
break;
case ADD:
encode = assembleRmRegImm(instruction, 0x00, 0x80, 0);
break;
case ADDPS:
encode = assembleRegRm(instruction.op0, instruction.op1, 0x58).pre(0x0F);
break;
case AND:
encode = assembleRmRegImm(instruction, 0x20, 0x80, 4);
break;
case AOP:
encode = assemble(instruction, 0x67);
break;
case CALL:
if (instruction.op0 instanceof OpImm && instruction.op0.size == 4)
encode = assembleJumpImm((OpImm) instruction.op0, offset, -1, bs(0xE8));
else if (isRm.test(instruction.op0))
encode = assemble(instruction.op0, 0xFF, 2);
else
encode = invalid;
break;
case CLD:
encode = assemble(instruction, 0xFC);
break;
case CLI:
encode = assemble(instruction, 0xFA);
break;
case CMP:
encode = assembleRmRegImm(instruction, 0x38, 0x80, 7);
break;
case CMPXCHG:
encode = assembleRegRm(instruction.op1, instruction.op0, 0xB0);
break;
case CPUID:
encode = new InsnCode(4, bs(0x0F, 0xA2));
break;
case DEC:
encode = assembleRm(instruction, 0x48, 0xFE, 1);
break;
case DIV:
encode = assembleByteFlag(instruction.op0, 0xF6, 6);
break;
case HLT:
encode = assemble(instruction, 0xF4);
break;
case IDIV:
encode = assembleByteFlag(instruction.op0, 0xF6, 7);
break;
case IMM:
if (instruction.op0 instanceof OpImm) {
InsnCode insnCode_ = new InsnCode(0, (OpImm) instruction.op0);
insnCode_.bs = new byte[] {};
encode = insnCode_;
} else
encode = invalid;
break;
case IMUL:
if (instruction.op1 instanceof OpNone)
encode = assembleByteFlag(instruction.op0, 0xF6, 5);
else if (instruction.op0.size == instruction.op1.size)
if (instruction.op2 instanceof OpNone)
encode = assembleRegRm(instruction.op0, instruction.op1, 0xAF).pre(0x0F);
else if (instruction.op2 instanceof OpImm) {
OpImm imm = (OpImm) instruction.op2;
if (imm.size <= 1)
encode = assembleRegRm(instruction.op0, instruction.op1, 0x6B).imm(imm);
else if (imm.size == instruction.op0.size)
encode = assembleRegRm(instruction.op0, instruction.op1, 0x69).imm(imm);
else
encode = invalid;
} else
encode = invalid;
else
encode = invalid;
break;
case IN:
encode = assembleInOut(instruction.op1, instruction.op0, 0xE4);
break;
case INC:
encode = assembleRm(instruction, 0x40, 0xFE, 0);
break;
case INT:
if (instruction.op0 instanceof OpImm) {
long iv = ((OpImm) instruction.op0).imm;
if (iv != 3)
encode = assemble(instruction, 0xCD).imm(iv, 1);
else
encode = assemble(instruction, 0xCC);
} else
encode = invalid;
break;
case INTO:
encode = assemble(instruction, 0xCE);
break;
case INVLPG:
encode = assemble(instruction.op0, 0x01, 7).pre(0x0F);
break;
case IRET:
encode = assemble(instruction, 0xCF);
break;
case JA:
encode = assembleJump(instruction, offset, 0x77, bs(0x0F, 0x87));
break;
case JAE:
encode = assembleJump(instruction, offset, 0x73, bs(0x0F, 0x83));
break;
case JB:
encode = assembleJump(instruction, offset, 0x72, bs(0x0F, 0x82));
break;
case JBE:
encode = assembleJump(instruction, offset, 0x76, bs(0x0F, 0x86));
break;
case JE:
encode = assembleJump(instruction, offset, 0x74, bs(0x0F, 0x84));
break;
case JG:
encode = assembleJump(instruction, offset, 0x7F, bs(0x0F, 0x8F));
break;
case JGE:
encode = assembleJump(instruction, offset, 0x7D, bs(0x0F, 0x8D));
break;
case JL:
encode = assembleJump(instruction, offset, 0x7C, bs(0x0F, 0x8C));
break;
case JLE:
encode = assembleJump(instruction, offset, 0x7E, bs(0x0F, 0x8E));
break;
case JMP:
if (isRm.test(instruction.op0) && instruction.op0.size == 4)
encode = assemble(instruction.op0, 0xFF, 4);
else
encode = assembleJump(instruction, offset, 0xEB, bs(0xE9));
break;
case JNE:
encode = assembleJump(instruction, offset, 0x75, bs(0x0F, 0x85));
break;
case JNO:
encode = assembleJump(instruction, offset, 0x71, bs(0x0F, 0x81));
break;
case JNP:
encode = assembleJump(instruction, offset, 0x7B, bs(0x0F, 0x8B));
break;
case JNS:
encode = assembleJump(instruction, offset, 0x79, bs(0x0F, 0x89));
break;
case JNZ:
encode = assembleJump(instruction, offset, 0x75, bs(0x0F, 0x85));
break;
case JO:
encode = assembleJump(instruction, offset, 0x70, bs(0x0F, 0x80));
break;
case JP:
encode = assembleJump(instruction, offset, 0x7A, bs(0x0F, 0x8A));
break;
case JS:
encode = assembleJump(instruction, offset, 0x78, bs(0x0F, 0x88));
break;
case JZ:
encode = assembleJump(instruction, offset, 0x74, bs(0x0F, 0x84));
break;
case LABEL:
((OpImm) instruction.op0).imm = offset;
encode = new InsnCode(4, new byte[0]);
break;
case LEA:
encode = assembleRegRm(instruction.op0, instruction.op1, 0x8D);
break;
case LOCK:
encode = assemble(instruction, 0xF0);
break;
case LOOP:
encode = assembleJump(instruction, offset, 0xE2, null);
break;
case LOOPE:
encode = assembleJump(instruction, offset, 0xE1, null);
break;
case LOOPNE:
encode = assembleJump(instruction, offset, 0xE0, null);
break;
case LOOPNZ:
encode = assembleJump(instruction, offset, 0xE0, null);
break;
case LOOPZ:
encode = assembleJump(instruction, offset, 0xE1, null);
break;
case LGDT:
encode = assemble(instruction.op0, 0x01, 2).pre(0x0F);
break;
case LIDT:
encode = assemble(instruction.op0, 0x01, 3).pre(0x0F);
break;
case LTR:
encode = assemble(instruction.op0, 0x00, 3).pre(0x0F);
break;
case MOV:
if (instruction.op0.size == instruction.op1.size)
if (instruction.op1 instanceof OpImm) {
OpImm op1 = (OpImm) instruction.op1;
if (instruction.op0 instanceof OpReg) {
OpReg op0 = (OpReg) instruction.op0;
encode = new InsnCode(op1.size, op1).setByte(0xB0 + (op0.size <= 1 ? 0 : 8) + op0.reg);
} else if (isRm.test(instruction.op0))
encode = assembleByteFlag(instruction.op0, 0xC6, 0).imm(op1);
else
encode = invalid;
} else if (instruction.op0 instanceof OpRegSegment) {
OpRegSegment regSegment = (OpRegSegment) instruction.op0;
encode = assemble(instruction.op1, 0x8E, regSegment.sreg);
} else if (instruction.op1 instanceof OpRegSegment) {
OpRegSegment regSegment = (OpRegSegment) instruction.op1;
encode = assemble(instruction.op0, 0x8C, regSegment.sreg);
} else if (//
instruction.op0.size == 4 && //
instruction.op0 instanceof OpReg && instruction.op1 instanceof OpRegControl) {
OpReg reg = (OpReg) instruction.op0;
OpRegControl regControl = (OpRegControl) instruction.op1;
encode = new InsnCode(4, new byte[] { (byte) 0x0F, (byte) 0x20, b(reg.reg, regControl.creg, 3) });
} else if (//
instruction.op0.size == 4 && //
instruction.op0 instanceof OpRegControl && instruction.op1 instanceof OpReg) {
OpRegControl regControl = (OpRegControl) instruction.op0;
OpReg reg = (OpReg) instruction.op1;
encode = new InsnCode(4, new byte[] { (byte) 0x0F, (byte) 0x22, b(reg.reg, regControl.creg, 3) });
} else if ((encode = assembleRmReg(instruction, 0x88)).isValid())
;
else
encode = invalid;
else
encode = invalid;
break;
case MOVAPS:
encode = assembleRmReg(instruction, 0x29, 0x28, isXmm).size(4).pre(0x0F);
break;
case MOVD:
encode = assembleRmReg(instruction, 0x7E, 0x6E, isXmm).size(4).pre(bs(0x66, 0x0F));
break;
case MOVQ:
encode = assembleRmReg(instruction, 0x7E, 0x6E, isXmm).size(8).pre(bs(0x66, 0x0F));
break;
case MOVSB:
encode = new InsnCode(1, bs(0xA4));
break;
case MOVSD:
encode = new InsnCode(4, bs(0xA5));
break;
case MOVSW:
encode = new InsnCode(2, bs(0xA5));
break;
case MOVSX:
encode = assembleRegRmExtended(instruction, 0xBE).pre(0x0F);
break;
case MOVZX:
encode = assembleRegRmExtended(instruction, 0xB6).pre(0x0F);
break;
case MUL:
encode = assembleByteFlag(instruction.op0, 0xF6, 4);
break;
case MULPS:
encode = assembleRegRm(instruction.op0, instruction.op1, 0x59).pre(0x0F);
break;
case NEG:
encode = assembleByteFlag(instruction.op0, 0xF6, 3);
break;
case NOP:
encode = assemble(instruction, 0x90);
break;
case NOT:
encode = assembleByteFlag(instruction.op0, 0xF6, 2);
break;
case OR:
encode = assembleRmRegImm(instruction, 0x08, 0x80, 1);
break;
case OUT:
encode = assembleInOut(instruction.op0, instruction.op1, 0xE6);
break;
case POP:
if (1 < instruction.op0.size)
if (isRm.test(instruction.op0))
encode = assembleRm(instruction, 0x58, 0x8E, 0);
else if (instruction.op0 instanceof OpRegSegment) {
OpRegSegment sreg = (OpRegSegment) instruction.op0;
switch(sreg.sreg) {
case // POP ES
0:
encode = assemble(instruction, 0x07);
break;
// case 1: // POP CS, no such thing
case // POP SS
2:
encode = assemble(instruction, 0x17);
break;
case // POP DS
3:
encode = assemble(instruction, 0x1F);
break;
case // POP FS
4:
encode = new InsnCode(sreg.size, bs(0x0F, 0xA1));
break;
case // POP GS
5:
encode = new InsnCode(sreg.size, bs(0x0F, 0xA9));
break;
default:
encode = invalid;
}
} else
encode = invalid;
else
encode = invalid;
break;
case POPA:
encode = assemble(instruction, 0x61);
break;
case POPF:
encode = assemble(instruction, 0x9D);
break;
case PUSH:
if (instruction.op0 instanceof OpImm) {
int size = instruction.op0.size;
encode = new InsnCode(size, (OpImm) instruction.op0).setByte(0x68 + (1 < size ? 0 : 2));
} else if (1 < instruction.op0.size)
if (isRm.test(instruction.op0))
encode = assembleRm(instruction, 0x50, 0xFE, 6);
else if (instruction.op0 instanceof OpRegSegment) {
OpRegSegment sreg = (OpRegSegment) instruction.op0;
switch(sreg.sreg) {
case // PUSH ES
0:
encode = assemble(instruction, 0x06);
break;
case // PUSH CS
1:
encode = assemble(instruction, 0x0E);
break;
case // PUSH SS
2:
encode = assemble(instruction, 0x16);
break;
case // PUSH DS
3:
encode = assemble(instruction, 0x1E);
break;
case // PUSH FS
4:
encode = new InsnCode(sreg.size, bs(0x0F, 0xA0));
break;
case // PUSH GS
5:
encode = new InsnCode(sreg.size, bs(0x0F, 0xA8));
break;
default:
encode = invalid;
}
} else
encode = invalid;
else
encode = invalid;
break;
case PUSHA:
encode = assemble(instruction, 0x60);
break;
case PUSHF:
encode = assemble(instruction, 0x9C);
break;
case RDMSR:
encode = new InsnCode(4, bs(0x0F, 0x32));
break;
case REP:
encode = assemble(instruction, 0xF3);
break;
case REPE:
encode = assemble(instruction, 0xF3);
break;
case REPNE:
encode = assemble(instruction, 0xF2);
break;
case RET:
if (instruction.op0 instanceof OpNone)
encode = assemble(instruction, 0xC3);
else if (instruction.op0 instanceof OpImm && instruction.op0.size == 2)
encode = new InsnCode(instruction.op0.size, (OpImm) instruction.op0).setByte(0xC2);
else
encode = invalid;
break;
case SAL:
encode = assembleShift(instruction, 0xC0, 4);
break;
case SAR:
encode = assembleShift(instruction, 0xC0, 7);
break;
case SBB:
encode = assembleRmRegImm(instruction, 0x18, 0x80, 3);
break;
case SETA:
encode = assemble(instruction.op0, 0x97, 0).pre(0x0F);
break;
case SETAE:
encode = assemble(instruction.op0, 0x93, 0).pre(0x0F);
break;
case SETB:
encode = assemble(instruction.op0, 0x92, 0).pre(0x0F);
break;
case SETBE:
encode = assemble(instruction.op0, 0x96, 0).pre(0x0F);
break;
case SETE:
encode = assemble(instruction.op0, 0x94, 0).pre(0x0F);
break;
case SETG:
encode = assemble(instruction.op0, 0x9F, 0).pre(0x0F);
break;
case SETGE:
encode = assemble(instruction.op0, 0x9D, 0).pre(0x0F);
break;
case SETL:
encode = assemble(instruction.op0, 0x9C, 0).pre(0x0F);
break;
case SETLE:
encode = assemble(instruction.op0, 0x9E, 0).pre(0x0F);
break;
case SETNE:
encode = assemble(instruction.op0, 0x95, 0).pre(0x0F);
break;
case SHL:
encode = assembleShift(instruction, 0xC0, 4);
break;
case SHR:
encode = assembleShift(instruction, 0xC0, 5);
break;
case STI:
encode = assemble(instruction, 0xFB);
break;
case STOSB:
encode = new InsnCode(1, bs(0xAA));
break;
case STOSD:
encode = new InsnCode(4, bs(0xAB));
break;
case STOSW:
encode = new InsnCode(2, bs(0xAB));
break;
case SUB:
encode = assembleRmRegImm(instruction, 0x28, 0x80, 5);
break;
case SUBPS:
encode = assembleRegRm(instruction.op0, instruction.op1, 0x5C).pre(0x0F);
break;
case SYSENTER:
encode = new InsnCode(4, bs(0x0F, 0x34));
break;
case SYSEXIT:
encode = new InsnCode(4, bs(0x0F, 0x35));
break;
case TEST:
if (instruction.op0.size == instruction.op1.size)
if (instruction.op1 instanceof OpImm)
encode = assembleRmImm(instruction.op0, (OpImm) instruction.op1, 0xA8, 0xF6, 0);
else
encode = assembleByteFlag(instruction.op0, 0x84, instruction.op1);
else
encode = invalid;
break;
case VADDPS:
encode = assembleRegRm(instruction.op0, instruction.op2, 0x58).vex(Vexp.VP__, instruction.op1, Vexm.VM0F__);
break;
case VMOVAPS:
encode = assembleRmReg(instruction, 0x29, 0x28, isXmmYmm).vex(Vexp.VP__, 0, Vexm.VM0F__);
break;
case VMOVD:
encode = assembleRmReg(instruction, 0x7E, 0x6E, isXmm).size(4).vex(Vexp.VP66, 0, Vexm.VM0F__);
break;
case VMOVQ:
encode = assembleRmReg(instruction, 0x7E, 0x6E, isXmm).size(8).vex(Vexp.VP66, 0, Vexm.VM0F__);
break;
case VMULPS:
encode = assembleRegRm(instruction.op0, instruction.op2, 0x59).vex(Vexp.VP__, instruction.op1, Vexm.VM0F__);
break;
case VSUBPS:
encode = assembleRegRm(instruction.op0, instruction.op2, 0x5C).vex(Vexp.VP__, instruction.op1, Vexm.VM0F__);
break;
case XCHG:
if (instruction.op0.size == instruction.op1.size && instruction.op1 instanceof OpReg)
if (isAcc.test(instruction.op0))
encode = assemble(instruction, 0x90 + ((OpReg) instruction.op1).reg);
else
encode = assembleByteFlag(instruction.op0, 0x86, instruction.op1);
else
encode = invalid;
break;
case WRMSR:
encode = new InsnCode(4, bs(0x0F, 0x30));
break;
case XOR:
encode = assembleRmRegImm(instruction, 0x30, 0x80, 6);
break;
default:
encode = invalid;
}
return encode.encode_();
}
Aggregations