int rtn_replace (lua_State *L) { RTN* v1 = check_rtn(L,1); AFUNPTR v2 = (VOID(*)())((UINT64)lua_tonumber(L,2)); AFUNPTR r = RTN_Replace(*v1,v2); lua_pushnumber(L, (UINT64)r); return 1; }
//scan the image and try to hook all the function specified above void HookFunctions::hookDispatcher(IMG img){ //for each function that we want to hook or replace for (std::map<string,int>::iterator item = this->functionsMap.begin(); item != this->functionsMap.end(); ++item){ //get the pointer to the specified function const char * func_name = item->first.c_str(); RTN rtn = RTN_FindByName(img, func_name); //if we found a valid routine if(rtn != RTN_Invalid()){ ADDRINT va_address = RTN_Address(rtn); MYINFO("Inside %s Address of %s: %08x" ,IMG_Name(img).c_str(),func_name, va_address); RTN_Open(rtn); int index = item->second; //decide what to do based on the function hooked //Different arguments are passed to the hooking routine based on the function switch(index){ case(VIRTUALALLOC_INDEX): RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)VirtualAllocHook , IARG_FUNCARG_ENTRYPOINT_VALUE,1 , IARG_FUNCRET_EXITPOINT_VALUE, IARG_END); break; case(RTLALLOCATEHEAP_INDEX): //need to be IPOINT_AFTER because the allocated address is returned as return value RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)RtlAllocateHeapHook , IARG_FUNCARG_ENTRYPOINT_VALUE,2, IARG_FUNCRET_EXITPOINT_VALUE, IARG_END); break; case(ISDEBUGGERPRESENT_INDEX): RTN_Replace(rtn, AFUNPTR(IsDebuggerPresentHook)); break; case(RTLREALLOCATEHEAP_INDEX): //IPOINT_BEFORE because the address to be realloc is passed as an input paramenter RTN_InsertCall(rtn,IPOINT_BEFORE,(AFUNPTR)RtlReAllocateHeapHook, IARG_FUNCARG_ENTRYPOINT_VALUE,2 , IARG_FUNCARG_ENTRYPOINT_VALUE,3, IARG_END); break; case(MAPVIEWOFFILE_INDEX): //need to be IPOINT_AFTER because the allocated address is returned as return value RTN_InsertCall(rtn,IPOINT_AFTER,(AFUNPTR)MapViewOfFileHookAfter,IARG_FUNCARG_ENTRYPOINT_VALUE,1,IARG_FUNCARG_ENTRYPOINT_VALUE,2,IARG_FUNCARG_ENTRYPOINT_VALUE,3, IARG_FUNCARG_ENTRYPOINT_VALUE,4,IARG_FUNCRET_EXITPOINT_VALUE, IARG_END); break; case(VIRTUALFREE_INDEX): RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)VirtualFreeHook , IARG_FUNCARG_ENTRYPOINT_VALUE,0, IARG_END); break; case(VIRTUALQUERY_INDEX): //IPOINT_AFTER because we have to check if the query is on a whitelisted address RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)VirtualQueryHook, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCRET_EXITPOINT_REFERENCE, IARG_END); break; case(VIRTUALQUERYEX_INDEX): //IPOINT_AFTER because we have to check if the query is on a whitelisted address RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)VirtualQueryExHook, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_FUNCRET_EXITPOINT_REFERENCE, IARG_END); break; } RTN_Close(rtn); } } }
static VOID Trace(TRACE trace, VOID *v) { RTN rtn = TRACE_Rtn(trace); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (TRACE_Address(trace) == RTN_Address(rtn)) { // Pin does not support issuing an RTN_Replace from the TRACE instrumentation callback // This will cause Pin to terminate with an error RTN_Replace(rtn, AFUNPTR(WatchRtnReplacement)); } }
static VOID Instruction(INS ins, VOID *v) { RTN rtn = INS_Rtn(ins); if (!RTN_Valid(rtn) || RTN_Name(rtn) != watch_rtn) { return; } if (INS_Address(ins) == RTN_Address(rtn)) { // Pin does not support issuing an RTN_Replace from the INS instrumentation callback // This will cause Pin to terminate with an error RTN_Replace(rtn, AFUNPTR(WatchRtnReplacement)); } }
void Routine::replace (void) { typedef typename REPLACEMENT::funcptr_type funcptr_type; AFUNPTR funcptr = RTN_Replace (this->rtn_, AFUNPTR (REPLACEMENT::execute)); REPLACEMENT::original_funcptr (reinterpret_cast <funcptr_type> (funcptr)); }