WriteProcessMemory

Feb 3, 2012 at 11:09am
Can someone explain to me how to use WriteProcessMemory correctly
I definitely have the value of the address right but I don't think I'm passing it correctly because the value is not being written. The code I have is here (and yes it is definitely being called because the calling function is appended to the bottom of an onclick event that grabs the addresses and values it relies on)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HANDLE getAppId(const wxString appName) {
	PROCESSENTRY32 ai;
	ai.dwSize = sizeof(ai);
	wxString exe;
	Process32First(NULL, &ai);
	HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ai.th32ProcessID);
	exe.Printf(wxT("%s"), ai.szExeFile);
	if (!exe.CmpNoCase(appName)) {
		return hp;
	}
	while ( Process32Next(NULL, &ai) ) {
		if ( !appName.compare(ai.szExeFile) ) {
			return hp;
		}
	} return 0;
}

1
2
3
void hexWin::HCWrite(HANDLE p, DWORD x, int s, DWORD32 v) {
	WriteProcessMemory(p, (LPVOID*)x, (LPCVOID*)v, s, NULL);
}
Feb 3, 2012 at 11:25am
Try WriteProcessMemory(p, (LPVOID*)&x, (LPCVOID*)&v, s, NULL);
Feb 3, 2012 at 11:33am
Tried it, didn't work... wait just thought of something that I forgot, I should've added the Base Memory address to the address before passing it, I'll give that a go and see if there is any change.

BTW I'm hacking PCSX2 0.9.7+ since it base address is fixed, the game is Final Fantasy 12, I'm just looking for the GIL to change before I worry about Byte Orders.

Edit: Still didn't work, here's my current code, I know HCSet works because I was sending the output to a textctrl before to make sure it was analysing correctly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
void hexWin::HCUse(void) {
	wxTreeItemId r = HTRoot();
	HANDLE pid = getAppId(tApp->GetValue());
	//if (pid) {
		HCUse(r, pid); //}
}
void hexWin::HCUse(wxTreeItemId& r, HANDLE pid) {
	HACK* h = (HACK*)HT->GetItemData(r);
	DWORD ram = getHEX(tRAMStart->GetValue());
	if (h->use) {
		int j = 0, s; CL c;
		wxTreeItemId i; wxTreeItemIdValue v;
		// Use CL
		while (j < h->GetLen()) {
			c = HCSet(h, j);
			s = (int)c.s;
			switch (c.t) {
			/*case 0x01: // Copy
				switch (c.s) {
				case 0x01: // WORD
				case 0x02: // DWORD
				case 0x03: // QWORD
				default: // CHAR
				} break;
			case 0x02: // Test
				switch (c.s) {
				case 0x01: // WORD
				case 0x02: // DWORD
				case 0x03: // QWORD
				default: // CHAR
				} break;
			case 0x03: // Increment
				switch (c.s) {
				case 0x01: // WORD
				case 0x02: // DWORD
				case 0x03: // QWORD
				default: // CHAR
				} break;
			case 0x04: // Decrement
				switch (c.s) {
				case 0x01: // WORD
				case 0x02: // DWORD
				case 0x03: // QWORD
				default: // CHAR
				} break;
			case 0x05: // List Write
				switch (c.s) {
				case 0x01: // WORD
				case 0x02: // DWORD
				case 0x03: // QWORD
				default: // CHAR
				} break;*/
			default: HCWrite(pid, ram + c.x, s, c.v);
			} j += h->cLines[j];
		}
		// Recurse through children
		i = HT->GetFirstChild(r, v);
		while (i.IsOk()) {
			HCUse(i, pid);
			HT->GetNextChild(r, v);
		}
	}
}
Last edited on Feb 3, 2012 at 11:38am
Feb 3, 2012 at 11:52am
This should work:
1
2
3
4
5
6
7
8
9
void hexWin::HCWrite(HANDLE p, DWORD x, int s, DWORD32 v) {
       DWORD *addr=(DWORD*)x;
	if(WriteProcessMemory(p, (LPVOID)addr, (LPVOID)&v, s, NULL)==0)
	{
	    cout <<"GetLastError: "<<GetLastError()<<endl; // print error code if something goes wrong
	}
}

Last edited on Feb 3, 2012 at 12:03pm
Feb 3, 2012 at 12:07pm
Tried it but didn't see any change so I stuck in a bunch of message boxes to see how far it was getting and eventually found the reason, h->use had never been made true so I'm going to fix that and see what happens.

Edit: Didn't write because of handle now (had messagebox in write function), I'm having a look at the code you just posted so it'll be a few minutes before I reply for that one
Last edited on Feb 3, 2012 at 12:29pm
Feb 3, 2012 at 12:10pm
This is some code copied from Windows via C/C++ 5th Edition, Page 627.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      // Get a handle for the target process. 
      hProcess = OpenProcess( 
         PROCESS_QUERY_INFORMATION |   // Required by Alpha 
         PROCESS_CREATE_THREAD     |   // For CreateRemoteThread 
         PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx 
         PROCESS_VM_WRITE,             // For WriteProcessMemory 
         FALSE, dwProcessId); 
      if (hProcess == NULL) __leave; 
 
      // Calculate the number of bytes needed for the DLL's pathname 
      int cch = 1 + lstrlenW(pszLibFile); 
      int cb  = cch * sizeof(wchar_t); 
 
      // Allocate space in the remote process for the pathname 
      pszLibFileRemote = (PWSTR)  
         VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE); 
      if (pszLibFileRemote == NULL) __leave; 
 
      // Copy the DLL's pathname to the remote process' address space 
      if (!WriteProcessMemory(hProcess, pszLibFileRemote,  
         (PVOID) pszLibFile, cb, NULL)) __leave; 
Feb 3, 2012 at 12:39pm
(sigh) Still can't get the HANDLE, maybe you can see what is wrong
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HANDLE getAppId(const wxString appName) {
	PROCESSENTRY32 ai;
	ai.dwSize = sizeof(ai);
	wxString exe;
	Process32First(NULL, &ai);
	HANDLE hp;
	exe.Printf(wxT("%s"), ai.szExeFile);
	if (exe.CmpNoCase(appName) == 0) {
		hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ai.th32ProcessID);
		return hp;
	}
	while ( Process32Next(NULL, &ai) ) {
		if ( appName.CmpNoCase(ai.szExeFile) == 0 ) {
			hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ai.th32ProcessID);
			return hp;
		}
	} return NULL;
}

Edit: Process32First didn't like NULL
Last edited on Feb 3, 2012 at 12:54pm
Feb 3, 2012 at 1:00pm
It's definitely gotten to the write function with the right HANDLE, address and value, problem remains that it isn't changing the GIL
1
2
3
4
void hexWin::HCWrite(HANDLE p, DWORD x, int s, DWORD32 v) {
	DWORD *a=(DWORD*)x;
	WriteProcessMemory(p, (LPVOID)a, (LPCVOID*)&v, s, NULL);
}
I've tried with both x and a, once I have this function working I should be able to write HCRead on my own

Edit: Finally, Turned out I remembered the start address wrong for the RAM, once I corrected that I was getting the desired result :D At long last my app is starting to behave like the app it was designed to be from the start.
Just got to add the HCRead and fill out the rest of the code abilities. Thank you for your help, the app's source code will be uploaded to http://code.google.com/p/renegade on the 9th (I'm running off a Dongle at the moment so will wait for Broadband to be activated - recently moved)
Last edited on Feb 3, 2012 at 2:23pm
Topic archived. No new replies allowed.