Skip to content
Snippets Groups Projects
Commit 02f4bb77 authored by an7s's avatar an7s
Browse files

...

Former-commit-id: 6d863a1c8197124d7ed806862e7bef2dd4da2b86
parent 3c760bb7
No related branches found
No related tags found
No related merge requests found
......@@ -292,6 +292,7 @@ libtransform/include/integertransform.hpp -text
libtransform/include/transform.hpp -text
libtransform/src/Makefile -text
libtransform/src/integertransform.cpp -text
libtransform/src/leapattern.cpp -text
libtransform/src/transform.cpp -text
libtransform/tests/Makefile -text
libtransform/tests/austin/array.c -text
......
......@@ -2,6 +2,7 @@
#define _LIBTRANSFORM_INTEGERTRANSFORM_H_
#include "transform.hpp"
#include "MEDS_Register.hpp"
namespace libTransform
{
......@@ -19,11 +20,16 @@ class IntegerTransform : public Transform
private:
void handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void handleSignedness(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
// void addTruncationCheck32to16(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void addSignednessCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void addTruncationCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation);
void addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName&, const Register::RegisterName&, const Register::RegisterName&);
void addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName&, int p_constantValue, const Register::RegisterName&);
void addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName&, int p_constantValue, const Register::RegisterName&);
};
};
......
......@@ -36,7 +36,7 @@ class Transform {
void addPopf(Instruction_t *p_instr, Instruction_t *p_fallThrough);
void addNop(Instruction_t *p_instr, Instruction_t *p_fallThrough);
void addCallbackHandler(string p_detector, Instruction_t *p_instrumented, Instruction_t *p_instr, Instruction_t *_fallThrough);
void addCallbackHandler(string p_detector, Instruction_t *p_instrumented, Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_original = NULL);
void addTestRegister(Instruction_t *p_instr, Register::RegisterName, Instruction_t *p_fallThrough);
void addTestRegisterMask(Instruction_t *p_instr, Register::RegisterName, unsigned p_mask, Instruction_t *p_fallThrough);
......@@ -44,6 +44,11 @@ class Transform {
void addJz(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target);
void addNot(Instruction_t *p_instr, Register::RegisterName, Instruction_t *p_fallThrough);
void addAddRegisters(Instruction_t *p_instr, Register::RegisterName p_regTgt, Register::RegisterName p_regSrc, Instruction_t *p_fallThrough);
void addAddRegisterConstant(Instruction_t *p_instr, Register::RegisterName p_regTgt, int p_constantValue, Instruction_t *p_fallThrough);
void addMulRegisterConstant(Instruction_t *p_instr, Register::RegisterName p_regTgt, int p_constantValue, Instruction_t *p_fallThrough);
void addMovRegisters(Instruction_t *p_instr, Register::RegisterName p_regTgt, Register::RegisterName p_regSrc, Instruction_t *p_fallThrough);
Instruction_t* allocateNewInstruction(db_id_t p_fileID, Function_t* p_func);
virtual_offset_t getAvailableAddress();
......@@ -55,12 +60,14 @@ class Transform {
bool isMultiplyInstruction(libIRDB::Instruction_t*);
bool isAddSubNonEspInstruction(libIRDB::Instruction_t*);
Register::RegisterName getTargetRegister(libIRDB::Instruction_t*);
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);
void addTestRegister32(Instruction_t *p_instr, Register::RegisterName, Instruction_t *p_fallThrough);
void addTestRegisterMask32(Instruction_t *p_instr, Register::RegisterName, unsigned p_mask, Instruction_t *p_fallThrough);
bool hasTargetRegister(libIRDB::Instruction_t*);
VariantID_t *m_variantID;
VariantIR_t *m_variantIR;
......
LIB=../lib/libtransform.a
OBJS=transform.o integertransform.o
OBJS=transform.o integertransform.o leapattern.o
all: $(OBJS)
......
#include <assert.h>
#include "integertransform.hpp"
#include "leapattern.h"
using namespace libTransform;
......@@ -45,7 +46,7 @@ int IntegerTransform::execute()
if (!annotation.isValid())
continue;
if (annotation.isOverflow() && !annotation.isNoFlag())
if (annotation.isOverflow())
{
handleOverflowCheck(insn, annotation);
}
......@@ -135,12 +136,17 @@ void IntegerTransform::addSignednessCheck(Instruction_t *p_instruction, const ME
else if (p_annotation.getBitWidth() == 8)
detector = string(SIGNEDNESS_DETECTOR_8);
addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i);
addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_instruction);
addPopf(popf_i, originalInstrumentInstr);
}
void IntegerTransform::handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation)
{
if (p_annotation.isOverflow() && p_annotation.isNoFlag())
{
addOverflowCheckNoFlag(p_instruction, p_annotation);
}
else
if (isMultiplyInstruction(p_instruction) || p_annotation.isUnderflow() || p_annotation.isOverflow())
{
addOverflowCheck(p_instruction, p_annotation);
......@@ -149,130 +155,262 @@ void IntegerTransform::handleOverflowCheck(Instruction_t *p_instruction, const M
cerr << "integertransform: OVERFLOW/UNDERFLOW type not yet handled" << p_annotation.toString() << endl;
}
void IntegerTransform::handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation)
/*
NOFLAGUNKNOWNSIGN 32 ESI+EDX ZZ lea eax, [esi+edx]
NOFLAGUNSIGNED 32 EDX+ESI+1900 ZZ lea esi, [edx+esi+76Ch]
NOFLAGUNSIGNED 32 EAX+382 ZZ lea esi, [eax+17Eh]
NOFLAGUNKNOWNSIGN 32 EDX*8 ZZ lea eax, ds:0[edx*8]
NOFLAGUNSIGNED 32 ECX+ECX*4 ZZ lea ebx, [ecx+ecx*4]
NOFLAGUNSIGNED 32 EDI+-66 ZZ lea eax, [edi-42h]
NOFLAGSIGNED 32 ESI+100 ZZ lea ecx, [esi+64h]
posbible patterns after the bit width field:
rpr: <reg>+<reg>
rpc: <reg>+-<constant>
rpc: <reg>+<constant>
rtc: <reg>*constant
rprpc: <reg>+<reg>+<constant>
rprpc: <reg>+<reg>+-<constant>
rprtc: <reg>+<reg>*<constant>
*/
void IntegerTransform::addOverflowCheckNoFlag(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation)
{
if (p_annotation.getTruncationFromWidth() == 32 && (p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8))
cerr << "IntegerTransform::addOverflowCheckNoFlag(): Disable for now" << endl;
return;
LEAPattern leaPattern(p_annotation);
if (!leaPattern.isValid())
{
addTruncationCheck(p_instruction, p_annotation);
cerr << "IntegerTransform::addOverflowCheckNoFlag(): invalid lea pattern - skipping: " << p_annotation.toString() << endl;
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)
{
cerr << "IntegerTransform::addOverflowCheckNoFlag(): lea reg+reg pattern: error retrieving register:" << "reg1: " << Register::toString(reg1) << " reg2: " << Register::toString(reg2) << " target: " << Register::toString(target) << endl;
return;
}
else
{
addOverflowCheckNoFlag_RegPlusReg(p_instruction, p_annotation, reg1, reg2, target);
}
}
else if (leaPattern.isRegisterPlusConstant())
{
return;
Register::RegisterName reg1 = leaPattern.getRegister1();
int value = leaPattern.getConstant();
Register::RegisterName target = getTargetRegister(p_instruction);
if (reg1 == Register::UNKNOWN || target == Register::UNKNOWN)
{
cerr << "IntegerTransform::addOverflowCheckNoFlag(): lea reg+constant pattern: error retrieving register:" << "reg1: " << Register::toString(reg1) << " target: " << Register::toString(target) << endl;
return;
}
else
{
addOverflowCheckNoFlag_RegPlusConstant(p_instruction, p_annotation, reg1, value, target);
}
}
else if (leaPattern.isRegisterTimesConstant())
{
return;
Register::RegisterName reg1 = leaPattern.getRegister1();
int value = leaPattern.getConstant();
Register::RegisterName target = getTargetRegister(p_instruction);
if (reg1 == Register::UNKNOWN || target == Register::UNKNOWN)
{
cerr << "IntegerTransform::addOverflowCheckNoFlag(): lea reg*constant pattern: error retrieving register:" << "reg1: " << Register::toString(reg1) << " target: " << Register::toString(target) << endl;
return;
}
else
{
addOverflowCheckNoFlag_RegTimesConstant(p_instruction, p_annotation, reg1, value, target);
}
}
else
{
cerr << "integertransform: TRUNCATION annotation not yet handled: " << p_annotation.toString() << endl;
cerr << "IntegerTransform::addOverflowCheckNoFlag(): pattern not yet handled: " << p_annotation.toString() << endl;
return;
}
}
#ifdef NO_LONGER_USED
void IntegerTransform::addTruncationCheck32to16(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation)
// Example annotation to handle
// 804852e 3 INSTR CHECK OVERFLOW NOFLAGSIGNED 32 EDX+EAX ZZ lea eax, [edx+eax] Reg1: EDX Reg2: EAX
void IntegerTransform::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)
{
string detector; // name of SPRI/STRATA callback handler function
string dataBits;
// should we even attempt to instrument if we're not sure about the signedness for this pattern?
if (p_annotation.isUnknownSign() || p_annotation.isSigned())
{
// TESTING: handle only eax/ax for now
// potentially sign-extended
// need to check upper 16 bits are either all 1's or all 0's
// (false positive posible if it was in fact unsigned)
// 80486d2 5 INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 16 AX ZZ mov [esp+2Ah], ax
// ; make sure to use instructions that don't affect the condition flags
// push ecx ; temporary register
// push eax ; copy value of eax (since ax is used in instruction)
// movzx ecx, word [esp + 2] ; copy upper 16 bits into ecx (zero-extend)
// jecxz continue ; all 0's, all good
// not ecx ; flip all bits (all 1's becomes all 0's)
// jecxz continue ; originally all 1's, all good
//
// <invoke handler here>
// nop
//
// continue:
// pop eax ; restore eax
// pop ecx ; restore ecx
// mov [esp+2Ah], ax ; instrumented instruction
db_id_t fileID = p_instruction->GetAddress()->GetFileID();
Function_t* func = p_instruction->GetFunction();
Instruction_t* push_ecx_i = allocateNewInstruction(fileID, func);
Instruction_t* push_eax_i = allocateNewInstruction(fileID, func);
Instruction_t* movzx_i = allocateNewInstruction(fileID, func);
Instruction_t* jecxz_i = allocateNewInstruction(fileID, func);
Instruction_t* not_ecx_i = allocateNewInstruction(fileID, func);
Instruction_t* jecxz2_i = allocateNewInstruction(fileID, func);
Instruction_t* nop_i = allocateNewInstruction(fileID, func);
Instruction_t* pop_ecx_i = allocateNewInstruction(fileID, func);
Instruction_t* pop_eax_i = allocateNewInstruction(fileID, func);
// start instrumentation
addPushRegister(push_ecx_i, Register::ECX, push_eax_i);
cerr << "push_ecx: " << push_ecx_i->getDisassembly() << endl;
// insert start of instrumentation before the instrument instruction
Instruction_t* instrumentedInstr = carefullyInsertBefore(p_instruction, push_ecx_i);
push_ecx_i->SetFallthrough(push_eax_i);
addPushRegister(push_eax_i, Register::EAX, movzx_i);
cerr << "push_eax: " << push_eax_i->getDisassembly() << endl;
// movzx ecx, word [esp + 2] ; copy upper 16 bits into ecx (zero-extend)
dataBits.resize(5);
dataBits[0] = 0x0f;
dataBits[1] = 0xb7;
dataBits[2] = 0x4c;
dataBits[3] = 0x24;
dataBits[4] = 0x02;
addInstruction(movzx_i, dataBits, jecxz_i, NULL);
cerr << "movzx ecx, word [esp + 2]: " << movzx_i->getDisassembly() << endl;
// jecxz continue ; all 0's, all good
dataBits.resize(2);
dataBits[0] = 0xe3;
dataBits[1] = 0x00; // value doesn't matter here -- will be filled in later
addInstruction(jecxz_i, dataBits, not_ecx_i, pop_eax_i);
cerr << "jecxz: " << jecxz_i->getDisassembly() << endl;
// not ecx ; flip all bits (all 1's bcomes all 0's)
dataBits.resize(2);
dataBits[0] = 0xf7;
dataBits[1] = 0xd1;
addInstruction(not_ecx_i, dataBits, jecxz2_i, NULL);
cerr << "not ecx: " << not_ecx_i->getDisassembly() << endl;
// jecxz continue ; all 0's, all good
dataBits.resize(2);
dataBits[0] = 0xe3;
dataBits[1] = 0x00; // value doesn't matter here -- will be filled in later
addInstruction(jecxz2_i, dataBits, nop_i, pop_eax_i);
cerr << "jecxz2: " << jecxz2_i->getDisassembly() << endl;
// nop
addNop(nop_i, pop_eax_i);
addCallbackHandler(string(TRUNCATION_DETECTOR), instrumentedInstr, nop_i, pop_eax_i);
cerr << "nop: " << nop_i->getDisassembly() << endl;
// pop eax ; restore eax
addPopRegister(pop_eax_i, Register::EAX, pop_ecx_i);
cerr << "pop eax: " << pop_eax_i->getDisassembly() << endl;
// pop ecx ; restore ecx
addPopRegister(pop_ecx_i, Register::ECX, instrumentedInstr);
cerr << "pop ecx: " << pop_ecx_i->getDisassembly() << endl;
// need to use the correct PC (the one for the original lea instruction) when printing detector message
}
// Instrumentation:
// pushf ; save flags
// add r1, r2 ; r1 = r1 + r2;
// <check for overflow> ; reuse overflow code
// mov r3, r1 ; r3 = r1 (replaces lea r3, [r1+r2])
// ; possible optimization: do nothing if r3 == r1
// popf ; restore flags
//
db_id_t fileID = p_instruction->GetAddress()->GetFileID();
Function_t* func = p_instruction->GetFunction();
Instruction_t* fallthrough = p_instruction->GetFallthrough();
Instruction_t* pushf_i = allocateNewInstruction(fileID, func);
Instruction_t* addR1R2_i = allocateNewInstruction(fileID, func);
Instruction_t* movR3R1_i = allocateNewInstruction(fileID, func);
Instruction_t* popf_i = allocateNewInstruction(fileID, func);
MEDS_InstructionCheckAnnotation addR1R2_annot;
addR1R2_annot.setValid();
addR1R2_annot.setBitWidth(32);
addR1R2_annot.setOverflow();
if (p_annotation.isSigned())
addR1R2_annot.setSigned();
else if (p_annotation.isUnsigned())
addR1R2_annot.setUnsigned();
else
addR1R2_annot.setUnknownSign();
string msg = "Originally: " + p_instruction->getDisassembly();
addPushf(pushf_i, addR1R2_i);
Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i);
pushf_i->SetFallthrough(addR1R2_i); // do I need this?
addAddRegisters(addR1R2_i, p_reg1, p_reg2, movR3R1_i);
addMovRegisters(movR3R1_i, p_reg3, p_reg1, popf_i);
addPopf(popf_i, fallthrough);
movR3R1_i->SetComment(msg);
addOverflowCheck(addR1R2_i, addR1R2_annot);
}
void IntegerTransform::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const int p_constantValue, const Register::RegisterName& p_reg3)
{
cerr << "integertransform: reg+constant: register: " << Register::toString(p_reg1) << " constant: " << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl;
// should we even attempt to instrument if we're not sure about the signedness for this pattern?
// need to use the correct PC (the one for the original lea instruction) when printing detector message
// Original instruction is of the form: lea r3, [r1+constant]
// Instrumentation:
// pushf ; save flags
// add r1, constant ; r1 = r1 + constant;
// <check for overflow> ; reuse overflow code
// mov r3, r1 ; r3 = r1 (replaces lea r3, [r1+constant])
// ; possible optimization: do nothing if r3 == r1
// popf ; restore flags
//
db_id_t fileID = p_instruction->GetAddress()->GetFileID();
Function_t* func = p_instruction->GetFunction();
Instruction_t* fallthrough = p_instruction->GetFallthrough();
Instruction_t* pushf_i = allocateNewInstruction(fileID, func);
Instruction_t* addR1Constant_i = allocateNewInstruction(fileID, func);
Instruction_t* movR3R1_i = allocateNewInstruction(fileID, func);
Instruction_t* popf_i = allocateNewInstruction(fileID, func);
MEDS_InstructionCheckAnnotation addR1Constant_annot;
addR1Constant_annot.setValid();
addR1Constant_annot.setBitWidth(32);
addR1Constant_annot.setOverflow();
if (p_annotation.isSigned())
addR1Constant_annot.setSigned();
else if (p_annotation.isUnsigned())
addR1Constant_annot.setUnsigned();
else
addR1Constant_annot.setUnknownSign();
string msg = "Originally: " + p_instruction->getDisassembly();
addPushf(pushf_i, addR1Constant_i);
Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i);
pushf_i->SetFallthrough(addR1Constant_i); // do I need this?
addAddRegisterConstant(addR1Constant_i, p_reg1, p_constantValue, movR3R1_i);
addMovRegisters(movR3R1_i, p_reg3, p_reg1, popf_i);
addPopf(popf_i, fallthrough);
movR3R1_i->SetComment(msg);
addOverflowCheck(addR1Constant_i, addR1Constant_annot);
}
void IntegerTransform::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const int p_constantValue, const Register::RegisterName& p_reg3)
{
cerr << "integertransform: reg+constant: register: " << Register::toString(p_reg1) << " constant: " << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl;
// should we even attempt to instrument if we're not sure about the signedness for this pattern?
// need to use the correct PC (the one for the original lea instruction) when printing detector message
// Original instruction is of the form: lea r3, [r1+constant]
// Instrumentation:
// pushf ; save flags
// add r1, constant ; r1 = r1 + constant;
// <check for overflow> ; reuse overflow code
// mov r3, r1 ; r3 = r1 (replaces lea r3, [r1+constant])
// ; possible optimization: do nothing if r3 == r1
// popf ; restore flags
//
db_id_t fileID = p_instruction->GetAddress()->GetFileID();
Function_t* func = p_instruction->GetFunction();
Instruction_t* fallthrough = p_instruction->GetFallthrough();
Instruction_t* pushf_i = allocateNewInstruction(fileID, func);
Instruction_t* mulR1Constant_i = allocateNewInstruction(fileID, func);
Instruction_t* movR3R1_i = allocateNewInstruction(fileID, func);
Instruction_t* popf_i = allocateNewInstruction(fileID, func);
MEDS_InstructionCheckAnnotation mulR1Constant_annot;
mulR1Constant_annot.setValid();
mulR1Constant_annot.setBitWidth(32);
mulR1Constant_annot.setOverflow();
if (p_annotation.isSigned())
mulR1Constant_annot.setSigned();
else if (p_annotation.isUnsigned())
mulR1Constant_annot.setUnsigned();
else
mulR1Constant_annot.setUnknownSign();
string msg = "Originally: " + p_instruction->getDisassembly();
addPushf(pushf_i, mulR1Constant_i);
Instruction_t* originalInstrumentInstr = carefullyInsertBefore(p_instruction, pushf_i);
pushf_i->SetFallthrough(mulR1Constant_i); // do I need this?
addMulRegisterConstant(mulR1Constant_i, p_reg1, p_constantValue, movR3R1_i);
addMovRegisters(movR3R1_i, p_reg3, p_reg1, popf_i);
addPopf(popf_i, fallthrough);
movR3R1_i->SetComment(msg);
addOverflowCheck(mulR1Constant_i, mulR1Constant_annot);
return;
}
void IntegerTransform::handleTruncation(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation)
{
if (p_annotation.getTruncationFromWidth() == 32 && (p_annotation.getTruncationToWidth() == 16 || p_annotation.getTruncationToWidth() == 8))
{
cerr << "TRUNCATION: 32->16: need to handle unsigned case" << endl;
// need to check upper 16 bits are all 0's
addTruncationCheck(p_instruction, p_annotation);
}
else
{
cerr << "TRUNCATION: error: unknown sign type in annotation" << endl;
// error
cerr << "integertransform: TRUNCATION annotation not yet handled: " << p_annotation.toString() << endl;
}
}
#endif
//
// <instruction to instrument>
......@@ -292,6 +430,7 @@ void IntegerTransform::addTruncationCheck32to16(Instruction_t *p_instruction, co
//
void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation)
{
cerr << "IntegerTransform::addOverflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << endl;
assert(getVariantIR() && p_instruction);
string detector(INTEGER_OVERFLOW_DETECTOR);
......@@ -452,6 +591,6 @@ void IntegerTransform::addTruncationCheck(Instruction_t *p_instruction, const ME
addNop(nop_i, popf_i);
nop_i->SetComment(string("NOP NOP"));
addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i);
addCallbackHandler(detector, originalInstrumentInstr, nop_i, popf_i, p_instruction);
addPopf(popf_i, originalInstrumentInstr);
}
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <sstream>
#include "leapattern.h"
using namespace std;
using namespace libTransform;
LEAPattern::LEAPattern(const MEDS_InstructionCheckAnnotation& p_annotation)
{
m_isValid = false;
m_isRegPlusReg = false;
m_isRegPlusConstant = false;
m_isRegTimesConstant = false;
m_isRegTimesReg = false;
m_reg1 = Register::UNKNOWN;
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_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_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_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_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;
const int max = 5;
regmatch_t pmatch[max];
int countMatch = 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++;
m_isRegPlusReg = true;
m_reg1 = Register::getRegister(p_annotation.getTarget().substr(0,3));
m_reg2 = Register::getRegister(p_annotation.getTarget().substr(4,3));
if (m_reg1 != Register::UNKNOWN && m_reg2 != Register::UNKNOWN)
m_isValid = true;
}
if(regexec(&m_regex_reg_times_reg, p_annotation.getTarget().c_str(), max, pmatch, 0)==0)
{
// pattern is of the form reg*reg, e.g.: EDX*EAX
// nb: is this even a valid pattern -- not used
countMatch++;
m_isRegPlusReg = true;
m_reg1 = Register::getRegister(p_annotation.getTarget().substr(0,3));
m_reg2 = Register::getRegister(p_annotation.getTarget().substr(4,3));
if (m_reg1 != Register::UNKNOWN && m_reg2 != Register::UNKNOWN)
m_isValid = true;
}
if(regexec(&m_regex_reg_plus_constant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0 ||
regexec(&m_regex_reg_plus_negconstant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0)
{
// pattern is of the form: reg+constant, e.g.: EDX+16
// pattern is of the form: reg+-constant, e.g.: EAX+-16
// note that constant value of annotation is in decimal (not hex)
countMatch++;
m_isRegPlusConstant = true;
m_reg1 = Register::getRegister(p_annotation.getTarget().substr(0,3));
stringstream constantSS(p_annotation.getTarget().substr(4));
if (constantSS >> m_constant)
{
m_isValid = true;
}
cerr << "leapattern: reg+-constant: constant: " << m_constant << endl;
}
if(regexec(&m_regex_reg_times_constant, p_annotation.getTarget().c_str(), max, pmatch, 0)==0)
{
countMatch++;
// pattern is of the form: reg*constant, e.g.: EDX*4
// note that constant value of annotation is in decimal (not hex)
m_isRegTimesConstant = true;
m_reg1 = Register::getRegister(p_annotation.getTarget().substr(0,3));
stringstream constantSS(p_annotation.getTarget().substr(4));
if (constantSS >> m_constant)
{
m_isValid = true;
}
}
if (countMatch == 0 || countMatch > 1)
{
cerr << "leapattern: fail sanity check -- there are more than 1 pattern that match" << endl;
m_isValid = false;
}
}
bool LEAPattern::isValid() const
{
return m_isValid;
}
bool LEAPattern::isRegisterPlusRegister() const
{
return m_isRegPlusReg;
}
bool LEAPattern::isRegisterTimesRegister() const
{
return m_isRegTimesReg;
}
bool LEAPattern::isRegisterPlusConstant() const
{
return m_isRegPlusConstant;
}
bool LEAPattern::isRegisterTimesConstant() const
{
return m_isRegTimesConstant;
}
Register::RegisterName LEAPattern::getRegister1() const
{
return m_reg1;
}
Register::RegisterName LEAPattern::getRegister2() const
{
return m_reg2;
}
int LEAPattern::getConstant() const
{
return m_constant;
}
......@@ -236,7 +236,7 @@ virtual_offset_t Transform::getAvailableAddress()
return 0xf0000000 + counter;
}
void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumentedInstruction, Instruction_t *p_instruction, Instruction_t *p_fallThrough)
void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumentedInstruction, Instruction_t *p_instruction, Instruction_t *p_fallThrough, Instruction_t *p_originalInstruction)
{
assert(getVariantIR() && p_instruction);
......@@ -273,7 +273,10 @@ void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumen
dataBits.resize(5);
dataBits[0] = 0x68;
virtual_offset_t *tmp = (virtual_offset_t *) &dataBits[1];
*tmp = p_instrumentedInstruction->GetAddress()->GetVirtualOffset();
if (p_originalInstruction)
*tmp = p_originalInstruction->GetAddress()->GetVirtualOffset();
else
*tmp = p_instrumentedInstruction->GetAddress()->GetVirtualOffset();
pusharg_i->SetDataBits(dataBits);
pusharg_i->SetComment(pusharg_i->getDisassembly());
pusharg_i->SetFallthrough(pushret_i);
......@@ -303,6 +306,30 @@ void Transform::addCallbackHandler(string p_detector, Instruction_t *p_instrumen
addPopa(popa_i, p_fallThrough);
}
// returns true if BeaEngine says arg1 of the instruction is a register
bool Transform::hasTargetRegister(Instruction_t *p_instruction)
{
if (!p_instruction)
return false;
DISASM disasm;
p_instruction->Disassemble(disasm);
return disasm.Argument1.ArgType & 0xFFFF0000 & REGISTER_TYPE;
}
Register::RegisterName Transform::getTargetRegister(Instruction_t *p_instruction)
{
if (hasTargetRegister(p_instruction))
{
DISASM disasm;
p_instruction->Disassemble(disasm);
return Register::getRegister(disasm.Argument1.ArgMnemonic);
}
else
return Register::UNKNOWN;
}
//
// Returns true iff instruction is MUL (according to BeaEngine)
......@@ -313,7 +340,6 @@ bool Transform::isMultiplyInstruction(Instruction_t *p_instruction)
return false;
DISASM disasm;
p_instruction->Disassemble(disasm);
// beaengine adds space at the end of the mnemonic string
......@@ -703,3 +729,68 @@ void Transform::addNot(Instruction_t *p_instr, Register::RegisterName p_reg, Ins
addInstruction(p_instr, dataBits, p_fallThrough, NULL);
}
// add r1, r2
void Transform::addAddRegisters(Instruction_t *p_instr, Register::RegisterName p_regTgt, Register::RegisterName p_regSrc, Instruction_t *p_fallThrough)
{
// too many combinations, just use the assembler
string assembly = "add " + Register::toString(p_regTgt) + ", " + Register::toString(p_regSrc);
if (!p_instr->Assemble(assembly))
{
cerr << "addAddRegisters(): error in assembling instruction: " << assembly << endl;
return;
}
cerr << "addAddRegisters(): " << p_instr->getDisassembly() << endl;
p_instr->SetFallthrough(p_fallThrough);
}
// add r1, constant
void Transform::addAddRegisterConstant(Instruction_t *p_instr, Register::RegisterName p_reg, int p_constantValue, Instruction_t *p_fallThrough)
{
// too many combinations, just use the assembler
char buf[256];
sprintf(buf, "add %s, %d", Register::toString(p_reg).c_str(), p_constantValue);
string assembly(buf);
if (!p_instr->Assemble(assembly))
{
cerr << "Transform::addAddConstant(): error in assembling instruction: " << assembly << endl;
return;
}
cerr << "Transform::addAddConstant(): " << p_instr->getDisassembly() << endl;
p_instr->SetFallthrough(p_fallThrough);
}
// imul r1, constant
void Transform::addMulRegisterConstant(Instruction_t *p_instr, Register::RegisterName p_reg, int p_constantValue, Instruction_t *p_fallThrough)
{
// too many combinations, just use the assembler
char buf[256];
sprintf(buf, "imul %s, %d", Register::toString(p_reg).c_str(), p_constantValue);
string assembly(buf);
if (!p_instr->Assemble(assembly))
{
cerr << "Transform::addMulRegisterConstant(): error in assembling instruction: " << assembly << endl;
return;
}
cerr << "Transform::addMulRegisterConstant(): " << p_instr->getDisassembly() << endl;
p_instr->SetFallthrough(p_fallThrough);
}
// mov r1, r2
void Transform::addMovRegisters(Instruction_t *p_instr, Register::RegisterName p_regTgt, Register::RegisterName p_regSrc, Instruction_t *p_fallThrough)
{
// too many combinations, just use the assembler
string assembly = "mov " + Register::toString(p_regTgt) + ", " + Register::toString(p_regSrc);
if (!p_instr->Assemble(assembly))
{
cerr << "addMovRegisters(): error in assembling instruction: " << assembly << endl;
return;
}
p_instr->SetFallthrough(p_fallThrough);
cerr << "addMovRegisters(): " << p_instr->getDisassembly() << endl;
}
#!/bin/bash
#types="char short int long unsigned+char unsigned+short unsigned+int unsigned+long";
types="unsigned+int int"
types="int unsigned+int"
#types="int"
#sharedlib_gccflags="-O -O2 -w"
#sharedlib_gccflags="-w -O2"
sharedlib_gccflags="-w"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment