diff --git a/libtransform/include/integertransform.hpp b/libtransform/include/integertransform.hpp index 3bd0ef6b7e1ade9ccf25bc6268a8afaa003c1d13..097eda24a34e328c06c59320eecf2dc49fb40ff0 100644 --- a/libtransform/include/integertransform.hpp +++ b/libtransform/include/integertransform.hpp @@ -28,8 +28,11 @@ class IntegerTransform : public Transform protected: std::map<VirtualOffset, MEDS_InstructionCheckAnnotation>* getAnnotations() { return m_annotations; } + +/* void logMessage(const std::string &p_method, const std::string &p_msg); void logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation&, const std::string &p_msg); +*/ std::set<VirtualOffset>* m_benignFalsePositives; bool m_policySaturatingArithmetic; diff --git a/libtransform/include/integertransform64.hpp b/libtransform/include/integertransform64.hpp index 981bab4d5bf1013daf55237aeeb14033f82026c4..c5a98f7817e205a35f5d2e4be10f93d804505587 100644 --- a/libtransform/include/integertransform64.hpp +++ b/libtransform/include/integertransform64.hpp @@ -17,11 +17,14 @@ class IntegerTransform64 : public IntegerTransform int execute(); protected: + Instruction_t* addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t *p_fallthrough, std::string p_detector, int p_policy); void handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); void handleUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); void addOverflowUnderflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); void saturateSignedMultiplyOverflow(Instruction_t *p_orig, Instruction_t *p_instruction, Instruction_t* p_fallthrough); + void addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy); + void addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const Register::RegisterName& p_reg2, const Register::RegisterName& p_reg3, int p_policy); }; diff --git a/libtransform/include/transform.hpp b/libtransform/include/transform.hpp index 38528399c2a6455d6dc461eba465f5993ea6508d..17acc38780527d1bfcc89685682908ae5cfc5a18 100644 --- a/libtransform/include/transform.hpp +++ b/libtransform/include/transform.hpp @@ -72,13 +72,17 @@ class Transform { bool isMultiplyInstruction(libIRDB::Instruction_t*); bool isAddSubNonEspInstruction(libIRDB::Instruction_t*); Register::RegisterName getTargetRegister(libIRDB::Instruction_t*, int argNo = 1); - + Instruction_t* addNewMaxSaturation(Instruction_t *p_prev, Register::RegisterName p_reg, const MEDS_InstructionCheckAnnotation p_annotation); void addMinSaturation(Instruction_t *p_instruction, Register::RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); void addMaxSaturation(Instruction_t *p_instruction, Register::RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough); void addMovRegisterUnsignedConstant(Instruction_t *p_instr, Register::RegisterName p_regTgt, unsigned long p_constant, Instruction_t *p_fallThrough); void addMovRegisterSignedConstant(Instruction_t *p_instr, Register::RegisterName p_regTgt, long int p_constant, Instruction_t *p_fallThrough); void addAndRegister32Mask(Instruction_t *p_instr, Register::RegisterName p_regTgt, unsigned int p_mask, Instruction_t *p_fallThrough); + protected: + void logMessage(const std::string &p_method, const std::string &p_msg); + void logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation&, const std::string &p_msg); + private: void addTestRegister8(Instruction_t *p_instr, Register::RegisterName, Instruction_t *p_fallThrough); void addTestRegister16(Instruction_t *p_instr, Register::RegisterName, Instruction_t *p_fallThrough); diff --git a/libtransform/src/integertransform.cpp b/libtransform/src/integertransform.cpp index e820567f833b10fcec7c0f1c89b8673097890e51..224039d97e44ca5aff1f65580714d0e519f62ad7 100644 --- a/libtransform/src/integertransform.cpp +++ b/libtransform/src/integertransform.cpp @@ -50,6 +50,7 @@ bool IntegerTransform::isBlacklisted(Function_t *func) strcasestr(funcName, "yy_")); } +#ifdef xxx void IntegerTransform::logMessage(const std::string &p_method, const std::string &p_msg) { std::cerr << p_method << ": " << p_msg << std::endl; @@ -59,6 +60,7 @@ void IntegerTransform::logMessage(const std::string &p_method, const MEDS_Instru { logMessage(p_method, p_msg + " annotation: " + p_annotation.toString()); } +#endif void IntegerTransform::logStats() { diff --git a/libtransform/src/integertransform64.cpp b/libtransform/src/integertransform64.cpp index 5d7d71877bccc23b52c497c63f3c4480aaad6837..28d86118198345c046673ab5f7f81595f5a40b85 100644 --- a/libtransform/src/integertransform64.cpp +++ b/libtransform/src/integertransform64.cpp @@ -1,4 +1,5 @@ #include <assert.h> +#include "leapattern.hpp" #include "integertransform64.hpp" using namespace libTransform; @@ -135,6 +136,11 @@ void IntegerTransform64::handleOverflowCheck(Instruction_t *p_instruction, const // handle signed/unsigned add/sub overflows (non lea) addOverflowUnderflowCheck(p_instruction, p_annotation, p_policy); } + else if (p_annotation.isNoFlag()) + { + // handle lea + addOverflowCheckNoFlag(p_instruction, p_annotation, p_policy); + } else { m_numOverflowsSkipped++; @@ -230,8 +236,8 @@ void IntegerTransform64::addOverflowUnderflowCheck(Instruction_t *p_instruction, setAssembly(lea_i, "lea rsp, [rsp-128]"); // red zone // add callback handler here for diagnostics - // pass in PC of instrumented instruction - // pass in p_policy + // pass in PC of instrumented instruction + // pass in p_policy sprintf(tmpbuf,"push 0x%08x", p_policy); Instruction_t* instr = addNewAssembly(lea_i, tmpbuf); sprintf(tmpbuf,"push 0x%08x", p_instruction->GetAddress()->GetVirtualOffset()); @@ -302,3 +308,208 @@ void IntegerTransform64::saturateSignedMultiplyOverflow(Instruction_t *p_orig, I instr->SetFallthrough(p_fallthrough); } #endif + +void IntegerTransform64::addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) +{ + LEAPattern leaPattern(p_annotation); + + if (!leaPattern.isValid()) + { + logMessage(__func__, "invalid or unhandled lea pattern - skipping: "); + m_numOverflowsSkipped++; + return; + } + + if (leaPattern.getRegister1() == Register::UNKNOWN || + leaPattern.getRegister1() == Register::RSP || + leaPattern.getRegister1() == Register::RBP) + { + logMessage(__func__, "destination register is unknown, esp or ebp -- skipping: "); + m_numOverflowsSkipped++; + return; + } + + if (leaPattern.isRegisterPlusRegister()) + { + Register::RegisterName reg1 = leaPattern.getRegister1(); + Register::RegisterName reg2 = leaPattern.getRegister2(); + Register::RegisterName target = getTargetRegister(p_instruction); + + if (reg1 == Register::UNKNOWN || reg2 == Register::UNKNOWN || target == Register::UNKNOWN) + { + logMessage(__func__, "lea reg+reg pattern: error retrieving register: reg1: " + Register::toString(reg1) + " reg2: " + Register::toString(reg2) + " target: " + Register::toString(target)); + m_numOverflowsSkipped++; + return; + } + else if (reg2 == Register::RSP || target == Register::RSP) + { + logMessage(__func__, "source or target register is rsp -- skipping: "); + m_numOverflowsSkipped++; + return; + } + else + { + addOverflowCheckNoFlag_RegPlusReg(p_instruction, p_annotation, reg1, reg2, target, p_policy); + } + return; + } + + logMessage(__func__, "not yet handling lea -- placeholder"); +} + +// +// p_orig original instruction being instrumented +// p_fallthrough fallthrough once we're done with the callback handlers/detectors +// p_detector callback handler function to call +// p_policy instrumentation policy (e.g.: terminate, saturate, ...) +// +Instruction_t* IntegerTransform64::addCallbackHandlerSequence(Instruction_t *p_orig, Instruction_t *p_fallthrough, std::string p_detector, int p_policy) +{ + char tmpbuf[1024]; + Instruction_t* lea = addNewAssembly("lea rsp, [rsp-128]"); // red zone + + // pass in PC of instrumented instruction + // pass in p_policy + sprintf(tmpbuf,"push 0x%08x", p_policy); + Instruction_t* instr = addNewAssembly(lea, tmpbuf); + sprintf(tmpbuf,"push 0x%08x", p_orig->GetAddress()->GetVirtualOffset()); + instr = addNewAssembly(instr, tmpbuf); + + Instruction_t* call = allocateNewInstruction(p_orig->GetAddress()->GetFileID(), p_orig->GetFunction()); + instr->SetFallthrough(call); + setAssembly(call, "call 0"); + + addCallbackHandler64(call, p_detector, 2); // 2 args for now + + assert(call->GetTarget()); + + instr = addNewAssembly(call, "lea rsp, [rsp+128+16]"); + call->SetFallthrough(instr); + instr->SetFallthrough(p_fallthrough); + + return lea; +} + +// Example annotation to handle +// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+eax] Reg1: EDX Reg2: EAX +// Need to handle both 32-bit and 64-bit versions +// +// Original: +// lea r3, [r1+r2] +// <originalNext> +// +// Instrumentation: +// push r1 ; save r1 +// pushf ; save flags +// add r1, r2 ; r1 = r1 + r2 +// <overflowcheck> ; check for overflow +// (jno|jnc <restore>) ; SIGNED|UNSIGNED +// fallthrough--><policy> +// (jno&jnc <restore>) ; UNKNOWNSIGN check both flags +// fallthrough--><policy> +// +// <restore> +// popf ; restore flags +// pop r1 ; restore register +// +// <orig>: lea r3, [r1+r2] ; original instruction +// <originalNext> ; original next instruction +// +// <policy> +// () callback handler +// popf ; restore flags +// pop r1 ; restore register +// fallthrough-->originalNext (if no saturation) +// saturateMax(r3) ; optional saturation +// fallthrough-->originalNext +// +void IntegerTransform64::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const Register::RegisterName& p_reg2, const Register::RegisterName& p_reg3, int p_policy) +{ + assert(p_instruction && p_instruction->GetFallthrough()); + + cerr << __func__ << ": r3 <-- r1+r2: r1: " << Register::toString(p_reg1) << " r2: " << Register::toString(p_reg2) << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; + + Instruction_t *origFallthrough = p_instruction->GetFallthrough(); + Instruction_t *instr, *first, *saturation_policy; + Instruction_t *restore = addNewAssembly("popf"); + + // <policy> + // nop ; + // () callback handler ; + // popf ; restore flags + // pop r1 ; restore register + // fallthrough-->originalNext (if no saturation) + // saturateMax(r3) ; optional saturation + // fallthrough-->originalNext + // + // assume 64 bit for now + // + saturation_policy = addNewAssembly("nop"); + saturation_policy->SetComment("lea overflow instrumentation(reg+reg): policy code sequence"); + Instruction_t *popf = addNewAssembly("popf"); + Instruction_t *callback = addCallbackHandlerSequence(p_instruction, popf, OVERFLOW_DETECTOR_64, p_policy); + saturation_policy->SetFallthrough(callback); + instr = addNewAssembly(popf, "pop " + Register::toString(p_reg1)); + if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) // why do we need this? + { + instr = addNewMaxSaturation(instr, p_reg3, p_annotation); + } + + instr->SetFallthrough(origFallthrough); + + // Original code sequence: + // lea r3, [r1+r2] + // <originalNext> + // + // Instrumentation: + // push r1 ; save r1 + // pushf ; save flags + // add r1, r2 ; r1 = r1 + r2 + // <overflowcheck> ; check for overflow + // (jno|jnc <restore>) ; SIGNED|UNSIGNED + // fallthrough--><policy> + // (jno&jnc <restore>) ; UNKNOWNSIGN check both flags + // fallthrough--><policy> + // + first = addNewAssembly("push " + Register::toString(p_reg1)); + first->SetComment("lea overflow instrumentation(reg+reg): start"); + instr = addNewAssembly(first, "pushf"); + Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, first); + + // make sure we set the fallthrough post careful insertion + first->SetFallthrough(instr); + + instr = addNewAssembly(instr, "add " + Register::toString(p_reg1) + "," + Register::toString(p_reg2)); + if (p_annotation.isSigned()) + { + instr = addNewAssembly(instr, "jno 0x22"); + instr->SetFallthrough(saturation_policy); + instr->SetTarget(restore); + } + else if (p_annotation.isUnsigned()) + { + instr = addNewAssembly(instr, "jnc 0x22"); + instr->SetFallthrough(saturation_policy); + instr->SetTarget(restore); + } + else + { + Instruction_t *instr2 = addNewAssembly(instr, "jno 0x22"); + instr = addNewAssembly(instr2, "jnc 0x22"); + instr->SetFallthrough(saturation_policy); + instr->SetTarget(restore); + } + + // <restore> + // popf ; restore flags + // pop r1 ; restore register + // + // <orig>: lea r3, [r1+r2] ; original instruction + // <originalNext> ; original next instruction + // + restore->SetComment("lea overflow instrumentation(reg+reg): restore"); + instr = addNewAssembly(restore, "pop " + Register::toString(p_reg1)); + + instr->SetFallthrough(originalInstrumentInstr); + m_numOverflows++; +} diff --git a/libtransform/src/leapattern.cpp b/libtransform/src/leapattern.cpp index a59fb65c4e192fd701045f68034c31387aecfbee..855f00b66384a7fd105f875920923997d672a130 100644 --- a/libtransform/src/leapattern.cpp +++ b/libtransform/src/leapattern.cpp @@ -21,26 +21,26 @@ LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation) m_reg2 = Register::UNKNOWN; m_constant = 0; - if(regcomp(&m_regex_reg_plus_reg ,"[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]\\+[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]", REG_EXTENDED | REG_ICASE) !=0) - cerr << "Error: regular expression for reg32+reg32 failed" << endl; + if(regcomp(&m_regex_reg_plus_reg ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\+[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+reg failed" << endl; - if(regcomp(&m_regex_reg_times_reg ,"[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]\\*[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]", REG_EXTENDED | REG_ICASE) !=0) - cerr << "Error: regular expression for reg32*reg32 failed" << endl; + if(regcomp(&m_regex_reg_times_reg ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\*[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg*reg failed" << endl; - if(regcomp(&m_regex_reg_plus_constant ,"[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]\\+[0-9+]", REG_EXTENDED | REG_ICASE) !=0) - cerr << "Error: regular expression for reg32+constant failed" << endl; + if(regcomp(&m_regex_reg_plus_constant ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\+[0-9+]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+constant failed" << endl; - if(regcomp(&m_regex_reg_plus_negconstant ,"[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]\\+\\-[0-9+]", REG_EXTENDED | REG_ICASE) !=0) - cerr << "Error: regular expression for reg32+constant failed" << endl; + if(regcomp(&m_regex_reg_plus_negconstant ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\+\\-[0-9+]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+constant failed" << endl; - if(regcomp(&m_regex_reg_times_constant ,"[eax|EAX|ebx|EBX|ecx|ECX|edx|EDX|esi|ESI|edi|EDI|ebp|EDI]\\*[0-9+]", REG_EXTENDED | REG_ICASE) !=0) - cerr << "Error: regular expression for reg32+constant failed" << endl; + if(regcomp(&m_regex_reg_times_constant ,"[eax|ebx|ecx|edx|esi|edi|ebp|rax|rbx|rcx|rdx|rbp|rsi|rdi|r8|r9|r10|r11|r12|r13|r14|r15]\\*[0-9+]", REG_EXTENDED | REG_ICASE) !=0) + cerr << "Error: regular expression for reg+constant failed" << endl; const int max = 5; - regmatch_t pmatch[max]; + regmatch_t pmatch[max]; int countMatch = 0; - if(regexec(&m_regex_reg_plus_reg, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) + if(regexec(&m_regex_reg_plus_reg, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) { // pattern is of the form reg+reg, e.g.: EDX+EAX countMatch++; @@ -49,7 +49,10 @@ LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation) m_reg2 = Register::getRegister(p_annotation.getTarget().substr(4,3)); if (m_reg1 != Register::UNKNOWN && m_reg2 != Register::UNKNOWN) + { m_isValid = true; + cerr << "leapattern: reg+reg:" << Register::toString(m_reg1) << " " << Register::toString(m_reg2) << endl; + } } if(regexec(&m_regex_reg_times_reg, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) @@ -62,7 +65,10 @@ LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation) m_reg2 = Register::getRegister(p_annotation.getTarget().substr(4,3)); if (m_reg1 != Register::UNKNOWN && m_reg2 != Register::UNKNOWN) + { m_isValid = true; + cerr << "leapattern: reg*reg:" << Register::toString(m_reg1) << " " << Register::toString(m_reg2) << endl; + } } // integertransform: reg+constant: register: EDX constant: 80 target register: EAX annotation: 805525b 6 INSTR CHECK OVERFLOW NOFLAGUNSIGNED 32 EDX+128 ZZ lea eax, [edx+80h] @@ -81,9 +87,9 @@ LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation) if (constantSS >> m_constant) { m_isValid = true; + cerr << "leapattern: reg+-constant: stream: " << p_annotation.getTarget().substr(4) << " constant: " << dec << m_constant << " annotation: " << p_annotation.toString() << endl; } -// cerr << "leapattern: reg+-constant: stream: " << p_annotation.getTarget().substr(4) << " constant: " << dec << m_constant << " annotation: " << p_annotation.toString() << endl; } if(regexec(&m_regex_reg_times_constant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0) @@ -96,6 +102,7 @@ LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation) stringstream constantSS(p_annotation.getTarget().substr(4)); if (constantSS >> m_constant) { + cerr << "leapattern: reg*constant: stream: " << p_annotation.getTarget().substr(4) << " constant: " << dec << m_constant << " annotation: " << p_annotation.toString() << endl; m_isValid = true; } } diff --git a/libtransform/src/transform.cpp b/libtransform/src/transform.cpp index f5fb44b3daa48bd78a21e972d678f096286677dd..3eea15d5002f6e7b7b077bdbf177c848aeb55735 100644 --- a/libtransform/src/transform.cpp +++ b/libtransform/src/transform.cpp @@ -64,8 +64,11 @@ Instruction_t* Transform::carefullyInsertBefore(Instruction_t* &p_instrumented, // m_fileIR->ChangeRegistryKey(p_instrumented, dupInstr); - // replace instrumented with new instruction - p_instrumented->SetDataBits(p_newInstr->GetDataBits()); + if (p_newInstr->GetDataBits().size() == 0) + m_fileIR->RegisterAssembly(p_instrumented, m_fileIR->LookupAssembly(p_newInstr)); + else + p_instrumented->SetDataBits(p_newInstr->GetDataBits()); + p_instrumented->SetComment(p_newInstr->GetComment()); p_instrumented->SetCallback(p_newInstr->GetCallback()); p_instrumented->SetFallthrough(dupInstr); @@ -1173,6 +1176,15 @@ void Transform::addJnc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Ins p_instr->SetTarget(p_target); } +Instruction_t* Transform::addNewMaxSaturation(Instruction_t *p_prev, Register::RegisterName p_reg, const MEDS_InstructionCheckAnnotation p_annotation) +{ + Instruction_t *mov = allocateNewInstruction(p_prev->GetAddress()->GetFileID(), p_prev->GetFunction()); + if (p_prev) + p_prev->SetFallthrough(mov); + addMaxSaturation(mov, p_reg, p_annotation, NULL); + return mov; +} + void Transform::addMaxSaturation(Instruction_t *p_instruction, Register::RegisterName p_reg, const MEDS_InstructionCheckAnnotation& p_annotation, Instruction_t *p_fallthrough) { assert(getFileIR() && p_instruction); @@ -1351,10 +1363,10 @@ Instruction_t* Transform::registerCallbackHandler64(string p_callbackHandler, in instr = addNewAssembly(instr, "push r15"); instr = addNewAssembly(instr, "pushf"); - instr = addNewAssembly(instr, "mov rdi, rsp"); - // handle the arguments (if any): rdi, rsi, rdx, rcx, r8, r9 // first arg starts at byte +144 + instr = addNewAssembly(instr, "mov rdi, rsp"); + if (p_numArgs >= 1) instr = addNewAssembly(instr, "mov rsi, [rsp+144]"); if (p_numArgs >= 2) @@ -1385,7 +1397,7 @@ Instruction_t* Transform::registerCallbackHandler64(string p_callbackHandler, in // need to make sure the post callback address is pinned // (so that ILR and other transforms do not relocate it) - AddressID_t *indTarg =new AddressID_t(); + AddressID_t *indTarg = new AddressID_t(); m_fileIR->GetAddresses().insert(indTarg); indTarg->SetVirtualOffset(postCallback->GetAddress()->GetVirtualOffset()); indTarg->SetFileID(BaseObj_t::NOT_IN_DATABASE); // SPRI global namespace @@ -1415,3 +1427,14 @@ Instruction_t* Transform::registerCallbackHandler64(string p_callbackHandler, in // return first instruction in the callback handler chain return first; } + +void Transform::logMessage(const std::string &p_method, const std::string &p_msg) +{ + std::cerr << p_method << ": " << p_msg << std::endl; +} + +void Transform::logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation& p_annotation, const std::string &p_msg) +{ + logMessage(p_method, p_msg + " annotation: " + p_annotation.toString()); +} +