#ifndef SMPINSTR_H #define SMPINSTR_H 1 // SMPInstr.h // // This header defines the interfaces needed for analyzing instructions. #include <cstddef> #include <pro.h> #include <ida.hpp> #include <ua.hpp> #include "SMPDataFlowAnalysis.h" using namespace std; class SMPInstr { public: // Constructors SMPInstr(ea_t addr); // Operators int operator==(const SMPInstr &rhs) const; int operator<(const SMPInstr &rhs) const; int operator<=(const SMPInstr &rhs) const; int operator!=(const SMPInstr &rhs) const; // Get methods inline ea_t GetAddr(void) const { return address; }; inline char *GetDisasm(void) const { return (char *) disasm; }; inline DefOrUse GetUse(size_t index) const { return Uses.GetRef(index); }; inline DefOrUse GetDef(size_t index) const { return Defs.GetRef(index); }; inline size_t NumUses(void) const { return Uses.GetSize(); }; inline size_t NumDefs(void) const { return Defs.GetSize(); }; inline insn_t GetCmd(void) const { return SMPcmd; }; inline int GetOptType(void) const { return OptType; }; inline SMPitype GetDataFlowType(void) const { return type; }; // Set methods inline void SetCmd(insn_t cmd) { SMPcmd = cmd; return; }; inline void SetTerminatesBlock(void) { BlockTerm = true; }; inline void SetUseSSA(size_t index, int SSASub) { Uses.SetSSANum(index, SSASub); return; }; inline void SetDefSSA(size_t index, int SSASub) { Defs.SetSSANum(index, SSASub); return; }; inline void SetDeadRegs(char RegsString[]) { qstrncpy(DeadRegsString, RegsString, MAXSTR - 1); return; }; // Query methods bool HasDestMemoryOperand(void) const; // Does instruction write to memory? bool HasSourceMemoryOperand(void) const; // Does instruction read from memory? bool IsSecondSrcOperandNumeric(flags_t F) const; bool IsBasicBlockTerminator(void) const; // kind of inst that always terminates a block inline bool IsLastInBlock(void) const { return BlockTerm; }; inline bool IsJumpTarget(void) const { return JumpTarget; }; bool IsBranchToFarChunk(void) const; // instr jumps outside current chunk bool MDIsNop(void) const; // instruction is simple or complex no-op bool MDIsPushInstr(void) const; bool MDIsPopInstr(void) const; bool MDIsReturnInstr(void) const; bool MDIsEnterInstr(void) const; bool MDIsLeaveInstr(void) const; bool MDIsStackPointerCopy(bool UseFP) const; // copies ESP or EBP to register bool MDIsFrameAllocInstr(void) const; bool MDIsFrameDeallocInstr(bool UseFP, asize_t LocSize) const; bool MDUsesCalleeSavedReg(void) const; inline bool HasFlagsDef(void) const { return DefsFlags; }; inline bool HasFlagsUse(void) const { return UsesFlags; }; // Printing methods void PrintOperands(void) const; char *DestString(int OptType); void Dump(void) const; // Complete debug print, with DEF/USE list, SSA #s // Analysis methods void Analyze(void); // Fill in basic data for instruction. void AnnotateStackConstants(bool UseFP, FILE *AnnotFile); void EmitAnnotations(bool UseFP, bool AllocSeen, FILE *AnnotFile); private: // Data insn_t SMPcmd; // copy of 'cmd' for this instruction ulong features; // Canonical features for SMPcmd char disasm[MAXSTR]; // Disassembly text of instruction DefOrUseList Defs; // Definitions list DefOrUseList Uses; // Uses list SMPitype type; // Data flow analysis category int OptType; // Optimization category (see OptCategory[]) ea_t address; // Code address for 1st byte of instruction bool analyzed; // Has instr been analyzed yet, setting type // and DEF and USE lists? bool JumpTarget; // Is Instr the target of any jumps or branches? bool BlockTerm; // This instruction terminates a basic block. char DeadRegsString[MAXSTR]; // Registers that are dead at this instruction bool DefsFlags; // Instr DEFs the flags bool UsesFlags; // Instr USEs the flags // Methods void BuildSMPDefUseLists(void); // Build DEF and USE lists for instruction void MDFixupDefUseLists(void); // Machine-dependent ad hoc fixes void MDAddRegDef(ushort, bool); // Add DEF of register if not already a DEF void MDAddRegUse(ushort, bool); // Add USE of register if not already a USE void MDAnnotateSIBStackConstants(FILE *, op_t, ea_t, bool); // Handle x86 opcode SIB byte void MDAnalyzeDefType(void); // Set types of DEFs if possible void MDAnalyzeUseType(void); // Set types of USEs if possible }; // end class SMPInstr #endif