Newer
Older
#ifndef STARS_IDA_Instruction_h
#define STARS_IDA_Instruction_h
#include <memory>
#include <vector>
#include <cstddef>
#include <cstdint>
#include <pro.h>
#include <ua.hpp>
#include <intel.hpp>
#include "interfaces/STARSTypes.h"
#include "interfaces/SMPDBInterface.h"
#include "interfaces/abstract/STARSInstruction.h"
#include "interfaces/abstract/STARSInstructionID.h"
// struct to hold items that mimic the IDA Pro type insn_t.
struct STARS_IDA_insn_t
{
#if 0 // duplicate info
// Current segment base paragraph. Initialized by the kernel.
STARS_ea_t cs; // segment base (in paragraphs)
// Virtual address of the instruction (address within the segment)
// Initialized by the kernel.
STARS_ea_t ip; // offset in the segment
// Linear address of the instruction.
// Initialized by the kernel.
STARS_ea_t ea; // instruction start addresses
#endif
// Internal code of instruction. IDP should define its own instruction
// codes. These codes are usually defined in ins.hpp. The array of instruction
// names and features (ins.cpp) is accessed using this code.
uint16_t itype; // instruction code (see ins.hpp)
// only for canonical insns (not user defined!):
// Size of instruction in bytes.
// The analyzer should put here the actual size of the instruction.
uint16_t size; // instruction size in bytes
// Additional information about the instruction.
// Definitions are processor-dependent.
union
{
uint16_t auxpref; // processor dependent field
struct
{
uchar low;
uchar high;
} auxpref_chars;
};
char segpref; // processor dependent field
char insnpref; // processor dependent field
// Information about instruction operands.
std::vector<STARSOpndTypePtr> Operands;
char flags; // instruction flags
}; // end of struct STARS_IDA_insn_t
class STARS_IDA_Instruction_t : public STARS_Instruction_t
{
public:
// Constructors and destructors
STARS_IDA_Instruction_t(const STARS_InstructionID_t& p_id) : STARSCmd({}), STARS_Instruction_t(p_id), ImplicitDEFs(false) {
if (STARS_IsSSAMarkerPseudoID(p_id.GetIDWithinFile())) { // SSA marker pseudo-inst
STARScmd.itype = NN_fnop;
STARScmd.size = 1;
}
};
// Data initialization methods
bool STARS_GetCmd(void);
// Get (accessor) methods
inline uint16_t GetSize(void) const { return STARScmd.size; }; // Size of instruction in bytes
inline uint16_t GetIDAOpcode(void) { return STARScmd.itype; };
STARS_InstructionID_t GetNextInstructionID(void) const;
STARS_InstructionID_t GetTargetInstructionID(void) const;
uint32_t GetInstFeatures(void) const { return STARSfeatures; };
STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const {
assert(OpndNum < STARScmd.Operands.size());
return STARScmd.Operands.at(OpndNum);
};
// Set (mutator) methods
void SetOpUsed(std::size_t OpndNum); // set the USE bit
void SetOpNotUsed(std::size_t OpndNum); // reset the USE bit
void SetOpDefed(std::size_t OpndNum); // set the DEF bit
void SetOpNotDefed(std::size_t OpndNum); // reset the DEF bit
void RemoveIDAOp1ForIMUL(void); // Fix up IDA Pro IMUL instruction by removing operand 1
// Query methods
inline bool HasRepeatIfEqualPrefix(void) const { return (0 != (STARScmd.auxpref & aux_rep)); };
inline bool HasRepeatIfNotEqualPrefix(void) const { return (0 != (STARScmd.auxpref & aux_repne)); };
inline bool HasAnyRepeatPrefix(void) const { return (0 != (STARScmd.auxpref & (aux_rep | aux_repne))); };
inline bool Uses64BitAddressing(void) const {
#ifdef __EA64__
return ((STARScmd.auxpref & (aux_use32 | aux_use64 | aux_natad)) == (aux_natad | aux_use64));
#else
return false;
#endif
};
bool Uses32BitAddressing(void) const;
inline bool IsRegOpnd(std::size_t OpndNum) const { return (STARScmd.Operands.at(OpndNum)->IsRegOp()); };
inline bool IsImmedOpnd(std::size_t OpndNum) const { return (STARScmd.Operands.at(OpndNum)->IsImmedOp()); };
inline bool RegOpndMatches(std::size_t OpndNum, STARS_regnum_t RegNum) const { return STARScmd.Operands.at(OpndNum)->MatchesReg(RegNum); };
clc5q
committed
inline bool HasImplicitlyModifiedRegs(void) const { return ImplicitDEFs; };
bool IsUseOpnd(std::size_t OpndNum) const;
bool IsDefOpnd(std::size_t OpndNum) const;
bool IsBranchToFarChunk(SMPInstr *CurrInst, STARS_ea_t &TargetAddr);
// Operand creation methods
STARSOpndTypePtr MakeVoidOpnd(void) const ;
STARSOpndTypePtr MakeImmediateOpnd(STARS_uval_t value) const;
clc5q
committed
STARSOpndTypePtr MakeRegOpnd(STARS_regnum_t RegNum, bool DefaultToMachineWidth = true);
STARSOpndTypePtr MakeFloatingPointRegOpnd(STARS_regnum_t RegNum);
STARSOpndTypePtr MakeMMXRegOpnd(STARS_regnum_t RegNum);
STARSOpndTypePtr MakeXMMRegOpnd(STARS_regnum_t RegNum);
STARSOpndTypePtr MakeYMMRegOpnd(STARS_regnum_t RegNum);
STARSOpndTypePtr MakeNearPointerOpnd(STARS_ea_t TargetAddr) const;
STARSOpndTypePtr MakeMemDisplacementOpnd(STARS_regnum_t BaseRegNum, STARS_regnum_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset);
STARSOpndTypePtr MakeMemPhraseOpnd(STARS_regnum_t BaseRegNum, STARS_regnum_t IndexRegNum, uint16_t ScaleFactor);
// Analysis methods
virtual bool IsPushFromFixedCall(void) const; // Is push from a call that became a push/jump pair?
virtual STARS_InstructionID_Set_t GetReferencedInstructionIDs(bool &success);
Clark Coleman
committed
// Get inst IDs of jump targets, call targets, etc., including for analyzeable indirect calls and jumps; success = false otherwise
virtual STARS_InstructionID_Set_t GetTargetedInstructionIDs(bool &success);
Clark Coleman
committed
// return inst ID addr for fall-through from this inst
virtual STARS_ea_t GetFallThroughInstID(void);
// Analyze the indirect jump at IndirJumpInst, put switch table info in TableInfo if available, return false otherwise.
// Note: The TableInfo.FollowNodeNum field must be determined by later analysis.
virtual bool AnalyzeSwitchStatement(SMPInstr *IndirJumpInst, struct SwitchTableInfo &TableInfo);
struct STARS_IDA_insn_t STARScmd;
uint32_t STARSfeatures;
STARSOpndTypePtr VoidOpndsPtr; // common pointer to a void operand for all operands not used, to save memory
private:
clc5q
committed
bool ImplicitDEFs; // Modifies regs that do not appear as operands, e.g. many mul/div
void InitOperand(op_t &InitOp) const;