Пример #1
0
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);
            }
        }
    }
}
Пример #2
0
BaseIRBuilder::BaseIRBuilder(__uint address, const std::string &dis) {
  RTN rtn;
  SEC sec;
  IMG img;

  this->address             = address;
  this->branchTaken         = false;
  this->branchTargetAddress = 0;
  this->disas               = dis;
  this->needSetup           = false;
  this->nextAddress         = 0;
  this->imageName           = "unknown";
  this->sectionName         = "unknown";

  rtn = RTN_FindByAddress(address);
  if (RTN_Valid(rtn)) {

    sec = RTN_Sec(rtn);
    if (SEC_Valid(sec)) {

      this->sectionName = SEC_Name(sec);

      img = SEC_Img(sec);
      if (IMG_Valid(img)) {
        this->baseAddress = IMG_LowAddress(img);
        this->imageName   = IMG_Name(img);
      }
    }
  }

  this->offset        = this->address - this->baseAddress;
  this->routineName   = RTN_FindNameByAddress(address);
  if (this->routineName.empty())
    this->routineName = "unknown";
}
Пример #3
0
PyObject* Python_RTN_FindByAddress(PyObject* self, PyObject* args) {
    PyObject* address;
    PyArg_ParseTuple(args, "L", &address);
    ADDRINT address_object = (ADDRINT) address;
    RTN* rtn_return = (RTN*) malloc(sizeof(RTN));
    *rtn_return = RTN_FindByAddress(address_object);
    return Py_BuildValue("L", rtn_return);
}
Пример #4
0
 std::string getRoutineName(triton::__uint address) {
   RTN rtn;
   PIN_LockClient();
   rtn = RTN_FindByAddress(address);
   PIN_UnlockClient();
   if (RTN_Valid(rtn)) {
     return RTN_Name(rtn);
   }
   return "";
 }
// Pin calls this function every time a new img is loaded
VOID ImageLoad(IMG img, VOID *v)
{
    if (!IMG_IsMainExecutable(img))
        return;

    printf("%s loaded\n", IMG_Name(img).c_str());
    fflush(stdout);

    ADDRINT imageBase = IMG_LowAddress(img);
    WINDOWS::PIMAGE_DATA_DIRECTORY pExpDir = GetExportDirectory(imageBase);
    if ((pExpDir == 0) || (pExpDir->Size == 0))
    {
        // Failure: Executable image lacks export directory.
        printf("ERROR: No export directory in executable image\n");
        fflush(stdout);
        exit(3);
    }
    ADDRINT exportBase = imageBase + pExpDir->VirtualAddress;

    // First check that bytes in export directory range do not belong to a RTN
    for (ADDRINT addr = exportBase; addr < exportBase + pExpDir->Size; ++addr)
    {
        if (RTN_FindByAddress(addr) != RTN_Invalid())
        {
            // Test failure. Byte in export directory belongs to a RTN.
            printf("ERROR: Data from export directory included in RTN\n");
            fflush(stdout);
            exit(1);
        }
    }

    // Second check RTN size. RTN range should not overlap with export directory range.
    for (SEC sec = IMG_SecHead(img); sec != SEC_Invalid(); sec = SEC_Next(sec))
    {
        for (RTN rtn = SEC_RtnHead(sec); rtn != RTN_Invalid(); rtn = RTN_Next(rtn))
        {
            if (((RTN_Address(rtn) <= exportBase) && (RTN_Address(rtn) + RTN_Size(rtn) > exportBase)) ||
                ((RTN_Address(rtn) > exportBase) && (exportBase + pExpDir->Size > RTN_Address(rtn))))
            {
                // Test failure. RTN overlaps with export directory.
                printf("ERROR: RTN overlaps with export directory\n");
                fflush(stdout);
                exit(2);
            }
        }
    }

    return;
}
Пример #6
0
// -------------------------------------------------------------
// Get function address by branch target address
// -------------------------------------------------------------
ADDRINT Target2FunAddr(ADDRINT target) {
    PIN_LockClient();
    
    ADDRINT funAddr;
    
    const RTN rtn = RTN_FindByAddress(target);

    if ( RTN_Valid(rtn) ) 
         funAddr = RTN_Address(rtn);
    else funAddr = target;

    PIN_UnlockClient();

    return funAddr;
}
Пример #7
0
// -------------------------------------------------------------
// STool_LibraryIDByAddr
// -------------------------------------------------------------
// Return ID of the library of the routine to which the instruction 
// at address rtnAddr belongs, or STool_INVALID_LIB, if rtnAddr does not belong to
// any routine.
UINT32 STool_LibraryIDByAddr(ADDRINT rtnAddr){

    PIN_LockClient();
    
    const RTN rtn = RTN_FindByAddress(rtnAddr);
    
    UINT32 libID;

    if( RTN_Valid(rtn) ) 
         libID = IMG_Id(SEC_Img(RTN_Sec(rtn)));
    else libID = STool_INVALID_LIB;

    PIN_UnlockClient();

    return libID;
}
Пример #8
0
 std::string getImageName(triton::__uint address) {
   RTN rtn;
   SEC sec;
   IMG img;
   PIN_LockClient();
   rtn = RTN_FindByAddress(address);
   PIN_UnlockClient();
   if (RTN_Valid(rtn)) {
     sec = RTN_Sec(rtn);
     if (SEC_Valid(sec)) {
       img = SEC_Img(sec);
       if (IMG_Valid(img)) {
         return IMG_Name(img);
       }
     }
   }
   return "";
 }
Пример #9
0
 triton::__uint getBaseAddress(triton::__uint address) {
   RTN rtn;
   SEC sec;
   IMG img;
   PIN_LockClient();
   rtn = RTN_FindByAddress(address);
   PIN_UnlockClient();
   if (RTN_Valid(rtn)) {
     sec = RTN_Sec(rtn);
     if (SEC_Valid(sec)) {
       img = SEC_Img(sec);
       if (IMG_Valid(img)) {
         return IMG_LowAddress(img);
       }
     }
   }
   return 0;
 }
Пример #10
0
RTN FindRTN(IMG img, const char *func_name) {
  RTN rtn = RTN_FindByName(img, func_name);
  if (RTN_Valid(rtn))
    return rtn;

  // handle those symbols with version numbers.
  // e.g. pthread_create has global name: pthread_create@@GLIBC...
  std::string func_name_v(func_name);
  func_name_v.append("@@");
  for(SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym)) {
    if (SYM_Name(sym).find(func_name_v) != std::string::npos) {
      RTN rtn = RTN_FindByAddress(SYM_Address(sym));
      DEBUG_ASSERT(RTN_Valid(rtn));
      return rtn;
    }
  }

  return RTN_Invalid();
}
Пример #11
0
static VOID tpss_on_module_loading(IMG img, VOID *data)
{
    unsigned long origAttrs = 0;

    if (IMG_Valid(img))
    {
        if (IMG_IsMainExecutable(img))
        {
            g_tpss_entry_point =
                           (void(*)())RTN_ReplaceProbed(
                                         RTN_FindByAddress(IMG_Entry(img)),
                                         (AFUNPTR)tpss_mainStartup);
        }
        else
        {
           tpss_instrument_module(img, data);
        }
    }
}
Пример #12
0
const string& Target2LibName(ADDRINT target)
{
    PIN_LockClient();
    
    const RTN rtn = RTN_FindByAddress(target);
    static const string _invalid_rtn("[Unknown image]");

    string name;
    
    if( RTN_Valid(rtn) ) {
        name = IMG_Name(SEC_Img(RTN_Sec(rtn)));
    } else {
        name = _invalid_rtn;
    }

    PIN_UnlockClient();

    return *new string(name);
}
Пример #13
0
// This function is called whenever Pin wants to report a breakpoint event to the
// debugger.
//
static BOOL InterceptBreakpoint(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *)
{
    if (eventType != DEBUGGING_EVENT_BREAKPOINT)
    {
        std::cout << "FAILURE: Wrong event type in InterceptBreakpoint()" << std::endl;
        std::exit(1);
    }

    ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
    RTN rtn = RTN_FindByAddress(pc);

    // When the application triggers the breakpoint in Breakpoint1(), squash the breakpoint
    // and roll the application back to the Checkpoint() call.  The application will NOT stop
    // at the breakpoint, and it will immediately resume from Checkpoint().
    //
    if (rtn != RTN_Invalid() && RTN_Name(rtn) == "Breakpoint1")
    {
        std::cout << "Intercepting breakpoint #1 at 0x" << std::hex << pc << std::endl;
        PIN_SaveContext(&SavedContext, ctxt);
        PIN_SetContextReg(ctxt, REG_GAX, 1);
        MemLog.Restore();
        IsCheckpointing = FALSE;
        return FALSE;
    }

    // When the application triggers the breakpoint in Breakpoint2(), do not squash the
    // breakpoint, but change the return value from Breakpoint2().  The application will stop
    // in the debugger, and the debugger should see the modified return value.
    //
    if (rtn != RTN_Invalid() && (RTN_Name(rtn) == "Breakpoint2" || RTN_Name(rtn) == "Breakpoint2Label"))
    {
        std::cout << "Intercepting breakpoint #2 at 0x" << std::hex << pc << std::endl;
        std::cout << "RTN=" << RTN_Name(rtn) << std::endl;
        PIN_SetContextReg(ctxt, REG_GAX, 1);
        return TRUE;
    }

    std::cout << "Skipping breakpoint at 0x" << std::hex << pc << ", RTN=" << RTN_Name(rtn) << std::endl;
    return TRUE;
}
Пример #14
0
int rtn_find_by_address (lua_State *L) {
  ADDRINT v1 = lua_tonumber(L,1);
  RTN_to_lua(L, RTN_FindByAddress(v1));
  return 1;
}
Пример #15
0
VOID PrintUntouchedRanges(SEC sec)
{
    // Make a bool vector big enough to describe the whole section, 1 bool per byte
    vector<bool> touched(SEC_Size(sec));

    // Put the rtn's that are touched in a set
    set<RTN> rtnSet;

    // Mark the ranges for bbls that have been executed
    for (list<const BBLSTATS*>::const_iterator bi = statsList.begin(); bi != statsList.end(); bi++)
    {
        const BBLSTATS * stats = *bi;
        
        // Is this bbl contained in the section?
        if (stats->_start < SEC_Address(sec) || stats->_start >= SEC_Address(sec) + SEC_Size(sec))
            continue;
        
        // Is the bbl executed?
        if (!stats->_executed)
            continue;
        
        RTN rtn = RTN_FindByAddress(stats->_start);
        if (RTN_Valid(rtn))
            rtnSet.insert(rtn);
        
        // Mark all the bytes of the bbl as executed
        for (ADDRINT i = stats->_start - SEC_Address(sec); i < stats->_start + stats->_size - SEC_Address(sec); i++)
        {
            ASSERTX(i < SEC_Size(sec));
            
            touched[i] = true;
        }
    }

    // Print the routines that are not touched
    out << "    Routines that are not executed" << endl;
    for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn))
    {
        if (rtnSet.find(rtn) == rtnSet.end())
        {
            out << "      " << RTN_Name(rtn) << endl;
        }
    }
    
    // Print the ranges of untouched addresses
    out << "    Code ranges that are not executed" << endl;
    string rtnName = "";
    for (UINT32 i = 0; i < SEC_Size(sec);)
    {
        // Find the first not touched address
        while(touched[i])
        {
            i++;
            
            if (i == SEC_Size(sec))
                return;
        }
        UINT32 start = i;
        
        // Find the first touched address
        while(!touched[i] && i < SEC_Size(sec)) i++;

        ADDRINT startAddress = SEC_Address(sec) + start;

        // Print the rtn name, if it has changed
        IMG img = IMG_FindByAddress(startAddress);
        string imgName = (IMG_Valid(img) ? IMG_Name(img) : "InvalidImg");
        RTN rtn = RTN_FindByAddress(startAddress);
        string newName = (RTN_Valid(rtn) ? RTN_Name(rtn) : "InvalidRtn");
        if (rtnName != newName)
        {
            out << " Image: " << imgName <<  "  Rtn: " << newName << endl;
            rtnName = newName;
        }

        out << "        " << SEC_Address(sec) + start << ":" << SEC_Address(sec) + i - 1 << endl;
    }
}
Пример #16
0
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);
}