diff --git a/.gitattributes b/.gitattributes index 97e7454d79d3299ea173a0b8920ba65e09f5269d..7105d2cec1eaaeb5b846f00df09e6ca60374d5d9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -80,6 +80,8 @@ src/interfaces/idapro/STARSInterface.cpp -text src/interfaces/irdb/Makefile.in -text src/interfaces/irdb/STARSFunction.cpp -text src/interfaces/irdb/STARSIRDBProgram.cpp -text +src/interfaces/irdb/STARSInterface.cpp -text +src/interfaces/irdb/STARSOp.cpp -text src/interfaces/irdb/STARS_IRDB_Instruction.cpp -text tests/commit/busybox.psexe -text tests/commit/bzip2.psexe -text diff --git a/src/interfaces/irdb/STARSInterface.cpp b/src/interfaces/irdb/STARSInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1252e5415b8fea69bcd1ff900133764b1ae97c6b --- /dev/null +++ b/src/interfaces/irdb/STARSInterface.cpp @@ -0,0 +1,77 @@ + + +#include "interfaces/abstract/STARSInterface.h" +#include "interfaces/irdb/STARSSegment.h" +#include "interfaces/irdb/STARSFunction.h" +#include "interfaces/irdb/STARSInstruction.h" +#include "interfaces/irdb/STARSSSAInstruction.h" +#include "interfaces/irdb/STARSFunction.h" +#include <elfio/elfio.hpp> +#include <elfio/elfio_dump.hpp> + +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include <pqxx/pqxx> + + + +STARS_Instruction_t * STARS_IRDB_Interface_t::CreateInst(STARS_InstructionID_t InstID) +{ + // check for psuedo-instructions + if(STARS_IsSSAMarkerPseudoID(InstID.GetIDWithinFile())) + return new STARS_IRDB_Instruction_t(InstID); + // already created, just return what we need. + STARS_Instruction_t* insn=(STARS_Instruction_t*)InstID.GetInstruction(); + assert(insn); + return insn; +}; + + +bool STARS_IRDB_Interface_t::STARS_generate_disasm_line(STARS_ea_t addr, char *buf, std::size_t bufsize, int flags) +{ + STARS_InstructionID_t id(addr); + const STARS_Instruction_t* insn=id.GetInstruction(); + const STARS_IRDB_Instruction_t* irdb_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(insn); + strncpy(buf,irdb_insn->GetIRDBInstruction()->getDisassembly().c_str(), bufsize); + return true; +} + + +bool STARS_IRDB_Interface_t::IsInstJumpTarget(STARS_InstructionID_t InstID) const +{ + const STARS_IRDB_Instruction_t* interface_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(InstID.GetInstruction()); + assert(interface_insn); + libIRDB::Instruction_t* insn=(libIRDB::Instruction_t*)interface_insn->GetIRDBInstruction(); + + // return true if + // jumped to indirectly (jmp instruction) + // called indirectly (call instruction) + if(insn->GetIndirectBranchTargetAddress() != NULL) + return true; + + // jumped to directly (jmp or jcc instruction) + // called directly (call instruction) + + for(libIRDB::InstructionSet_t::iterator it=instruction_preds[insn].begin(); + it!=instruction_preds[insn].end(); ++it) + { + if(insn->GetTarget()==insn) + return true; + } + + return false; + + + // jumped to via a return doesn't count. + // be careful and think about this as you impl it. + // not sure how to do this, because we don't know if a return will go there. + // typically what is meant by a "return goes there" is that a call + // instruction preceeds it. Since call instructions don't (typically) mark + // the return point as an IBT, we should be OK. + + // aka -- not (is only-fallthroughed to) + assert(0); return 0; +} diff --git a/src/interfaces/irdb/STARSOp.cpp b/src/interfaces/irdb/STARSOp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..52117ab2cede671c41a1312ac6d28262e1d29cf8 --- /dev/null +++ b/src/interfaces/irdb/STARSOp.cpp @@ -0,0 +1,248 @@ + +#include "interfaces/irdb/STARSOp.h" +#include <libIRDB-core.hpp> + + +using namespace std; + +static int log2int(int index) +{ + int targetlevel = 0; + while (index >>= 1) ++targetlevel; + return targetlevel; +} + + + +STARS_IRDB_op_t::STARS_IRDB_op_t(const DISASM &d, int indx, const ARGTYPE &the_arg) +{ + Init(); // make void + int bea_regno=log2int(the_arg.ArgType&0xFFFF); + visible=1; + switch((the_arg.ArgType&0xFFFF0000)) + { + case NO_ARGUMENT: + /* leave as void */ + break; + case REGISTER_TYPE + GENERAL_REG : + { + OpType=op_Reg; + + if(string(the_arg.ArgMnemonic)=="al") { operand.reg.RegNum=STARS_x86_R_al; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="cl") { operand.reg.RegNum=STARS_x86_R_cl; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="dl") { operand.reg.RegNum=STARS_x86_R_dl; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="bl") { operand.reg.RegNum=STARS_x86_R_bl; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="ah") { operand.reg.RegNum=STARS_x86_R_ah; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="ch") { operand.reg.RegNum=STARS_x86_R_ch; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="dh") { operand.reg.RegNum=STARS_x86_R_dh; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="bh") { operand.reg.RegNum=STARS_x86_R_bh; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="spl") { operand.reg.RegNum=STARS_x86_R_spl; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="spl") { operand.reg.RegNum=STARS_x86_R_spl; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="bpl") { operand.reg.RegNum=STARS_x86_R_bpl; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="sil") { operand.reg.RegNum=STARS_x86_R_sil; byteWidth=1; } + else if(string(the_arg.ArgMnemonic)=="dil") { operand.reg.RegNum=STARS_x86_R_dil; byteWidth=1; } + else + { + // set the operand.reg.RegNum appropriately. + operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_ax+bea_regno); + + // if the first character is an r, it's a 64-bit reg. + // e.g. rax, rsp, rdi + if(the_arg.ArgMnemonic[0]=='r') + byteWidth=8; + + // otherwise, if the first character is an e, and the 3rd char is an 'x', 'p', or 'i' it's a 32-bit reg. + // e.g., eax, esp, edi + // caution: es + else if(the_arg.ArgMnemonic[0]=='e' && (the_arg.ArgMnemonic[2]=='x' || the_arg.ArgMnemonic[2]=='i' || the_arg.ArgMnemonic[2]=='p')) + byteWidth=4; + // e.g ax, sp, bp, di + else if(the_arg.ArgMnemonic[1]=='x' || the_arg.ArgMnemonic[1]=='i' || the_arg.ArgMnemonic[1]=='p') + byteWidth=2; + else + byteWidth=1; + } + break; + } + case REGISTER_TYPE + MMX_REG : + byteWidth=8; + OpType=op_MMXReg; + operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_mm0+bea_regno); + break; + case REGISTER_TYPE + FPU_REG : + byteWidth=8; + OpType=op_MMXReg; + operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_st0+bea_regno); + break; + case REGISTER_TYPE + SSE_REG : + if(the_arg.ArgMnemonic[0]=='x') + { + byteWidth=8; + OpType=op_XMMReg; + operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_xmm0+bea_regno); + break; + } + else if(the_arg.ArgMnemonic[0]=='y') + { + byteWidth=16; + OpType=op_YMMReg; + operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_ymm0+bea_regno); + break; + } + else + assert(0); + case REGISTER_TYPE + CR_REG : + assert(0); +/* +no stars type for control regs? + OpType=CrReg; + operand.reg.RegNum=STARS_x86_R_cr0+bea_regno; +*/ + break; + case REGISTER_TYPE + DR_REG : + assert(0); +/* +no stars type for debug regs? + OpType=op_CrReg; + operand.reg.RegNum=STARS_x86_R_cr0+bea_regno; +*/ + break; + case REGISTER_TYPE + SPECIAL_REG : + { + assert(0); +/* + +this isn't even close to right. should be gdtr, ldtr, idtr, tr, etc. +no operands for eflags or mxcsr? + switch(bea_regno) + { + case EFLAGS: + OpType=op_Eflags; + operand.reg.RegNum=0; + break; + case MXCSR: + OpType=op_Mxcsr; + operand.reg.RegNum=0; + break; + break; + assert(0); + } + break; +*/ + } + case REGISTER_TYPE + MEMORY_MANAGEMENT_REG : + assert(0); + break; + case REGISTER_TYPE + SEGMENT_REG : + OpType=op_SegReg; + operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_es+bea_regno); + break; + case MEMORY_TYPE: + case MEMORY_TYPE + RELATIVE_: + case MEMORY_TYPE + ABSOLUTE_: + { + operand.mem.base=(STARS_RegNo)the_arg.Memory.BaseRegister; + operand.mem.index=(STARS_RegNo)the_arg.Memory.IndexRegister; + operand.mem.scale=(STARS_RegNo)the_arg.Memory.Scale; + operand.mem.disp=(STARS_RegNo)the_arg.Memory.Displacement; + byteWidth=the_arg.ArgSize; + OpType=op_Mem; + break; + } + case CONSTANT_TYPE + RELATIVE_ : + OpType=op_Imm; + operand.imm.imm=d.Instruction.Immediat; + operand.imm.pc_rel=true; + byteWidth=the_arg.ArgSize; + break; + case CONSTANT_TYPE + ABSOLUTE_ : + OpType=op_Imm; + operand.imm.imm=d.Instruction.Immediat; + operand.imm.pc_rel=false; + byteWidth=the_arg.ArgSize; + break; + default: + assert(0); + } + + + // deal with segment register + switch(the_arg.SegmentReg) + { + case 0: // bea reporting 0 means no register. + SegReg=STARS_x86_R_none; // map to no reg. + case ESReg: // bea seg reg ESReg maps to + SegReg=STARS_x86_R_es; // STARS_x86_R_es reg. + break; + case CSReg: // etc. + SegReg=STARS_x86_R_cs; + break; + case SSReg: + SegReg=STARS_x86_R_ss; + break; + case DSReg: + SegReg=STARS_x86_R_ds; + break; + case FSReg: + SegReg=STARS_x86_R_fs; + break; + case GSReg: + SegReg=STARS_x86_R_gs; + break; + default: + assert(0); + + } + + + + + +} + +bool STARS_IRDB_op_t::operator<(const STARS_op_t &rOp_param) const +{ + const STARS_IRDB_op_t* p=dynamic_cast<const STARS_IRDB_op_t*>(&rOp_param); + assert(p); + const STARS_IRDB_op_t& rOp=*p; + + if(GetOpType() != rOp.GetOpType()) + return GetOpType() < rOp.GetOpType(); + + switch(GetOpType()) + { + case op_Mem: + if ( operand.mem.base != rOp.operand.mem.base) + return ( operand.mem.base < rOp.operand.mem.base); + if ( operand.mem.index != rOp.operand.mem.index) + return ( operand.mem.index < rOp.operand.mem.index); + if ( operand.mem.scale != rOp.operand.mem.scale) + return ( operand.mem.scale < rOp.operand.mem.scale); + if ( operand.mem.disp != rOp.operand.mem.disp) + return ( operand.mem.disp < rOp.operand.mem.disp); + return false; // equal + case op_Imm: + return operand.imm.imm < rOp.operand.imm.imm; + case op_CrReg: + case op_DrReg: + case op_Eflags: + case op_MMXReg: + case op_XMMReg: + case op_YMMReg: + case op_FPReg: + case op_Reg: + return operand.reg.RegNum < rOp.operand.reg.RegNum; + + case op_Void: + case op_Mxcsr: + case op_SegReg: + return true; + + case op_Addr: + return operand.addr.addr < rOp.operand.addr.addr; + + default: + assert(0); + + } +}