PDA

View Full Version : Strange problem when hotpatching function..


BanMe
07-20-2009, 08:51 PM
ok so I got this function but it is not behaving like it should..
Code:

bool Native_HotPatchAddr(void *oldProc, void *newProc, void**ppOrigFn)
{
bool bRet = false;
DWORD oldProtect = NULL;
ULONG ProtectSize = 7;
WORD* pJumpBack = (WORD*)oldProc;
BYTE* pLongJump = ((BYTE*)oldProc- 0x5);
DWORD* pLongJumpAdr = ((DWORD*)oldProc-0x4);
if(!NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),(PVOID*)pLongJump, &ProtectSize, PAGE_EXECUTE_READWRITE, &oldProtect)))
{
return bRet;
}
// don’t hook functions which have already been hooked
if ((0xff8b == *pJumpBack) && (0x90 == *pLongJump) && (0x90909090 == *pLongJumpAdr))
{
*pLongJump = 0xE9; // long jmp
*pLongJumpAdr = ((DWORD)newProc)-((DWORD)oldProc); //
*pJumpBack = 0xF9EB; // short jump back -7 (back 5, plus two for this jump)

if (ppOrigFn)
*ppOrigFn = ((BYTE*)oldProc)+2;
bRet = true;
}
if(!NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),(PVOID*)pLongJump, &ProtectSize, oldProtect, &oldProtect)))
{
return bRet;
}
return bRet;
}


at this BYTE* pLongJump = ((BYTE*)oldProc- 0x5); pLongJump should equal the begging of the nop padding just before most functions..but it doesn't it gets all mangled and equal 00030441..any idea why?I tried changed the location of NtProtectVirtualMemory thinking the nops might be a GUARD_PAGE
or non-readable but this had same effect..

to remedy this i just changed the void * parameters to ULONG's (no *) and used a little inline asm.. but its naggin me as to why it would not work properly..any why the address is so far off..also if I change the parenthisies around a bit i get the end of the previous Function - 15... and thats definitly not right..


regards BanMe

disavowed
07-21-2009, 01:50 AM
if ((BYTE*)oldProc- 0x5) = 0x00030441 as you said, then oldProc = 0x00030446, so clearly your problem is that oldProc is geting passed in incorrectly

BanMe
07-21-2009, 02:22 PM
but it doesn't, it equals _BaseThreadStart or 0x7c80b662..
only at the conversion to (BYTE*) does oldProc switch to 0x00030441.

naides
07-21-2009, 02:32 PM
BYTE* pLongJump = ((BYTE*)oldProc- 0x5);

Should this be:

BYTE* pLongJump = (BYTE*)(oldProc- 0x5);

BanMe
07-21-2009, 02:59 PM
thats when it goes all whacky on me..
I tried that and from the #'s the debugger was showing me it found the end of the previous function in linear order up and - 15 from that address..that threw me for a loop ..ie +0xf would not lead me to nops but to my original function address when clearly the debugger shows + 0x14 as where the function begins...

naides
07-21-2009, 03:19 PM
I think the problem might lie on the pointer arithmetic the compiler is generating.

*oldProc comes as a void pointer. You do pointer addition (subtraction) to it, which by default goes in 4 byte increments and decrements, not in single bytes. You'd need to cast it to a byte pointer first, then do the pointer arithmetic. . .

BanMe
07-21-2009, 03:46 PM
hmm that is how I solved it, now that I look back at It..
thank you naides for clearing that up for me
that was confuzziling..

regards BanMe