Thread: Reading Process Memory

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230

    Reading Process Memory

    Hi guys, so I'm trying to write a program that will read a user chosen process' memory starting at address 0x400000 and ending at 0x7FFFFFFF. The problem is it will only read a processes memory every 5 or so times I run the program. Some times I have to restart the program like 15 times before it reads the processes memory. The times it doesn't work GetLastError() will return 299, which is the following:

    ERROR_PARTIAL_COPY: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

    Can anyone tell me why it can work sometimes and not others?

    This is all a learning experience for me so it wouldn't surprise me if I'm doing something quite strange. You probably only need to see the ReadProcessMemory() loop but I'll post the whole program just in case.

    Thanks a lot guys!

    Code:
    #include <iostream>
    #include <windows.h>
    #include <Tlhelp32.h>
    #include <vector>
    
    using namespace std;
    
    typedef struct ProcessInfo {
    	int procId;
    	char * procName;
    } ProcessInfo;
    
    ProcessInfo EnumerateProcesses();
    
    int main(int argc, char * argv[]) {
    	if (argc != 2 && argc != 1) {
    		printf("Usage: <memHack.exe> <executable.exe>\n");
    		return 1;
    	}
    	
    	LUID privLuid;
    	HANDLE hTokenHandle = 0;
    	
    	/* Change the process security token to debug mode */
    	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hTokenHandle))
    		printf("[!] Error opening process token: %d\n", GetLastError());
    
    	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privLuid))
    		printf("[!] Error looking up the privilege value: %d\n", GetLastError());
    
    	TOKEN_PRIVILEGES sTokenPrivs;
    	sTokenPrivs.PrivilegeCount = 1;
    	sTokenPrivs.Privileges[0].Luid = privLuid;
    	sTokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    	if (!AdjustTokenPrivileges(hTokenHandle, FALSE, &sTokenPrivs, NULL, NULL, NULL))
    		printf("[!] Error adjusting process token privileges: %d\n", GetLastError());
    
    	CloseHandle(hTokenHandle);
    
    	bool userInput = false;
    	ProcessInfo sProcInfo;
    	memset(&sProcInfo, 0, sizeof(ProcessInfo));
    
    	/* Check if file exists */
    	if (argc == 2) {
    		OFSTRUCT fileInfo;
    		HFILE fileHandle = 0;
    		if ((fileHandle = OpenFile(argv[1], &fileInfo, OF_EXIST)) == HFILE_ERROR) {
    			if (GetLastError() == ERROR_FILE_NOT_FOUND) {
    				printf("[!] File \"%s\" does not exist.\n", argv[1]);
    				CloseHandle((HANDLE)fileHandle);
    				return 1;
    			}
    		}
    		CloseHandle((HANDLE)fileHandle);
    	}
    	
    	/* If not parsed a file to load, enumerate processes for user decision */
    	else {
    		userInput = true;
    		sProcInfo = EnumerateProcesses();
    	}
    	
    	HANDLE targetProcess = 0;
    
    	/* Opening a running process or loading a process */
    	if (userInput) {
    		if ((targetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sProcInfo.procId)) == NULL) {
    			printf("[!] Error acquiring %s process handle with PID %d: %d\n", 
    				sProcInfo.procName, 
    				sProcInfo.procId, 
    				GetLastError());
    			return 1;
    		}
    	}
    
    	else {
    		STARTUPINFO startupInfo;
    		PROCESS_INFORMATION processInformation;
    
    		memset(&startupInfo, 0, sizeof STARTUPINFO);
    		memset(&processInformation, 0, sizeof PROCESS_INFORMATION);
    
    		startupInfo.cb = sizeof STARTUPINFO;
    		
    		if (!CreateProcess(argv[1], NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation)) {
    			printf("[!] Error loading program and creating process: %d\n", GetLastError());
    			return 1;
    		}
    		
    		if (processInformation.hProcess)
    			targetProcess = processInformation.hProcess;
    
    		if (processInformation.hThread)
    			CloseHandle(processInformation.hThread);
    	}
    
    	unsigned char memoryDump[65535];
    	int byteCount = 0;
    	SIZE_T readAmount = 0;
    	
    	// Read memory into buffer in 65k byte chunks
    	for (SIZE_T y = 0x00400000; y < 0x7FFFFFFF; y += 65535) {
    		if (ReadProcessMemory(targetProcess, &y, memoryDump, 65535, &readAmount)) {
    			for (SIZE_T n = 0; n < 65535; n++) {
    				// 16 bytes have been printed
    				if (byteCount % 16 == 0)
    					printf("\n0x%x: ", y+n);
    				printf("%02x ", memoryDump[n]);
    				byteCount++;
    			}
    		}
    		else {
    			printf("\n[!] Error reading process memory: %d, read %d bytes before error.\n", GetLastError(), readAmount);
    			break;
    		}
    	}
    
    	if (targetProcess)
    		CloseHandle(targetProcess);
    }
    
    
    // Returns the name of the user chosen process
    ProcessInfo EnumerateProcesses() {
    		HANDLE hSnapshot = 0;
    		hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    		
    		if (hSnapshot == INVALID_HANDLE_VALUE) {
    			printf("[!] Failed to obtain process snapshot handle: %d\n", GetLastError());
    			CloseHandle(hSnapshot);
    			exit(0);
    		}
    
    		PROCESSENTRY32 sProc;
    		sProc.dwSize = sizeof(PROCESSENTRY32);
    		if (!Process32First(hSnapshot, &sProc)) {
    			printf("Failed to enumerate first process from snapshot: %d\n", GetLastError());
    			CloseHandle(hSnapshot);
    			exit(0);
    		}
    		
    		vector<char *> processes;
    		vector<int> processIds;
    
    		do {
    			char * tmp = new char[MAX_PATH];
    			strcpy(tmp, sProc.szExeFile);
    			processes.push_back(tmp);
    			processIds.push_back(sProc.th32ProcessID);
    		} while (Process32Next(hSnapshot, &sProc));
    
    		for (int i = 2; i < processes.size(); i++) {
    			printf("[%d] %s - %d\n", i - 1, processes[i], processIds[i]);
    		}
    		
    		int process = 0;
    		printf("\nProcess #: ");
    		cin >> process;
    		process += 1;
    		
    		ProcessInfo sProcInfo;
    		sProcInfo.procName = new char[MAX_PATH];
    		strcpy(sProcInfo.procName, processes[process]);
    		sProcInfo.procId = processIds[process];
    
    		for (int i = 0; i < processes.size(); i++)
    			delete [] processes[i];
    
    		return sProcInfo;
    }
    Last edited by pobri19; 02-09-2010 at 07:22 AM. Reason: Fixed output
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bug in Best-Fit Memory Allocation program (Simulation)
    By RommelTJ in forum C Programming
    Replies: 6
    Last Post: 12-13-2009, 04:43 PM
  2. sequenceing or queueing multiple process
    By sv_joshi_pune in forum Windows Programming
    Replies: 1
    Last Post: 08-14-2009, 09:43 AM
  3. Question regarding Memory Leak
    By clegs in forum C++ Programming
    Replies: 29
    Last Post: 12-07-2007, 01:57 AM
  4. patching memory in another process
    By 44ffcc in forum Windows Programming
    Replies: 2
    Last Post: 02-06-2006, 09:32 AM
  5. Reading from file into memory
    By GaPe in forum C Programming
    Replies: 15
    Last Post: 12-17-2001, 04:19 PM