Log in

View Full Version : Strange problem when hotpatching function..


BanMe
July 20th, 2009, 19:51
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
July 21st, 2009, 00:50
if ((BYTE*)oldProc- 0x5) = 0x00030441 as you said, then oldProc = 0x00030446, so clearly your problem is that oldProc is geting passed in incorrectly

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

naides
July 21st, 2009, 13:32
BYTE* pLongJump = ((BYTE*)oldProc- 0x5);

Should this be:

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

BanMe
July 21st, 2009, 13:59
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
July 21st, 2009, 14:19
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
July 21st, 2009, 14:46
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