// Fixes ripped code segments in a dumped file - here it scans
// a file in memory, and fixes the segments from the process
// this is currently running.
BOOL FixRippedCodeMemory(HANDLE hProcess,LPVOID lpMem)
{
LPVOID lpBase = lpMem;
LPVOID OriglpMem = lpMem;
unsigned char* Byte;
DWORD* CallData;
DWORD JumpAddress;
DWORD AddressOfOrigCode;
DWORD Distance;
DWORD LastValidAddress;
// Scan for CALLS that are above mem space
// need to calculate the difference between our mapped mem
// and the file's imagebase
/*
if ((DWORD)lpMem > MemImageBase)
MemDifference = ((DWORD)lpMem - MemImageBase);
if ((DWORD)lpMem < MemImageBase)
MemDifference = (MemImageBase - (DWORD)lpMem);
*/
// Scanner. MemSize if relative
for (unsigned long i = (DWORD)lpBase; i < (DWORD)lpBase + LastSectionVA;i++)
{
// Look for "E8" byte first (CALL)
// if found, grab next four bytes. if they are higher than BASE+SIZE ignore them.
// if they are higher than MemMatchLow then Calc where they go to
// by getting next address (current address + 5) and adding..
// DWORD to call should always be positive, it exists in higher memory.
Byte = (unsigned char*)lpMem;
if (*Byte == 0xE8)
{
// read next 4 bytes (DWORD) , see it it's a valid address
CallData = (DWORD*)((DWORD)lpMem + 1);
if (*CallData != 0)
{
// calculate the distance from the next instruction.
Distance = (((DWORD)lpMem+5) + ((DWORD)*CallData) - (DWORD)lpBase);
Distance = Distance + (DWORD)PEImageBase;
if ((Distance > (PEImageBase+LastSectionVA)) && (Distance < (PEImageBase + PEImageSize)))
{
// this is a valid CALL instruction into higher memory.
//printf("CallData: %Xh \n",*CallData);
//printf("Address: %Xh \n",(DWORD)lpMem - (DWORD)lpBase);
LastValidAddress = Distance;
//ClearMessage();
//sprintf(MESSAGE,"CALL found to: %Xh ",Distance);
//ShowMessage();
// grab the value of the JMP from this call.
// first, make sure it's a JMP instruction
// REMEMBER, lpMEM still points to the original CALL instruction
// look at the bytes at "Distance"
// convert back to our file mapping postion
Distance = Distance - (DWORD)PEImageBase;
Distance = Distance + (DWORD)lpBase;
//printf("Distance new is %Xh \n",Distance);
ZeroMemory(&JumpData,sizeof(JumpData));
memcpy(&JumpData,(void*)Distance,2);
if (memcmp(JumpData,JMP_INSTRUCT,2)==0)
{
// this is a valid JMP
//printf("JMP Valid "

;
// get the JMP [<address>]
memcpy(&JumpAddress,(void*)(Distance+2),sizeof(DWORD));
ClearMessage();
sprintf(MESSAGE,"CALL Found at: %Xh - JMP Valid, address Found: %Xh",LastValidAddress,JumpAddress);
ShowMessage();
//printf("Address found: %Xh \n",JumpAddress);
// now we would read in the value from that address, from the
// other process space, move to that value, and grab five bytes
// and replace the original CALL instruction with the original bytes
ZeroMemory(&ORIG_CODE,sizeof(ORIG_CODE));
if (ReadProcessMemory(hProcess,(LPVOID)JumpAddress,&AddressOfOrigCode,sizeof(DWORD),NULL)==0)
{
ClearMessage();
printf("Couldn't read process mem to patch Code: Error: %d \n",GetLastError());
ShowMessage();
return FALSE;
}
// read the five bytes, and copy them
ReadProcessMemory(hProcess,(LPVOID)AddressOfOrigCode,ORIG_CODE,5,NULL);
// copy the original bytes back.
memcpy(lpMem,ORIG_CODE,5);
}
//break;
}
}
}
// move lpBase
lpMem = (LPVOID)((DWORD)lpMem + sizeof(unsigned char));
}
lpMem = OriglpMem;
return TRUE;
}