diff --git a/.gitignore b/.gitignore index 7adf868..1222e61 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.dot *_jak.asm *.pdf +.idea/ +Jakstab.iml diff --git a/jakstab b/jakstab index ea401c8..bc6258b 100755 --- a/jakstab +++ b/jakstab @@ -1,6 +1,6 @@ #!/bin/bash JS_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -JSCLASSPATH=${JS_HOME}/lib/antlr.jar:${JS_HOME}/lib/google-collect-1.0.jar:lib/javabdd-1.0b2.jar:${JS_HOME}/bin +JSCLASSPATH=${JS_HOME}/lib/antlr.jar:${JS_HOME}/lib/google-collect-1.0.jar:lib/javabdd-1.0b2.jar:${JS_HOME}/bin:${JS_HOME}/lib/capstone.jar:${JS_HOME}/lib/jna-4.4.0.jar case `uname` in CYGWIN*) JSCLASSPATH=`cygpath -p -w -m -s "$JSCLASSPATH"` diff --git a/lib/capstone.jar b/lib/capstone.jar new file mode 100644 index 0000000..131aed3 Binary files /dev/null and b/lib/capstone.jar differ diff --git a/lib/jna-4.4.0.jar b/lib/jna-4.4.0.jar new file mode 100644 index 0000000..521bd92 Binary files /dev/null and b/lib/jna-4.4.0.jar differ diff --git a/lib/jna-platform-4.4.0.jar b/lib/jna-platform-4.4.0.jar new file mode 100644 index 0000000..ce54d8f Binary files /dev/null and b/lib/jna-platform-4.4.0.jar differ diff --git a/lib/libcapstone.so b/lib/libcapstone.so new file mode 100755 index 0000000..38d527d Binary files /dev/null and b/lib/libcapstone.so differ diff --git a/src/org/jakstab/Program.java b/src/org/jakstab/Program.java index 9816e20..9d4a98a 100644 --- a/src/org/jakstab/Program.java +++ b/src/org/jakstab/Program.java @@ -402,7 +402,8 @@ public final Instruction getInstruction(AbsoluteAddress address) { logger.error("Requested instruction outside code section: " + address); return null; } - instr = module.getDisassembler().decodeInstruction(fp); + instr = module.getDisassembler().decodeInstruction(fp, address.getValue()); + //logger.warn("TT: " + fp + " " + address); if (instr == null) { logger.error("Instruction could not be disassembled at: " + address); } diff --git a/src/org/jakstab/asm/AbsoluteAddress.java b/src/org/jakstab/asm/AbsoluteAddress.java index 24d0080..52feb11 100644 --- a/src/org/jakstab/asm/AbsoluteAddress.java +++ b/src/org/jakstab/asm/AbsoluteAddress.java @@ -94,8 +94,6 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; AbsoluteAddress other = (AbsoluteAddress) obj; - if (value != other.value) - return false; - return true; + return (value == other.value); } } diff --git a/src/org/jakstab/asm/AbstractInstruction.java b/src/org/jakstab/asm/AbstractInstruction.java index c5aad4f..a0537ec 100644 --- a/src/org/jakstab/asm/AbstractInstruction.java +++ b/src/org/jakstab/asm/AbstractInstruction.java @@ -42,6 +42,8 @@ public abstract class AbstractInstruction implements Instruction { * @param name the instruction mnemonic. */ public AbstractInstruction(String name) { + if (name.contains(" "))//TODO-Dom Actually replace with real code this hack is worse than before + name = name.split(" ")[1]; this.name = name; } @@ -52,4 +54,6 @@ public String getName() { public String toString(long currentPc, SymbolFinder symFinder) { return name; } + } + diff --git a/src/org/jakstab/asm/DataType.java b/src/org/jakstab/asm/DataType.java index b871cc2..c4dedec 100644 --- a/src/org/jakstab/asm/DataType.java +++ b/src/org/jakstab/asm/DataType.java @@ -57,7 +57,7 @@ public enum DataType { private int bits; - private DataType(int bits) { + DataType(int bits) { this.bits = bits; } diff --git a/src/org/jakstab/asm/Register.java b/src/org/jakstab/asm/Register.java index fc0182a..e5ec70b 100644 --- a/src/org/jakstab/asm/Register.java +++ b/src/org/jakstab/asm/Register.java @@ -54,13 +54,13 @@ public Register(int number) { * Returns the total number of available registers on this platform */ public abstract int getNumberOfRegisters(); - - /** +/* + *//** * Returns whether this register has a valid code number. - */ + *//* public boolean isValid() { return ((0 <= number) && (number <= getNumberOfRegisters())); - } + }*/ /** * Returns the code of this register as it appears in instructions. diff --git a/src/org/jakstab/asm/x86/X86ControlRegisters.java b/src/org/jakstab/asm/x86/X86ControlRegisters.java index 4d67f7f..a2cb73c 100644 --- a/src/org/jakstab/asm/x86/X86ControlRegisters.java +++ b/src/org/jakstab/asm/x86/X86ControlRegisters.java @@ -30,6 +30,7 @@ package org.jakstab.asm.x86; +import capstone.X86_const; import org.jakstab.util.Logger; /** @@ -52,11 +53,11 @@ public class X86ControlRegisters { private static X86ControlRegister controlRegisters[]; static { - CR0 = new X86ControlRegister(0, "%cr0"); - INVALID = new X86ControlRegister(1, "Invalid Control Register"); - CR2 = new X86ControlRegister(2, "%cr2"); - CR3 = new X86ControlRegister(3, "%cr3"); - CR4 = new X86ControlRegister(4, "%cr4"); + CR0 = new X86ControlRegister(X86_const.X86_REG_CR0, "%cr0"); + INVALID = new X86ControlRegister(X86_const.X86_REG_CR1, "Invalid Control Register");//Not sure if capstone would output CR1 or invalid must test. + CR2 = new X86ControlRegister(X86_const.X86_REG_CR2, "%cr2"); + CR3 = new X86ControlRegister(X86_const.X86_REG_CR3, "%cr3"); + CR4 = new X86ControlRegister(X86_const.X86_REG_CR4, "%cr4"); controlRegisters = (new X86ControlRegister[] { CR0, INVALID, CR2, CR3, CR4 diff --git a/src/org/jakstab/asm/x86/X86FloatRegister.java b/src/org/jakstab/asm/x86/X86FloatRegister.java index b977299..f0ebc4e 100644 --- a/src/org/jakstab/asm/x86/X86FloatRegister.java +++ b/src/org/jakstab/asm/x86/X86FloatRegister.java @@ -33,9 +33,10 @@ import org.jakstab.asm.Register; public class X86FloatRegister extends Register { - - public X86FloatRegister(int number) { + protected String name; + public X86FloatRegister(int number, String name) { super(number); + this.name = name; } public int getNumber() { @@ -43,7 +44,7 @@ public int getNumber() { } public int getNumberOfRegisters() { - return X86FloatRegisters.getNumRegisters(); + return 8;//X86FloatRegisters.getNumRegisters(); } public boolean isFloat() { @@ -58,12 +59,14 @@ public boolean isStackPointer() { return false; } - public boolean isValid() { - return number >= 0 && number < X86FloatRegisters.getNumRegisters(); - } +/* public boolean isValid() { + return true;//TODO-Dom temporary fix + //return number >= 0 && number < X86FloatRegisters.getNumRegisters(); + }*/ public String toString() { - return X86FloatRegisters.getRegisterName(number); + return name; + //return X86FloatRegisters.getRegisterName(number); } } diff --git a/src/org/jakstab/asm/x86/X86FloatRegisters.java b/src/org/jakstab/asm/x86/X86FloatRegisters.java deleted file mode 100644 index 9944f95..0000000 --- a/src/org/jakstab/asm/x86/X86FloatRegisters.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.asm.x86; - -import org.jakstab.util.Logger; - - -public class X86FloatRegisters { - - private final static Logger logger = Logger.getLogger(X86FloatRegisters.class); - - public static int getNumRegisters() { - return NUM_REGISTERS; - } - - public static X86FloatRegister getRegister(int regNum) { - if (regNum < 0 || regNum >= NUM_REGISTERS) { - logger.error("Invalid float register number!"); - return null; - } - return registers[regNum]; - } - - public static String getRegisterName(int i) { - //return "ST(" + i + ")"; - // JK: Changed to SSL style - return "%st" + i; - } - - public static final X86FloatRegister ST0; - public static final X86FloatRegister ST1; - public static final X86FloatRegister ST2; - public static final X86FloatRegister ST3; - public static final X86FloatRegister ST4; - public static final X86FloatRegister ST5; - public static final X86FloatRegister ST6; - public static final X86FloatRegister ST7; - - public static final int NUM_REGISTERS = 8; - - private static final X86FloatRegister registers[]; - - static { - ST0 = new X86FloatRegister(0); - ST1 = new X86FloatRegister(1); - ST2 = new X86FloatRegister(2); - ST3 = new X86FloatRegister(3); - ST4 = new X86FloatRegister(4); - ST5 = new X86FloatRegister(5); - ST6 = new X86FloatRegister(6); - ST7 = new X86FloatRegister(7); - registers = (new X86FloatRegister[] { - ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7 - }); - } -} diff --git a/src/org/jakstab/asm/x86/X86Instruction.java b/src/org/jakstab/asm/x86/X86Instruction.java index 196c41f..91feabe 100644 --- a/src/org/jakstab/asm/x86/X86Instruction.java +++ b/src/org/jakstab/asm/x86/X86Instruction.java @@ -195,7 +195,7 @@ public Instruction evaluate(Context ctx) { if (!changed) return this; else { - X86Instruction inst = null; + X86Instruction inst; try { inst = (X86Instruction) super.clone(); inst.operands = new Operand[inst.operands.length]; diff --git a/src/org/jakstab/asm/x86/X86InstructionFactory.java b/src/org/jakstab/asm/x86/X86InstructionFactory.java index e32be20..f79fe10 100644 --- a/src/org/jakstab/asm/x86/X86InstructionFactory.java +++ b/src/org/jakstab/asm/x86/X86InstructionFactory.java @@ -76,4 +76,6 @@ public interface X86InstructionFactory { public X86Instruction newGeneralInstruction(String name, Operand op1, int size, int prefixes); + public X86Instruction newGeneralInstruction(String name, int size, int prefixes); + } diff --git a/src/org/jakstab/asm/x86/X86InstructionFactoryImpl.java b/src/org/jakstab/asm/x86/X86InstructionFactoryImpl.java index f02eb93..8bbbefb 100644 --- a/src/org/jakstab/asm/x86/X86InstructionFactoryImpl.java +++ b/src/org/jakstab/asm/x86/X86InstructionFactoryImpl.java @@ -106,5 +106,9 @@ public X86Instruction newGeneralInstruction(String name, Operand op1, int size, return new X86Instruction(name, op1, size, prefixes); } + @Override + public X86Instruction newGeneralInstruction(String name, int size, int prefixes) { + return new X86Instruction(name, size, prefixes); + } } diff --git a/src/org/jakstab/asm/x86/X86MMXRegisters.java b/src/org/jakstab/asm/x86/X86MMXRegisters.java index 968a805..69e7f40 100644 --- a/src/org/jakstab/asm/x86/X86MMXRegisters.java +++ b/src/org/jakstab/asm/x86/X86MMXRegisters.java @@ -30,6 +30,7 @@ package org.jakstab.asm.x86; +import capstone.X86_const; import org.jakstab.util.Logger; public class X86MMXRegisters { @@ -50,14 +51,14 @@ public class X86MMXRegisters { private static X86MMXRegister mmxRegisters[]; static { - MM0 = new X86MMXRegister(0, "%mm0"); - MM1 = new X86MMXRegister(1, "%mm1"); - MM2 = new X86MMXRegister(2, "%mm2"); - MM3 = new X86MMXRegister(3, "%mm3"); - MM4 = new X86MMXRegister(4, "%mm4"); - MM5 = new X86MMXRegister(5, "%mm5"); - MM6 = new X86MMXRegister(6, "%mm6"); - MM7 = new X86MMXRegister(7, "%mm7"); + MM0 = new X86MMXRegister(X86_const.X86_REG_MM0, "%mm0"); + MM1 = new X86MMXRegister(X86_const.X86_REG_MM1, "%mm1"); + MM2 = new X86MMXRegister(X86_const.X86_REG_MM2, "%mm2"); + MM3 = new X86MMXRegister(X86_const.X86_REG_MM3, "%mm3"); + MM4 = new X86MMXRegister(X86_const.X86_REG_MM4, "%mm4"); + MM5 = new X86MMXRegister(X86_const.X86_REG_MM5, "%mm5"); + MM6 = new X86MMXRegister(X86_const.X86_REG_MM6, "%mm6"); + MM7 = new X86MMXRegister(X86_const.X86_REG_MM7, "%mm7"); mmxRegisters = (new X86MMXRegister[] { MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7 diff --git a/src/org/jakstab/asm/x86/X86MemoryOperand.java b/src/org/jakstab/asm/x86/X86MemoryOperand.java index 9a56bc0..0a9e8bf 100644 --- a/src/org/jakstab/asm/x86/X86MemoryOperand.java +++ b/src/org/jakstab/asm/x86/X86MemoryOperand.java @@ -54,7 +54,7 @@ public X86SegmentRegister getSegmentRegister() { } public X86MemoryOperand(DataType dataType, X86SegmentRegister segReg, X86Register base, X86Register index, long disp, int scale) { - super(dataType, base, index, disp, 1 << scale); + super(dataType, base, index, disp, scale);//1 << scale); this.segReg = segReg; } @@ -62,7 +62,11 @@ public X86MemoryOperand(DataType dataType, X86SegmentRegister segReg, X86Registe this(dataType, segReg, base, index, disp, 0); } - public X86MemoryOperand(DataType dataType, X86SegmentRegister segReg, X86Register base) { + public X86MemoryOperand(DataType dataType, X86SegmentRegister segReg, X86Register base, long disp){//Dom- Added long disp instead of assuming 0 + this(dataType, segReg, base, null, disp, 0); + } + + public X86MemoryOperand(DataType dataType, X86SegmentRegister segReg, X86Register base){//Dom- Added long disp instead of assuming 0 this(dataType, segReg, base, null, 0, 0); } diff --git a/src/org/jakstab/asm/x86/X86PCRelativeAddress.java b/src/org/jakstab/asm/x86/X86PCRelativeAddress.java index ec21bfa..cb5a41c 100644 --- a/src/org/jakstab/asm/x86/X86PCRelativeAddress.java +++ b/src/org/jakstab/asm/x86/X86PCRelativeAddress.java @@ -62,7 +62,6 @@ public long getEffectiveValue(long pcValue) { * @return the target's displacement from the start of the next instruction. */ public long getDisplacement() { - long displacement = super.getDisplacement(); - return displacement; + return super.getDisplacement(); } } diff --git a/src/org/jakstab/asm/x86/X86Registers.java b/src/org/jakstab/asm/x86/X86Registers.java index 4bc6bb4..3227a28 100644 --- a/src/org/jakstab/asm/x86/X86Registers.java +++ b/src/org/jakstab/asm/x86/X86Registers.java @@ -19,17 +19,21 @@ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. - * - */ + * + *//* + -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications +*/ +/* + * Original code for this class taken from the Java HotSpot VM. + * Modified for use with the Jakstab project. All modifications * Copyright 2007-2015 Johannes Kinder */ + package org.jakstab.asm.x86; +import capstone.X86_const; import org.jakstab.util.Logger; public class X86Registers { @@ -65,39 +69,39 @@ public class X86Registers { public static final X86Register DH; public static final X86Register BH; - private static X86Register registers8[]; +/* private static X86Register registers8[]; private static X86Register registers16[]; - private static X86Register registers32[]; + private static X86Register registers32[];*/ static { - EAX = new X86Register(0, "%eax"); - ECX = new X86Register(1, "%ecx"); - EDX = new X86Register(2, "%edx"); - EBX = new X86Register(3, "%ebx"); - ESP = new X86Register(4, "%esp"); - EBP = new X86Register(5, "%ebp"); - ESI = new X86Register(6, "%esi"); - EDI = new X86Register(7, "%edi"); - - AX = new X86RegisterPart(0, "%ax", 0, 16); - CX = new X86RegisterPart(1, "%cx", 0, 16); - DX = new X86RegisterPart(2, "%dx", 0, 16); - BX = new X86RegisterPart(3, "%bx", 0, 16); - SP = new X86RegisterPart(4, "%sp", 0, 16); - BP = new X86RegisterPart(5, "%bp", 0, 16); - SI = new X86RegisterPart(6, "%si", 0, 16); - DI = new X86RegisterPart(7, "%di", 0, 16); - - AL = new X86RegisterPart(0, "%al", 0, 8); - CL = new X86RegisterPart(1, "%cl", 0, 8); - DL = new X86RegisterPart(2, "%dl", 0, 8); - BL = new X86RegisterPart(3, "%bl", 0, 8); - AH = new X86RegisterPart(0, "%ah", 8, 8); - CH = new X86RegisterPart(1, "%ch", 8, 8); - DH = new X86RegisterPart(2, "%dh", 8, 8); - BH = new X86RegisterPart(3, "%bh", 8, 8); - - registers32 = (new X86Register[] { + EAX = new X86Register(X86_const.X86_REG_EAX, "%eax"); + ECX = new X86Register(X86_const.X86_REG_ECX, "%ecx"); + EDX = new X86Register(X86_const.X86_REG_EDX, "%edx"); + EBX = new X86Register(X86_const.X86_REG_EBX, "%ebx"); + ESP = new X86Register(X86_const.X86_REG_ESP, "%esp"); + EBP = new X86Register(X86_const.X86_REG_EBP, "%ebp"); + ESI = new X86Register(X86_const.X86_REG_ESI, "%esi"); + EDI = new X86Register(X86_const.X86_REG_EDI, "%edi"); + + AX = new X86RegisterPart(X86_const.X86_REG_AX, "%ax", 0, 16); + CX = new X86RegisterPart(X86_const.X86_REG_CX, "%cx", 0, 16); + DX = new X86RegisterPart(X86_const.X86_REG_DX, "%dx", 0, 16); + BX = new X86RegisterPart(X86_const.X86_REG_BX, "%bx", 0, 16); + SP = new X86RegisterPart(X86_const.X86_REG_SP, "%sp", 0, 16); + BP = new X86RegisterPart(X86_const.X86_REG_BP, "%bp", 0, 16); + SI = new X86RegisterPart(X86_const.X86_REG_SI, "%si", 0, 16); + DI = new X86RegisterPart(X86_const.X86_REG_DI, "%di", 0, 16); + + AL = new X86RegisterPart(X86_const.X86_REG_AL, "%al", 0, 8); + CL = new X86RegisterPart(X86_const.X86_REG_CL, "%cl", 0, 8); + DL = new X86RegisterPart(X86_const.X86_REG_DL, "%dl", 0, 8); + BL = new X86RegisterPart(X86_const.X86_REG_BL, "%bl", 0, 8); + AH = new X86RegisterPart(X86_const.X86_REG_AH, "%ah", 8, 8); + CH = new X86RegisterPart(X86_const.X86_REG_CH, "%ch", 8, 8); + DH = new X86RegisterPart(X86_const.X86_REG_DH, "%dh", 8, 8); + BH = new X86RegisterPart(X86_const.X86_REG_BH, "%bh", 8, 8); + +/* registers32 = (new X86Register[] { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI }); registers16 = (new X86Register[] { @@ -105,20 +109,20 @@ public class X86Registers { }); registers8 = (new X86Register[] { AL, CL, DL, BL, AH, CH, DH, BH - }); + });*/ } public static int getNumberOfRegisters() { return NUM_REGISTERS; } - public static X86Register getRegister8(int regNum) { - if (regNum < 0 || regNum >= NUM_REGISTERS) { - logger.error("Invalid integer register number!"); - return null; +/* public static X86Register getRegister8(int regNum) { + if (regNum < 0 || regNum >= NUM_REGISTERS) { + logger.error("Invalid integer register number!"); + return null; + } + return registers8[regNum]; } - return registers8[regNum]; - } public static X86Register getRegister16(int regNum) { if (regNum < 0 || regNum >= NUM_REGISTERS) { @@ -136,14 +140,12 @@ public static X86Register getRegister32(int regNum) { return registers32[regNum]; } - /** - * Returns the name of the 32bit register with the given code number. - */ + // Returns the name of the 32bit register with the given code number.//TODO-Dom fix this again public static String getRegisterName(int regNum) { if (regNum < 0 || regNum >= NUM_REGISTERS) { logger.error("Invalid integer register number!"); return null; } return registers32[regNum].toString(); - } + }*/ } diff --git a/src/org/jakstab/asm/x86/X86SegmentRegister.java b/src/org/jakstab/asm/x86/X86SegmentRegister.java index b1b74c4..6388cd1 100644 --- a/src/org/jakstab/asm/x86/X86SegmentRegister.java +++ b/src/org/jakstab/asm/x86/X86SegmentRegister.java @@ -35,6 +35,10 @@ public class X86SegmentRegister extends X86Register { public X86SegmentRegister(int num, String name) { super(num, name); } + + public X86SegmentRegister(X86Register reg){ + super(reg.getNumber(), reg.name); + } public int getNumberOfRegisters() { return X86SegmentRegisters.getNumberOfRegisters(); diff --git a/src/org/jakstab/asm/x86/X86SegmentRegisters.java b/src/org/jakstab/asm/x86/X86SegmentRegisters.java index a1511b1..8028f68 100644 --- a/src/org/jakstab/asm/x86/X86SegmentRegisters.java +++ b/src/org/jakstab/asm/x86/X86SegmentRegisters.java @@ -30,6 +30,7 @@ package org.jakstab.asm.x86; +import capstone.X86_const; import org.jakstab.util.Logger; public class X86SegmentRegisters { @@ -49,12 +50,12 @@ public class X86SegmentRegisters { static { //Segment registers - ES = new X86SegmentRegister(0, "%es"); - CS = new X86SegmentRegister(1, "%cs"); - SS = new X86SegmentRegister(2, "%ss"); - DS = new X86SegmentRegister(3, "%ds"); - FS = new X86SegmentRegister(4, "%fs"); - GS = new X86SegmentRegister(5, "%gs"); + ES = new X86SegmentRegister(X86_const.X86_REG_ES, "%es"); + CS = new X86SegmentRegister(X86_const.X86_REG_CS, "%cs"); + SS = new X86SegmentRegister(X86_const.X86_REG_SS, "%ss"); + DS = new X86SegmentRegister(X86_const.X86_REG_DS, "%ds"); + FS = new X86SegmentRegister(X86_const.X86_REG_FS, "%fs"); + GS = new X86SegmentRegister(X86_const.X86_REG_GS, "%gs"); segmentRegisters = (new X86SegmentRegister[] { ES, CS, SS, DS, FS, GS diff --git a/src/org/jakstab/asm/x86/X86XMMRegisters.java b/src/org/jakstab/asm/x86/X86XMMRegisters.java index 9d14746..524b203 100644 --- a/src/org/jakstab/asm/x86/X86XMMRegisters.java +++ b/src/org/jakstab/asm/x86/X86XMMRegisters.java @@ -30,6 +30,7 @@ package org.jakstab.asm.x86; +import capstone.X86_const; import org.jakstab.util.Logger; /* There are 8 128-bit XMM registers*/ @@ -53,14 +54,14 @@ public class X86XMMRegisters { static { //XMM registers - XMM0 = new X86XMMRegister(0, "%xmm0"); - XMM1 = new X86XMMRegister(1, "%xmm1"); - XMM2 = new X86XMMRegister(2, "%xmm2"); - XMM3 = new X86XMMRegister(3, "%xmm3"); - XMM4 = new X86XMMRegister(4, "%xmm4"); - XMM5 = new X86XMMRegister(5, "%xmm5"); - XMM6 = new X86XMMRegister(6, "%xmm6"); - XMM7 = new X86XMMRegister(7, "%xmm7"); + XMM0 = new X86XMMRegister(X86_const.X86_REG_XMM0, "%xmm0"); + XMM1 = new X86XMMRegister(X86_const.X86_REG_XMM1, "%xmm1"); + XMM2 = new X86XMMRegister(X86_const.X86_REG_XMM2, "%xmm2"); + XMM3 = new X86XMMRegister(X86_const.X86_REG_XMM3, "%xmm3"); + XMM4 = new X86XMMRegister(X86_const.X86_REG_XMM4, "%xmm4"); + XMM5 = new X86XMMRegister(X86_const.X86_REG_XMM5, "%xmm5"); + XMM6 = new X86XMMRegister(X86_const.X86_REG_XMM6, "%xmm6"); + XMM7 = new X86XMMRegister(X86_const.X86_REG_XMM7, "%xmm7"); xmmRegisters = (new X86XMMRegister[] { XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7 diff --git a/src/org/jakstab/disasm/Disassembler.java b/src/org/jakstab/disasm/Disassembler.java index ccc613f..82d031f 100644 --- a/src/org/jakstab/disasm/Disassembler.java +++ b/src/org/jakstab/disasm/Disassembler.java @@ -23,11 +23,16 @@ * @author Johannes Kinder */ public interface Disassembler { - +/** + * Disassembles one instruction at the given index in the code array. + * + * @return instr The disassembled instruction, null on failure. + */ + //public Instruction decodeInstruction(long fp); /** * Disassembles one instruction at the given index in the code array. * * @return instr The disassembled instruction, null on failure. */ - public Instruction decodeInstruction(long fp); + public Instruction decodeInstruction(long fp, long addr); } diff --git a/src/org/jakstab/disasm/x86/ArithmeticDecoder.java b/src/org/jakstab/disasm/x86/ArithmeticDecoder.java deleted file mode 100644 index 70133e2..0000000 --- a/src/org/jakstab/disasm/x86/ArithmeticDecoder.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.Operation; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class ArithmeticDecoder extends InstructionDecoder { - private Operation rtlOperation; - - public ArithmeticDecoder(String name, int addrMode1, int operandType1, Operation rtlOperation) { - super(name, addrMode1, operandType1); - this.rtlOperation = rtlOperation; - } - public ArithmeticDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, Operation rtlOperation) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - this.rtlOperation = rtlOperation; - } - public ArithmeticDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, int addrMode3, int operandType3, Operation rtlOperation) { - super(name, addrMode1, operandType1, addrMode2, operandType2, addrMode3, operandType3); - this.rtlOperation = rtlOperation; - } - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - Operand op3 = getOperand3(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newArithmeticInstruction(name, rtlOperation, op1, op2, op3, size, prefixes); - } -} - diff --git a/src/org/jakstab/disasm/x86/CallDecoder.java b/src/org/jakstab/disasm/x86/CallDecoder.java deleted file mode 100644 index bcac581..0000000 --- a/src/org/jakstab/disasm/x86/CallDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class CallDecoder extends InstructionDecoder { - public CallDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand operand = getOperand1(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newCallInstruction(name, operand, size, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/ConditionalJmpDecoder.java b/src/org/jakstab/disasm/x86/ConditionalJmpDecoder.java deleted file mode 100644 index 71b52f6..0000000 --- a/src/org/jakstab/disasm/x86/ConditionalJmpDecoder.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.asm.x86.X86PCRelativeAddress; -import org.jakstab.util.BinaryInputBuffer; - -public class ConditionalJmpDecoder extends InstructionDecoder { - - public ConditionalJmpDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand addr = getOperand1(bytesArray, operandSize, addrSize); - assert(addr instanceof X86PCRelativeAddress) : "Address should be PC Relative!"; - return factory.newCondJmpInstruction(name, (X86PCRelativeAddress)addr, byteIndex-instrStartIndex, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/FPArithmeticDecoder.java b/src/org/jakstab/disasm/x86/FPArithmeticDecoder.java deleted file mode 100644 index 79c992d..0000000 --- a/src/org/jakstab/disasm/x86/FPArithmeticDecoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.Operation; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class FPArithmeticDecoder extends FPInstructionDecoder { - private Operation rtlOperation; - - public FPArithmeticDecoder(String name, int addrMode1, int operandType1, Operation rtlOperation) { - super(name, addrMode1, operandType1); - this.rtlOperation = rtlOperation; - } - public FPArithmeticDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, Operation rtlOperation) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - this.rtlOperation = rtlOperation; - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newFPArithmeticInstruction(name, rtlOperation, op1, op2, size, prefixes); - } -} - diff --git a/src/org/jakstab/disasm/x86/FPInstructionDecoder.java b/src/org/jakstab/disasm/x86/FPInstructionDecoder.java deleted file mode 100644 index 446ffa2..0000000 --- a/src/org/jakstab/disasm/x86/FPInstructionDecoder.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; -import org.jakstab.util.Logger; - -// basic float instruction decoder class -public class FPInstructionDecoder extends InstructionDecoder { - - private final static Logger logger = Logger.getLogger(FPInstructionDecoder.class); - - - public FPInstructionDecoder(String name) { - super(name); - } - public FPInstructionDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - public FPInstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - - if (byteIndex <= instrStartIndex + 1) { - logger.warn("Adjusting instruction size of float instruction " + name); - byteIndex = instrStartIndex + 2; - } - - - int size = byteIndex - instrStartIndex; - return factory.newFPInstruction(name, op1, size, prefixes); - } -} - diff --git a/src/org/jakstab/disasm/x86/FPLoadDecoder.java b/src/org/jakstab/disasm/x86/FPLoadDecoder.java deleted file mode 100644 index 5eb8d8d..0000000 --- a/src/org/jakstab/disasm/x86/FPLoadDecoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -class FPLoadDecoder extends FPInstructionDecoder { - FPLoadDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op = getOperand1(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newFPLoadInstruction(name, op, size, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/FPStoreDecoder.java b/src/org/jakstab/disasm/x86/FPStoreDecoder.java deleted file mode 100644 index bf6c029..0000000 --- a/src/org/jakstab/disasm/x86/FPStoreDecoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -class FPStoreDecoder extends FPInstructionDecoder { - FPStoreDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op = getOperand1(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newFPStoreInstruction(name, op, size, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/FloatDecoder.java b/src/org/jakstab/disasm/x86/FloatDecoder.java deleted file mode 100644 index 105903a..0000000 --- a/src/org/jakstab/disasm/x86/FloatDecoder.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operation; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class FloatDecoder extends FPInstructionDecoder { - - public FloatDecoder() { - super(null); - } - - //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2 - //APPENDIX A - Escape opcodes - - /*When ModR/M byte is within 00h to BFh*/ - private static final FPInstructionDecoder floatMapOne[][] = { - /* d8 */ - { - new FPArithmeticDecoder("fadds", ADDR_E, fs_mode, Operation.ADD), - new FPArithmeticDecoder("fmuls", ADDR_E, fs_mode, Operation.SMUL), - new FPInstructionDecoder("fcoms", ADDR_E, fs_mode), - new FPInstructionDecoder("fcomps", ADDR_E, fs_mode), - new FPArithmeticDecoder("fsubs", ADDR_E, fs_mode, Operation.SUB), - new FPArithmeticDecoder("fsubrs", ADDR_E, fs_mode, Operation.SUB), - new FPArithmeticDecoder("fdivs", ADDR_E, fs_mode, Operation.SDIV), - new FPArithmeticDecoder("fdivrs", ADDR_E, fs_mode, Operation.SDIV) - }, - /* d9 */ - { - new FPLoadDecoder("flds", ADDR_E, fs_mode), - null, - new FPStoreDecoder("fsts", ADDR_E, fs_mode), - new FPStoreDecoder("fstps", ADDR_E, fs_mode), - new FPStoreDecoder("fldenv", ADDR_E, v_mode), - new FPStoreDecoder("fldcw", ADDR_E, w_mode), - new FPStoreDecoder("fNstenv", ADDR_E, b_mode), - new FPStoreDecoder("fNstcw", ADDR_E, w_mode) - }, - /* da */ - { - new FPArithmeticDecoder("fiaddl", ADDR_E, d_mode, Operation.ADD), - new FPArithmeticDecoder("fimull", ADDR_E, d_mode, Operation.SMUL), - new FPInstructionDecoder("ficoml", ADDR_E, d_mode), - new FPInstructionDecoder("ficompl", ADDR_E, d_mode), - new FPArithmeticDecoder("fisubl", ADDR_E, d_mode, Operation.SUB), - new FPArithmeticDecoder("fisubrl", ADDR_E, d_mode, Operation.SUB), - new FPArithmeticDecoder("fidivl", ADDR_E, d_mode, Operation.SDIV), - new FPArithmeticDecoder("fidivrl", ADDR_E, d_mode, Operation.SDIV) - }, - /* db */ - { - new FPLoadDecoder("fildl", ADDR_E, d_mode), - null, - new FPStoreDecoder("fistl", ADDR_E, d_mode), - new FPStoreDecoder("fistpl", ADDR_E, d_mode), - null, - new FPLoadDecoder("fldt", ADDR_E, fe_mode), - null, - new FPStoreDecoder("fstpt", ADDR_E, fe_mode) - }, - /* dc */ - { - new FPArithmeticDecoder("faddl", ADDR_E, fd_mode, Operation.ADD), - new FPArithmeticDecoder("fmull", ADDR_E, fd_mode, Operation.SMUL), - new FPInstructionDecoder("fcoml", ADDR_E, fd_mode), - new FPInstructionDecoder("fcompl", ADDR_E, fd_mode), - new FPArithmeticDecoder("fsubl", ADDR_E, fd_mode, Operation.SUB), - new FPArithmeticDecoder("fsubrl", ADDR_E, fd_mode, Operation.SUB), - new FPArithmeticDecoder("fdivl", ADDR_E, fd_mode, Operation.SDIV), - new FPArithmeticDecoder("fdivrl", ADDR_E, fd_mode, Operation.SDIV) - }, - /* dd */ - { - new FPLoadDecoder("fldl", ADDR_E, fd_mode), - null, - new FPStoreDecoder("fstl", ADDR_E, fd_mode), - new FPStoreDecoder("fstpl", ADDR_E, fd_mode), - new FPStoreDecoder("frstor", ADDR_E, v_mode), - null, - new FPStoreDecoder("fNsave", ADDR_E, w_mode), - new FPStoreDecoder("fNstsw", ADDR_E, w_mode) - }, - /* de */ - { - new FPArithmeticDecoder("fiadd", ADDR_E, w_mode, Operation.ADD), - new FPArithmeticDecoder("fimul", ADDR_E, w_mode, Operation.SMUL), - new FPInstructionDecoder("ficom", ADDR_E, w_mode), - new FPInstructionDecoder("ficomp", ADDR_E, w_mode), - new FPArithmeticDecoder("fisub", ADDR_E, w_mode, Operation.SUB), - new FPArithmeticDecoder("fisubr", ADDR_E, w_mode, Operation.SUB), - new FPArithmeticDecoder("fidiv", ADDR_E, w_mode, Operation.SDIV), - new FPArithmeticDecoder("fidivr", ADDR_E, w_mode, Operation.SDIV) - }, - /* df */ - { - new FPLoadDecoder("fild", ADDR_E, w_mode), - null, - new FPStoreDecoder("fist", ADDR_E, w_mode), - new FPStoreDecoder("fistp", ADDR_E, w_mode), - new FPLoadDecoder("fbld", ADDR_E, v_mode), - new FPLoadDecoder("fildll", ADDR_E, q_mode), - new FPStoreDecoder("fbstp", ADDR_E, v_mode), - new FPStoreDecoder("fistpll", ADDR_E, q_mode) - } - }; - - /*When ModR/M byte is outside 00h to BFh*/ - private static final FPInstructionDecoder floatMapTwo[][] = { - - /* d8 */ - /*parameter for ADDR_FPREG, 0 means ST(0), 1 means ST at rm value. */ - { - new FPArithmeticDecoder("fadd", ADDR_FPREG, 0, ADDR_FPREG, 1, Operation.ADD), - new FPArithmeticDecoder("fmul", ADDR_FPREG, 0, ADDR_FPREG, 1, Operation.SMUL), - new FPInstructionDecoder("fcom", ADDR_FPREG, 1), - new FPInstructionDecoder("fcomp", ADDR_FPREG, 1), - new FPArithmeticDecoder("fsub", ADDR_FPREG, 0, ADDR_FPREG, 1, Operation.SUB), - new FPArithmeticDecoder("fsubr", ADDR_FPREG, 0, ADDR_FPREG, 1, Operation.SUB), - new FPArithmeticDecoder("fdiv", ADDR_FPREG, 0, ADDR_FPREG, 1, Operation.SDIV), - new FPArithmeticDecoder("fdivr", ADDR_FPREG, 0, ADDR_FPREG, 1, Operation.SDIV) - }, - /* d9 */ - { - new FPLoadDecoder("fld", ADDR_FPREG, 1), - new FPInstructionDecoder("fxch", ADDR_FPREG, 1), - new FloatGRPDecoder(null, 0), - null, - new FloatGRPDecoder(null, 1), - new FloatGRPDecoder(null, 2), - new FloatGRPDecoder(null, 3), - new FloatGRPDecoder(null, 4) - }, - /* da */ - { - null, - null, - null, - null, - null, - new FloatGRPDecoder(null, 5), - null, - null - }, - /* db */ - { - null, - null, - null, - null, - new FloatGRPDecoder(null, 6), - null, - null, - null - }, - /* dc */ - { - new FPArithmeticDecoder("fadd", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.ADD), - new FPArithmeticDecoder("fmul", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SMUL), - null, - null, - new FPArithmeticDecoder("fsub", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SUB), - new FPArithmeticDecoder("fsubr",ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SUB), - new FPArithmeticDecoder("fdiv", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SDIV), - new FPArithmeticDecoder("fdivr", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SDIV) - }, - /* dd */ - { - new FPInstructionDecoder("ffree", ADDR_FPREG, 1), - null, - new FPStoreDecoder("fst", ADDR_FPREG, 1), - new FPStoreDecoder("fstp", ADDR_FPREG, 1), - new FPInstructionDecoder("fucom", ADDR_FPREG, 1), - new FPInstructionDecoder("fucomp", ADDR_FPREG, 1), - null, - null - }, - /* de */ - { - new FPArithmeticDecoder("faddp", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.ADD), - new FPArithmeticDecoder("fmulp", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SMUL), - null, - new FloatGRPDecoder(null, 7), - new FPArithmeticDecoder("fsubrp", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SUB), - new FPArithmeticDecoder("fsubp", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SUB), - new FPArithmeticDecoder("fdivrp", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SDIV), - new FPArithmeticDecoder("fdivp", ADDR_FPREG, 1, ADDR_FPREG, 0, Operation.SDIV) - }, - /* df */ - { - null, - null, - null, - null, - new FloatGRPDecoder(null, 8), - null, - null, - null - } - }; - - public Instruction decode(BinaryInputBuffer bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) { - this.byteIndex = index; - this.instrStartIndex = instrStartIndex; - this.prefixes = prefixes; - - int ModRM = readByte(bytesArray, byteIndex); - int reg = (ModRM >> 3) & 7; - // int regOrOpcode = (ModRM >> 3) & 7; - // int rm = ModRM & 7; - - int startIndexWithoutPrefix; - - // JK: FWAIT was broken - if ((prefixes & PREFIX_FWAIT) != 0) - startIndexWithoutPrefix = instrStartIndex + 1; - else - startIndexWithoutPrefix = instrStartIndex; - - int floatOpcode = InstructionDecoder.readByte(bytesArray, startIndexWithoutPrefix); - - FPInstructionDecoder instrDecoder = null; - - if(ModRM < 0xbf) { - instrDecoder = floatMapOne[floatOpcode - 0xd8][reg]; - } - else { - instrDecoder = floatMapTwo[floatOpcode - 0xd8][reg]; - } - - Instruction instr = null; - if(instrDecoder != null) { - instr = instrDecoder.decode(bytesArray, byteIndex, instrStartIndex, segmentOverride, prefixes, factory); - byteIndex = instrDecoder.getCurrentIndex(); - } - - return instr; - } -} diff --git a/src/org/jakstab/disasm/x86/FloatGRPDecoder.java b/src/org/jakstab/disasm/x86/FloatGRPDecoder.java deleted file mode 100644 index 96a8a2e..0000000 --- a/src/org/jakstab/disasm/x86/FloatGRPDecoder.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; -import org.jakstab.util.Logger; - -public class FloatGRPDecoder extends FPInstructionDecoder { - - @SuppressWarnings("unused") - private final static Logger logger = Logger.getLogger(FloatGRPDecoder.class); - - final private int number; - - //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2 - //APPENDIX A - Escape opcodes - - private static final FPInstructionDecoder floatGRPMap[][] = { - /* d9_2 */ - { - new FPInstructionDecoder("fnop"), - null, - null, - null, - null, - null, - null, - null - }, - /* d9_4 */ - { - new FPInstructionDecoder("fchs"), - new FPInstructionDecoder("fabs"), - null, - null, - new FPInstructionDecoder("ftst"), - new FPInstructionDecoder("fxam"), - null, - null - }, - /* d9_5 */ - { - new FPInstructionDecoder("fld1"), - new FPInstructionDecoder("fldl2t"), - new FPInstructionDecoder("fldl2e"), - new FPInstructionDecoder("fldpi"), - new FPInstructionDecoder("fldlg2"), - new FPInstructionDecoder("fldln2"), - new FPInstructionDecoder("fldz"), - null - }, - /* d9_6 */ - { - new FPInstructionDecoder("f2xm1"), - new FPInstructionDecoder("fyl2x"), - new FPInstructionDecoder("fptan"), - new FPInstructionDecoder("fpatan"), - new FPInstructionDecoder("fxtract"), - new FPInstructionDecoder("fprem1"), - new FPInstructionDecoder("fdecstp"), - new FPInstructionDecoder("fincstp") - }, - /* d9_7 */ - { - new FPInstructionDecoder("fprem"), - new FPInstructionDecoder("fyl2xp1"), - new FPInstructionDecoder("fsqrt"), - new FPInstructionDecoder("fsincos"), - new FPInstructionDecoder("frndint"), - new FPInstructionDecoder("fscale"), - new FPInstructionDecoder("fsin"), - new FPInstructionDecoder("fcos") - }, - /* da_5 */ - { - null, - new FPInstructionDecoder("fucompp", ADDR_FPREG, 1), - null, - null, - null, - null, - null, - null - }, - /* db_4 */ - { - new FPInstructionDecoder("feni(287 only)"), - new FPInstructionDecoder("fdisi(287 only)"), - new FPInstructionDecoder("fNclex"), - new FPInstructionDecoder("fNinit"), - new FPInstructionDecoder("fNsetpm(287 only)"), - null, - null, - null - }, - /* de_3 */ - { - null, - new FPInstructionDecoder("fcompp"), - null, - null, - null, - null, - null, - null - }, - /* df_4 */ - { - new FPInstructionDecoder("fNstsw", ADDR_REG, AX), - null, - null, - null, - null, - null, - null, - null - } - }; - - public FloatGRPDecoder(String name, int number) { - super(name); - this.number = number; - } - - public Instruction decode(BinaryInputBuffer bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) { - this.byteIndex = index; - this.instrStartIndex = instrStartIndex; - this.prefixes = prefixes; - - int ModRM = readByte(bytesArray, byteIndex); - int rm = ModRM & 7; - - FPInstructionDecoder instrDecoder = null; - instrDecoder = floatGRPMap[number][rm]; - - Instruction instr = null; - if(instrDecoder != null) { - instr = instrDecoder.decode(bytesArray, byteIndex, instrStartIndex, segmentOverride, prefixes, factory); - byteIndex = instrDecoder.getCurrentIndex(); - } - return instr; - } -} diff --git a/src/org/jakstab/disasm/x86/GRPDecoder.java b/src/org/jakstab/disasm/x86/GRPDecoder.java deleted file mode 100644 index 9d0ee97..0000000 --- a/src/org/jakstab/disasm/x86/GRPDecoder.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operation; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class GRPDecoder extends InstructionDecoder { - - final private int number; - //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2 - //APPENDIX A - Table A-4. Opcode Extensions for One and Two-byte Opcodes by Group Number. - private static final InstructionDecoder grpTable[][] = { - { - new ArithmeticDecoder("addb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.ADD), - new ArithmeticDecoder("orb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.OR), - new ArithmeticDecoder("adcb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.ADDC), - new ArithmeticDecoder("sbbb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.SUBC), - new ArithmeticDecoder("andb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.AND), - new ArithmeticDecoder("subb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.SUB), - new ArithmeticDecoder("xorb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.XOR), - new InstructionDecoder("cmpb", ADDR_E, b_mode, ADDR_I, b_mode) - }, - { - new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.ADD), - new ArithmeticDecoder("orS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.OR), - new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.ADDC), - new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.SUBC), - new ArithmeticDecoder("andS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.AND), - new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.SUB), - new ArithmeticDecoder("xorS", ADDR_E, v_mode, ADDR_I, v_mode, Operation.XOR), - new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_I, v_mode) - }, - { - new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.ADD), /*note: sIb here*/ - new ArithmeticDecoder("orS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.OR), - new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.ADDC), - new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.SUBC), - new ArithmeticDecoder("andS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.AND), - new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.SUB), - new ArithmeticDecoder("xorS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.XOR), - new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_I, b_mode) - }, - { - new ArithmeticDecoder("rolb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.RL), - new ArithmeticDecoder("rorb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.RR), - new ArithmeticDecoder("rclb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.RLC), - new ArithmeticDecoder("rcrb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.RRC), - new ArithmeticDecoder("shlb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.SLL), - new ArithmeticDecoder("shrb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.SRL), - null, - new ArithmeticDecoder("sarb", ADDR_E, b_mode, ADDR_I, b_mode, Operation.SRA), - }, - { - new ArithmeticDecoder("rolS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.RL), - new ArithmeticDecoder("rorS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.RR), - new ArithmeticDecoder("rclS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.RLC), - new ArithmeticDecoder("rcrS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.RRC), - new ArithmeticDecoder("shlS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.SLL), - new ArithmeticDecoder("shrS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.SRL), - null, - new ArithmeticDecoder("sarS", ADDR_E, v_mode, ADDR_I, b_mode, Operation.SRA) - }, - { - new ArithmeticDecoder("rolb", ADDR_E, b_mode, Operation.RL), - new ArithmeticDecoder("rorb", ADDR_E, b_mode, Operation.RR), - new ArithmeticDecoder("rclb", ADDR_E, b_mode, Operation.RLC), - new ArithmeticDecoder("rcrb", ADDR_E, b_mode, Operation.RRC), - new ArithmeticDecoder("shlb", ADDR_E, b_mode, Operation.SLL), - new ArithmeticDecoder("shrb", ADDR_E, b_mode, Operation.SRL), - null, - new ArithmeticDecoder("sarb", ADDR_E, b_mode, Operation.SRA) - }, - { - new ArithmeticDecoder("rolS", ADDR_E, v_mode, Operation.RL), - new ArithmeticDecoder("rorS", ADDR_E, v_mode, Operation.RR), - new ArithmeticDecoder("rclS", ADDR_E, v_mode, Operation.RLC), - new ArithmeticDecoder("rcrS", ADDR_E, v_mode, Operation.RRC), - new ArithmeticDecoder("shlS", ADDR_E, v_mode, Operation.SLL), - new ArithmeticDecoder("shrS", ADDR_E, v_mode, Operation.SRL), - null, - new ArithmeticDecoder("sarS", ADDR_E, v_mode, Operation.SRA) - }, - { - new ArithmeticDecoder("rolb", ADDR_E, b_mode, ADDR_REG, CL, Operation.RL), - new ArithmeticDecoder("rorb", ADDR_E, b_mode, ADDR_REG, CL, Operation.RR), - new ArithmeticDecoder("rclb", ADDR_E, b_mode, ADDR_REG, CL, Operation.RLC), - new ArithmeticDecoder("rcrb", ADDR_E, b_mode, ADDR_REG, CL, Operation.RRC), - new ArithmeticDecoder("shlb", ADDR_E, b_mode, ADDR_REG, CL, Operation.SLL), - new ArithmeticDecoder("shrb", ADDR_E, b_mode, ADDR_REG, CL, Operation.SRL), - null, - new ArithmeticDecoder("sarb", ADDR_E, b_mode, ADDR_REG, CL, Operation.SRA) - }, - { - new ArithmeticDecoder("rolS", ADDR_E, v_mode, ADDR_REG, CL, Operation.RL), - new ArithmeticDecoder("rorS", ADDR_E, v_mode, ADDR_REG, CL, Operation.RR), - new ArithmeticDecoder("rclS", ADDR_E, v_mode, ADDR_REG, CL, Operation.RLC), - new ArithmeticDecoder("rcrS", ADDR_E, v_mode, ADDR_REG, CL, Operation.RRC), - new ArithmeticDecoder("shlS", ADDR_E, v_mode, ADDR_REG, CL, Operation.SLL), - new ArithmeticDecoder("shrS", ADDR_E, v_mode, ADDR_REG, CL, Operation.SRL), - null, - new ArithmeticDecoder("sarS", ADDR_E, v_mode, ADDR_REG, CL, Operation.SRA) - }, - { - new InstructionDecoder("testb", ADDR_E, b_mode, ADDR_I, b_mode), - null, /*new InstructionDecoder("(bad)", ADDR_E, b_mode)*/ - new ArithmeticDecoder("notb", ADDR_E, b_mode, Operation.NOT), - new InstructionDecoder("negb", ADDR_E, b_mode), - new ArithmeticDecoder("mulb", ADDR_REG, AL, ADDR_E, b_mode, Operation.UMUL), - new ArithmeticDecoder("imulb", ADDR_REG, AL, ADDR_E, b_mode, Operation.SMUL), - new ArithmeticDecoder("divb", ADDR_REG, AL, ADDR_E, b_mode, Operation.UDIV), - new ArithmeticDecoder("idivb", ADDR_REG, AL, ADDR_E, b_mode, Operation.SDIV) - }, - { - new InstructionDecoder("testS", ADDR_E, v_mode, ADDR_I, v_mode), - null, - new ArithmeticDecoder("notS", ADDR_E, v_mode, Operation.NOT), - new InstructionDecoder("negS", ADDR_E, v_mode), - new ArithmeticDecoder("mulS", ADDR_REG, EAX, ADDR_E, v_mode, Operation.UMUL), - new ArithmeticDecoder("imulS", ADDR_REG, EAX, ADDR_E, v_mode, Operation.SMUL), - new ArithmeticDecoder("divS", ADDR_REG, EAX, ADDR_E, v_mode, Operation.SDIV), - new ArithmeticDecoder("idivS", ADDR_REG, EAX, ADDR_E, v_mode, Operation.SDIV) - }, - { - new ArithmeticDecoder("incb", ADDR_E, b_mode, Operation.ADD), - new ArithmeticDecoder("decb", ADDR_E, b_mode, Operation.SUB), - null, - null, - null, - null, - null, - null - }, - { - new ArithmeticDecoder("incS", ADDR_E, v_mode, Operation.ADD), - new ArithmeticDecoder("decS", ADDR_E, v_mode, Operation.SUB), - new CallDecoder("call", ADDR_E, v_mode), - new CallDecoder("lcall", ADDR_E, p_mode), - new JmpDecoder("jmp", ADDR_E, v_mode), - new JmpDecoder("ljmp", ADDR_E, p_mode), - new InstructionDecoder("pushS", ADDR_E, v_mode), - null - }, - { - new InstructionDecoder("sldt", ADDR_E, w_mode), - new InstructionDecoder("str", ADDR_E, w_mode), - new InstructionDecoder("lldt", ADDR_E, w_mode), - new InstructionDecoder("ltr", ADDR_E, w_mode), - new InstructionDecoder("verr", ADDR_E, w_mode), - new InstructionDecoder("verw", ADDR_E, w_mode), - null, - null - }, - { - new InstructionDecoder("sgdt", ADDR_E, w_mode), - new InstructionDecoder("sidt", ADDR_E, w_mode), - new InstructionDecoder("lgdt", ADDR_E, w_mode), - new InstructionDecoder("lidt", ADDR_E, w_mode), - new InstructionDecoder("smsw", ADDR_E, w_mode), - null, - new InstructionDecoder("lmsw", ADDR_E, w_mode), - new InstructionDecoder("invlpg", ADDR_E, w_mode) - }, - { - null, - null, - null, - null, - new InstructionDecoder("btS", ADDR_E, v_mode, ADDR_I, b_mode), - new InstructionDecoder("btsS", ADDR_E, v_mode, ADDR_I, b_mode), - new InstructionDecoder("btrS", ADDR_E, v_mode, ADDR_I, b_mode), - new InstructionDecoder("btcS", ADDR_E, v_mode, ADDR_I, b_mode) - }, - /*16*/ - { - null, - new SSEInstructionDecoder("cmpxch8b", ADDR_W, q_mode), - null, - null, - null, - null, - null, - null - }, - /*17*/ - { - null, - null, - new SSEArithmeticDecoder("psrlw", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SRL), - null, - new SSEArithmeticDecoder("psraw", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SRA), - null, - new SSEArithmeticDecoder("psllw", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SLL), - null - }, - /*18*/ - { - null, - null, - new SSEArithmeticDecoder("psrld", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SRL), - null, - new SSEArithmeticDecoder("psrad", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SRA), - null, - new SSEArithmeticDecoder("pslld", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SLL), - null - }, - /*19*/ - { - null, - null, - new SSEArithmeticDecoder("psrlq", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SRL), - null, - null, - null, - new SSEArithmeticDecoder("psllq", ADDR_P, q_mode, ADDR_I, b_mode, Operation.SLL), - null - }, - /*20 - Grp15*/ - { - // FIXME: JK: I think these are wrong - byteindex is not advanced by constructor - // without operands, even though a modrm byte is present! - new SSEInstructionDecoder("fxsave", ADDR_E, b_mode), - new SSEInstructionDecoder("fxrstor", ADDR_E, b_mode), - new SSEInstructionDecoder("ldmxcsr", ADDR_E, d_mode), - new SSEInstructionDecoder("stmxcsr", ADDR_E, d_mode), - null, - null, - null, - new SSEInstructionDecoder("clflush", ADDR_E, b_mode) - }, - /*21 - Grp16*/ - { - new SSEInstructionDecoder("prefetchnta", ADDR_E, b_mode), - new SSEInstructionDecoder("prefetcht0", ADDR_E, b_mode), - new SSEInstructionDecoder("prefetcht1", ADDR_E, b_mode), - new SSEInstructionDecoder("prefetcht2", ADDR_E, b_mode), - null, - null, - null, - null - }, - /*22 - Grp12:66*/ - { - null, - null, - new SSEArithmeticDecoder("psrlw", ADDR_P, dq_mode, ADDR_I, b_mode, Operation.SRL), - null, - new SSEArithmeticDecoder("psraw", ADDR_P, dq_mode, ADDR_I, b_mode, Operation.SRA), - null, - new SSEArithmeticDecoder("psllw", ADDR_P, dq_mode, ADDR_I, b_mode, Operation.SLL), - null - }, - /*23 - Grp13:66*/ - { - null, - null, - new SSEArithmeticDecoder("psrld", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SRL), - null, - new SSEArithmeticDecoder("psrad", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SRA), - null, - new SSEArithmeticDecoder("pslld", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SLL), - null - }, - /*24 - - Grp14:66*/ - { - null, - null, - new SSEArithmeticDecoder("psrlq", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SRL), - new SSEArithmeticDecoder("psrldq", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SRL), - null, - null, - new SSEArithmeticDecoder("psllq", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SLL), - new SSEArithmeticDecoder("psllq", ADDR_W, dq_mode, ADDR_I, b_mode, Operation.SLL) - } -}; - - public GRPDecoder(String name, int number) { - super(name); - this.number = number; - } - - public Instruction decode(BinaryInputBuffer bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) { - this.byteIndex = index; - this.instrStartIndex = instrStartIndex; - this.prefixes = prefixes; - - int ModRM = readByte(bytesArray, byteIndex); - int reg = (ModRM >> 3) & 7; - - InstructionDecoder instrDecoder = grpTable[number][reg]; - Instruction instr = null; - if(instrDecoder != null) { - instr = instrDecoder.decode(bytesArray, byteIndex, instrStartIndex, segmentOverride, prefixes, factory); - byteIndex = instrDecoder.getCurrentIndex(); - } - return instr; - } -} diff --git a/src/org/jakstab/disasm/x86/InstructionDecoder.java b/src/org/jakstab/disasm/x86/InstructionDecoder.java deleted file mode 100644 index bbcb516..0000000 --- a/src/org/jakstab/disasm/x86/InstructionDecoder.java +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.util.BinaryInputBuffer; -import org.jakstab.util.Logger; -import org.jakstab.asm.*; -import org.jakstab.asm.x86.*; - -public class InstructionDecoder implements /* imports */ X86Opcodes { - private final static Logger logger = Logger.getLogger(InstructionDecoder.class); - - /* - * The three read methods are now changed to call into BinaryInputBuffer - * to remove the dependency on byte[]. This could be much nicer, i.e., - * integrate all the reading logic with BinaryInputBuffer, but it's - * probably not worth the effort. --JK, 8.11.2010 - */ - static int readByte(BinaryInputBuffer bytesArray, int index) { - int ret = 0; - if (index < bytesArray.getSize()) { - ret = bytesArray.getByteAt(index); - ret = ret & 0xff; - } else { - throw new ArrayIndexOutOfBoundsException("Disassembler requested byte outside of file area: 0x" + Long.toHexString(index)); - } - return ret; - } - - static int readInt16(BinaryInputBuffer bytesArray, int index) { - int ret = 0; - ret = readByte(bytesArray, index); - ret |= readByte(bytesArray, index+1) << 8; - return ret; - } - - static int readInt32(BinaryInputBuffer bytesArray, int index) { - int ret = 0; - ret = readByte(bytesArray, index); - ret |= readByte(bytesArray, index+1) << 8; - ret |= readByte(bytesArray, index+2) << 16; - ret |= readByte(bytesArray, index+3) << 24; - return ret; - } - - // Fixed for every instance - protected final int addrMode1; - protected final int addrMode2; - protected final int addrMode3; - protected final String nameTemplate; - protected final int operandType1; - protected final int operandType2; - protected final int operandType3; - - // Working variables, change with every decoded instruction - private int mod; - private int regOrOpcode; - private int rm; - protected int byteIndex; - protected int instrStartIndex; - protected String name; - protected int prefixes; - - public InstructionDecoder(String name) { - this(name, INVALID_ADDRMODE, INVALID_OPERANDTYPE); - } - - public InstructionDecoder(String name, int addrMode1, int operandType1) { - this(name, addrMode1, operandType1, INVALID_ADDRMODE, INVALID_OPERANDTYPE); - } - - public InstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2) { - this(name, addrMode1, operandType1, addrMode2, operandType2, INVALID_ADDRMODE, INVALID_OPERANDTYPE); - } - - public InstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, - int addrMode3, int operandType3) { - this.nameTemplate = name; - this.operandType1 = operandType1; - this.operandType2 = operandType2; - this.operandType3 = operandType3; - this.addrMode1 = addrMode1; - this.addrMode2 = addrMode2; - this.addrMode3 = addrMode3; - } - - public Instruction decode(BinaryInputBuffer bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) { - this.byteIndex = index; - this.instrStartIndex = instrStartIndex; - this.prefixes = prefixes; - boolean operandSize; //operand-size prefix - boolean addrSize; //address-size prefix - // segmentoverride is set to 1 in X86Disassembler. Correct for 32bit mode. - if ( ( (prefixes & PREFIX_DATA) ^ segmentOverride ) == 1) - operandSize = true; // set 32bit operand mode - else - operandSize = false; - if ( ((prefixes & PREFIX_ADR) ^ segmentOverride) == 1) - addrSize = true; - else - addrSize = false; - this.name = getCorrectOpcodeName(nameTemplate, prefixes, operandSize, addrSize); - - //Fetch the mod/reg/rm byte only if it is present. - if( isModRMPresent(addrMode1) || isModRMPresent(addrMode2) || isModRMPresent(addrMode3) ) { - - int ModRM = readByte(bytesArray, byteIndex); - byteIndex++; - mod = (ModRM >> 6) & 3; - regOrOpcode = (ModRM >> 3) & 7; - rm = ModRM & 7; - } - // Call instruction specific code - return decodeInstruction(bytesArray, operandSize, addrSize, factory); - } - - public int getCurrentIndex() { - return byteIndex; - } - - /** - * This is the instruction specific decoder. Gets overridden by the subclasses of - * InstructionDecoder. This is the fallback implementation for X86Instruction - * Objects. Note that 8bit operands are encoded implicitly in the opcode. - * - * @param bytesArray The array of bytes representing the binary. - * @param operandSize True for 32bit, false for 16bit operands. - * @param addrSize True for 32bit addresses, false for 16bit. - * @param factory The instruction factory to use. - * @return A new object representing the instruction at the current byteIndex. - */ - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - Operand op3 = getOperand3(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newGeneralInstruction(name, op1, op2, op3, size, prefixes); - } - - protected Operand getOperand1(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize) { - if( (addrMode1 != INVALID_ADDRMODE) && (operandType1 != INVALID_OPERANDTYPE) ) - return getOperand(bytesArray, addrMode1, operandType1, operandSize, addrSize); - else - return null; - } - - protected Operand getOperand2(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize) { - if( (addrMode2 != INVALID_ADDRMODE) && (operandType2 != INVALID_OPERANDTYPE) ) - return getOperand(bytesArray, addrMode2, operandType2, operandSize, addrSize); - else - return null; - } - - protected Operand getOperand3(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize) { - if( (addrMode3 != INVALID_ADDRMODE) && (operandType3 != INVALID_OPERANDTYPE) ) - return getOperand(bytesArray, addrMode3, operandType3, operandSize, addrSize); - else - return null; - } - - /** - * Instantiates the name template for the current instruction by replacing - * capital letters with their correct counterparts depending on various - * prefixes. - * - * @param oldName the instruction template string - * @param prefixes instruction prefixes - * @param operandSize true for 32bit operands, false for 16bit. - * @param addrSize true for 32bit addressing, false for 16bit. - * @return a new string with the correct AT&T name. - */ - private String getCorrectOpcodeName(String oldName, int prefixes, boolean operandSize, boolean addrSize) { - StringBuffer newName = new StringBuffer(oldName.length()); - int index = 0; - for(index=0; index> 6) & 3; - index = (sib >> 3) & 7; - base = sib & 7; - } - - switch (mod) { - case 0: - switch(rm) { - case 4: - if(base == 5) { - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - if (index != 4) { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, null, X86Registers.getRegister32(index), disp, scale); - } else { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, null, null, disp, scale); - } - } - else { - if (index != 4) { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), X86Registers.getRegister32(index), 0, scale); - } else { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), null, 0, scale); - } - } - break; - case 5: - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - //Create an Address object only with displacement - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, null, null, disp); - break; - default: - base = rm; - //Create an Address object only with base - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), null, 0); - break; - } - break; - case 1: - disp = (byte)readByte(bytesArray, byteIndex); - byteIndex++; - if (rm !=4) { - base = rm; - //Address with base and disp only - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), null, disp); - } else { - if (index != 4) { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), X86Registers.getRegister32(index), disp, scale); - } else { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), null, disp, scale); - } - } - break; - case 2: - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - if (rm !=4) { - base = rm; - //Address with base and disp - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), null, disp); - } else if (index != 4) { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), X86Registers.getRegister32(index), disp, scale); - } else { - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, X86Registers.getRegister32(base), null, disp, scale); - } - break; - } - } - break; - - case ADDR_I: - switch (operandType) { - case b_mode: - op = new Immediate(new Byte((byte)readByte(bytesArray, byteIndex)), DataType.UINT8); - byteIndex++; - break; - case w_mode: - op = new Immediate(new Short((short)readInt16(bytesArray, byteIndex)), DataType.UINT16); - byteIndex += 2; - break; - case v_mode: - if (operandSize == true) { //Operand size prefix is present - op = new Immediate(new Integer(readInt32(bytesArray, byteIndex)), DataType.UINT32); - byteIndex += 4; - } else { - op = new Immediate(new Short((short)readInt16(bytesArray, byteIndex)), DataType.UINT16); - byteIndex += 2; - } - break; - default: - break; - } - break; - case ADDR_REG: //registers - switch(operandType) { - case EAX: - case ECX: - case EDX: - case EBX: - case ESP: - case EBP: - case ESI: - case EDI: - if(operandSize == true) { - op = X86Registers.getRegister32(operandType - EAX); - } - else { - op = X86Registers.getRegister16(operandType - EAX); - } - break; - case AX: - case CX: - case DX: - case BX: - case SP: - case BP: - case SI: - case DI: - op = X86Registers.getRegister16(operandType - AX); - break; - case AL: - case CL: - case DL: - case BL: - case AH: - case CH: - case DH: - case BH: - op = X86Registers.getRegister8(operandType - AL); - break; - case ES: //ES, CS, SS, DS, FS, GS - case CS: - case SS: - case DS: - case FS: - case GS: - op = X86SegmentRegisters.getSegmentRegister(operandType - ES); - break; - } - break; - case ADDR_DIR: //segment and offset - long segment = 0; - long offset = 0; - switch (operandType) { - case p_mode: - if (addrSize == true) { - offset = readInt32(bytesArray, byteIndex); - byteIndex += 4; - segment = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } else { - offset = readInt16(bytesArray, byteIndex); - byteIndex += 2; - segment = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - op = new X86AbsoluteAddress(segment, offset); //with offset - break; - case v_mode: - if (addrSize == true) { - offset = readInt32(bytesArray, byteIndex); - byteIndex += 4; - } else { - offset = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - op = new X86AbsoluteAddress(offset); //with offset - break; - default: - break; - } - break; - case ADDR_G: - switch (operandType) { - case b_mode: - op = X86Registers.getRegister8(regOrOpcode); - break; - case w_mode: - op = X86Registers.getRegister16(regOrOpcode); - break; - case d_mode: - op = X86Registers.getRegister32(regOrOpcode); - break; - case v_mode: - if (operandSize == true) - op = X86Registers.getRegister32(regOrOpcode); - else - op = X86Registers.getRegister16(regOrOpcode); - break; - default: - break; - } - break; - case ADDR_SEG: - op = X86SegmentRegisters.getSegmentRegister(regOrOpcode); - break; - case ADDR_OFF: - int off = 0; - if (addrSize == true) { - off = readInt32(bytesArray, byteIndex); - byteIndex += 4; - } - else { - off = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - //op = new X86AbsoluteAddress((long)off); - // --JK: This is actually a memory operand with constant address used by MOV. - // Absolute Addresses are now used only for far calls and far jumps. - op = new X86MemoryOperand(getDataType(operandType, operandSize), segReg, off); // JK- Added segReg for mov fs:0, ecx - break; - case ADDR_J: - long disp = 0; - //The effective address is Instruction pointer + relative offset - switch(operandType) { - case b_mode: - disp = (byte)readByte(bytesArray, byteIndex); - byteIndex++; - break; - case v_mode: - if (operandSize == true) { - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - } - else { - disp = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - //disp = disp + (byteIndex-instrStartIndex); - break; - } - op = new X86PCRelativeAddress(disp); - break; - case ADDR_ESDI: - op = new X86MemoryOperand(getDataType(operandType, operandSize), X86SegmentRegisters.ES, X86Registers.EDI); - break; - case ADDR_DSSI: - op = new X86MemoryOperand(getDataType(operandType, operandSize), X86SegmentRegisters.DS, X86Registers.ESI); - break; - case ADDR_R: - switch (operandType) { - case b_mode: - op = X86Registers.getRegister8(mod); - break; - case w_mode: - op = X86Registers.getRegister16(mod); - break; - case d_mode: - op = X86Registers.getRegister32(mod); - break; - case v_mode: - if (operandSize == true) - op = X86Registers.getRegister32(mod); - else - op = X86Registers.getRegister16(mod); - break; - default: - break; - } - break; - case ADDR_FPREG: - switch (operandType) { - case 0: - op = X86FloatRegisters.getRegister(0); - break; - case 1: - op = X86FloatRegisters.getRegister(rm); - break; - } - break; - - //SSE: reg field of ModR/M byte selects a 128-bit XMM register - case ADDR_V: - op = X86XMMRegisters.getRegister(regOrOpcode); - break; - - //SSE: reg field of ModR/M byte selects a 64-bit MMX register - case ADDR_P: - op = X86MMXRegisters.getRegister(regOrOpcode); - break; - case ADDR_C: - op = X86ControlRegisters.getRegister(regOrOpcode); - break; - case ADDR_RMR: - op = X86Registers.getRegister32(rm); - break; - case ADDR_D: - logger.error("Debug registers not supported!"); - case INDIR_REG: - if (operandType != DX) - logger.warn("Operand type for I/O port addressing should be DX"); - op = X86Registers.DX; - break; - default: - logger.error("Error decoding operand: Unsupported addressing mode: " + addrMode - + "\n Register code: " + regOrOpcode); - } - if (op == null) throw new - RuntimeException("Unable to decode instruction operand for addressing mode " + addrMode + ", operand type " + operandType + ", and operand size " + operandSize); - return op; - } - - private X86SegmentRegister getSegmentRegisterFromPrefix(int prefixes) { - X86SegmentRegister segRegister = null; - - if ( (prefixes & PREFIX_CS) != 0) - segRegister = X86SegmentRegisters.CS; - if ( (prefixes & PREFIX_DS) != 0) - segRegister = X86SegmentRegisters.DS; - if ( (prefixes & PREFIX_ES) != 0) - segRegister = X86SegmentRegisters.ES; - if ( (prefixes & PREFIX_FS) != 0) - segRegister = X86SegmentRegisters.FS; - if ( (prefixes & PREFIX_SS) != 0) - segRegister = X86SegmentRegisters.SS; - if ( (prefixes & PREFIX_GS) != 0) - segRegister = X86SegmentRegisters.GS; - - return segRegister; - } - - private boolean isModRMPresent(int addrMode) { - if( (addrMode == ADDR_E) || (addrMode == ADDR_G) || (addrMode == ADDR_FPREG) - || (addrMode == ADDR_Q) || (addrMode == ADDR_W) - || (addrMode == ADDR_C) || (addrMode == ADDR_D)) - return true; - else - return false; - } -} diff --git a/src/org/jakstab/disasm/x86/JmpDecoder.java b/src/org/jakstab/disasm/x86/JmpDecoder.java deleted file mode 100644 index 90b1b1f..0000000 --- a/src/org/jakstab/disasm/x86/JmpDecoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class JmpDecoder extends InstructionDecoder { - public JmpDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand operand = getOperand1(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newJmpInstruction(name, operand, size, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/MoveDecoder.java b/src/org/jakstab/disasm/x86/MoveDecoder.java deleted file mode 100644 index 573b499..0000000 --- a/src/org/jakstab/disasm/x86/MoveDecoder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class MoveDecoder extends InstructionDecoder { - public MoveDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newMoveInstruction(name, op1, op2, size, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/RetDecoder.java b/src/org/jakstab/disasm/x86/RetDecoder.java deleted file mode 100644 index 0242d9a..0000000 --- a/src/org/jakstab/disasm/x86/RetDecoder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Immediate; -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class RetDecoder extends InstructionDecoder { - - public RetDecoder(String name) { - super(name); - } - public RetDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - assert(op1 == null || op1 instanceof Immediate) : "Operand should be immediate Value!"; - int size = byteIndex - instrStartIndex; - return factory.newRetInstruction(name, (Immediate)op1, size, prefixes); - } -} diff --git a/src/org/jakstab/disasm/x86/SSEArithmeticDecoder.java b/src/org/jakstab/disasm/x86/SSEArithmeticDecoder.java deleted file mode 100644 index f1b3fb3..0000000 --- a/src/org/jakstab/disasm/x86/SSEArithmeticDecoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.Operation; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class SSEArithmeticDecoder extends SSEInstructionDecoder { - private Operation rtlOperation; - - public SSEArithmeticDecoder(String name, int addrMode1, int operandType1, Operation rtlOperation) { - super(name, addrMode1, operandType1); - this.rtlOperation = rtlOperation; - } - - public SSEArithmeticDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, Operation rtlOperation) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - this.rtlOperation = rtlOperation; - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newArithmeticInstruction(name, rtlOperation, op1, op2, size, prefixes); - } -} - diff --git a/src/org/jakstab/disasm/x86/SSEInstructionDecoder.java b/src/org/jakstab/disasm/x86/SSEInstructionDecoder.java deleted file mode 100644 index 71244aa..0000000 --- a/src/org/jakstab/disasm/x86/SSEInstructionDecoder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -// SSE instructions decoder class -public class SSEInstructionDecoder extends InstructionDecoder { - - public SSEInstructionDecoder(String name) { - super(name); - } - public SSEInstructionDecoder(String name, int addrMode1, int operandType1) { - super(name, addrMode1, operandType1); - } - public SSEInstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - } - - public SSEInstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, int addrMode3, int operandType3) { - super(name, addrMode1, operandType1, addrMode2, operandType2, addrMode3, operandType3); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - Operand op3 = getOperand3(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newGeneralInstruction(name, op1, op2, op3, size, 0); - } -} - diff --git a/src/org/jakstab/disasm/x86/SSEMoveDecoder.java b/src/org/jakstab/disasm/x86/SSEMoveDecoder.java deleted file mode 100644 index a5cc7e7..0000000 --- a/src/org/jakstab/disasm/x86/SSEMoveDecoder.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -/* - * Original code for this class taken from the Java HotSpot VM. - * Modified for use with the Jakstab project. All modifications - * Copyright 2007-2015 Johannes Kinder - */ - -package org.jakstab.disasm.x86; - -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operand; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.util.BinaryInputBuffer; - -public class SSEMoveDecoder extends SSEInstructionDecoder { - - public SSEMoveDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2) { - super(name, addrMode1, operandType1, addrMode2, operandType2); - } - - protected Instruction decodeInstruction(BinaryInputBuffer bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newMoveInstruction(name, op1, op2, size, 0); - } -} diff --git a/src/org/jakstab/disasm/x86/X86CapstoneParser.java b/src/org/jakstab/disasm/x86/X86CapstoneParser.java new file mode 100644 index 0000000..a78f233 --- /dev/null +++ b/src/org/jakstab/disasm/x86/X86CapstoneParser.java @@ -0,0 +1,135 @@ +package org.jakstab.disasm.x86; + +import capstone.Capstone; +import capstone.X86; +import capstone.X86_const; +import org.jakstab.asm.DataType; +import org.jakstab.asm.Immediate; +import org.jakstab.asm.Instruction; +import org.jakstab.asm.Operand; +import org.jakstab.asm.x86.*; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; +import org.jakstab.util.Logger; + +/** + * Created by dmium on 7/28/17. + */ +public class X86CapstoneParser{ + public static Instruction getInstruction(Capstone.CsInsn csinstr, int prefixes, X86InstructionFactory factory, Logger logger) { + if (csinstr.group(X86_const.X86_GRP_CALL)) { + return getCallInstruction(csinstr, prefixes, factory); + } + if (csinstr.group(X86_const.X86_GRP_RET)) { + return getRetInstruction(csinstr,prefixes,factory); + } + if (csinstr.group(X86_const.X86_GRP_JUMP)) { + return getJumpInstruction(csinstr,prefixes,factory); + } + return getGeneralInstruction(csinstr,prefixes,factory); + } + + private static Instruction getCallInstruction(Capstone.CsInsn csinstr, int prefixes, X86InstructionFactory factory) { + if (getOperand(((X86.OpInfo)(csinstr.operands)).op[0], csinstr) instanceof Immediate) + return factory.newCallInstruction(csinstr.mnemonic, new X86PCRelativeAddress((((X86.OpInfo) (csinstr.operands)).op[0].value.imm - csinstr.size) - csinstr.address), csinstr.size, prefixes); + return factory.newCallInstruction(csinstr.mnemonic, getOperand(((X86.OpInfo)(csinstr.operands)).op[0], csinstr), csinstr.size, prefixes); + } + + private static Instruction getRetInstruction(Capstone.CsInsn csinstr, int prefixes, X86InstructionFactory factory){ + if (csinstr.opCount(X86_const.X86_OP_IMM) != 0) + return factory.newRetInstruction(csinstr.mnemonic, (Immediate) getOperand(((X86.OpInfo) (csinstr.operands)).op[0], csinstr), csinstr.size, prefixes); + return factory.newRetInstruction(csinstr.mnemonic, csinstr.size, prefixes); + } + + private static Instruction getJumpInstruction(Capstone.CsInsn csinstr, int prefixes, X86InstructionFactory factory){ + if (csinstr.mnemonic.startsWith("jmp")) { + if(csinstr.mnemonic.endsWith("l")) + return factory.newJmpInstruction(csinstr.mnemonic, getOperand(((X86.OpInfo) (csinstr.operands)).op[0], csinstr), csinstr.size, prefixes); + return factory.newJmpInstruction(csinstr.mnemonic, new X86PCRelativeAddress((((X86.OpInfo)(csinstr.operands)).op[0].value.imm - csinstr.size) - csinstr.address) /*getOperand(((X86.OpInfo) (csinstr.operands)).op[0], csinstr)*/, csinstr.size, prefixes); + } else { + return factory.newCondJmpInstruction(csinstr.mnemonic, new X86PCRelativeAddress((((X86.OpInfo) (csinstr.operands)).op[0].value.imm - csinstr.size) - csinstr.address), csinstr.size, prefixes); + } + } + + private static Instruction getGeneralInstruction(Capstone.CsInsn csinstr, int prefixes, X86InstructionFactory factory){ + switch (((X86.OpInfo) (csinstr.operands)).op.length) { + case 0: + return factory.newGeneralInstruction(csinstr.mnemonic, csinstr.size, prefixes); + case 1: + return factory.newGeneralInstruction(csinstr.mnemonic, getOperand(((X86.OpInfo) (csinstr.operands)).op[0], csinstr), csinstr.size, prefixes); + case 2: + return factory.newGeneralInstruction(csinstr.mnemonic, getOperand(((X86.OpInfo) (csinstr.operands)).op[1], csinstr), getOperand(((X86.OpInfo) (csinstr.operands)).op[0], csinstr), csinstr.size, prefixes); + case 3: + return factory.newGeneralInstruction(csinstr.mnemonic, getOperand(((X86.OpInfo) (csinstr.operands)).op[2], csinstr), getOperand(((X86.OpInfo) (csinstr.operands)).op[1], csinstr), getOperand(((X86.OpInfo) (csinstr.operands)).op[0], csinstr), csinstr.size, prefixes); + } + return null; + } + + private static Operand getOperand(X86.Operand op, Capstone.CsInsn csinstr) { + switch (op.type) { + case X86_const.X86_OP_REG: + if (csinstr.regName(op.value.reg).toUpperCase().startsWith("ST")) { + return new X86FloatRegister(op.value.reg, "%st" + csinstr.regName(op.value.reg).charAt(3)); + } + return getRegister(op.value.reg, csinstr); + case X86_const.X86_OP_IMM: + return getImmediate(op.value.imm, op.size); + case X86_const.X86_OP_MEM: + return getMemOp(op, csinstr); + default: + throw new NotImplementedException(); + } + } + + private static Immediate getImmediate(long imm, int size) { + return new Immediate(getNumber(imm, getDataType(size)), getDataType(size)); + } + + public static X86Register getRegister(int reg, Capstone.CsInsn csinstr) { + return new X86Register(reg, "%" + csinstr.regName(reg)); + } + + private static X86MemoryOperand getMemOp(X86.Operand op, Capstone.CsInsn csinstr) { + X86SegmentRegister sr = null; + X86Register ir = null; + X86Register br = null; + if (op.value.mem.segment != 0) + sr = new X86SegmentRegister(op.value.mem.segment, csinstr.regName(op.value.mem.segment)); + if (op.value.mem.index != 0) + ir = getRegister(op.value.mem.index, csinstr); + if (op.value.mem.base != 0) + br = getRegister(op.value.mem.base, csinstr); + return new X86MemoryOperand(getDataType(op.size), sr, br, ir, op.value.mem.disp, op.value.mem.scale); + } + + private static DataType getDataType(int size) { + switch (size) { + case 1: + return DataType.INT8; + case 2: + return DataType.INT16; + case 4: + return DataType.INT32; + case 8: + return DataType.INT64; + case 16: + return DataType.INT128; + } + throw new NotImplementedException(); + } + + private static Number getNumber(long val, DataType type) { + switch (type) { + case INT8: + return (byte) val; + case INT16: + return (short) val; + case INT32: + return (int) val; + case INT64: + return/* (long)*/ val; + case INT128: + throw new NotImplementedException();//TODO-Dom Work out what to do with this + } + throw new NotImplementedException(); + } +} diff --git a/src/org/jakstab/disasm/x86/X86Disassembler.java b/src/org/jakstab/disasm/x86/X86Disassembler.java index faef9b1..77e866d 100644 --- a/src/org/jakstab/disasm/x86/X86Disassembler.java +++ b/src/org/jakstab/disasm/x86/X86Disassembler.java @@ -33,151 +33,118 @@ */ package org.jakstab.disasm.x86; - +import org.jakstab.asm.*; +import org.jakstab.asm.x86.*; import org.jakstab.util.BinaryInputBuffer; import org.jakstab.util.Logger; -import org.jakstab.asm.Instruction; -import org.jakstab.asm.Operation; -import org.jakstab.asm.x86.X86InstructionFactory; -import org.jakstab.asm.x86.X86InstructionFactoryImpl; -import org.jakstab.asm.x86.X86Opcodes; import org.jakstab.disasm.Disassembler; +import capstone.Capstone; public class X86Disassembler implements Disassembler, X86Opcodes { - private final static Logger logger = Logger.getLogger(X86Disassembler.class); - - protected final X86InstructionFactory factory; - protected final BinaryInputBuffer code; - private int byteIndex; - - private X86Disassembler(BinaryInputBuffer code, X86InstructionFactory factory) { - this.code = code; - this.factory = factory; - } - - /** - * Creates a new disassembler working on the given bytearray. - * - * @param code Byte array of code to be disassembled. - */ - public X86Disassembler(BinaryInputBuffer code) { - this(code, new X86InstructionFactoryImpl()); - } - - @Override - public final Instruction decodeInstruction(long index) { - Instruction instr = null; - InstructionDecoder instrDecoder = null; - byteIndex = (int)index; // For 64bit systems, this needs to be fixed - //int len = byteIndex; - int instrStartIndex = 0; - - int prefixes = 0; - instrStartIndex = byteIndex; - - try { - //check if there is any prefix - prefixes = getPrefixes(); - - int segmentOverride = 1; //get segment override prefix - - //Read opcode - int opcode = InstructionDecoder.readByte(code, byteIndex); - byteIndex++; - - // Check for escape opcode 0Fh - if (opcode == 0x0f) { - opcode = InstructionDecoder.readByte(code, byteIndex); - byteIndex++; - - //SSE: SSE instructions have reserved use of 0xF2, 0xF3, 0x66 prefixes - if ((prefixes & PREFIX_REPNZ) != 0) { - instrDecoder = twoBytePrefixF2Table[opcode]; - // Remove the prefix if the instruction is from this table - if (instrDecoder != null) prefixes = prefixes & (-1 ^ PREFIX_REPNZ); - } else if ((prefixes & PREFIX_REPZ) != 0) { - instrDecoder = twoBytePrefixF3Table[opcode]; - if (instrDecoder != null) prefixes = prefixes & (-1 ^ PREFIX_REPZ); - } else if ((prefixes & PREFIX_DATA) != 0) { - instrDecoder = twoBytePrefix66Table[opcode]; - if (instrDecoder != null) prefixes = prefixes & (-1 ^ PREFIX_DATA); - } /* does not work with prefixed standard - 2-Byte instructions! else { - instrDecoder = twoByteTable[opcode]; - } */ - if (instrDecoder == null) - instrDecoder = twoByteTable[opcode]; - - } else { - instrDecoder = oneByteTable[opcode]; - } - - if (instrDecoder == null) { - logger.error("Cannot find decoder for opcode " + Long.toHexString(opcode) + "."); - return null; - } - - instr = instrDecoder.decode(code, byteIndex, instrStartIndex, - segmentOverride, prefixes, factory); - if (instr == null) { - logger.error("Decoder " + instrDecoder.getClass().toString() + " for opcode " + - Long.toHexString(opcode)+ " returned null instruction!"); - return null; - } - //len = instrDecoder.getCurrentIndex(); - //byteIndex = len; - byteIndex = instrDecoder.getCurrentIndex(); - } catch (Exception exp) { - logger.error("Error during disassembly:", exp); - if (logger.isInfoEnabled()) - exp.printStackTrace(); - return null; - } - return instr; - } - - private final int getPrefixes() { - - int prefixes = 0; - boolean isPrefix = true; - - while (isPrefix) { - int prefixByte = InstructionDecoder.readByte(code, byteIndex); - - switch (prefixByte) { - case 0xf3: - prefixes |= PREFIX_REPZ; - break; - case 0xf2: - prefixes |= PREFIX_REPNZ; - break; - case 0xf0: - prefixes |= PREFIX_LOCK; - break; - case 0x2e: - prefixes |= PREFIX_CS; - break; - case 0x36: - prefixes |= PREFIX_SS; - break; - case 0x3e: - prefixes |= PREFIX_DS; - break; - case 0x26: - prefixes |= PREFIX_ES; - break; - case 0x64: - prefixes |= PREFIX_FS; - break; - case 0x65: - prefixes |= PREFIX_GS; - break; - case 0x66: - prefixes |= PREFIX_DATA; - break; - case 0x67: - prefixes |= PREFIX_ADR; - break; + private final static Logger logger = Logger.getLogger(X86Disassembler.class); + + protected final X86InstructionFactory factory; + protected final BinaryInputBuffer code; + private int byteIndex; + private Capstone cs; + + private X86Disassembler(BinaryInputBuffer code, X86InstructionFactory factory) { + this.code = code; + this.factory = factory; + cs = new Capstone(Capstone.CS_ARCH_X86, Capstone.CS_MODE_32); + cs.setSyntax(Capstone.CS_OPT_SYNTAX_ATT); + cs.setDetail(Capstone.CS_OPT_ON); + } + + /** + * Creates a new disassembler working on the given bytearray. + * + * @param code Byte array of code to be disassembled. + */ + public X86Disassembler(BinaryInputBuffer code) { + this(code, new X86InstructionFactoryImpl()); + } + + @Override + public final Instruction decodeInstruction(long index, long addr) { + Instruction instr; + byteIndex = (int) index; // For 64bit systems, this needs to be fixed //TODO-Dom test replacing this + + int prefixes ; + int instrStartIndex = byteIndex; + Capstone.CsInsn csinstr; + try { + prefixes = getPrefixes(); + byte[] insbytes = new byte[15 + (byteIndex - instrStartIndex)]; + for (int i = instrStartIndex; i < 15 + byteIndex; i++) {// TODO Dom - This is a (mostly) arbitrary number should probably calculate this. + insbytes[i - instrStartIndex] = (byte)readByte(code, i); + } + csinstr = cs.disasm(insbytes, addr, 1)[0]; + //logger.warn(csinstr.address + " " + csinstr.mnemonic + " " + csinstr.opStr); + instr = X86CapstoneParser.getInstruction(csinstr, prefixes, factory, logger); + byteIndex = csinstr.size + instrStartIndex; + } catch (Exception exp) { + logger.error("Error during disassembly:", exp); + if (logger.isInfoEnabled()) + exp.printStackTrace(); + return null; + } + return instr; + } + + static int readByte(BinaryInputBuffer bytesArray, int index) { + int ret; + if (index < bytesArray.getSize()) { + ret = bytesArray.getByteAt(index); + ret = ret & 0xff; + } else { + throw new ArrayIndexOutOfBoundsException("Disassembler requested byte outside of file area: 0x" + Long.toHexString(index)); + } + return ret; + } + + private final int getPrefixes() { + + int prefixes = 0; + boolean isPrefix = true; + + while (isPrefix) { + int prefixByte = readByte(code, byteIndex); + + switch (prefixByte) { + case 0xf3: + prefixes |= PREFIX_REPZ; + break; + case 0xf2: + prefixes |= PREFIX_REPNZ; + break; + case 0xf0: + prefixes |= PREFIX_LOCK; + break; + case 0x2e: + prefixes |= PREFIX_CS; + break; + case 0x36: + prefixes |= PREFIX_SS; + break; + case 0x3e: + prefixes |= PREFIX_DS; + break; + case 0x26: + prefixes |= PREFIX_ES; + break; + case 0x64: + prefixes |= PREFIX_FS; + break; + case 0x65: + prefixes |= PREFIX_GS; + break; + case 0x66: + prefixes |= PREFIX_DATA; + break; + case 0x67: + prefixes |= PREFIX_ADR; + break; /* * This had to be removed, since FWAIT is really an instruction and can appear on its own. * Mnemonics like FSTSW are only macros, anyway, and a jump to the FNSTSW part after 0x9B is ok. @@ -187,1473 +154,12 @@ private final int getPrefixes() { prefixes |= PREFIX_FWAIT; break; */ - default: - isPrefix = false; - } - if(isPrefix) - byteIndex++; - } - return prefixes; - } - - //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2 - //APPENDIX A - Table A-2. One-byte Opcode Map - private static final InstructionDecoder oneByteTable[] = { - /* 00 */ - new ArithmeticDecoder("addb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.ADD), - new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.ADD), - new ArithmeticDecoder("addb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.ADD), - new ArithmeticDecoder("addS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.ADD), - new ArithmeticDecoder("addb", ADDR_REG, AL, ADDR_I, b_mode, Operation.ADD), - new ArithmeticDecoder("addS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.ADD), - new InstructionDecoder("pushl", ADDR_REG, ES), - new InstructionDecoder("popl", ADDR_REG, ES), - /* 08 */ - new ArithmeticDecoder("orb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.OR), - new ArithmeticDecoder("orS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.OR), - new ArithmeticDecoder("orb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.OR), - new ArithmeticDecoder("orS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.OR), - new ArithmeticDecoder("orb", ADDR_REG, AL, ADDR_I, b_mode, Operation.OR), - new ArithmeticDecoder("orS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.OR), - new InstructionDecoder("pushl", ADDR_REG, CS), - null, /* 0x0f extended opcode escape */ - /* 10 */ - new ArithmeticDecoder("adcb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.ADDC), - new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.ADDC), - new ArithmeticDecoder("adcb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.ADDC), - new ArithmeticDecoder("adcS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.ADDC), - new ArithmeticDecoder("adcb", ADDR_REG, AL, ADDR_I, b_mode, Operation.ADDC), - new ArithmeticDecoder("adcS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.ADDC), - new InstructionDecoder("pushl", ADDR_REG, SS), - new InstructionDecoder("popl", ADDR_REG, SS), - /* 18 */ - new ArithmeticDecoder("sbbb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.SUBC), - new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.SUBC), - new ArithmeticDecoder("sbbb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.SUBC), - new ArithmeticDecoder("sbbS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.SUBC), - new ArithmeticDecoder("sbbb", ADDR_REG, AL, ADDR_I, b_mode, Operation.SUBC), - new ArithmeticDecoder("sbbS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.SUBC), - new InstructionDecoder("pushl", ADDR_REG, DS), - new InstructionDecoder("popl", ADDR_REG, DS), - /* 20 */ - new ArithmeticDecoder("andb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.AND), - new ArithmeticDecoder("andS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.AND), - new ArithmeticDecoder("andb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.AND), - new ArithmeticDecoder("andS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.AND), - new ArithmeticDecoder("andb", ADDR_REG, AL, ADDR_I, b_mode, Operation.AND), - new ArithmeticDecoder("andS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.AND), - null, /* SEG es prefix */ - new InstructionDecoder("daa"), - /* 28 */ - new ArithmeticDecoder("subb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.SUB), - new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.SUB), - new ArithmeticDecoder("subb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.SUB), - new ArithmeticDecoder("subS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.SUB), - new ArithmeticDecoder("subb", ADDR_REG, AL, ADDR_I, b_mode, Operation.SUB), - new ArithmeticDecoder("subS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.SUB), - null, /* SEG CS prefix */ - new InstructionDecoder("das"), - /* 30 */ - new ArithmeticDecoder("xorb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.XOR), - new ArithmeticDecoder("xorS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.XOR), - new ArithmeticDecoder("xorb", ADDR_G, b_mode, ADDR_E, b_mode, Operation.XOR), - new ArithmeticDecoder("xorS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.XOR), - new ArithmeticDecoder("xorb", ADDR_REG, AL, ADDR_I, b_mode, Operation.XOR), - new ArithmeticDecoder("xorS", ADDR_REG, EAX, ADDR_I, v_mode, Operation.XOR), - null, /* SEG SS prefix */ - new InstructionDecoder("aaa"), - /* 38 */ - new InstructionDecoder("cmpb", ADDR_E, b_mode, ADDR_G, b_mode), - new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_G, v_mode), - new InstructionDecoder("cmpb", ADDR_G, b_mode, ADDR_E, b_mode), - new InstructionDecoder("cmpS", ADDR_G, v_mode, ADDR_E, v_mode), - new InstructionDecoder("cmpb", ADDR_REG, AL, ADDR_I, b_mode), - new InstructionDecoder("cmpS", ADDR_REG, EAX, ADDR_I, v_mode), - null, /* SEG DS prefix */ - new InstructionDecoder("aas"), - /* 40 */ - new ArithmeticDecoder("incS", ADDR_REG, EAX, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, ECX, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, EDX, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, EBX, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, ESP, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, EBP, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, ESI, Operation.ADD), - new ArithmeticDecoder("incS", ADDR_REG, EDI, Operation.ADD), - /* 48 */ - new ArithmeticDecoder("decS", ADDR_REG, EAX, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, ECX, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, EDX, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, EBX, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, ESP, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, EBP, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, ESI, Operation.SUB), - new ArithmeticDecoder("decS", ADDR_REG, EDI, Operation.SUB), - /* 50 */ - new InstructionDecoder("pushS", ADDR_REG, EAX), - new InstructionDecoder("pushS", ADDR_REG, ECX), - new InstructionDecoder("pushS", ADDR_REG, EDX), - new InstructionDecoder("pushS", ADDR_REG, EBX), - new InstructionDecoder("pushS", ADDR_REG, ESP), - new InstructionDecoder("pushS", ADDR_REG, EBP), - new InstructionDecoder("pushS", ADDR_REG, ESI), - new InstructionDecoder("pushS", ADDR_REG, EDI), - /* 58 */ - new InstructionDecoder("popS", ADDR_REG, EAX), - new InstructionDecoder("popS", ADDR_REG, ECX), - new InstructionDecoder("popS", ADDR_REG, EDX), - new InstructionDecoder("popS", ADDR_REG, EBX), - new InstructionDecoder("popS", ADDR_REG, ESP), - new InstructionDecoder("popS", ADDR_REG, EBP), - new InstructionDecoder("popS", ADDR_REG, ESI), - new InstructionDecoder("popS", ADDR_REG, EDI), - /* 60 */ - new InstructionDecoder("pusha"), - new InstructionDecoder("popa"), - new InstructionDecoder("boundS", ADDR_G, v_mode, ADDR_E, v_mode), - new InstructionDecoder("arpl", ADDR_E, w_mode, ADDR_G, w_mode), - null, /* seg fs */ - null, /* seg gs */ - null, /* op size prefix */ - null, /* adr size prefix */ - /* 68 */ - new InstructionDecoder("pushS", ADDR_I, v_mode), /* 386 book wrong */ - new ArithmeticDecoder("imulS", ADDR_G, v_mode, ADDR_E, v_mode, ADDR_I, v_mode, Operation.SMUL), - new InstructionDecoder("pushl", ADDR_I, b_mode), /* push of byte really pushes 4 bytes (or 2 with data prefix) */ - new ArithmeticDecoder("imulS", ADDR_G, v_mode, ADDR_E, v_mode, ADDR_I, b_mode, Operation.SMUL), - new InstructionDecoder("insb", ADDR_ESDI, b_mode, INDIR_REG, DX), - new InstructionDecoder("insS", ADDR_ESDI, v_mode, INDIR_REG, DX), - new InstructionDecoder("outsb", INDIR_REG, DX, ADDR_DSSI, b_mode), - new InstructionDecoder("outsS", INDIR_REG, DX, ADDR_DSSI, v_mode), - /* 70 */ - new ConditionalJmpDecoder("jo", ADDR_J, b_mode), - new ConditionalJmpDecoder("jno", ADDR_J, b_mode), - new ConditionalJmpDecoder("jb", ADDR_J, b_mode), - new ConditionalJmpDecoder("jae", ADDR_J, b_mode), - new ConditionalJmpDecoder("je", ADDR_J, b_mode), - new ConditionalJmpDecoder("jne", ADDR_J, b_mode), - new ConditionalJmpDecoder("jbe", ADDR_J, b_mode), - new ConditionalJmpDecoder("ja", ADDR_J, b_mode), - /* 78 */ - new ConditionalJmpDecoder("js", ADDR_J, b_mode), - new ConditionalJmpDecoder("jns", ADDR_J, b_mode), - new ConditionalJmpDecoder("jp", ADDR_J, b_mode), - new ConditionalJmpDecoder("jnp", ADDR_J, b_mode), - new ConditionalJmpDecoder("jl", ADDR_J, b_mode), - new ConditionalJmpDecoder("jnl", ADDR_J, b_mode), - new ConditionalJmpDecoder("jle", ADDR_J, b_mode), - new ConditionalJmpDecoder("jg", ADDR_J, b_mode), - /* 80 */ - new GRPDecoder(null, 0), - new GRPDecoder(null, 1), - new GRPDecoder(null, 0), // undocumented - new GRPDecoder(null, 2), - new InstructionDecoder("testb", ADDR_E, b_mode, ADDR_G, b_mode), - new InstructionDecoder("testS", ADDR_E, v_mode, ADDR_G, v_mode), - new MoveDecoder("xchgb", ADDR_E, b_mode, ADDR_G, b_mode), - new MoveDecoder("xchgS", ADDR_E, v_mode, ADDR_G, v_mode), - /* 88 */ - new MoveDecoder("movb", ADDR_E, b_mode, ADDR_G, b_mode), - new MoveDecoder("movS", ADDR_E, v_mode, ADDR_G, v_mode), - new MoveDecoder("movb", ADDR_G, b_mode, ADDR_E, b_mode), - new MoveDecoder("movS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("movw", ADDR_E, w_mode, ADDR_SEG, w_mode), - new InstructionDecoder("leaS", ADDR_G, v_mode, ADDR_E, v_mode), // JK: was ("leaS", ADDR_G, v_mode, ADDR_E, 0); but mode 0 introduced errors! - new MoveDecoder("movw", ADDR_SEG, w_mode, ADDR_E, w_mode), - new InstructionDecoder("popS", ADDR_E, v_mode), - /* 90 */ - new InstructionDecoder("nop"), - new MoveDecoder("xchgS", ADDR_REG, ECX, ADDR_REG, EAX), - new MoveDecoder("xchgS", ADDR_REG, EDX, ADDR_REG, EAX), - new MoveDecoder("xchgS", ADDR_REG, EBX, ADDR_REG, EAX), - new MoveDecoder("xchgS", ADDR_REG, ESP, ADDR_REG, EAX), - new MoveDecoder("xchgS", ADDR_REG, EBP, ADDR_REG, EAX), - new MoveDecoder("xchgS", ADDR_REG, ESI, ADDR_REG, EAX), - new MoveDecoder("xchgS", ADDR_REG, EDI, ADDR_REG, EAX), - /* 98 */ - new InstructionDecoder("cwtl"), - new InstructionDecoder("cltd"), - new CallDecoder("lcall", ADDR_DIR, p_mode), - // Made fwait an instruction, too, to handle multiple fwait prefixes! - new InstructionDecoder("fwait"), - //null, /* fwait */ - new InstructionDecoder("pushfS"), - new InstructionDecoder("popfS"), - new InstructionDecoder("sahf"), - new InstructionDecoder("lahf"), - /* a0 */ - new MoveDecoder("movb", ADDR_REG, AL, ADDR_OFF, b_mode), - new MoveDecoder("movS", ADDR_REG, EAX, ADDR_OFF, v_mode), - new MoveDecoder("movb", ADDR_OFF, b_mode, ADDR_REG, AL), - new MoveDecoder("movS", ADDR_OFF, v_mode, ADDR_REG, EAX), - new InstructionDecoder("movsb", ADDR_ESDI, b_mode, ADDR_DSSI, b_mode), - new InstructionDecoder("movsS", ADDR_ESDI, v_mode, ADDR_DSSI, v_mode), - new InstructionDecoder("cmpsb", ADDR_ESDI, b_mode, ADDR_DSSI, b_mode), - new InstructionDecoder("cmpsS", ADDR_ESDI, v_mode, ADDR_DSSI, v_mode), - /* a8 */ - new InstructionDecoder("testb", ADDR_REG, AL, ADDR_I, b_mode), - new InstructionDecoder("testS", ADDR_REG, EAX, ADDR_I, v_mode), - new InstructionDecoder("stosb", ADDR_ESDI, b_mode, ADDR_REG, AL), - new InstructionDecoder("stosS", ADDR_ESDI, v_mode, ADDR_REG, EAX), - new InstructionDecoder("lodsb", ADDR_REG, AL, ADDR_DSSI, b_mode), - new InstructionDecoder("lodsS", ADDR_REG, EAX, ADDR_DSSI, v_mode), - new InstructionDecoder("scasb", ADDR_REG, AL, ADDR_ESDI, b_mode), - new InstructionDecoder("scasS", ADDR_REG, EAX, ADDR_ESDI, v_mode), - /* b0 */ - new MoveDecoder("movb", ADDR_REG, AL, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, CL, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, DL, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, BL, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, AH, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, CH, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, DH, ADDR_I, b_mode), - new MoveDecoder("movb", ADDR_REG, BH, ADDR_I, b_mode), - /* b8 */ - new MoveDecoder("movS", ADDR_REG, EAX, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, ECX, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, EDX, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, EBX, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, ESP, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, EBP, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, ESI, ADDR_I, v_mode), - new MoveDecoder("movS", ADDR_REG, EDI, ADDR_I, v_mode), - /* c0 */ - new GRPDecoder(null, 3), - new GRPDecoder(null, 4), - new RetDecoder("ret", ADDR_I, w_mode), - new RetDecoder("ret"), - new InstructionDecoder("lesS", ADDR_G, v_mode, ADDR_E, p_mode), // JK: changed 0 to p_mode according to lgs, lfs - new InstructionDecoder("ldsS", ADDR_G, v_mode, ADDR_E, p_mode), - new MoveDecoder("movb", ADDR_E, b_mode, ADDR_I, b_mode), - new MoveDecoder("movS", ADDR_E, v_mode, ADDR_I, v_mode), - /* c8 */ - new InstructionDecoder("enter", ADDR_I, w_mode, ADDR_I, b_mode), - new InstructionDecoder("leave"), - new RetDecoder("lret", ADDR_I, w_mode), - new RetDecoder("lret"), - new InstructionDecoder("int3"), - new InstructionDecoder("int", ADDR_I, b_mode), - new InstructionDecoder("into"), - new RetDecoder("iret"), - /* d0 */ - new GRPDecoder(null, 5), - new GRPDecoder(null, 6), - new GRPDecoder(null, 7), - new GRPDecoder(null, 8), - new InstructionDecoder("aam", ADDR_I, b_mode), - new InstructionDecoder("aad", ADDR_I, b_mode), - null, - new InstructionDecoder("xlat"), - /* d8 */ - new FloatDecoder(), - new FloatDecoder(), - new FloatDecoder(), - new FloatDecoder(), - new FloatDecoder(), - new FloatDecoder(), - new FloatDecoder(), - new FloatDecoder(), - /* e0 */ - new ConditionalJmpDecoder("loopne", ADDR_J, b_mode), - new ConditionalJmpDecoder("loope", ADDR_J, b_mode), - new ConditionalJmpDecoder("loop", ADDR_J, b_mode), - new ConditionalJmpDecoder("jCcxz", ADDR_J, b_mode), - new InstructionDecoder("inb", ADDR_REG, AL, ADDR_I, b_mode), - new InstructionDecoder("inS", ADDR_REG, EAX, ADDR_I, b_mode), - new InstructionDecoder("outb", ADDR_I, b_mode, ADDR_REG, AL), - new InstructionDecoder("outS", ADDR_I, b_mode, ADDR_REG, EAX), - /* e8 */ - new CallDecoder("call", ADDR_J, v_mode), - new JmpDecoder("jmp", ADDR_J, v_mode), - new JmpDecoder("ljmp", ADDR_DIR, p_mode), - new JmpDecoder("jmp", ADDR_J, b_mode), - new InstructionDecoder("inb", ADDR_REG, AL, INDIR_REG, DX), - new InstructionDecoder("inS", ADDR_REG, EAX, INDIR_REG, DX), - new InstructionDecoder("outb", INDIR_REG, DX, ADDR_REG,AL), - new InstructionDecoder("outS", INDIR_REG, DX, ADDR_REG, EAX), - /* f0 */ - new InstructionDecoder("lock"), /* lock prefix */ - null, - new InstructionDecoder("repne"), /* repne */ - new InstructionDecoder("rep"), /* repz */ - new InstructionDecoder("hlt"), - new InstructionDecoder("cmc"), - new GRPDecoder(null, 9), - new GRPDecoder(null, 10), - /* f8 */ - new InstructionDecoder("clc"), - new InstructionDecoder("stc"), - new InstructionDecoder("cli"), - new InstructionDecoder("sti"), - new InstructionDecoder("cld"), - new InstructionDecoder("std"), - new GRPDecoder(null, 11), - new GRPDecoder(null, 12) - }; - - //APPENDIX A - Table A-3. Two-byte Opcode Map - private static final InstructionDecoder twoByteTable[] = { - /* 00 */ - new GRPDecoder(null, 13), - new GRPDecoder(null, 14), - new InstructionDecoder("larS", ADDR_G, v_mode, ADDR_E, w_mode), - new InstructionDecoder("lslS", ADDR_G, v_mode, ADDR_E, w_mode), - null, - null, - new InstructionDecoder("clts"), - null, - /* 08 */ - new InstructionDecoder("invd"), - new InstructionDecoder("wbinvd"), - null, - null, - null, - null, - null, - null, - /* 10 */ //SSE - new SSEMoveDecoder("movups", ADDR_V, ps_mode, ADDR_W, ps_mode), - new SSEMoveDecoder("movups", ADDR_W, ps_mode, ADDR_V, ps_mode), - new SSEMoveDecoder("movlps", ADDR_W, q_mode, ADDR_V, q_mode), - new SSEMoveDecoder("movlps", ADDR_V, q_mode, ADDR_W, q_mode), - new SSEInstructionDecoder("unpcklps", ADDR_V, ps_mode, ADDR_W, q_mode), - new SSEInstructionDecoder("unpckhps", ADDR_V, ps_mode, ADDR_W, q_mode), - new SSEMoveDecoder("movhps", ADDR_V, q_mode, ADDR_W, q_mode), - new SSEMoveDecoder("movhps", ADDR_W, q_mode, ADDR_V, q_mode), - /* 18 */ - new GRPDecoder(null, 21), - null, - null, - null, - null, - null, - null, - null, - /* 20 */ - /* these are all backward in appendix A of the intel book */ - new MoveDecoder("movl", ADDR_RMR, d_mode, ADDR_C, d_mode), - new MoveDecoder("movl", ADDR_R, d_mode, ADDR_D, d_mode), - new MoveDecoder("movl", ADDR_C, d_mode, ADDR_RMR, d_mode), - new MoveDecoder("movl", ADDR_D, d_mode, ADDR_R, d_mode), - new MoveDecoder("movl", ADDR_R, d_mode, ADDR_T, d_mode), - null, - new MoveDecoder("movl", ADDR_T, d_mode, ADDR_R, d_mode), - null, - /* 28 */ - new SSEMoveDecoder("movaps", ADDR_V, ps_mode, ADDR_W, ps_mode), - new SSEMoveDecoder("movaps", ADDR_W, ps_mode, ADDR_V, ps_mode), - new SSEInstructionDecoder("cvtpi2ps", ADDR_V, ps_mode, ADDR_Q, q_mode), - new SSEMoveDecoder("movntps", ADDR_W, ps_mode, ADDR_V, ps_mode), - new SSEInstructionDecoder("cvttps2pi", ADDR_Q, q_mode, ADDR_W, ps_mode), - new SSEInstructionDecoder("cvtps2pi", ADDR_Q, q_mode, ADDR_W, ps_mode), - new SSEInstructionDecoder("ucomiss", ADDR_V, ss_mode, ADDR_W, ss_mode), - new SSEInstructionDecoder("comiss", ADDR_V, ps_mode, ADDR_W, ps_mode), - /* 30 */ - new SSEInstructionDecoder("wrmsr"), - new SSEInstructionDecoder("rdtsc"), - new SSEInstructionDecoder("rdmsr"), - new SSEInstructionDecoder("rdpmc"), - new SSEInstructionDecoder("sysenter"), - new SSEInstructionDecoder("sysexit"), - null, - null, - /* 38 */ - null, - null, - null, - null, - new SSEMoveDecoder("movnti", ADDR_G, v_mode, ADDR_E, v_mode), - null, - null, - null, - /* 40 */ - new MoveDecoder("cmovoS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovnoS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovbS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovaeS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmoveS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovneS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovbeS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovaS", ADDR_G, v_mode, ADDR_E, v_mode), - /* 48 */ - new MoveDecoder("cmovsS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovnsS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovpS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovnpS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovlS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovgeS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovleS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("cmovgS", ADDR_G, v_mode, ADDR_E, v_mode), - /* 50 */ - new SSEMoveDecoder("movmskps", ADDR_E, d_mode, ADDR_V, ps_mode), - new SSEInstructionDecoder("sqrtps", ADDR_V, ps_mode, ADDR_W, ps_mode), - new SSEInstructionDecoder("rsqrtps", ADDR_V, ps_mode, ADDR_W, ps_mode), - new SSEInstructionDecoder("rcpps", ADDR_V, ps_mode, ADDR_W, ps_mode), - new SSEArithmeticDecoder("andps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.AND), - new SSEArithmeticDecoder("andnps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.AND), - new SSEArithmeticDecoder("orps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.OR), - new SSEArithmeticDecoder("xorps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.XOR), - /* 58 */ - new SSEArithmeticDecoder("addps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.ADD), - new SSEArithmeticDecoder("mulps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.SMUL), - new SSEInstructionDecoder("cvtps2pd", ADDR_V, pd_mode, ADDR_W, ps_mode), - new SSEInstructionDecoder("cvtdq2ps", ADDR_V, ps_mode, ADDR_W, dq_mode), - new SSEArithmeticDecoder("subps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.SUB), - new SSEInstructionDecoder("minps", ADDR_V, ps_mode, ADDR_W, ps_mode), - new SSEArithmeticDecoder("divps", ADDR_V, ps_mode, ADDR_W, ps_mode, Operation.SDIV), - new SSEInstructionDecoder("maxps", ADDR_V, ps_mode, ADDR_W, ps_mode), - /* 60 */ - new SSEInstructionDecoder("punpcklbw", ADDR_P, q_mode, ADDR_Q, d_mode), - new SSEInstructionDecoder("punpcklwd", ADDR_P, q_mode, ADDR_Q, d_mode), - new SSEInstructionDecoder("punpckldq", ADDR_P, q_mode, ADDR_Q, d_mode), - new SSEInstructionDecoder("packsswb", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("pcmpgtb", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("pcmpgtw", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("pcmpgtd", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("packuswb", ADDR_P, q_mode, ADDR_Q, q_mode), - /* 68 */ - new SSEInstructionDecoder("punpckhbw", ADDR_P, q_mode, ADDR_Q, d_mode), - new SSEInstructionDecoder("punpckhwd", ADDR_P, q_mode, ADDR_Q, d_mode), - new SSEInstructionDecoder("punpckhdq", ADDR_P, q_mode, ADDR_Q, d_mode), - new SSEInstructionDecoder("packssdw", ADDR_P, q_mode, ADDR_Q, d_mode), - null, - null, - new SSEMoveDecoder("movd", ADDR_P, d_mode, ADDR_E, d_mode), - new SSEMoveDecoder("movq", ADDR_P, q_mode, ADDR_E, q_mode), - /* 70 */ - new SSEInstructionDecoder("pshufw", ADDR_P, q_mode, ADDR_Q, q_mode, ADDR_I, b_mode), - new GRPDecoder(null, 17), - new GRPDecoder(null, 18), - new GRPDecoder(null, 19), - new SSEInstructionDecoder("pcmpeqb", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("pcmpeqw", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("pcmpeqd", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("emms"), - /* 78 */ - null, - null, - null, - null, - null, - null, - new SSEMoveDecoder("movd", ADDR_E, d_mode, ADDR_P, d_mode), - new SSEMoveDecoder("movq", ADDR_Q, q_mode, ADDR_P, q_mode), - /* 80 */ - new ConditionalJmpDecoder("jo", ADDR_J, v_mode), - new ConditionalJmpDecoder("jno", ADDR_J, v_mode), - new ConditionalJmpDecoder("jb", ADDR_J, v_mode), - new ConditionalJmpDecoder("jae", ADDR_J, v_mode), - new ConditionalJmpDecoder("je", ADDR_J, v_mode), - new ConditionalJmpDecoder("jne", ADDR_J, v_mode), - new ConditionalJmpDecoder("jbe", ADDR_J, v_mode), - new ConditionalJmpDecoder("ja", ADDR_J, v_mode), - /* 88 */ - new ConditionalJmpDecoder("js", ADDR_J, v_mode), - new ConditionalJmpDecoder("jns", ADDR_J, v_mode), - new ConditionalJmpDecoder("jp", ADDR_J, v_mode), - new ConditionalJmpDecoder("jnp", ADDR_J, v_mode), - new ConditionalJmpDecoder("jl", ADDR_J, v_mode), - new ConditionalJmpDecoder("jge", ADDR_J, v_mode), - new ConditionalJmpDecoder("jle", ADDR_J, v_mode), - new ConditionalJmpDecoder("jg", ADDR_J, v_mode), - /* 90 */ - new InstructionDecoder("seto", ADDR_E, b_mode), - new InstructionDecoder("setno", ADDR_E, b_mode), - new InstructionDecoder("setb", ADDR_E, b_mode), - new InstructionDecoder("setae", ADDR_E, b_mode), - new InstructionDecoder("sete", ADDR_E, b_mode), - new InstructionDecoder("setne", ADDR_E, b_mode), - new InstructionDecoder("setbe", ADDR_E, b_mode), - new InstructionDecoder("seta", ADDR_E, b_mode), - /* 98 */ - new InstructionDecoder("sets", ADDR_E, b_mode), - new InstructionDecoder("setns", ADDR_E, b_mode), - new InstructionDecoder("setp", ADDR_E, b_mode), - new InstructionDecoder("setnp", ADDR_E, b_mode), - new InstructionDecoder("setl", ADDR_E, b_mode), - new InstructionDecoder("setge", ADDR_E, b_mode), - new InstructionDecoder("setle", ADDR_E, b_mode), - new InstructionDecoder("setg", ADDR_E, b_mode), - /* a0 */ - new InstructionDecoder("pushl", ADDR_REG, FS), - new InstructionDecoder("popl", ADDR_REG, FS), - new InstructionDecoder("cpuid"), - new InstructionDecoder("btS", ADDR_E, v_mode, ADDR_G, v_mode), - new InstructionDecoder("shldS", ADDR_E, v_mode, ADDR_G, v_mode, ADDR_I, b_mode), - new InstructionDecoder("shldS", ADDR_E, v_mode, ADDR_G, v_mode, ADDR_REG, CL), - null, - null, - /* a8 */ - new InstructionDecoder("pushl", ADDR_REG, GS), - new InstructionDecoder("popl", ADDR_REG, GS), - new SSEInstructionDecoder("rsm"), - new InstructionDecoder("btsS", ADDR_E, v_mode, ADDR_G, v_mode), - new InstructionDecoder("shrdS", ADDR_E, v_mode, ADDR_G, v_mode, ADDR_I, b_mode), - new InstructionDecoder("shrdS", ADDR_E, v_mode, ADDR_G, v_mode, ADDR_REG, CL), - new GRPDecoder(null, 20), - new ArithmeticDecoder("imulS", ADDR_G, v_mode, ADDR_E, v_mode, Operation.SMUL), - /* b0 */ - new InstructionDecoder("cmpxchgb", ADDR_E, b_mode, ADDR_G, b_mode), - new InstructionDecoder("cmpxchgS", ADDR_E, v_mode, ADDR_G, v_mode), - new InstructionDecoder("lssS", ADDR_G, v_mode, ADDR_M, p_mode), - new InstructionDecoder("btrS", ADDR_E, v_mode, ADDR_G, v_mode), - new InstructionDecoder("lfsS", ADDR_G, v_mode, ADDR_M, p_mode), - new InstructionDecoder("lgsS", ADDR_G, v_mode, ADDR_M, p_mode), - new MoveDecoder("movzbS", ADDR_G, v_mode, ADDR_E, b_mode), - new MoveDecoder("movzwS", ADDR_G, v_mode, ADDR_E, w_mode), - /* b8 */ - null, - null, - new GRPDecoder(null, 15), - new InstructionDecoder("btcS", ADDR_E, v_mode, ADDR_G, v_mode), - new InstructionDecoder("bsfS", ADDR_G, v_mode, ADDR_E, v_mode), - new InstructionDecoder("bsrS", ADDR_G, v_mode, ADDR_E, v_mode), - new MoveDecoder("movsbS", ADDR_G, v_mode, ADDR_E, b_mode), - new MoveDecoder("movswS", ADDR_G, v_mode, ADDR_E, w_mode), - /* c0 */ - new ArithmeticDecoder("xaddb", ADDR_E, b_mode, ADDR_G, b_mode, Operation.ADD), - new ArithmeticDecoder("xaddS", ADDR_E, v_mode, ADDR_G, v_mode, Operation.ADD), - new SSEInstructionDecoder("cmpps", ADDR_V, ps_mode, ADDR_W, ps_mode, ADDR_I, b_mode), - new SSEMoveDecoder("movnti", ADDR_E, d_mode, ADDR_G, d_mode), - new SSEInstructionDecoder("pinsrw", ADDR_P, q_mode, ADDR_E, d_mode, ADDR_I, b_mode), - new SSEInstructionDecoder("pextrw", ADDR_G, d_mode, ADDR_P, q_mode, ADDR_I, b_mode), - new SSEInstructionDecoder("shufps", ADDR_V, ps_mode, ADDR_W, ps_mode, ADDR_I, b_mode), - new GRPDecoder(null, 16), - /* c8 */ - new InstructionDecoder("bswap", ADDR_REG, EAX), - new InstructionDecoder("bswap", ADDR_REG, ECX), - new InstructionDecoder("bswap", ADDR_REG, EDX), - new InstructionDecoder("bswap", ADDR_REG, EBX), - new InstructionDecoder("bswap", ADDR_REG, ESP), - new InstructionDecoder("bswap", ADDR_REG, EBP), - new InstructionDecoder("bswap", ADDR_REG, ESI), - new InstructionDecoder("bswap", ADDR_REG, EDI), - /* d0 */ - null, - new SSEArithmeticDecoder("psrlw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SRL), - new SSEArithmeticDecoder("psrld", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SRL), - new SSEArithmeticDecoder("psrlq", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SRL), - new SSEArithmeticDecoder("paddq", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEArithmeticDecoder("pmullw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SMUL), - null, - new SSEMoveDecoder("pmovmskb", ADDR_G, d_mode, ADDR_P, q_mode), - /* d8 */ - new SSEArithmeticDecoder("psubusb", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEArithmeticDecoder("psubusw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEInstructionDecoder("pminub", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEArithmeticDecoder("pand", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.AND), - new SSEArithmeticDecoder("paddusb", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEArithmeticDecoder("paddusw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEInstructionDecoder("pmaxub", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEArithmeticDecoder("pandn", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.AND), - /* e0 */ - new SSEInstructionDecoder("pavgb", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("psraw", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("psrad", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEInstructionDecoder("pavgw", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEArithmeticDecoder("pmulhuw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.UMUL), - new SSEArithmeticDecoder("pmulhw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SMUL), - null, - new SSEMoveDecoder("movntq", ADDR_W, q_mode, ADDR_V, q_mode), - /* e8 */ - new SSEArithmeticDecoder("psubsb", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEArithmeticDecoder("psubsw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEInstructionDecoder("pminsw", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEArithmeticDecoder("por", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.OR), - new SSEArithmeticDecoder("paddsb", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEArithmeticDecoder("paddsw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEInstructionDecoder("pmaxsw", ADDR_P, q_mode, ADDR_Q, q_mode), - new SSEArithmeticDecoder("pxor", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.XOR), - /* f0 */ - null, - new SSEArithmeticDecoder("psllw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SLL), - new SSEArithmeticDecoder("pslld", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SLL), - new SSEArithmeticDecoder("psllq", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SLL), - new SSEArithmeticDecoder("pmuludq", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.UMUL), - new SSEArithmeticDecoder("pmaddwd", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEArithmeticDecoder("psadbw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEMoveDecoder("maskmoveq", ADDR_P, pi_mode, ADDR_Q, pi_mode), - /* f8 */ - new SSEArithmeticDecoder("psubb", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEArithmeticDecoder("psubw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEArithmeticDecoder("psubd", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEArithmeticDecoder("psubq", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.SUB), - new SSEArithmeticDecoder("paddb", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEArithmeticDecoder("paddw", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - new SSEArithmeticDecoder("paddd", ADDR_P, q_mode, ADDR_Q, q_mode, Operation.ADD), - null - }; - - private static final InstructionDecoder twoBytePrefixF2Table[] = { - /* 00 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 08 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 10 */ - new SSEMoveDecoder("movsd", ADDR_V, sd_mode, ADDR_W, sd_mode), - new SSEMoveDecoder("movsd", ADDR_V, sd_mode, ADDR_W, sd_mode), - null, - null, - null, - null, - null, - null, - /* 18 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 20 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 28 */ - null, - null, - new SSEInstructionDecoder("cvtsi2sd", ADDR_V, sd_mode, ADDR_E, d_mode), - null, - new SSEInstructionDecoder("cvttsd2si", ADDR_G, d_mode, ADDR_W, sd_mode), - new SSEInstructionDecoder("cvtsd2si", ADDR_G, d_mode, ADDR_W, sd_mode), - null, - null, - /* 30 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 38 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 40 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 48 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 50 */ - null, - new SSEInstructionDecoder("sqrtsd", ADDR_V, sd_mode, ADDR_W, sd_mode), - null, - null, - null, - null, - null, - null, - /* 58 */ - new SSEArithmeticDecoder("addsd", ADDR_V, sd_mode, ADDR_W, sd_mode, Operation.ADD), - new SSEArithmeticDecoder("mulsd", ADDR_V, sd_mode, ADDR_W, sd_mode, Operation.SMUL), - new SSEInstructionDecoder("cvtsd2ss", ADDR_V, sd_mode, ADDR_W, sd_mode), - null, - new SSEArithmeticDecoder("subsd", ADDR_V, sd_mode, ADDR_W, sd_mode, Operation.SUB), - new SSEInstructionDecoder("minsd", ADDR_V, sd_mode, ADDR_W, sd_mode), - new SSEArithmeticDecoder("divsd", ADDR_V, sd_mode, ADDR_W, sd_mode, Operation.SDIV), - new SSEInstructionDecoder("maxsd", ADDR_V, sd_mode, ADDR_W, sd_mode), - /* 60 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 68 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 70 */ - new SSEInstructionDecoder("pshuflw", ADDR_V, dq_mode, ADDR_W, dq_mode, ADDR_I, b_mode), - null, - null, - null, - null, - null, - null, - null, - /* 78 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 80 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 88 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 90 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 98 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* a0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* a8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* b0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* b8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* c0 */ - null, - null, - new SSEInstructionDecoder("cmpsd", ADDR_V, sd_mode, ADDR_W, sd_mode, ADDR_I, b_mode), - null, - null, - null, - null, - null, - /* c8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* d0 */ - null, - null, - null, - null, - null, - null, - new SSEMoveDecoder("movdq2q", ADDR_P, q_mode, ADDR_W, q_mode), - null, - /* d8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* e0 */ - null, - null, - null, - null, - null, - null, - new SSEInstructionDecoder("cvtpd2dq", ADDR_V, dq_mode, ADDR_W, pd_mode), - null, - /* e8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* f0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* f8 */ - null, - null, - null, - null, - null, - null, - null, - null - }; - - private static final InstructionDecoder twoBytePrefixF3Table[] = { - /* 00 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 08 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 10 */ - new SSEMoveDecoder("movss", ADDR_V, ss_mode, ADDR_W, ss_mode), - new SSEMoveDecoder("movss", ADDR_W, ss_mode, ADDR_V, ss_mode), - null, - null, - null, - null, - null, - null, - /* 18 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 20 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 28 */ - null, - null, - new SSEInstructionDecoder("cvtsi2ss", ADDR_V, ss_mode, ADDR_E, d_mode), - null, - new SSEInstructionDecoder("cvttss2si", ADDR_G, d_mode, ADDR_W, ss_mode), - new SSEInstructionDecoder("cvtss2si", ADDR_G, d_mode, ADDR_W, ss_mode), - null, - null, - /* 30 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 38 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 40 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 48 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 50 */ - null, - new SSEInstructionDecoder("sqrtss", ADDR_V, ss_mode, ADDR_W, ss_mode), - new SSEInstructionDecoder("rsqrtss", ADDR_V, ss_mode, ADDR_W, ss_mode), - new SSEInstructionDecoder("rcpss", ADDR_V, ss_mode, ADDR_W, ss_mode), - null, - null, - null, - null, - /* 58 */ - new SSEArithmeticDecoder("addss", ADDR_V, ss_mode, ADDR_W, ss_mode, Operation.ADD), - new SSEArithmeticDecoder("mulss", ADDR_V, ss_mode, ADDR_W, ss_mode, Operation.SMUL), - new SSEInstructionDecoder("cvtss2sd", ADDR_V, ss_mode, ADDR_W, ss_mode), - new SSEInstructionDecoder("cvttps2dq", ADDR_V, dq_mode, ADDR_W, ps_mode), - new SSEArithmeticDecoder("subss", ADDR_V, ss_mode, ADDR_W, ss_mode, Operation.SUB), - new SSEInstructionDecoder("minss", ADDR_V, ss_mode, ADDR_W, ss_mode), - new SSEArithmeticDecoder("divss", ADDR_V, ss_mode, ADDR_W, ss_mode, Operation.SDIV), - new SSEInstructionDecoder("maxss", ADDR_V, ss_mode, ADDR_W, ss_mode), - /* 60 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 68 */ - null, - null, - null, - null, - null, - null, - null, - new SSEMoveDecoder("movdqu", ADDR_V, dq_mode, ADDR_W, dq_mode), - /* 70 */ - new SSEInstructionDecoder("pshufhw", ADDR_V, dq_mode, ADDR_W, dq_mode, ADDR_I, b_mode), - null, - null, - null, - null, - null, - null, - null, - /* 78 */ - null, - null, - null, - null, - null, - null, - new SSEMoveDecoder("movq", ADDR_V, q_mode, ADDR_W, q_mode), - new SSEMoveDecoder("movdqu", ADDR_W, dq_mode, ADDR_V, dq_mode), - /* 80 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 88 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 90 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 98 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* a0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* a8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* b0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* b8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* c0 */ - null, - null, - new SSEInstructionDecoder("cmpss", ADDR_V, ss_mode, ADDR_W, ss_mode, ADDR_I, b_mode), - null, - null, - null, - null, - null, - /* c8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* d0 */ - null, - null, - null, - null, - null, - null, - new SSEMoveDecoder("movq2dq", ADDR_V, dq_mode, ADDR_Q, q_mode), - null, - /* d8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* e0 */ - null, - null, - null, - null, - null, - null, - new SSEInstructionDecoder("cvtdq2pd", ADDR_V, pd_mode, ADDR_W, dq_mode), - null, - /* e8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* f0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* f8 */ - null, - null, - null, - null, - null, - null, - null, - null - }; - - private static final InstructionDecoder twoBytePrefix66Table[] = { - /* 00 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 08 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 10 */ - new SSEMoveDecoder("movupd", ADDR_V, pd_mode, ADDR_W, pd_mode), - new SSEMoveDecoder("movupd", ADDR_W, pd_mode, ADDR_V, pd_mode), - new SSEMoveDecoder("movlpd", ADDR_W, q_mode, ADDR_V, q_mode), - new SSEMoveDecoder("movlpd", ADDR_V, q_mode, ADDR_W, q_mode), - new SSEInstructionDecoder("unpcklpd", ADDR_V, pd_mode, ADDR_W, q_mode), - new SSEInstructionDecoder("unpckhpd", ADDR_V, pd_mode, ADDR_W, q_mode), - new SSEMoveDecoder("movhpd", ADDR_V, q_mode, ADDR_W, q_mode), - new SSEMoveDecoder("movhpd", ADDR_W, q_mode, ADDR_V, q_mode), - /* 18 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 20 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 28 */ - new SSEMoveDecoder("movapd", ADDR_V, pd_mode, ADDR_W, pd_mode), - new SSEMoveDecoder("movapd", ADDR_W, pd_mode, ADDR_V, pd_mode), - new SSEInstructionDecoder("cvtpi2pd", ADDR_V, pd_mode, ADDR_Q, dq_mode), - new SSEMoveDecoder("movntpd", ADDR_W, pd_mode, ADDR_V, pd_mode), - new SSEInstructionDecoder("cvttpd2pi", ADDR_Q, dq_mode, ADDR_W, pd_mode), - new SSEInstructionDecoder("cvtpd2pi", ADDR_Q, dq_mode, ADDR_W, pd_mode), - new SSEInstructionDecoder("ucomisd", ADDR_V, sd_mode, ADDR_W, sd_mode), - new SSEInstructionDecoder("comisd", ADDR_V, sd_mode, ADDR_W, sd_mode), - /* 30 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 38 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 40 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 48 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 50 */ - new SSEMoveDecoder("movmskpd", ADDR_E, d_mode, ADDR_V, pd_mode), - new SSEInstructionDecoder("sqrtpd", ADDR_V, pd_mode, ADDR_W, pd_mode), - null, - null, - new SSEArithmeticDecoder("andpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.AND), - new SSEArithmeticDecoder("andnpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.AND), - new SSEArithmeticDecoder("orpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.OR), - new SSEArithmeticDecoder("xorpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.XOR), - /* 58 */ - new SSEArithmeticDecoder("addpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.ADD), - new SSEArithmeticDecoder("mulpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.SMUL), - new SSEInstructionDecoder("cvtpd2ps", ADDR_V, ps_mode, ADDR_W, pd_mode), - new SSEInstructionDecoder("cvtps2dq", ADDR_V, dq_mode, ADDR_W, ps_mode), - new SSEArithmeticDecoder("subpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.SUB), - new SSEInstructionDecoder("minpd", ADDR_V, pd_mode, ADDR_W, pd_mode), - new SSEArithmeticDecoder("divpd", ADDR_V, pd_mode, ADDR_W, pd_mode, Operation.SDIV), - new SSEInstructionDecoder("maxpd", ADDR_V, pd_mode, ADDR_W, pd_mode), - /* 60 */ - new SSEInstructionDecoder("punpcklbw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("punpcklwd", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("punpckldq", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("packsswb", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("pcmpgtb", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("pcmpgtw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("pcmpgtd", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("packuswb", ADDR_V, dq_mode, ADDR_W, dq_mode), - /* 68 */ - new SSEInstructionDecoder("punpckhbw", ADDR_P, dq_mode, ADDR_Q, dq_mode), - new SSEInstructionDecoder("punpckhwd", ADDR_P, dq_mode, ADDR_Q, dq_mode), - new SSEInstructionDecoder("punpckhdq", ADDR_P, dq_mode, ADDR_Q, dq_mode), - new SSEInstructionDecoder("packssdw", ADDR_P, dq_mode, ADDR_Q, dq_mode), - new SSEInstructionDecoder("punpcklqdq", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("punpckhqdq", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEMoveDecoder("movd", ADDR_V, dq_mode, ADDR_E, d_mode), - new SSEMoveDecoder("movdqa", ADDR_V, dq_mode, ADDR_W, dq_mode), - /* 70 */ - new SSEInstructionDecoder("pshufd", ADDR_V, dq_mode, ADDR_W, dq_mode, ADDR_I, b_mode), - new GRPDecoder(null, 22), - new GRPDecoder(null, 23), - new GRPDecoder(null, 24), - new SSEInstructionDecoder("pcmpeqb", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("pcmpeqw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("pcmpeqd", ADDR_V, dq_mode, ADDR_W, dq_mode), - null, - /* 78 */ - null, - null, - null, - null, - null, - null, - new SSEMoveDecoder("movd", ADDR_E, d_mode, ADDR_V, dq_mode), - new SSEMoveDecoder("movdqa", ADDR_W, dq_mode, ADDR_V, dq_mode), - /* 80 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 88 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 90 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* 98 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* a0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* a8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* b0 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* b8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* c0 */ - null, - null, - new SSEInstructionDecoder("cmppd", ADDR_V, pd_mode, ADDR_W, pd_mode, ADDR_I, b_mode), - null, - new SSEInstructionDecoder("pinsrw", ADDR_V, dq_mode, ADDR_E, d_mode, ADDR_I, b_mode), - new SSEInstructionDecoder("pextrw", ADDR_G, d_mode, ADDR_V, dq_mode, ADDR_I, b_mode), - new SSEInstructionDecoder("shufpd", ADDR_V, pd_mode, ADDR_W, pd_mode, ADDR_I, b_mode), - null, - /* c8 */ - null, - null, - null, - null, - null, - null, - null, - null, - /* d0 */ - null, - new SSEArithmeticDecoder("psrlw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SRL), - new SSEArithmeticDecoder("psrld", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SRL), - new SSEArithmeticDecoder("psrlq", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SRL), - new SSEArithmeticDecoder("paddq", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEArithmeticDecoder("pmullw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SMUL), - new SSEMoveDecoder("movq", ADDR_W, q_mode, ADDR_V, q_mode), - new SSEMoveDecoder("pmovmskb", ADDR_G, d_mode, ADDR_V, dq_mode), - /* d8 */ - new SSEArithmeticDecoder("psubusb", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEArithmeticDecoder("psubusw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEInstructionDecoder("pminub", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEArithmeticDecoder("pand", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.AND), - new SSEArithmeticDecoder("paddusb", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEArithmeticDecoder("paddusw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEInstructionDecoder("pmaxub", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEArithmeticDecoder("pandn", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.AND), - /* e0 */ - new SSEInstructionDecoder("pavgb", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("psraw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("psrad", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEInstructionDecoder("pavgw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEArithmeticDecoder("pmulhuw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.UMUL), - new SSEArithmeticDecoder("pmulhw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SMUL), - new SSEInstructionDecoder("cvttpd2dq", ADDR_V, dq_mode, ADDR_W, pd_mode), - new SSEMoveDecoder("movntdq", ADDR_W, dq_mode, ADDR_V, dq_mode), - /* e8 */ - new SSEArithmeticDecoder("psubusb", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEArithmeticDecoder("psubusw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEInstructionDecoder("pminsw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEArithmeticDecoder("por", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.OR), - new SSEArithmeticDecoder("paddsb", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEArithmeticDecoder("paddsw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEInstructionDecoder("pmaxsw", ADDR_V, dq_mode, ADDR_W, dq_mode), - new SSEArithmeticDecoder("pxor", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.XOR), - /* f0 */ - null, - new SSEArithmeticDecoder("psllw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SLL), - new SSEArithmeticDecoder("pslld", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SLL), - new SSEArithmeticDecoder("psllq", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SLL), - new SSEArithmeticDecoder("pmuludq", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.UMUL), - new SSEArithmeticDecoder("pmaddwd", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEArithmeticDecoder("psadbw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEMoveDecoder("maskmovdqu", ADDR_V, dq_mode, ADDR_W, dq_mode), - /* f8 */ - new SSEArithmeticDecoder("psubb", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEArithmeticDecoder("psubw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEArithmeticDecoder("psubd", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEArithmeticDecoder("psubq", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.SUB), - new SSEArithmeticDecoder("paddb", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEArithmeticDecoder("paddw", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - new SSEArithmeticDecoder("paddd", ADDR_V, dq_mode, ADDR_W, dq_mode, Operation.ADD), - null - }; + default: + isPrefix = false; + } + if (isPrefix) + byteIndex++; + } + return prefixes; + } } diff --git a/src/org/jakstab/loader/elf/ELFModule.java b/src/org/jakstab/loader/elf/ELFModule.java index 255e481..3ff21cb 100644 --- a/src/org/jakstab/loader/elf/ELFModule.java +++ b/src/org/jakstab/loader/elf/ELFModule.java @@ -119,11 +119,11 @@ public ELFModule(File moduleFile, Architecture architecture) throws IOException, X86Disassembler disasm = new X86Disassembler(inBuf); // push GOT + 4 - Instruction instr = disasm.decodeInstruction(pltIdx); + Instruction instr = disasm.decodeInstruction(pltIdx, pltStart);//TODO-Dom update these to parse the current address when ELF loader is working (probably use pltStart)-Done but untested assert instr.getName().equals("pushl"); pltIdx += instr.getSize(); // jmp *(GOT + 8) - instr = disasm.decodeInstruction(pltIdx); + instr = disasm.decodeInstruction(pltIdx, pltStart); assert instr instanceof X86JmpInstruction; pltIdx += instr.getSize(); @@ -131,7 +131,7 @@ public ELFModule(File moduleFile, Architecture architecture) throws IOException, if (data[pltIdx] == 0) { pltIdx++; } else { - instr = disasm.decodeInstruction(pltIdx); + instr = disasm.decodeInstruction(pltIdx, pltStart); pltIdx += instr.getSize(); if (!instr.getName().equals("nop")) break; } @@ -151,7 +151,7 @@ public ELFModule(File moduleFile, Architecture architecture) throws IOException, //logger.debug("Trampoline destination is " + trampolineDest); pltIdx = (int)getFilePointer(trampolineDest); // Read the push instruction - instr = disasm.decodeInstruction(pltIdx); + instr = disasm.decodeInstruction(pltIdx,pltStart); X86Instruction pushSTOff = (X86Instruction)instr; // The push instruction's parameter is an index into the symbol table int symbolTableOff = ((Immediate)pushSTOff.getOperand1()).getNumber().intValue(); @@ -177,7 +177,7 @@ public ELFModule(File moduleFile, Architecture architecture) throws IOException, symbolMap.put(pltSlot, "__imp_" + functionName); // Now skip the following jump to PLT0 (a call to the dynamic loader) pltIdx += instr.getSize(); - instr = disasm.decodeInstruction(pltIdx); + instr = disasm.decodeInstruction(pltIdx, pltStart); assert instr instanceof X86JmpInstruction : "Expected jmp to PLT[0] in PLT at this offset!"; pltIdx += instr.getSize(); // And now pltIdx points to the next PLT entry @@ -186,7 +186,7 @@ public ELFModule(File moduleFile, Architecture architecture) throws IOException, if (data[pltIdx] == 0) { break; } - instr = disasm.decodeInstruction(pltIdx); + instr = disasm.decodeInstruction(pltIdx, pltStart); if (!(instr instanceof X86JmpInstruction)) { break; } diff --git a/src/org/jakstab/ssl/Architecture.java b/src/org/jakstab/ssl/Architecture.java index 2361ee8..3d4cc88 100644 --- a/src/org/jakstab/ssl/Architecture.java +++ b/src/org/jakstab/ssl/Architecture.java @@ -20,6 +20,8 @@ import java.io.*; import java.util.*; +import capstone.X86; +import capstone.X86_const; import org.jakstab.Options; import org.jakstab.util.Logger; import org.jakstab.asm.*; @@ -289,17 +291,18 @@ else if (x86instr.hasPrefixREPZ() || x86instr.hasPrefixREPNZ()) { Operand oper = instr.getOperand(i); // Special handling for implicit operands - if (oper instanceof Register && ( - (oper.equals(X86Registers.EAX) && proto.getName().endsWith("EAX")) || + //((X86Register)oper).toString().equals("EAX"); + if (oper instanceof X86Register && (//Dom-Replaced this code with .Equals(X86Registers.register) instead of comparing strings. May break. + (oper.equals(X86Registers.EAX) && proto.getName().endsWith("EAX"))|| (oper.equals(X86Registers.AX) && proto.getName().endsWith("AX")) || (oper.equals(X86Registers.AL) && proto.getName().endsWith("AL")) || - (oper.equals(X86SegmentRegisters.CS) && proto.getName().endsWith("CS")) || + (oper.equals(X86SegmentRegisters.CS)&& proto.getName().endsWith("CS")) || (oper.equals(X86SegmentRegisters.DS) && proto.getName().endsWith("DS")) || (oper.equals(X86SegmentRegisters.ES) && proto.getName().endsWith("ES")) || (oper.equals(X86SegmentRegisters.FS) && proto.getName().endsWith("FS")) || - (oper.equals(X86SegmentRegisters.GS) && proto.getName().endsWith("GS")) || - (oper.equals(X86SegmentRegisters.SS) && proto.getName().endsWith("SS")) - + (oper.equals(X86SegmentRegisters.GS)&& proto.getName().endsWith("GS")) || + (oper.equals(X86SegmentRegisters.SS)&& proto.getName().endsWith("SS")) + )) { score += IMPLICIT_OPERAND_MATCH_SCORE; if (instr.getOperandCount() == proto.getParameterCount() + 1) { diff --git a/ssl/pentium.ssl b/ssl/pentium.ssl index 3bc55da..406e2f3 100644 --- a/ssl/pentium.ssl +++ b/ssl/pentium.ssl @@ -704,7 +704,7 @@ BTSL.OD modrm, reg32 *1* %CF := modrm@[reg32:reg32] *32* modrm := modrm | tmp1; -CALL.JVOW reloc16 +CALLL.JVOW reloc16 *32* %esp := %esp - 2 *16* m[%esp] := %pc@[0:15] #--JK *32* %pc := %pc + 3 + reloc16; @@ -722,7 +722,7 @@ CALL.JVOW reloc16 # *destination*, not the offset (the offset is not avialable to the SSL, nor # is the "delta" required to convert from host to native. # Corrected in the matcher file -CALL.JVOD reloc32 +CALLL.JVOD reloc32 *32* %esp := %esp - 4 *32* m[%esp] := %pc #--JK *32* %pc := %pc + 5 + reloc32; @@ -742,7 +742,7 @@ CALL.JVOD reloc32 # Careful: A "call [esp + x]" instruction reads the operand first before modifying esp # So, with modrm operands, modify esp last -CALL.EVOD modrm +CALLL.EVOD modrm *32* tmp1 := modrm *32* %esp := %esp - 4 *32* m[%esp] := %pc @@ -1050,15 +1050,15 @@ JMP.JB reloc8 *32* %pc := %pc + reloc8; #--JK *32* %pc := %pc + 2 + reloc8; -JMP.JVOW reloc16 +JMP.JVOW reloc16 *32* %pc := %pc + reloc16; #--JK *32* %pc := %pc + 3 + reloc16; -JMP.JVOD reloc32 +JMPL.JVOD reloc32 *32* %pc := %pc + reloc32; #--JK *32* %pc := %pc + 5 + reloc32; -JMP.EVOD modrm +JMPL.EVOD modrm *32* %pc := modrm; #LJMP seg, off @@ -1093,7 +1093,7 @@ MOVB.EB.IB modrm, i8 MOVW.EW.IVOW modrm, i16 *16* modrm := i16; -MOVL.ED.IVOD modrm, i32 +MOVL.ED.IVOD modrm, i32 *32* modrm := i32; MOVB.IB reg8, i8 @@ -1425,7 +1425,7 @@ ROTL[IDX].B.EV.IBOD modrm, i8 ROLSL[IDX].B.EV.IBOD modrm, i8 ROLFLAGS32(tmp2, tmp1, i8); RORSL[IDX].B.EV.IBOD modrm, i8 RORFLAGS32(tmp2, tmp1, i8); -RET +RETL *32* retaddr := m[%esp]{32} *32* %esp := %esp + 4 *32* %pc := retaddr; @@ -1434,7 +1434,7 @@ RET # we now use tmp1 to allow forgetting the stack below esp -RET.IW i16 +RETL.IW i16 *32* retaddr := m[%esp]{32} *32* %esp := %esp + 4 + zfill(16,31,i16) *32* %pc := retaddr;