// 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;
}