View Single Post
  #5  
Old 01-20-2005, 21:43
Shub-Nigurrath's Avatar
Shub-Nigurrath Shub-Nigurrath is offline
VIP
 
Join Date: Mar 2004
Location: Obscure Kadath
Posts: 971
Rept. Given: 70
Rept. Rcvd 431 Times in 101 Posts
Thanks Given: 83
Thanks Rcvd at 405 Times in 127 Posts
Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499 Shub-Nigurrath Reputation: 400-499
here's a code snippet form a tool I'm writing. it's in C++ but might help.
The concept is to wrap the real ReadProcessMemory and use the new one. The code I wrote in C++ is useful because for classes derived from the one here attached there's nothing to change, and you might write the code as before.

I hope it helps: despite you are programming in ASM the concepts are the same and also the code structure doesn't change that much.

AccessMemory.h
Code:
#include <windows.h>

typedef BOOL (__stdcall *ACCESS_PROCESS_MEMORY_FCN)(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD );

class CAccessMemory  
{
public:
	CAccessMemory();
	virtual ~CAccessMemory();

	BOOL ReadProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer,
		DWORD nSize, LPDWORD lpNumberOfBytesRead);
	BOOL WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer,
		DWORD nSize, LPDWORD lpNumberOfBytesWritten);

private:
	BOOL _accessProcessMemory(
		ACCESS_PROCESS_MEMORY_FCN fcn, 
		HANDLE hProcess, 
		LPVOID lpBaseAddress, LPVOID lpBuffer,
		DWORD nSize, LPDWORD lpNumberOfBytesWritten);

};
AccessMemory.cpp
Code:
CAccessMemory::CAccessMemory()
{

}

CAccessMemory::~CAccessMemory()
{

}

//A wrapper for the ::ReadProcessMemory which set also the memory 
//access right properly
BOOL CAccessMemory::ReadProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer,
		DWORD nSize, LPDWORD lpNumberOfBytesRead) {
	
	ACCESS_PROCESS_MEMORY_FCN fcn;
	
	//There's a little difference between the two function pointers or 
	//::ReadProcessMemory and ::WriteProcessMemory, because the two prototypes are different
	//This trick cast the pointer of the function pointer of ::ReadProcessMemory to a 
	//void* then cast it back to an ACCESS_PROCESS_MEMORY_FCN function pointer. 
	//The differences between these two prototypes are not important and 
	//everything works excellently.
	fcn=(ACCESS_PROCESS_MEMORY_FCN)((void*)&(::ReadProcessMemory));
	
	return _accessProcessMemory(fcn, hProcess, lpBaseAddress, lpBuffer,
		nSize, lpNumberOfBytesRead);
}

//A wrapper for the ::WriteProcessMemory which set also the memory 
//access right properly
BOOL CAccessMemory::WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer,
		DWORD nSize, LPDWORD lpNumberOfBytesWritten)
{
	ACCESS_PROCESS_MEMORY_FCN fcn;

	//Assign the function pointer, this time there are no problems, 
	//because ACCESS_PROCESS_MEMORY_FCN is the prototype of ::WriteProcessMemory
	fcn=::WriteProcessMemory; 
	
	return _accessProcessMemory(fcn, hProcess, lpBaseAddress, lpBuffer,
		nSize, lpNumberOfBytesWritten);
}

//It is used by the WriteProcessMemory and ReadProcessMemory methods. 
//It worry to grant access to memory.
BOOL CAccessMemory::_accessProcessMemory(
		ACCESS_PROCESS_MEMORY_FCN fcn, 
		HANDLE hProcess, 
		LPVOID lpBaseAddress, LPVOID lpBuffer,
		DWORD nSize, LPDWORD lpNumberOfBytes)
{
	DWORD OldProtection=0;
	//It is not really used because the VirtualProtectEx function always requires a valid
	//variable to hold the old page protection values, otherwise fails. When restoring the 
	//protection values of the page, on the existing of this program, the old values are not
	//important of course.
	DWORD dummyProtection=0;

	BOOL bVal=FALSE;

	int tries=0;
	
	//Do 3 tries loop, so as not the block forever..
	while(tries<3) {
		__try {
			tries++;
			bVal=fcn(hProcess, lpBaseAddress, lpBuffer,nSize, lpNumberOfBytes);
			if(!bVal) 
				//The RaiseException function raises an exception in the calling thread.
				RaiseException(1, // exception code 
                0,                // continuable exception (non death exception)
                0, NULL);         // no arguments 
		}
		__except(TRUE) {
			if(IsBadReadPtr(lpBaseAddress, nSize) || IsBadWritePtr(lpBaseAddress, nSize))
				VirtualProtectEx(hProcess, lpBaseAddress, nSize, 
					PAGE_EXECUTE_READWRITE, &OldProtection);
			continue;
		}
		break;
	}
	
	//Restore the previous protections of the patched address.
	//OlProtection is !=0 if the previous VirtualProtectEx has been done.
	if(OldProtection!=0)
		VirtualProtectEx(hProcess, lpBaseAddress, nSize, 
			OldProtection, &dummyProtection);

	return bVal;

}
__________________
Ŝħůb-Ňìĝùŕřaŧħ ₪)
There are only 10 types of people in the world: Those who understand binary, and those who don't
http://www.accessroot.com
Reply With Quote