void report_sym_structure( SYM sym, int depth ) { // TODO int k = 0; for ( k = 0; k< depth ; k ++ ) TraceFile << "\t" ; TraceFile << "<SYM>"; string sym_1 = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY); string sym_2 = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_COMPLETE ); ADDRINT offset = SYM_Value( sym ); TraceFile << hex << offset << " sym.1:" << sym_1 << " sym.2:" << sym_2 << "</SYM>" << endl; }
VOID Image(IMG img, VOID *v) { // Walk through the symbols in the symbol table. // for (SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym)) { string undFuncName = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY); // Find the RtlAllocHeap() function. if (undFuncName == "RtlAllocateHeap") { RTN allocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym)); if (RTN_Valid(allocRtn)) { // Instrument to print the input argument value and the return value. RTN_Open(allocRtn); RTN_InsertCall(allocRtn, IPOINT_BEFORE, (AFUNPTR)Before, IARG_ADDRINT, "RtlAllocateHeap", IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_END); RTN_InsertCall(allocRtn, IPOINT_AFTER, (AFUNPTR)After, IARG_ADDRINT, "RtlAllocateHeap", IARG_FUNCRET_EXITPOINT_VALUE, IARG_END); RTN_Close(allocRtn); } } } }
VOID Routine(RTN rtn, VOID *v) { std::string name = PIN_UndecorateSymbolName(RTN_Name(rtn).c_str(), UNDECORATION_NAME_ONLY); std::vector<std::string>::iterator it; for (it = userFuncs.begin(); it != userFuncs.end(); ++it) { std::string userFunc = *it; if (name.find(userFunc) == std::string::npos) continue; RTN_Open(rtn); // For each instruction of the routine for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { UINT32 memOperands = INS_MemoryOperandCount(ins); // Iterate over each memory operand of the instruction. for (UINT32 memOp = 0; memOp < memOperands; memOp++) { if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) break; if (INS_MemoryOperandIsRead(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END); } if (INS_MemoryOperandIsWritten(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END); } } } RTN_Close(rtn); } }
// ------------------------------------------------------------- // STool_RoutineDemangledNameByAddr // ------------------------------------------------------------- // Same as STool_RoutineNameByAddr, but names are fully demangled. const char* STool_RoutineDemangledNameByAddr(ADDRINT rtnAddr, BOOL full) { const string& name = RTN_FindNameByAddress(rtnAddr); if (name == "") return "<unknown_routine>"; else return PIN_UndecorateSymbolName(name, full ? UNDECORATION_COMPLETE : UNDECORATION_NAME_ONLY).c_str(); }
static const char *PIN_UndecorateSymbolName_detour( const char *symbol_name, UNDECORATION style) { return strdup(PIN_UndecorateSymbolName(symbol_name, style).c_str()); }
instruction::instruction(const INS& ins) { this->address = INS_Address(ins); this->next_address = INS_NextAddress(ins); // this->opcode = INS_Mnemonic(ins); this->opcode_size = static_cast<uint8_t>(INS_Size(ins)); this->opcode_buffer = std::shared_ptr<uint8_t>(new uint8_t[this->opcode_size], std::default_delete<uint8_t[]>()); PIN_SafeCopy(opcode_buffer.get(), reinterpret_cast<const VOID*>(this->address), this->opcode_size); this->disassemble = INS_Disassemble(ins); // including image, routine auto img = IMG_FindByAddress(this->address); this->including_image = IMG_Valid(img) ? IMG_Name(img) : ""; // this->including_routine = RTN_FindNameByAddress(this->address); PIN_LockClient(); auto routine = RTN_FindByAddress(this->address); PIN_UnlockClient(); if (RTN_Valid(routine)) { auto routine_mangled_name = RTN_Name(routine); this->including_routine_name = PIN_UndecorateSymbolName(routine_mangled_name, UNDECORATION_NAME_ONLY); } else this->including_routine_name = ""; // has fall through this->has_fall_through = INS_HasFallThrough(ins); // is call, ret or syscall this->is_call = INS_IsCall(ins); this->is_branch = INS_IsBranch(ins); this->is_ret = INS_IsRet(ins); this->is_syscall = INS_IsSyscall(ins); this->category = static_cast<xed_category_enum_t>(INS_Category(ins)); this->iclass = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); // read registers auto read_reg_number = INS_MaxNumRRegs(ins); for (decltype(read_reg_number) reg_id = 0; reg_id < read_reg_number; ++reg_id) { this->src_registers.push_back(INS_RegR(ins, reg_id)); } // written registers auto written_reg_number = INS_MaxNumWRegs(ins); for (decltype(written_reg_number) reg_id = 0; reg_id < written_reg_number; ++reg_id) { this->dst_registers.push_back(INS_RegW(ins, reg_id)); } auto is_special_reg = [](const REG& reg) -> bool { return (reg >= REG_MM_BASE); }; this->is_special = std::any_of(std::begin(this->src_registers), std::end(this->src_registers), is_special_reg) || std::any_of(std::begin(this->dst_registers), std::end(this->dst_registers), is_special_reg) || (this->category == XED_CATEGORY_X87_ALU) || (this->iclass == XED_ICLASS_XEND) || (this->category == XED_CATEGORY_LOGICAL_FP) || (this->iclass == XED_ICLASS_PUSHA) || (this->iclass == XED_ICLASS_PUSHAD) || (this->iclass == XED_ICLASS_PUSHF) || (this->iclass == XED_ICLASS_PUSHFD) || (this->iclass == XED_ICLASS_PUSHFQ); // is memory read, write this->is_memory_read = INS_IsMemoryRead(ins); this->is_memory_write = INS_IsMemoryWrite(ins); this->is_memory_read2 = INS_HasMemoryRead2(ins); }
VOID ImageLoad(IMG img, VOID *v) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn) ) { string rtnName = RTN_Name(rtn); if (rtnName.find("method") != string::npos || rtnName.find("foo") != string::npos || rtnName.find("my_operator") != string::npos) { // The tested application has class "A" with interface "method" // We just check that A::method is successfully demangled string demangledName = PIN_UndecorateSymbolName(rtnName, UNDECORATION_COMPLETE); string demangledNameNoParams = PIN_UndecorateSymbolName(rtnName, UNDECORATION_NAME_ONLY); out << "Mangled name: " << rtnName << endl; out << "Full demangled name: " << demangledName << endl; out << "Demangled name w/o parameters: " << demangledNameNoParams << endl; BOOL matched = FALSE; for (UINT32 i=0; i<sizeof(testNames)/sizeof(testNames[0]); i++) { if (demangledName == testNames[i].fullName && demangledNameNoParams == testNames[i].noArgsName) { matched = TRUE; break; } } if (!matched) { cout << "Error in demangling: " << endl; cout << "Mangled name: " << rtnName << endl; cout << "Demangled name: " << demangledName << endl; cout << "Demangled name, no parameters: " << demangledNameNoParams << endl; exit(-1); } continue; } if (rtnName.find("@@") != string::npos) { // Check C and C++ names demangling with version (Linux) // Like // _ZNSt11char_traitsIcE2eqERKcS2_@@GLIBCXX_3.4.5 // localeconv@@GLIBC_2.2 string name = PIN_UndecorateSymbolName(rtnName, UNDECORATION_COMPLETE); if (rtnName.find("_Z") == 0) { out << "C++ name with version: " << rtnName << endl; out << "Demangled name: " << name << endl; } else { out << "C name with version: " << rtnName << endl; out << "Demangled name: " << name << endl; } if (name.find("@@") != string::npos) { printf("Error: undecorated name should not include \"@@\"\n"); exit(-1); } continue; } // Otherwise just demangle the name both ways but normally don't bother to print them. // We can't easily tell what the results should be, but throwing a lot more // names at our demangler must be a good thng to do, and this should include // all the names from the standard C++ runtime, is a reasonable stress test. string complete = PIN_UndecorateSymbolName(rtnName, UNDECORATION_COMPLETE); string nameOnly = PIN_UndecorateSymbolName(rtnName, UNDECORATION_NAME_ONLY); if (KnobVerbose) { out << rtnName << " => " << endl; out << " " << complete << endl; out << " " << nameOnly << endl; } } } }