VOID DbgPrintEvent(PLOGENTRY pLogEntry) { PSTR pstr; switch (pLogEntry->nEventType) { case EVENT_ALLOCATE: pstr = "Allocate"; break; case EVENT_CREATE_HANDLE: pstr = "CreatHdl"; break; case EVENT_REFERENCE: pstr = "Ref"; break; case EVENT_DEREFERENCE: pstr = "Deref"; break; case EVENT_LOCK: pstr = "Lock"; break; case EVENT_UNLOCK: pstr = "Unlock"; break; case EVENT_DELETE: pstr = "Delete"; break; case EVENT_FREE: pstr = "Free"; break; case EVENT_SET_OWNER: pstr = "SetOwner"; break; default: pstr = "Unknown"; break; } DbgPrint("[%ld] %03x:%03x %.8s val=%p <%lx,%lx,%lx,%lx>\n", pLogEntry->ulUnique, pLogEntry->dwProcessId, pLogEntry->dwThreadId, pstr, pLogEntry->lParam, REL_ADDR(pLogEntry->apvBackTrace[2]), REL_ADDR(pLogEntry->apvBackTrace[3]), REL_ADDR(pLogEntry->apvBackTrace[4]), REL_ADDR(pLogEntry->apvBackTrace[5])); }
//--------------------------------------- HookMIPS_Set -------------------------------- // void HookMIPS_Set (dword *pFirmware, dword *pHook, dword *pHookReturn) { bool AlreadyHooked = FALSE; dword *p; AlreadyHooked = ((pFirmware [0] & CMD_MASK) == JMP_CMD); #ifdef DEBUG_FIREBIRDLIB TAP_Print ("FireBirdLib: F/W=%8.8p, Hook=%8.8p, HookRet=%8.8p, AlreadyHooked = %s\n", pFirmware, pHook, pHookReturn, AlreadyHooked ? "Yes" : "No"); #endif if (!AlreadyHooked) { //Wir sind die Ersten, die den Hook setzen //Patche die beiden OpCodes der Original-Routine, die durch unseren Hook überschrieben werden pHookReturn [-2] = pFirmware [0]; pHookReturn [-1] = pFirmware [1]; //Jetzt noch der Return-Jump pHookReturn [0] = JMP_CMD | REL_ADDR ((dword) pFirmware + 8); //Aktiviere den Hook durch Umleiten auf unseren MIPS-Code. Ab jetzt wird scharf geschossen. pFirmware [0] = JMP_CMD | REL_ADDR ((dword) pHook); pFirmware [1] = NOP_CMD; } else { //Ein anderes TAP hat bereits einen Hook gesetzt, wir müssen dieses suchen p = pFirmware; do { #ifdef DEBUG_FIREBIRDLIB TAP_Print ("FireBirdLib: Search for JMP: %p -> %x\n", p, ABS_ADDR (*p)); #endif p = (dword *) ABS_ADDR (*p); while ((*p & CMD_MASK) != JMP_CMD) { p++; } } while (ABS_ADDR (*p) != ((dword) &pFirmware [0] + 8)); #ifdef DEBUG_FIREBIRDLIB TAP_Print ("FireBirdLib: Found JMP: %p -> %x\n", p, ABS_ADDR (*p)); #endif //Gefunden, p zeigt auf den Return-JMP des letzten TAPs der Chain. Kopiere die beiden original OpCodes und leite den Jump auf uns um pHookReturn [-2] = p [-2]; pHookReturn [-1] = p [-1]; //Jetzt noch der Return-Jump pHookReturn [0] = JMP_CMD | REL_ADDR ((dword) pFirmware + 8); p [0] = JMP_CMD | REL_ADDR ((dword) pHook); p [-2] = 0; p [-1] = 0; } }
//----------------------------------------------------------------------------- // initCodeWrapper() creates a code wrapper based on TAP_GetTime. The function // allocates a buffer and copies the code of TAP_GetTime into it except for // the actual call of the getTime() firmware function. The address of the // getTime() is replaced with the provided address. // The wrapped function call supports up to 4 parameters and returns a // short value. // Parameters: // fwFuncAddr - address of the FW function to be wrapped // initCodeWrapper() returns a buffer with code wrapping the call to provided // firmware function address. // The buffer can be assigned to a function pointer which can be used to execute // the wrapped code. dword* initCodeWrapper (dword *pFwFuncAddr) { dword i; // TAP_GetTime provides a template for wrapper code. The only thing to be // changed is the address of the wrapped function. dword *pSrc = (dword*)TAP_GetTime; dword *pBuffer; dword bufSize = 0; bool found = FALSE; // ###################### // Step 2 // get a copy of TAP_GetTime() pSrc = (dword*)TAP_GetTime; bufSize = 0; // find the return statement while(pSrc[bufSize] != JR_RA_CMD) { bufSize++; } // the buffer should include the return statement and the command following // the return statement bufSize += 2; // allocate memory pBuffer = malloc(sizeof(dword) * bufSize); if(pBuffer == NULL) return NULL; // patch the copy with the call to the address of the copied sendToVfdDisplay() DBG_PRINT("MPDisplayLib: wrapper started for %08x ...\n", pFwFuncAddr); for(i = 0; i < bufSize; i++) { if((pSrc[i] & CMD_MASK) == JAL_CMD) { // this is the wrapped call to the actual FW implementation // replace it with the call to the provided address pBuffer[i] = JAL_CMD | REL_ADDR(pFwFuncAddr); found = TRUE; } else { pBuffer[i] = pSrc[i]; } DBG_PRINT("MPDisplayLib: %08x: %08x\n", pBuffer + i, pBuffer[i]); } if(!found) { free(pBuffer); pBuffer = NULL; } // return the address of the allocated code wrapper return pBuffer; }
void MHEGState_Enable() { dword *fn; dword *addr; if ( !MHEGState_Available ) return; // patch TAP_GetState to return STATE_Ttx and SUBSTATE_Ttx when full screen MHEG is active fn = (dword*)GetState; addr = (dword*)TAP_GetState; // save the original instructions to be executed prior to the hook code fn[0] = addr[0]; fn[1] = addr[1]; fn[2] = JMP_CMD | REL_ADDR(addr+2); fn[3] = NOP_CMD; HackFirmware( (dword)(addr), JMP_CMD | REL_ADDR(GetStateHook) ); HackFirmware( (dword)(addr+1), NOP_CMD ); }