VOID WriteMem(UINT32 insAddr, std::string insDis, UINT32 opCount, REG reg_r, UINT32 memOp, UINT32 sp) { list<UINT32>::iterator i; list<struct mallocArea>::iterator i2; UINT32 addr = memOp; if (opCount != 2) return; for(i2 = mallocAreaList.begin(); i2 != mallocAreaList.end(); i2++){ if (addr >= i2->base && addr < (i2->base + i2->size) && i2->status == FREE){ std::cout << std::hex << "[UAF in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; return; } } for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; if (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r)) removeMemTainted(addr); if (sp > addr && addr > 0x700000000000) std::cout << std::hex << "[UAF in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; return ; } } if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; addMemTainted(addr); } }
VOID followData(UINT32 insAddr, std::string insDis, REG reg) { if (!REG_valid(reg)) return; if (checkAlreadyRegTainted(reg)){ std::cout << "[FOLLOW]\t\t" << insAddr << ": " << insDis << std::endl; } }
VOID spreadRegTaint(UINT32 insAddr, std::string insDis, UINT32 opCount, REG reg_r, REG reg_w) { if (opCount != 2) return; if (REG_valid(reg_w)){ if (checkAlreadyRegTainted(reg_w) && (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r))){ std::cout << "[SPREAD]\t\t" << insAddr << ": " << insDis << std::endl; std::cout << "\t\t\toutput: "<< REG_StringShort(reg_w) << " | input: " << (REG_valid(reg_r) ? REG_StringShort(reg_r) : "constant") << std::endl; removeRegTainted(reg_w); } else if (!checkAlreadyRegTainted(reg_w) && checkAlreadyRegTainted(reg_r)){ std::cout << "[SPREAD]\t\t" << insAddr << ": " << insDis << std::endl; std::cout << "\t\t\toutput: " << REG_StringShort(reg_w) << " | input: "<< REG_StringShort(reg_r) << std::endl; taintReg(reg_w); } } }
bool taintReg(REG reg) { if (checkAlreadyRegTainted(reg) == true){ std::cout << "\t\t\t" << REG_StringShort(reg) << " is already tainted" << std::endl; return false; } switch(reg){ case REG_RAX: regsTainted.push_front(REG_RAX); case REG_EAX: regsTainted.push_front(REG_EAX); case REG_AX: regsTainted.push_front(REG_AX); case REG_AH: regsTainted.push_front(REG_AH); case REG_AL: regsTainted.push_front(REG_AL); break; case REG_RBX: regsTainted.push_front(REG_RBX); case REG_EBX: regsTainted.push_front(REG_EBX); case REG_BX: regsTainted.push_front(REG_BX); case REG_BH: regsTainted.push_front(REG_BH); case REG_BL: regsTainted.push_front(REG_BL); break; case REG_RCX: regsTainted.push_front(REG_RCX); case REG_ECX: regsTainted.push_front(REG_ECX); case REG_CX: regsTainted.push_front(REG_CX); case REG_CH: regsTainted.push_front(REG_CH); case REG_CL: regsTainted.push_front(REG_CL); break; case REG_RDX: regsTainted.push_front(REG_RDX); case REG_EDX: regsTainted.push_front(REG_EDX); case REG_DX: regsTainted.push_front(REG_DX); case REG_DH: regsTainted.push_front(REG_DH); case REG_DL: regsTainted.push_front(REG_DL); break; case REG_RDI: regsTainted.push_front(REG_RDI); case REG_EDI: regsTainted.push_front(REG_EDI); case REG_DI: regsTainted.push_front(REG_DI); case REG_DIL: regsTainted.push_front(REG_DIL); break; case REG_RSI: regsTainted.push_front(REG_RSI); case REG_ESI: regsTainted.push_front(REG_ESI); case REG_SI: regsTainted.push_front(REG_SI); case REG_SIL: regsTainted.push_front(REG_SIL); break; default: std::cout << "\t\t\t" << REG_StringShort(reg) << " can't be tainted" << std::endl; return false; } std::cout << "\t\t\t" << REG_StringShort(reg) << " is now tainted" << std::endl; return true; }
VOID WriteMem(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg_r, UINT64 memOp) { list<UINT64>::iterator i; UINT64 addr = memOp; if (opCount != 2) return; for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; if (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r)) removeMemTainted(addr); return ; } } if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; addMemTainted(addr); } }
VOID spreadRegTaint(INS ins) { REG reg_r, reg_w; if (INS_OperandCount(ins) != 2) return; reg_r = INS_RegR(ins, 0); reg_w = INS_RegW(ins, 0); if (REG_valid(reg_w)){ if (checkAlreadyRegTainted(reg_w) && (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r))){ std::cout << "[SPREAD]\t\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; std::cout << "\t\t\toutput: "<< REG_StringShort(reg_w) << " | input: " << (REG_valid(reg_r) ? REG_StringShort(reg_r) : "constant") << std::endl; removeRegTainted(reg_w); } else if (!checkAlreadyRegTainted(reg_w) && checkAlreadyRegTainted(reg_r)){ std::cout << "[SPREAD]\t\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; std::cout << "\t\t\toutput: " << REG_StringShort(reg_w) << " | input: "<< REG_StringShort(reg_r) << std::endl; taintReg(reg_w); } } }
VOID WriteMem(INS ins, UINT64 memOp) { list<UINT64>::iterator i; UINT64 addr = memOp; REG reg_r; if (INS_OperandCount(ins) != 2) return; reg_r = INS_OperandReg(ins, 1); for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; if (!REG_valid(reg_r) || !checkAlreadyRegTainted(reg_r)) removeMemTainted(addr); return ; } } if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[WRITE in " << addr << "]\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; addMemTainted(addr); } }
VOID ReadMem(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg_r, UINT64 memOp) { list<UINT64>::iterator i; UINT64 addr = memOp; if (opCount != 2) return; for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[READ in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; taintReg(reg_r); return ; } } /* if mem != tained and reg == taint => free the reg */ if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[READ in " << addr << "]\t" << insAddr << ": " << insDis << std::endl; removeRegTainted(reg_r); } }
VOID ReadMem(INS ins, UINT64 memOp) { list<UINT64>::iterator i; UINT64 addr = memOp; REG reg_r; if (INS_OperandCount(ins) != 2) return; reg_r = INS_OperandReg(ins, 0); for(i = addressTainted.begin(); i != addressTainted.end(); i++){ if (addr == *i){ std::cout << std::hex << "[READ in " << addr << "]\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; taintReg(reg_r); return ; } } /* if mem != tained and reg == taint => free the reg */ if (checkAlreadyRegTainted(reg_r)){ std::cout << std::hex << "[READ in " << addr << "]\t" << INS_Address(ins) << ": " << INS_Disassemble(ins) << std::endl; removeRegTainted(reg_r); } }