Newer
Older
//
// SMPInstr.cpp
//
// This module performs the instruction level analyses needed for the
// SMP project (Software Memory Protection).
//
#include <cstring>
#include <pro.h>
#include <assert.h>
#include <ida.hpp>
#include <idp.hpp>
#include <allins.hpp>
#include <auto.hpp>
#include <bytes.hpp>
#include <funcs.hpp>
#include <intel.hpp>
#include <loader.hpp>
#include <lines.hpp>
#include <name.hpp>
#include "SMPStaticAnalyzer.h"
#include "SMPDataFlowAnalysis.h"
#include "SMPInstr.h"
// Set to 1 for debugging output
#define SMP_DEBUG 1
#define SMP_DEBUG2 0 // verbose
#define SMP_DEBUG_XOR 0
#define SMP_DEBUG_BUILD_RTL 0
// Make the CF_CHG1 .. CF_CHG6 and CF_USE1..CF_USE6 macros more usable
// by allowing us to pick them up with an array index.
static ulong DefMacros[UA_MAXOP] = {CF_CHG1, CF_CHG2, CF_CHG3, CF_CHG4, CF_CHG5, CF_CHG6};
static ulong UseMacros[UA_MAXOP] = {CF_USE1, CF_USE2, CF_USE3, CF_USE4, CF_USE5, CF_USE6};
// Text to be printed in each optimizing annotation explaining why
// the annotation was emitted.
static char *OptExplanation[LAST_OPT_CATEGORY + 1] =
{ "NoOpt", "NoMetaUpdate", "AlwaysNUM", "NUMVia2ndSrcIMMEDNUM",
"Always1stSrc", "1stSrcVia2ndSrcIMMEDNUM", "AlwaysPtr",
"AlwaysNUM", "AlwaysNUM", "NUMViaFPRegDest"
};
// *****************************************************************
// Class SMPGuard
// *****************************************************************
// Constructor
SMPGuard::SMPGuard(void) {
this->LeftOperand.type = o_void;
this->RightOperand.type = o_void;
return;
}
// *****************************************************************
// Class SMPRegTransfer
// *****************************************************************
// Constructor
SMPRegTransfer::SMPRegTransfer(void) {
this->LeftOperand.type = o_void;
this->RightOperand.type = o_void;
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
this->RightSubTree = false;
this->RightRT = NULL;
this->Guard = NULL;
return;
}
// Destructor
SMPRegTransfer::~SMPRegTransfer() {
#if 0
msg("Destroying SMPRegTransfer.\n");
#endif
if (NULL != this->RightRT)
delete this->RightRT;
if (NULL != this->Guard)
delete this->Guard;
return;
}
// *****************************************************************
// Class SMPRTL
// *****************************************************************
// Constructor
SMPRTL::SMPRTL() {
this->ExtraKills.clear();
this->RTCount = 0;
return;
}
// Destructor
SMPRTL::~SMPRTL() {
for (size_t index = 0; index < this->RTCount; ++index) {
delete (this->RTvector[index]);
}
this->ExtraKills.clear();
return;
}
// Get methods
SMPRegTransfer *SMPRTL::GetRT(size_t index) {
if (index > this->RTCount)
return NULL;
else
return this->RTvector[index];
}
// Set methods
void SMPRTL::push_back(SMPRegTransfer *NewEffect) {
assert(SMP_RT_LIMIT > this->RTCount);
this->RTvector[this->RTCount] = NewEffect;
++(this->RTCount);
return;
}
// *****************************************************************
// Class SMPInstr
// *****************************************************************
// Constructor for instruction.
SMPInstr::SMPInstr(ea_t addr) {
this->address = addr;
this->analyzed = false;
this->JumpTarget = false;
this->BlockTerm = false;
this->DeadRegsString[0] = '\0';
this->DefsFlags = false;
this->UsesFlags = false;
return;
}
// Is the instruction the type that terminates a basic block?
bool SMPInstr::IsBasicBlockTerminator() const {
return ((type == JUMP) || (type == COND_BRANCH)
|| (type == INDIR_JUMP) || (type == RETURN));
}
// Is the destination operand a memory reference?
bool SMPInstr::HasDestMemoryOperand(void) {
set<DefOrUse, LessDefUse>::iterator CurrDef;
for (CurrDef = this->GetFirstDef(); CurrDef != this->GetLastDef(); ++CurrDef) {
optype_t CurrType = CurrDef->GetOp().type;
MemDest = ((CurrType == o_mem) || (CurrType == o_phrase) || (CurrType == o_displ));
if (MemDest)
break;
}
return MemDest;
} // end of SMPInstr::HasDestMemoryOperand()
// Is a source operand a memory reference?
bool SMPInstr::HasSourceMemoryOperand(void) {
set<DefOrUse, LessDefUse>::iterator CurrUse;
for (CurrUse = this->GetFirstUse(); CurrUse != this->GetLastUse(); ++CurrUse) {
optype_t CurrType = CurrUse->GetOp().type;
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
MemSrc = ((CurrType == o_mem) || (CurrType == o_phrase) || (CurrType == o_displ));
if (MemSrc)
break;
}
return MemSrc;
} // end of SMPInstr::HasSourceMemoryOperand()
// Does the instruction whose flags are in F have a numeric type
// as the second source operand?
// NOTE: We can only analyze immediate values now, using a heuristic
// that values in the range +/- 8K are numeric and others are
// probably addresses. When data flow analyses are implemented,
// we will be able to analyze many non-immediate operands.
#define IMMEDNUM_LOWER -8191
#define IMMEDNUM_UPPER 8191
bool SMPInstr::IsSecondSrcOperandNumeric(flags_t F) const {
bool SecondOpImm = (SMPcmd.Operands[1].type == o_imm);
signed long TempImm;
if (SecondOpImm) {
TempImm = (signed long) SMPcmd.Operands[1].value;
}
#if SMP_DEBUG
if (SecondOpImm && (0 > TempImm)) {
#if 0
msg("Negative immediate: %d Hex: %x ASM: %s\n", TempImm,
SMPcmd.Operands[1].value, disasm);
#endif
}
else if ((!SecondOpImm) && (SMPcmd.Operands[1].type == o_imm)) {
msg("Problem with flags on immediate src operand: %s\n", disasm);
}
#endif
return (SecondOpImm && (TempImm > IMMEDNUM_LOWER)
&& (TempImm < IMMEDNUM_UPPER));
} // end of SMPInstr::IsSecondSrcOperandNumeric()
// DEBUG print operands for Inst.
Loading
Loading full blame...