/* procedure AddPatch(dAddr,dJmpTo: DWORD; NumNops: Integer = 0); var I: Integer; WorkingAddr: Cardinal; OldProt: DWORD; begin SetLength(PatchedArr,Length(PatchedArr)+1); with PatchedArr[Length(PatchedArr)-1] do begin Addr := dAddr; JmpTo := dJmpTo; SetLength(OrigMemory,5+NumNops); // Overwriting + new Jump/Call sled SetLength(NewMemory,15+NumNops); VirtualProtect(@NewMemory[0], Length(NewMemory), PAGE_EXECUTE_READWRITE, @OldProt); for I := 0 to Length(OrigMemory) - 1 do begin OrigMemory[I] := PBYTE(Addr+Cardinal(I))^; NewMemory[I] := OrigMemory[I]; WriteLn('Copied byte from [0x' + IntToHex(Addr+Cardinal(I),8) + ']: 0x' + IntToHex(OrigMemory[I],2)); end; // handle redirecting jmps/calls if (NewMemory[0] = $E8) or (NewMemory[0] = $E9) then begin WorkingAddr := PDword(@NewMemory[1])^ + Addr + 5; WriteLn('Reworking Call/Jmp to: 0x' + IntToHex(WorkingAddr,8)); PDword(@NewMemory[1])^ := (WorkingAddr - Cardinal(@NewMemory[0])) - 5; end; WorkingAddr := Cardinal(@NewMemory[0]) + Cardinal(5 + NumNops); CallPatch(WorkingAddr,JmpTo); // Call our hooking function WorkingAddr := WorkingAddr + 5; JmpPatch(WorkingAddr, Addr + Cardinal(5 + NumNops)); // Jump back right past where we overwrite end; end; */ void Patcher::AddPatch(DWORD dAddr, DWORD dJmpTo, int numNops) { if(patchArrPos == patchArrSize) { // resize needed PPatchedJmp* oldArray = patchedArr; int newSize = patchArrSize * 2; patchedArr = (PPatchedJmp*)malloc(newSize * sizeof(PPatchedJmp)); for(int i = 0; i < patchArrSize; i++) { patchedArr[i] = oldArray[i]; } patchArrSize = newSize; free(oldArray); } PatchedJmp * newPatch = (PatchedJmp *)malloc(sizeof(PatchedJmp)); newPatch->addr = dAddr; newPatch->jmpTo = dJmpTo; newPatch->numNops = numNops; newPatch->origMemory = (byte *)malloc(5+numNops); newPatch->newMemory = (byte *)malloc(15+numNops); DWORD OldProt; VirtualProtect((LPVOID)newPatch->newMemory, 15+numNops, PAGE_EXECUTE_READWRITE, &OldProt); // make our sled executable for(int i = 0; i < 5+numNops; i++) { newPatch->origMemory[i] = *(byte *)(newPatch->addr + i); newPatch->newMemory[i] = newPatch->origMemory[i]; } //handle redirecting jmps/calls DWORD workingAddr; if((newPatch->newMemory[0] == 0xE8) || (newPatch->newMemory[0] == 0xE9)) { workingAddr = *(DWORD *)(&newPatch->newMemory[1]); workingAddr += newPatch->addr + 5; *(DWORD *)(&newPatch->newMemory[1]) = (workingAddr - (DWORD)(newPatch->newMemory)) - 5; } workingAddr = (DWORD)(&newPatch->newMemory[0]) + 5 + numNops; CallPatch(workingAddr, newPatch->jmpTo); // Call our hooking function workingAddr += 5; JmpPatch(workingAddr, newPatch->addr + 5 + numNops); // Jump back right past where we overwrite patchedArr[patchArrPos++] = newPatch; }
void CallPatch(u32 dest, void* patch) { CallPatch((void*)dest, patch); return; }