BYTE CPatcher::InstallDetourPatchWithData(char * szLibrary, unsigned int uOrdinal, DWORD dwFunctionAddress) { DWORD dwAddress = GetFunctionAddress(szLibrary, uOrdinal); DWORD dwDetourAddress = dwFunctionAddress; BYTE byteType = X86_JMP; int iSize = 5; // Allocate the trampoline memory BYTE * pbyteTrampoline = (BYTE *)malloc(iSize + 5); // Unprotect the trampoline memory Unprotect((DWORD)pbyteTrampoline, (iSize + 5)); // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwAddress, (iSize + 5)); // Copy the overwritten address memory to the trampoline memory memcpy(pbyteTrampoline, (void *)dwAddress, iSize); // Write the type to the trampoline memory DWORD dwTrampoline = (DWORD)(pbyteTrampoline + iSize); *(BYTE *)dwTrampoline = byteType; *(DWORD *)(dwTrampoline + 1) = ((dwAddress + iSize) - dwTrampoline - 5); // Write the type to the address memory *(BYTE *)dwAddress = byteType; *(DWORD *)(dwAddress + 1) = (dwDetourAddress - dwAddress - 5); // Re-protect the address memory Reprotect(protectionInfo); return (pbyteTrampoline != NULL); }
void * CPatcher::InstallDetourPatchInternal(DWORD dwAddress, DWORD dwDetourAddress, BYTE byteType, int iSize) { // Allocate the trampoline memory BYTE * pbyteTrampoline = (BYTE *)malloc(iSize + 5); // Unprotect the trampoline memory Unprotect((DWORD)pbyteTrampoline, (iSize + 5)); // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwAddress, (iSize + 5)); // Copy the overwritten address memory to the trampoline memory memcpy(pbyteTrampoline, (void *)dwAddress, iSize); // Write the type to the trampoline memory DWORD dwTrampoline = (DWORD)(pbyteTrampoline + iSize); *(BYTE *)dwTrampoline = byteType; *(DWORD *)(dwTrampoline + 1) = ((dwAddress + iSize) - dwTrampoline - 5); // Write the type to the address memory *(BYTE *)dwAddress = byteType; *(DWORD *)(dwAddress + 1) = (dwDetourAddress - dwAddress - 5); // Re-protect the address memory Reprotect(protectionInfo); return pbyteTrampoline; }
Shmem::Shmem(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, SharedMemory* aSegment, id_t aId) : mSegment(aSegment), mData(0), mSize(0) { NS_ABORT_IF_FALSE(mSegment, "NULL segment"); NS_ABORT_IF_FALSE(aId != 0, "invalid ID"); Unprotect(mSegment); Header* header; char* frontSentinel; char* data; char* backSentinel; GetSections(aSegment, &header, &frontSentinel, &data, &backSentinel); // do a quick validity check to avoid weird-looking crashes in libc char check = *frontSentinel; (void)check; NS_ABORT_IF_FALSE(!strncmp(header->mMagic, sMagic, sizeof(sMagic)), "invalid segment"); mSize = static_cast<size_t>(header->mSize); size_t pageSize = SharedMemory::SystemPageSize(); // transition into the "mapped" state by protecting the front and // back sentinels (which guard against buffer under/overflows) mSegment->Protect(frontSentinel, pageSize, RightsNone); mSegment->Protect(backSentinel, pageSize, RightsNone); // don't set these until we know they're valid mData = data; mId = aId; }
void CPatcher::InstallPushPatch(DWORD dwAddress, DWORD dwFunc) { ProtectionInfo protectionInfo = Unprotect(dwAddress, 5); *(BYTE*)(dwAddress) = 0x68; *(DWORD*)(dwAddress+1) = dwFunc; Reprotect(protectionInfo); }
void CPatcher::InstallPushPatch(DWORD dwAddress, DWORD dwFunc) { // Unprotect the address Unprotect(dwAddress, 5); // Make the call *(BYTE*)(dwAddress) = 0x68; // Make the call address *(DWORD*)(dwAddress+1) = dwFunc; }
void SetJump(void *from, void *to, unsigned char (&oldCode)[5]) { Unprotect(from, 5); // Store the code we are going to overwrite (probably to copy it back later) memcpy(oldCode, from, 5); // E9 - jump near, relative unsigned char JMP = 0xE9; memcpy(from, &JMP, 1); // Jump address is relative to the next instruction's address size_t offset = (uint32_t)to - ((uint32_t)from + 5); memcpy((void*)((uint32_t)from + 1), &offset, 4); }
void CPatcher::InstallNopPatch(DWORD dwAddress, int iSize) { DWORD dwAddr = dwAddress; // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwAddr, iSize); // Write the no operation to the address memory memset((void *)dwAddr, X86_NOP, iSize); // Re-protect the address memory Reprotect(protectionInfo); }
void CPatcher::InstallHookCall(DWORD dwAddr, DWORD dwFunc) { DWORD dwHookFunc = (dwFunc - (dwAddr + 5)); // Unprotect the address Unprotect(dwAddr, 5); // Make the call *(BYTE*)(dwAddr) = 0xE8; // Make the call address *(DWORD*)(dwAddr+1) = (DWORD)dwHookFunc; }
void CPatcher::InstallMethodPatch(DWORD dwHookAddress, DWORD dwFunctionAddress) { DWORD dwHookAddr = dwHookAddress; // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwHookAddr, 4); // Write the function to the address memory *(DWORD *)dwHookAddr = (DWORD)dwFunctionAddress; // Re-protect the address memory Reprotect(protectionInfo); }
void CPatcher::InstallStringPatch(DWORD dwAddress, char * szString, int iSize) { DWORD dwAddr = dwAddress; // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwAddr, iSize); // Write the string to the address memory memcpy((void *)dwAddr, szString, iSize); // Re-protect the address memory Reprotect(protectionInfo); }
void CPatcher::InstallRetnPatch(DWORD dwAddress) { DWORD dwAddr = dwAddress; // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwAddr, 1); // Write the return to the address memory *(BYTE *)dwAddr = X86_RETN; // Re-protect the address memory Reprotect(protectionInfo); }
// TODO: A method to just use the trampoline and jmp function void CPatcher::UninstallDetourPatchInternal(DWORD dwAddress, void * pTrampoline, int iSize) { // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwAddress, iSize); // Copy the trampoline to the address memcpy((void *)dwAddress, pTrampoline, iSize); // Re-protect the address memory Reprotect(protectionInfo); // Free trampoline free(pTrampoline); }
void CPatcher::UninstallDetourPatch(void * pTrampoline, DWORD dwFunctionAddress) { // Unprotect the address memory ProtectionInfo protectionInfo = Unprotect(dwFunctionAddress, 5); // Copy the trampoline to the address memcpy((void *)dwFunctionAddress, pTrampoline, 5); // Re-protect the address memory Reprotect(protectionInfo); // Free trampoline free(pTrampoline); }
bool Hook::Install() { if (installed_) { return false; } // Set write permission Unprotect(src_, kJmpInstrSize); // Store the code we are going to overwrite (probably to copy it back later) memcpy(code_, src_, kJmpInstrSize); // E9 - jump near, relative unsigned char JMP = 0xE9; memcpy(src_, &JMP, 1); // Jump address is relative to the next instruction's address size_t offset = (int)dst_ - ((int)src_ + kJmpInstrSize); memcpy((void*)((int)src_ + 1), &offset, kJmpInstrSize - 1); installed_ = true; return true; }