use of suite.assembler.Amd64.OpMem in project suite by stupidsing.
the class Amd64Dump method dump.
private String dump(Operand op0) {
int pointerSize = 4;
OpReg[] regs;
String name;
if (pointerSize == 4)
regs = amd64.reg32;
else if (pointerSize == 8)
regs = amd64.reg64;
else
return Fail.t();
if (op0 instanceof OpImm) {
OpImm opImm = (OpImm) op0;
return dump(opImm.imm, opImm.size);
} else if (op0 instanceof OpMem) {
OpMem opMem = (OpMem) op0;
int baseReg = opMem.baseReg;
int indexReg = opMem.indexReg;
String s = //
"" + //
(0 <= baseReg ? " + " + dump(regs[baseReg]) : "") + //
(0 <= indexReg ? " + " + dump(regs[indexReg]) + " * " + (1 << opMem.scale) : "") + (0 < opMem.dispSize ? dumpDisp(opMem.disp, pointerSize) : "");
return "[" + s.substring(3) + "]";
} else if ((name = (amd64.registerByName.inverse().get(op0).name)) != null)
return name;
else
return op0.toString();
}
use of suite.assembler.Amd64.OpMem in project suite by stupidsing.
the class Amd64Interpret method interpret.
public int interpret(List<Instruction> instructions, Bytes code, Bytes input) {
mem.position(positionCode0);
mem.put(code.bs);
eip = positionCode0;
regs[esp] = baseStackx - 16;
IntIntMap labels = new IntIntMap();
for (int i = 0; i < instructions.size(); i++) {
int i_ = i;
Instruction instruction = instructions.get(i_);
if (instruction.insn == Insn.LABEL)
labels.update((int) ((OpImm) instruction.op0).imm, i0 -> i_ + 1);
}
while (true) {
Instruction instruction = instructions.get(eip++);
if (Boolean.FALSE)
LogUtil.info(state(instruction));
try {
Operand op0 = instruction.op0;
Operand op1 = instruction.op1;
int source0, source1;
IntSink assign;
if (op0 instanceof OpImm) {
source0 = (int) ((OpImm) op0).imm;
assign = null;
} else if (op0 instanceof OpMem) {
int index = index(address((OpMem) op0));
source0 = mem.getInt(index);
assign = i -> mem.putInt(index, i);
} else if (op0 instanceof OpReg) {
int reg = ((OpReg) op0).reg;
source0 = regs[reg];
assign = i -> {
regs[reg] = i;
};
} else {
source0 = 0;
assign = null;
}
if (op1 instanceof OpImm)
source1 = (int) ((OpImm) op1).imm;
else if (op1 instanceof OpMem)
source1 = mem.getInt(index(address((OpMem) op1)));
else if (op1 instanceof OpReg)
source1 = regs[((OpReg) op1).reg];
else
source1 = 0;
switch(instruction.insn) {
case ADD:
assign.sink(source0 + source1);
break;
case CALL:
push(eip);
eip = labels.get(source0);
break;
case CMP:
c = Integer.compare(source0, source1);
break;
case DEC:
assign.sink(source0 - 1);
break;
case INC:
assign.sink(source0 + 1);
break;
case INT:
if (source0 == -128)
if (regs[eax] == 1)
return regs[ebx];
else if (regs[eax] == 3) {
int length = min(regs[edx], input.size());
int di = index(regs[ecx]);
for (int i = 0; i < length; i++) mem.put(di++, input.get(i));
input = input.range(length);
regs[eax] = length;
} else if (regs[eax] == 4) {
int length = regs[edx];
int si = index(regs[ecx]);
byte[] bs = new byte[length];
for (int i = 0; i < length; i++) bs[i] = mem.get(si++);
output.sink(Bytes.of(bs));
} else
Fail.t();
else
Fail.t();
break;
case JE:
if (c == 0)
eip = labels.get(source0);
break;
case JMP:
eip = labels.get(source0);
break;
case JG:
if (0 < c)
eip = labels.get(source0);
break;
case JGE:
if (0 <= c)
eip = labels.get(source0);
break;
case JL:
if (c < 0)
eip = labels.get(source0);
break;
case JLE:
if (c <= 0)
eip = labels.get(source0);
break;
case JNE:
if (c != 0)
eip = labels.get(source0);
break;
case LABEL:
break;
case LEA:
assign.sink(address((OpMem) op1));
break;
case MOV:
assign.sink(source1);
break;
case POP:
assign.sink(pop());
break;
case PUSH:
push(source0);
break;
case RET:
eip = pop();
break;
case SUB:
assign.sink(source0 - source1);
break;
case XOR:
assign.sink(source0 ^ source1);
break;
default:
Fail.t();
}
} catch (Exception ex) {
LogUtil.info(state(instruction));
throw ex;
}
}
}
use of suite.assembler.Amd64.OpMem in project suite by stupidsing.
the class Amd64Assemble method modrm.
private Modrm modrm(Operand operand, int num) {
int mod, rm, s, i, b, dispSize;
long disp;
if (operand instanceof OpReg) {
// EAX
OpReg op = (OpReg) operand;
mod = 3;
rm = op.reg;
s = i = b = -1;
dispSize = 0;
disp = 0;
} else if (operand instanceof OpMem) {
OpMem op = (OpMem) operand;
int baseReg = op.baseReg;
int indexReg;
int ds0 = op.dispSize;
if ((op.indexReg & 7) != 4)
indexReg = op.indexReg;
else
indexReg = Fail.t("bad operand");
if (baseReg < 0 && indexReg < 0) {
// [0x1234]
mod = 0;
rm = 5;
s = i = b = -1;
dispSize = 4;
} else if (0 <= baseReg && indexReg < 0)
if ((baseReg & 7) != 4) {
// [EAX], [EAX + 0x1234]
int ds1 = (baseReg & 7) == 5 && ds0 == 0 ? 1 : ds0;
mod = dispMod(ds1);
rm = baseReg;
s = i = b = -1;
dispSize = ds1;
} else {
// [ESP + 0], [ESP + 0x1234]
int ds1 = baseReg == 4 && ds0 == 0 ? 1 : ds0;
mod = dispMod(ds1);
rm = 4;
s = 0;
i = 4;
b = baseReg & 7;
dispSize = ds1;
}
else if (baseReg < 0 && 0 <= indexReg) {
// [4 * EBX + 0x1234]
mod = 0;
rm = 4;
s = scale(op);
i = indexReg;
b = 5;
dispSize = 4;
} else if (0 <= baseReg && 0 <= indexReg)
if ((baseReg & 7) != 5) {
// [4 * EBX + EAX + 0x1234]
mod = dispMod(ds0);
rm = 4;
s = scale(op);
i = indexReg;
b = baseReg;
dispSize = ds0;
} else
throw new RuntimeException("bad operand");
else
throw new RuntimeException("bad operand");
disp = op.disp;
} else
throw new RuntimeException("bad operand");
Modrm modrm = new Modrm();
modrm.size = operand.size;
modrm.mod = mod;
modrm.num = num;
modrm.rm = rm;
modrm.s = s;
modrm.i = i;
modrm.b = b;
modrm.dispSize = dispSize;
modrm.disp = disp;
return modrm;
}
use of suite.assembler.Amd64.OpMem in project suite by stupidsing.
the class Amd64Parse method parseOpMem.
private Operand parseOpMem(Node[] m, int size) {
OpMem opMem = amd64.new OpMem();
opMem.size = size;
opMem.indexReg = -1;
opMem.baseReg = -1;
opMem.dispSize = 0;
for (Node component : scan(m[0], ".0 + .1")) if ((m = Suite.pattern(".0 * .1").match(component)) != null)
if (opMem.indexReg < 0) {
opMem.indexReg = amd64.regByName.get(m[0]).reg;
opMem.scale = ((Int) m[1]).number;
} else
Fail.t("bad operand");
else if (component instanceof Int)
if (opMem.dispSize == 0) {
opMem.disp = ((Int) component).number;
opMem.dispSize = 4;
} else
Fail.t("bad operand");
else if (opMem.baseReg < 0)
opMem.baseReg = amd64.regByName.get(component).reg;
else
Fail.t("bad operand");
return opMem;
}
use of suite.assembler.Amd64.OpMem in project suite by stupidsing.
the class P4DecomposeOperand method decomposeOpMem.
public OpMem decomposeOpMem(int fd, Funp n0, int disp0, int size) {
class Decompose {
private Operator operator;
private List<Funp> nodes = new ArrayList<>();
private Decompose(Operator operator) {
this.operator = operator;
}
private void decompose(Funp n_) {
FunpTree tree;
if (n_ instanceof FunpTree && (tree = (FunpTree) n_).operator == operator) {
decompose(tree.left);
decompose(tree.right);
} else
nodes.add(n_);
}
}
Fun2<Operator, Funp, List<Funp>> decompose = (operator, n_) -> {
Decompose dec = new Decompose(operator);
dec.decompose(n_);
return dec.nodes;
};
class DecomposeMult {
private long scale = 1;
private OpReg reg;
private List<Funp> mults = new ArrayList<>();
private void decompose(Funp n0) {
FunpTree2 tree;
Funp r;
for (Funp n1 : decompose.apply(TermOp.MULT__, n0)) if (n1 instanceof FunpFramePointer && isUseEbp && reg == null)
reg = amd64.ebp;
else if (n1 instanceof FunpNumber)
scale *= ((FunpNumber) n1).i.get();
else if (//
n1 instanceof FunpTree2 && //
(tree = (FunpTree2) n1).operator == TreeUtil.SHL && (r = tree.right) instanceof FunpNumber) {
decompose(tree.left);
scale <<= ((FunpNumber) r).i.get();
} else
mults.add(n1);
}
}
class DecomposePlus {
private OpReg baseReg = null, indexReg = null;
private int scale = 1, disp = disp0;
private boolean ok = is124(size);
private DecomposePlus(Funp n0) {
for (Funp n1 : decompose.apply(TermOp.PLUS__, n0)) if (n1 instanceof FunpFramePointer && !isUseEbp) {
addReg(amd64.esp, 1);
disp -= fd;
} else {
DecomposeMult dec = new DecomposeMult();
dec.decompose(n1);
if (dec.mults.isEmpty()) {
OpReg reg_ = dec.reg;
long scale_ = dec.scale;
if (reg_ != null)
addReg(reg_, scale_);
else
disp += scale_;
} else
ok = false;
}
}
private void addReg(OpReg reg_, long scale_) {
if (scale_ == 1 && baseReg == null)
baseReg = reg_;
else if (is1248(scale_) && indexReg == null) {
indexReg = reg_;
scale = (int) scale_;
} else
ok = false;
}
private OpMem op() {
return ok ? amd64.mem(baseReg, indexReg, scale, disp, size) : null;
}
}
return new DecomposePlus(n0).op();
}
Aggregations