Write String to Memory address using WriteProcessMemory

Hello,

as my title says I try to write a string to a certain memory address.

When i do it with a DWORD value its working fine,
but not with a string.

For instance this works:

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
int main()
{
hwnd = FindWindow(NULL,"MyApplication");
if(!hwnd)
{
cout <<"Window not found!\n";
cin.get();
	}
	else
	{
GetWindowThreadProcessId(hwnd,&pid);
HANDLE phandle = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,0,pid); 
// I do have the appropriate rights to write to memory
		if(!phandle)
		{
		cout <<"Could not get handle!\n";
		cin.get();
		}
		else
		{
		while(1)
		{
		ReadProcessMemory(phandle,(void*)(Static_Pointer),&BasePointer,sizeof(DWORD),0);
		ReadProcessMemory(phandle,(void*)(BasePointer+offset1),&Base_address,sizeof(DWORD),0);
		ReadProcessMemory(phandle,(void*)(Base_address+offset2),&Final_address,sizeof(DWORD),0);
		
		WriteProcessMemory(phandle,(void*)(Base_address+offset2),&New_Value,sizeof(New_Value),0);
		
		{
		return 0;
		}
		}
		}
	}
}


While this code doesnt.

I tried using CHAR instead of std:: string.
strcpy woulnt work for my purpose right?
Also string.lenght instead of "sizeof"

1
2
3
4
5
6
7
8

#include <windows.h>
#include <string>

std:: string New_Name = "New_Name";

ReadProcessMemory(phandle,(char*)(Base_address+offset3),&Name_address,sizeof(DWORD),0);
WriteProcessMemory(phandle,(void*)(Base_address+offset3),&New_Name,sizeof(New_Name),0);


Thanks for your hlep.
You can't write non-POD types to memory for the same reason that you can't write them to a file.

Consider the following:

1
2
3
4
5
6
7
8
std::string small = "foo";
std::string big  = "A very long string that contains a lot more data.  Logically"
        " you would think this string would take more space in memory because"
        " it contains a lot more characters.  But take a look at this example and"
        " maybe you'll see what I mean.";

cout << sizeof(small) << endl;  // prints the size of the small string
cout << sizeof(big) << endl;    // prints the size of the big string 


You might be surprised to know that sizeof(small) and sizeof(big) are EXACTLY THE SAME. They're both just giving you the size of the std::string class.

But how can this be? One is obviously larger than the other, right?

The thing is... the std::string does not actually contain the string data. It contains a POINTER TO the string data. So when you attempt to write a string object to memory like you're doing... you're not actually writing the string, you're just writing an arbitrary pointer.


Clearly... this will not work.


What you need to do instead is get a pointer to the actual string data, and write THAT data to memory. You can get this with the c_str member function.

So instead of this:
WriteProcessMemory(phandle,(void*)(Base_address+offset3),&New_Name,sizeof(New_Name),0);

You can do this:
WriteProcessMemory(phandle,(void*)(Base_address+offset3),New_Name.c_str(),New_Name.length(),0);

Note the 2 key differences here:
1) using c_str() to get a pointer to the string data
2) using length() to get the length of the string, rather than sizeof() to get the size of the std::string object.


However... this is still problematic because the length of the string is variable... and therefore it will be impossible to read this string back from memory unless you first know the length of it.

Therefore, you have 2 options:

1) Write an integer value to memory first to indicate the length of the string.
or
2) Write an additional '\0' character after the string data to indicate the end of the string.

I highly recommend approach #1, as it not only makes the string easier to read back, but it also is more "solid" than approach #2 (#2 will fail, for example, if the string you want to write already contains null characters).
Last edited on
Disch thanks a lot for that fast reply.
Good example to clear up where i was thinking wrong.

Its working now, considering your second option, it would work for me,
since it is not supposed to contain null chars.

But a more solid way as you said is always good to know of.
What do you mean by writing value to memory that indicated the string lenght?

Getting the lenght of string with the lenght fuction .length() and then writing its value,
to which memory location?

Another problem i have been running into, is when ever i input a string that is equal or longer than
the old one its working fine, since the old one gets overriden.
But when its shorter than there are remaining characters of the old string.

For instance:

I read out Name_address = "My_Old_Name"
and I set the new one to: "New_Name"

then it becomes: "New_Nameame"

A simply hackish way to overcome this, I did it like this, before writing the name to the address, but its more like a stopgap

std::string Clear_Name = " "; // Clear_Name contains 17 Space signs, since I actually only need space for 16 chars.

WriteProcessMemory(phandle,(void*)(Base_address+offset3),Clear_Name.c_str(), Clear_Name.length(),0);

I googled and found out about a function: str.clear()
But couldnt get it to work with Writeprocessmemory
Well the data you're writing to memory has to match whatever format the app on the other end is going to expect when it reads it.

So the real questions here are:

1) How is this string data being read?
2) Are you sure the reading code matches the writing code?


Poking and tweaking until you "get it to work" is probably a bad idea, as there are a lot of ways raw memory access can go wrong if you're not careful... so you should have a very clear understanding on exactly what it is you're reading/writing.
Topic archived. No new replies allowed.