Newer
Older
ReturnAddrStatus = FUNC_SAFE;
if (!AnalyzedSP || this->IndirectCalls) {
msg(" Function marked as unsafe %s coz AnalyzedSP = false\n", this->GetFuncName());
msg(" Function marked as unsafe %s coz function has indirect calls\n", this->GetFuncName());
#endif
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
if (!this->DirectCallTargets.empty()) {
msg(" Function marked as unknown %s \n", this->GetFuncName());
#endif
ReturnAddrStatus = FUNC_UNKNOWN;
}
#if SMP_USE_SWITCH_TABLE_INFO
if (this->UnresolvedIndirectJumps) {
#else
msg(" Function marked as unsafe due to indirect jumps %s\n", this->GetFuncName());
#endif
ReturnAddrStatus = FUNC_UNSAFE;
return ;
}
if (this->HasSharedChunks()) {
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
list<SMPInstr>::iterator Instructions;
// while processing the stack pointer write the prolog containing for
// saving frame register and allcating local variables needs to be
// handled
bool SaveEBP = false;
bool XferESPtoEBP = false;
for (Instructions = Instrs.begin(); Instructions != Instrs.end(); Instructions++) {
#if SMP_USE_SSA_FNOP_MARKER
if (this->Instrs.begin() == Instructions)
continue; // skip marker instruction
#endif
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
msg(" Total number of defs for this instruction %d\n", Instructions->NumDefs());
#endif
if (!SaveEBP) { // still looking for "push ebp"
if (Instructions->MDIsPushInstr() && Instructions->GetCmd().Operands[0].is_reg(R_bp)) {
SaveEBP = true;
continue;
}
}
else if (!XferESPtoEBP) { // found "push ebp", looking for "mov ebp,esp"
insn_t CurrCmd = Instructions->GetCmd();
if ((CurrCmd.itype == NN_mov)
&& (Instructions->GetFirstDef()->GetOp().is_reg(R_bp))
&& (Instructions->GetFirstUse()->GetOp().is_reg(R_sp))) {
XferESPtoEBP = true;
continue;
}
}
ea_t address = Instructions->GetAddr();
if (address == this->LocalVarsAllocInstr ||
address == this->LocalVarsDeallocInstr)
continue;
if (Instructions->MDIsStackPointerCopy(this->UseFP)) {
msg(" Function marked as unsafe %s due to stack pointer copy \n ", this->GetFuncName());
msg("%s %x \n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
#endif
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
if (Instructions->MDIsPushInstr()) {
// not exactly sure how to handle this instruction
// for the moment if its a push on a esp or usefp & ebp
// mark as unsafe
if (Instructions->GetCmd().Operands[0].is_reg(R_sp) ||
( this->UseFP && Instructions->GetCmd().Operands[0].is_reg(R_bp))) {
msg(" Function marked as unsafe %s due to push on ebp or esp outside of function header \n", this->GetFuncName());
msg("%s %x\n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
#endif
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
continue;
}
if (Instructions->MDIsPopInstr()) {
// ignore pops for the moment
continue;
}
set<DefOrUse, LessDefUse>::iterator setIterator;
for (setIterator = Instructions->GetFirstDef(); setIterator != Instructions->GetLastDef(); setIterator++) {
op_t Operand = setIterator->GetOp();
clc5q
committed
int BaseReg;
int IndexReg;
ushort ScaleFactor;
ea_t offset;
if (Operand.type == o_mem) {
// now o_mem can have sib byte as well, as
clc5q
committed
// reported by IDA. Check if the base reg is R_none
// and index reg is R_none. If they are, then this is
// probably a global write and can be marked safe.
MDExtractAddressFields(Operand, BaseReg, IndexReg, ScaleFactor, offset);
if ((BaseReg == R_none) && (IndexReg == R_none)) {
// go onto next def
continue;
}
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
if (Operand.type == o_displ) {
clc5q
committed
MDExtractAddressFields(Operand, BaseReg, IndexReg, ScaleFactor, offset);
if ((BaseReg == R_sp) || (this->UseFP && (BaseReg == R_bp))) {
if (IndexReg == R_none) {
if (offset > this->LocalVarsSize ) {
clc5q
committed
msg(" Function marked as unsafe %s due to write above loc variables offset=%x loc=%x\n ", this->GetFuncName(), offset, this->LocalVarsSize);
msg("%s %x\n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
#endif
clc5q
committed
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
}
else {
clc5q
committed
msg(" Function marked as unsafe %s due to index write above loc variables \n", this->GetFuncName());
msg("%s %x\n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
clc5q
committed
ReturnAddrStatus = FUNC_UNSAFE;
clc5q
committed
else {
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
}
if (Operand.type == o_phrase) {
// so phrase is of the form [BASE_REG + IND ]
// if the index register is missing just make sure that
// the displacement is below stack frame top
clc5q
committed
MDExtractAddressFields(Operand, BaseReg, IndexReg, ScaleFactor, offset);
// check the base reg
// if index reg is used mark as unsafe
if ((BaseReg == R_sp || (this->UseFP && BaseReg == R_bp))
&& (IndexReg == R_none)) {
clc5q
committed
msg(" Does function with phrase have displ %s %x ", this->GetFuncName(), Operand.addr);
clc5q
committed
continue;
}
else {
ReturnAddrStatus = FUNC_UNSAFE;
return;
}
}
}
}
} // end of SMPFunction::MarkFunctionSafe()