Last active
June 6, 2019 05:59
-
-
Save connglli/a305fefdf9b3b152983ff14481ba9374 to your computer and use it in GitHub Desktop.
Taint Analysis Example (Intel Pin 3.7, Ubuntu 14.04, 32bit)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* See the following link for a tutorial | |
* http://shell-storm.org/blog/Taint-analysis-and-pattern-matching-with-Pin/#1 | |
*/ | |
#include <iostream> | |
#include <list> | |
#include <set> | |
#include <algorithm> | |
#include <asm/unistd.h> | |
#include "pin.H" | |
#ifndef __DEBUG_MY | |
#define __DEBUG_MY 0 | |
#endif | |
#ifndef __DEBUG_MY_INFO | |
#define __DEBUG_MY_INFO 0 | |
#endif | |
#ifndef __DEBUG_MY_INFO_ONLY_USER | |
#define __DEBUG_MY_INFO_ONLY_USER 1 | |
#endif | |
#define TO_ADDR(x) static_cast<ADDRINT>(x) | |
#define TO_UINT(x) static_cast<UINT32>(x) | |
#define TRICKS() do { if (lock ++ == 0) return; } while(0) | |
#define ADDR_VALID(a) ((a) <= 0x8049000 ? true : false) | |
unsigned int lock = 0; | |
// tainted addresses | |
std::set<ADDRINT> taintedAddr; | |
// tainted registers | |
std::set<REG> taintedReg; | |
// tainting addresses of functions | |
std::set<ADDRINT> taintedFunc; | |
// tainting addresses of cmp/test | |
std::set<ADDRINT> taintedCT; | |
VOID PrintTaintedAddr() { | |
std::list<ADDRINT> l; | |
for (std::set<ADDRINT>::iterator it = taintedAddr.begin(); it!=taintedAddr.end(); it ++) { | |
if (*it >= 0x80d7000 && *it <=0x80db000) { | |
l.push_back(*it); | |
} | |
} | |
l.sort(); | |
for (std::list<ADDRINT>::iterator it = l.begin(); it != l.end(); it ++) { | |
std::cout << std::hex << "0x" << *it << std::endl; | |
} | |
} | |
VOID PrintTaintedFunc() { | |
std::list<ADDRINT> l; | |
for (std::set<ADDRINT>::iterator it = taintedFunc.begin(); it!=taintedFunc.end(); it ++) { | |
if (*it <= 0x8049000) { | |
l.push_back(*it); | |
} | |
} | |
l.sort(); | |
for (std::list<ADDRINT>::iterator it = l.begin(); it != l.end(); it ++) { | |
std::cout << std::hex << "0x" << *it << std::endl; | |
} | |
} | |
VOID PrintTaintedCT() { | |
std::list<ADDRINT> l; | |
for (std::set<ADDRINT>::iterator it = taintedCT.begin(); it!=taintedCT.end(); it ++) { | |
if (*it <= 0xb0000000) { | |
l.push_back(*it); | |
} | |
} | |
l.sort(); | |
for (std::list<ADDRINT>::iterator it = l.begin(); it != l.end(); it ++) { | |
std::cout << std::hex << "0x" << *it << std::endl; | |
} | |
} | |
VOID Fini(INT32 code, VOID* v) { | |
// PrintTaintedAddr(); | |
// PrintTaintedFunc(); | |
PrintTaintedCT(); | |
} | |
VOID UntaintAddr(ADDRINT addr) { | |
std::set<ADDRINT>::iterator it = taintedAddr.find(addr); | |
if (it != taintedAddr.end()) { | |
taintedAddr.erase(it); | |
} | |
} | |
VOID TaintAddrSafely(ADDRINT addr, UINT32 len) { | |
for (UINT32 i = 0; i < len; i ++) { | |
taintedAddr.insert(TO_ADDR(TO_UINT(addr) + i)); | |
} | |
} | |
VOID UntaintAddrSafely(ADDRINT addr, UINT32 len) { | |
for (UINT32 i = 0; i < len; i ++) { | |
UntaintAddr(TO_ADDR(TO_UINT(addr) + i)); | |
} | |
} | |
VOID UntaintReg(REG reg) { | |
std::set<REG>::iterator it = taintedReg.find(reg); | |
if (it != taintedReg.end()) { | |
taintedReg.erase(it); | |
} | |
} | |
VOID TaintRegSafely(REG reg) { | |
switch(reg){ | |
case REG_EAX: taintedReg.insert(REG_EAX); | |
case REG_AX: taintedReg.insert(REG_AX); | |
case REG_AH: taintedReg.insert(REG_AH); | |
case REG_AL: taintedReg.insert(REG_AL); | |
break; | |
case REG_EBX: taintedReg.insert(REG_EBX); | |
case REG_BX: taintedReg.insert(REG_BX); | |
case REG_BH: taintedReg.insert(REG_BH); | |
case REG_BL: taintedReg.insert(REG_BL); | |
break; | |
case REG_ECX: taintedReg.insert(REG_ECX); | |
case REG_CX: taintedReg.insert(REG_CX); | |
case REG_CH: taintedReg.insert(REG_CH); | |
case REG_CL: taintedReg.insert(REG_CL); | |
break; | |
case REG_EDX: taintedReg.insert(REG_EDX); | |
case REG_DX: taintedReg.insert(REG_DX); | |
case REG_DH: taintedReg.insert(REG_DH); | |
case REG_DL: taintedReg.insert(REG_DL); | |
break; | |
case REG_EDI: taintedReg.insert(REG_EDI); | |
case REG_DI: taintedReg.insert(REG_DI); | |
break; | |
case REG_ESI: taintedReg.insert(REG_ESI); | |
case REG_SI: taintedReg.insert(REG_SI); | |
break; | |
case REG_EBP: taintedReg.insert(REG_EBP); | |
case REG_BP: taintedReg.insert(REG_BP); | |
break; | |
case REG_ESP: taintedReg.insert(REG_ESP); | |
case REG_SP: taintedReg.insert(REG_SP); | |
break; | |
case REG_EIP: taintedReg.insert(REG_EIP); | |
case REG_IP: taintedReg.insert(REG_IP); | |
break; | |
case REG_EFLAGS: taintedReg.insert(REG_EFLAGS); | |
case REG_FLAGS: taintedReg.insert(REG_FLAGS); | |
break; | |
default: | |
taintedReg.insert(reg); | |
break; | |
} | |
} | |
VOID UntaintRegSafely(REG reg) { | |
switch(reg){ | |
case REG_EAX: UntaintReg(REG_EAX); | |
case REG_AX: UntaintReg(REG_AX); | |
case REG_AH: UntaintReg(REG_AH); | |
case REG_AL: UntaintReg(REG_AL); | |
break; | |
case REG_EBX: UntaintReg(REG_EBX); | |
case REG_BX: UntaintReg(REG_BX); | |
case REG_BH: UntaintReg(REG_BH); | |
case REG_BL: UntaintReg(REG_BL); | |
break; | |
case REG_ECX: UntaintReg(REG_ECX); | |
case REG_CX: UntaintReg(REG_CX); | |
case REG_CH: UntaintReg(REG_CH); | |
case REG_CL: UntaintReg(REG_CL); | |
break; | |
case REG_EDX: UntaintReg(REG_EDX); | |
case REG_DX: UntaintReg(REG_DX); | |
case REG_DH: UntaintReg(REG_DH); | |
case REG_DL: UntaintReg(REG_DL); | |
break; | |
case REG_EDI: UntaintReg(REG_EDI); | |
case REG_DI: UntaintReg(REG_DI); | |
break; | |
case REG_ESI: UntaintReg(REG_ESI); | |
case REG_SI: UntaintReg(REG_SI); | |
break; | |
case REG_EBP: UntaintReg(REG_EBP); | |
case REG_BP: UntaintReg(REG_BP); | |
break; | |
case REG_ESP: UntaintReg(REG_ESP); | |
case REG_SP: UntaintReg(REG_SP); | |
break; | |
case REG_EIP: UntaintReg(REG_EIP); | |
case REG_IP: UntaintReg(REG_IP); | |
break; | |
case REG_EFLAGS: UntaintReg(REG_EFLAGS); | |
case REG_FLAGS: UntaintReg(REG_FLAGS); | |
break; | |
default: | |
UntaintReg(reg); | |
break; | |
} | |
} | |
VOID SyscallEntry(THREADID thread_id, CONTEXT* ctx, SYSCALL_STANDARD std, VOID* v) { | |
ADDRINT start_addr, end_addr; | |
if (PIN_GetSyscallNumber(ctx, std) != __NR_read) return; | |
// TRICKS(); | |
start_addr = TO_ADDR(PIN_GetSyscallArgument(ctx, std, 1)); | |
end_addr = start_addr + TO_ADDR(PIN_GetSyscallArgument(ctx, std, 2)); | |
for (ADDRINT addr = start_addr; addr < end_addr; addr ++) { | |
taintedAddr.insert(TO_ADDR(addr)); | |
} | |
#if(__DEBUG_MY) | |
std::cout << "[Source]: " << std::hex | |
<< "(0x" << TO_UINT(start_addr) << ", 0x" | |
<< TO_UINT(end_addr) << ")" | |
<< std::endl; | |
#endif | |
} | |
VOID ReadMem(ADDRINT insAddr, | |
std::string insAsm, | |
UINT32 opCount, | |
REG reg_w, | |
UINT32 memOp, | |
UINT32 sp) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[R] 0x" << TO_UINT(insAddr) << " " << insAsm << ", " | |
<< "opCount: " << opCount << ", " | |
<< "reg_w: " << REG_StringShort(reg_w) << ", " | |
<< "memOp: 0x" << memOp << ", " | |
<< "sp: 0x" << sp | |
<< std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
if (opCount != 2) return; | |
ADDRINT addr_r = TO_ADDR(memOp); | |
std::set<ADDRINT>::iterator it = taintedAddr.find(addr_r); | |
// addr_r is tainted, then taint reg_w | |
if (it != taintedAddr.end()) { | |
if (taintedReg.find(reg_w) == taintedReg.end()) { | |
TaintRegSafely(reg_w); | |
#if(__DEBUG_MY) | |
std::cout << "[Taint: ReadMem] " | |
<< REG_StringShort(reg_w) << " <- 0x" << TO_UINT(addr_r) | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
return; | |
} | |
// addr_r is untainted, untaint reg_w if already tainted | |
if (taintedReg.find(reg_w) != taintedReg.end()) { | |
UntaintRegSafely(reg_w); | |
#if(__DEBUG_MY) | |
std::cout << "[Untaint: ReadMem] " | |
<< REG_StringShort(reg_w) << " <- 0x" << TO_UINT(addr_r) | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
} | |
VOID WriteMem(ADDRINT insAddr, | |
std::string insAsm, | |
UINT32 opCount, | |
REG reg_r, | |
REG reg_0, | |
UINT32 memOp, | |
UINT32 sp) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[W] 0x" << TO_UINT(insAddr) << " " << insAsm << ", " | |
<< "opCount: " << opCount << ", " | |
<< "reg_r: " << REG_StringShort(reg_r) << ", " | |
<< "reg_0: " << REG_StringShort(reg_0) << ", " | |
<< "memOp: 0x" << memOp << ", " | |
<< "sp: 0x" << sp | |
<< std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
if (opCount != 2) return; | |
ADDRINT addr_w = TO_ADDR(memOp); | |
if (!REG_valid(reg_r)) { | |
if (REG_valid(reg_0)) { | |
// push ebp => write stack | |
reg_r = reg_0; | |
} else { | |
// mov dword ptr [ebx+0x1880], 0x0 => write constant to the memory | |
// call 0xf5509595 => write return address to stack | |
} | |
} | |
// reg_r is invalid, untaint addr_w if already tainted | |
if (!REG_valid(reg_r)) { | |
if (taintedAddr.find(addr_w) != taintedAddr.end()) { | |
UINT32 len = 4; | |
if (insAsm.find("dword ptr", 0) != std::string::npos) { | |
len = 4; | |
} else if (insAsm.find("word ptr", 0) != std::string::npos) { | |
len = 2; | |
} else { | |
len = 1; | |
} | |
UntaintAddrSafely(addr_w, len); | |
#if(__DEBUG_MY) | |
std::cout << "[Untaint: WriteMem] " | |
<< "0x" << TO_UINT(addr_w) << "(" << len << ") <- const" | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
return; | |
} | |
// reg_r is valid, and reg_r is tainted, taint addr_w if untainted | |
if (taintedReg.find(reg_r) != taintedReg.end() && | |
taintedAddr.find(addr_w) == taintedAddr.end()) { | |
UINT32 len = 4; | |
if (REG_is_Lower8(reg_r) || REG_is_Upper8(reg_r)) { | |
len = 1; | |
} else if (REG_is_Half16(reg_r)) { | |
len = 2; | |
} else if (REG_is_Half32(reg_r)) { | |
len = 4; | |
} | |
TaintAddrSafely(addr_w, len); | |
#if(__DEBUG_MY) | |
std::cout << "[Taint: WriteMem] " | |
<< "0x" << TO_UINT(addr_w) << "(" << len << ") <- " << REG_StringShort(reg_r) | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
} | |
VOID SpreadReg(ADDRINT insAddr, | |
std::string insAsm, | |
UINT32 opCount, | |
REG reg_r, | |
REG reg_w) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[S] 0x" << TO_UINT(insAddr) << " " << insAsm << ", " | |
<< "opCount: " << opCount << ", " | |
<< "reg_r: " << REG_StringShort(reg_r) << ", " | |
<< "reg_w: " << REG_StringShort(reg_w) | |
<< std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
if (!REG_valid(reg_w)) return; | |
// reg_r is valid, (un)taint reg_w if needed | |
if (REG_valid(reg_r)) { | |
// reg_r tainted, taint reg_w if untainted | |
if (taintedReg.find(reg_r) != taintedReg.end()) { | |
if (taintedReg.find(reg_w) == taintedReg.end()) { | |
TaintRegSafely(reg_w); | |
#if(__DEBUG_MY) | |
std::cout << "[Taint: SpreadReg] " | |
<< REG_StringShort(reg_w) << " <- " << REG_StringShort(reg_r) | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
} | |
// reg_r untainted, untained reg_w if tainted | |
else { | |
if (taintedReg.find(reg_w) != taintedReg.end()) { | |
UntaintRegSafely(reg_w); | |
#if(__DEBUG_MY) | |
std::cout << "[Untaint: SpreadReg] " | |
<< REG_StringShort(reg_w) << " <- " << REG_StringShort(reg_r) | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
} | |
return; | |
} | |
// reg_r is invalid, untaint reg_w if tainted, mov eax, 0x3 | |
if (taintedReg.find(reg_w) != taintedReg.end()) { | |
UntaintRegSafely(reg_w); | |
#if(__DEBUG_MY) | |
std::cout << "[Untaint: SpreadReg] " | |
<< REG_StringShort(reg_w) << " <- const" | |
<< ": 0x" << TO_UINT(insAddr) << " " << insAsm | |
<< std::endl; | |
#endif | |
} | |
} | |
VOID FunctionCall(ADDRINT insAddr, | |
std::string insAsm, | |
REG reg, | |
CONTEXT* ctx) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[FC] 0x" << TO_UINT(insAddr) << " " << insAsm << ", " | |
<< "reg: " << REG_StringShort(reg) | |
<< std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
if (!REG_valid(reg)) return; | |
// reg tainted, push its value | |
if (taintedReg.find(reg) != taintedReg.end()) { | |
UINT32 reg_value; | |
PIN_GetContextRegval(ctx, reg, (UINT8*)®_value); | |
taintedFunc.insert(insAddr); | |
std::cout << "WARN: Function address got tainted at 0x" << TO_ADDR(insAddr) << ": 0x" << reg_value << std::endl; | |
} | |
} | |
VOID FunctionReturn(ADDRINT insAddr, | |
std::string insAsm, | |
CONTEXT* ctx) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[FR] 0x" << TO_UINT(insAddr) << " " << insAsm << std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
// check esp (where return address is saved) | |
ADDRINT esp_value; | |
PIN_GetContextRegval(ctx, REG_ESP, (UINT8*)&esp_value); | |
if (taintedAddr.find(esp_value) != taintedAddr.end()) { | |
std::cout << "ERROR: Return address got tainted: $esp: 0x" << TO_UINT(esp_value) << std::endl; | |
} | |
} | |
VOID InstructionCmpReg(ADDRINT insAddr, | |
std::string insAsm, | |
REG reg_0, | |
REG reg_1) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[ICR] 0x" << TO_UINT(insAddr) << " " << insAsm << std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
if (REG_valid(reg_0)) { | |
if (taintedReg.find(reg_0) != taintedReg.end()) { | |
taintedCT.insert(insAddr); | |
std::cout << "WARN: Cmp address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
} | |
if (reg_1 != reg_0 && REG_valid(reg_1)) { | |
if (taintedReg.find(reg_1) != taintedReg.end()) { | |
taintedCT.insert(insAddr); | |
std::cout << "WARN: Cmp address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
} | |
} | |
VOID InstructionCmpMem(ADDRINT insAddr, | |
std::string insAsm, | |
UINT32 memOp, REG reg) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[ICM] 0x" << TO_UINT(insAddr) << " " << insAsm << std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
ADDRINT addr = TO_ADDR(memOp); | |
if (taintedAddr.find(addr) != taintedAddr.end()) { | |
taintedCT.insert(addr); | |
std::cout << "WARN: Cmp address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
if (REG_valid(reg)) { | |
if (taintedReg.find(reg) != taintedReg.end()) { | |
taintedCT.insert(insAddr); | |
std::cout << "WARN: Cmp address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
} | |
} | |
VOID InstructionTestReg(ADDRINT insAddr, | |
std::string insAsm, | |
REG reg_0, | |
REG reg_1) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[ITR] 0x" << TO_UINT(insAddr) << " " << insAsm << std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
if (REG_valid(reg_0)) { | |
if (taintedReg.find(reg_0) != taintedReg.end()) { | |
taintedCT.insert(insAddr); | |
std::cout << "WARN: Test address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
} | |
if (reg_1 != reg_0 && REG_valid(reg_1)) { | |
if (taintedReg.find(reg_1) != taintedReg.end()) { | |
taintedCT.insert(insAddr); | |
std::cout << "WARN: Test address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
} | |
} | |
VOID InstructionTestMem(ADDRINT insAddr, | |
std::string insAsm, | |
UINT32 memOp, REG reg) { | |
#if(__DEBUG_MY_INFO) | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
if (TO_UINT(insAddr) < 0x8049000) { | |
#endif | |
std::cout << "[ITM] 0x" << TO_UINT(insAddr) << " " << insAsm << std::endl; | |
#if(__DEBUG_MY_INFO_ONLY_USER) | |
} | |
#endif | |
#endif | |
ADDRINT addr = TO_ADDR(memOp); | |
if (taintedAddr.find(addr) != taintedAddr.end()) { | |
taintedCT.insert(addr); | |
std::cout << "WARN: Test address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
if (REG_valid(reg)) { | |
if (taintedReg.find(reg) != taintedReg.end()) { | |
taintedCT.insert(insAddr); | |
std::cout << "WARN: Cmp address got tainted at 0x" << TO_ADDR(insAddr) << std::endl; | |
} | |
} | |
} | |
VOID Instruction(INS ins, VOID* v) { | |
UINT32 opCount = INS_OperandCount(ins); | |
UINT32 opcode = INS_Opcode(ins); | |
// taint and spread | |
if (opCount > 1 && INS_MemoryOperandIsRead(ins, 0)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) ReadMem, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_UINT32, opCount, | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_MEMORYOP_EA, 0, | |
IARG_REG_VALUE, REG_STACK_PTR, | |
IARG_END); | |
} else if (opCount > 1 && INS_MemoryOperandIsWritten(ins, 0)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) WriteMem, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_UINT32, opCount, | |
IARG_UINT32, INS_OperandReg(ins, 1), | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_MEMORYOP_EA, 0, | |
IARG_REG_VALUE, REG_STACK_PTR, | |
IARG_END); | |
} else if (opCount > 1 && INS_OperandIsReg(ins, 0)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) SpreadReg, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_UINT32, opCount, | |
IARG_UINT32, INS_RegR(ins, 0), | |
IARG_UINT32, INS_RegW(ins, 0), | |
IARG_END); | |
} | |
// check | |
if (opcode == XED_ICLASS_CALL_FAR || opcode == XED_ICLASS_CALL_NEAR) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) FunctionCall, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_CONTEXT, | |
IARG_END); | |
} | |
if (INS_IsRet(ins)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) FunctionReturn, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_CONTEXT, | |
IARG_END); | |
} | |
if (opcode == XED_ICLASS_TEST) { | |
if (INS_OperandIsMemory(ins, 0)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) InstructionTestMem, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_MEMORYOP_EA, 0, | |
IARG_UINT32, INS_OperandReg(ins, 1), | |
IARG_END); | |
} else if (INS_OperandIsMemory(ins, 1)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) InstructionTestMem, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_MEMORYOP_EA, 0, | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_END); | |
} else if (INS_OperandIsReg(ins, 0) and INS_OperandIsReg(ins, 1)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) InstructionTestReg, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_UINT32, INS_OperandReg(ins, 1), | |
IARG_END); | |
} | |
} | |
if (opcode == XED_ICLASS_CMP) { | |
if (INS_OperandIsMemory(ins, 0)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) InstructionCmpMem, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_MEMORYOP_EA, 0, | |
IARG_UINT32, INS_OperandReg(ins, 1), | |
IARG_END); | |
} else if (INS_OperandIsMemory(ins, 1)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) InstructionCmpMem, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_MEMORYOP_EA, 0, | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_END); | |
} else if (INS_OperandIsReg(ins, 0)) { | |
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) InstructionCmpReg, | |
IARG_ADDRINT, INS_Address(ins), | |
IARG_PTR, new std::string(INS_Disassemble(ins)), | |
IARG_UINT32, INS_OperandReg(ins, 0), | |
IARG_UINT32, INS_OperandReg(ins, 1), | |
IARG_END); | |
} | |
} | |
} | |
int Usage() { | |
std::cout << "Usage" << std::endl; | |
return -1; | |
} | |
int main(int argc, char* argv[]) { | |
std::cout << std::hex; | |
if (PIN_Init(argc, argv)) { | |
return Usage(); | |
} | |
PIN_AddSyscallEntryFunction(SyscallEntry, 0); | |
INS_AddInstrumentFunction(Instruction, 0); | |
PIN_AddFiniFunction(Fini, 0); | |
PIN_StartProgram(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment