const char* findThisMsgInMem = "Hello World! Everyone is Happy";
                if(memcmp(&dataInMem[i], findThisMsgInMem, defaultMsgSize) == 0)
		{
			memcpy(&dataInMem[i], newMsg, strlen(newMsg));
                        //more code here
                }

This is first time for me trying to use malloc, and realloc. Please see the coding example for illustration purposes. Don't worry of this lengthy question, most of it is an explaination of the problem i'm facing.

Explain what going on:
memblock is of type char * .

dataInMem contains long stream data which includes this "Hello World! Everyone is Happy".

"Hello World! Everyone is Happy" that resides in dataInMem is of type const char*.

memcmp(&dataInMem, findThisMsgInMem, defaultMsgSize) is looking for "Hello World! Everyone is Happy" inside memcmp.

memcpy(&dataInMem, newMsg, strlen(newMsg)) copies/replaces the newMsg user entered into the place of "Hello World! Everyone is Happy". newMsg is of type const char*.

The expected result is:

"Hello World! Everyone is Happy" will be all overwritten if the length of newMsg equals the length the string "Hello World!.....". Otherwise, "Hello World! Everyone is Happy" inside dataInMem will be partially overwritten which produce a corrupted results. For example, if newMsg is "Don't Play with Memory" then the overwritten data in dataInMem will look like
Don't Play with MemoryHappy

Happy is not overwritten. Therefore, the solution is to go and take off the remained part (Happy) ONLY. I can solve such a problem when i'm dealing with strings, but in the current case most probably i will have to use memmove() or memcpy() to rid of "Happy". I thought to replace happy with spaces, but it is really not a good solution because putting spaces is not solving anything, space counted as char.

Anyhow, this is how i replaced Happy with spaces. I set newMsg as string, then i calculated the difference in length of the newMsg and defaultMsgSize. In our case, the remained length is 5 (Happy). After that, i appended spaces at the of newMsg, so newMsg has the word with five spaces and will be written in memory as "Don't Play with Memory " , which in someway not a proper solution.

I got other solutions, but they seems useless, because no matter what i do, i must solve this problem within dataInMem except if newMsg length equals defualtMsgSize. Therefore the proper solution as far as i see is to use malloc and realloc or anything related to alloc. I have no background on using malloc, etc yet.

dataInMem extracted data from a binary file (.exe). Thus, "Hello World! Everyone is Happy" already existed in the binary file. I can change the length of the string from "Hello World...." to
"X" before i compile the binary file (.exe), but it is expected that the newMsg will start from 1 to 15 (0 to 14) chars in length, so if i set the default message is "X" and newMsg "xxxxxxxxxxxxxxx" length is 15, then i'm facing the problem of overwriting other data that comes after X, which this corrupt the file totally, thats why i though about malloc and realloc. I got some questions about malloc and realloc too, but i will stop here by now.

I hope you got my point...

I need to hear your suggestions, tips, advices?

Recommended Answers

All 7 Replies

You could shift everything after "Happy" left 5 positions to overwrite that text, which will move the empty spaces to the end of the buffer. Since its a binary buffer (I think it is anyway from your description) you can fill the remaining bytes with '\0'.
So if the buffer looks like this: "Don't Play with MemoryHappyxxxxyyyzzz" you would shift "xxyyyzzz" left to overwrite Happy so that it winds up looking like this Don't Play with Memoryxxxyyyzzz'\0''\0''\0''\0''\0'" After that you could call realloc() to resize the buffer or just leave it alone.

You could shift everything after "Happy" left 5 positions to overwrite that text, which will move the empty spaces to the end of the buffer. Since its a binary buffer (I think it is anyway from your description) you can fill the remaining bytes with '\0'.
So if the buffer looks like this: "Don't Play with MemoryHappyxxxxyyyzzz" you would shift "xxyyyzzz" left to overwrite Happy so that it winds up looking like this Don't Play with Memoryxxxyyyzzz'\0''\0''\0''\0''\0'" After that you could call realloc() to resize the buffer or just leave it alone.

Ok, i thought about shifting, but when i reverse the .exe file using Hex Workshop i find there is nothing after Happy....

..G$...&....Don't Play with MemoryHappy........xxxxyyyzzz

the bold underlined part has these hex numbers
00 00 00 00 00 00 00 00 which means empty, or nothing. Assume the shifting succeeded won't the overwritten msg be corrupted, because Don't Play with Memory is not as same as Don't Play with Memoryxxxyyyzzz

Please note that "Don't Play with Memory" will have an IP number instead, so it must be altered in any way even with space. Otherwise, the IP won't be valid...

It might help understand the problem if you would post an actual example of the buffer.

It might help understand the problem if you would post an actual example of the buffer.

void MenusLayout::patchEXE(const char *newIPAddress, const char *newPortNumber)
{	
	string DEFAULT_IP = "255.255.255.255";
	string DEFAULT_PORT = "55555";

	size_t defaultIPSize = DEFAULT_IP.length();
	size_t defaultPortSize = DEFAULT_PORT.length();

	size_t newIPSize = strlen(newIPAddress);
	size_t newPortSize = strlen(newPortNumber);

	fstream fileStream;
	size_t size;
	char *memblock;

	fileStream.open ("App.exe", fstream::ate | fstream::in | fstream::binary);

	if( !(fileStream.is_open()) )
	{
		cout<<"Error opening file";
		cout<<"*Make sure the file App.exe exists in the folder."<<endl;
		cout<<"Please press any key to go back"<<endl;
		fileStream.close();
		cin.get();
                //exit
	}

	fileStream.seekg(0, ios::end);
	size = fileStream.tellg();
	memblock = new char[size];
	fileStream.seekg(0, ios::beg);
	fileStream.read(memblock, size);
	fileStream.close();

	for(int i = 0; i < (int)size; i++) 
	{
		if(memcmp(&memblock[i], DEFAULT_IP.c_str(), defaultIPSize) == 0)
		{
			memcpy(&memblock[i], newIPAddress, strlen(newIPAddress));
			
                        //Shifting should happen here as far as i know

		}
	}

        //Overwrite port too
	int outputServerSize;

	for(int i = 0; i < (int)size; i++) 
	{
		if(memcmp(&memblock[i], DEFAULT_PORT.c_str(), defaultPortSize) == 0)
		{
			memcpy(&memblock[i], newPortNumber, strlen(newPortNumber));
			
                        //shifting should happen here

                        //now output all data from memblock to a newly created .exe
			fileStream.open ("YourOutputApp.exe", fstream::ate | fstream::out | fstream::binary);

			if (!(fileStream.is_open()))
			{
				cout<<"Error opening file";
				cout<<"Please press any key to go back"<<endl;
				fileStream.close();
				cin.get();
                                //exit
			}

			fileStream.seekg(0, ios::beg);
			fileStream.write(memblock, size);
			fileStream.seekg(0, ios::end);
			outputServerSize = fileStream.tellg();
			fileStream.close();
		}
	}

        //make sure the original file and output file has same size
        //If not, then the output file is corrupted...This part is useful
        //to validate the output. Thus, i will have to look for another
        //solution to validate the output if its been corrupted or not
        //Anyway, i will leave it here for now 
	if(outputServerSize == size)
	{
		cout<<"Edited successfully. "<<endl;
		delete [] memblock;
		return; 
	}else{
		cout<<"Error occured. Repreat process"<<endl;
		cout<<"Press any key to go back"<<endl;
		delete [] memblock;
		cin.get();
		//exit or go back
	}
}

I set DEFAULT_IP and DEFAULT_PORT as string because i did this at first:

int unwantedDataSize_IP = defaultIPSize - newIPSize;
int unwantedDataSize_Port = defaultPortSize - newPortSize;

DEFAULT_IP.erase(newIPSize, unwantedDataSize_IP);
DEFAULT_PORT.erase(newPortSize, unwantedDataSize_Port);

defaultIPSize = DEFAULT_IP.length();
defaultPortSize = DEFAULT_PORT.length();

Although it worked fine, it is useless because actions should be in memblock.

App.cpp has the following simple code in main:

ConnectToClient connectNow("255.255.255.255", "55555");

So in reality when i overwrite App.exe, i'm overwriting the two parameters above and then these parameters are passed to getaddrinfo() and related winsock code.

The design might need to be fixed, but that's the last i can do it. Most importantly is solving problem first.

I code overwrite successfully, but the problem in what remains after the newly written IP.

Here is an image after i reversed YourOutputApp.exe:

http://img223.imageshack.us/img223/908/reversedcode.png

In the pic, i made newIPAddress = "192.160.0.11";
newPortNumber = "342";

I underlined the important parts with blue, red and green color lines.

I hope you can help me find the solution.

Best Regards,
F.J.

It might help understand the problem if you would post an actual example of the buffer.

Any help?

>>//Shifting should happen here as far as i know

As long as the original string and the new string have the same length there is no need for shifting. If however the original values are not the same it is not safe to change the size of the original *.exe file because you will change the location byte offset of its program variables and other symbols.

Also, you might corrupt the program's stack and other data areas by changing string lengths. Example: originally a program might be like this:

int main()
{
    char ip[] = "127.0.0.1";
}

Now if the program you are writing changes the text to "255.255.255.255" you will be changing the length of the string that the compiler had allocated for the original value. That is not good news!

>>//Shifting should happen here as far as i know

As long as the original string and the new string have the same length there is no need for shifting. If however the original values are not the same it is not safe to change the size of the original *.exe file because you will change the location byte offset of its program variables and other symbols.

Also, you might corrupt the program's stack and other data areas by changing string lengths. Example: originally a program might be like this:

int main()
{
    char ip[] = "127.0.0.1";
}

Now if the program you are writing changes the text to "255.255.255.255" you will be changing the length of the string that the compiler had allocated for the original value. That is not good news!

hmmm, i see. I must change the design structure. I will see what i can do. ..If you have a brief suggestion or tip, feel free to tell me. I will take it under consideration.

Extra note: I kind of heard of about something called read EOF() to solve such issues (create binary file out of another binary file).

Thanks for your support. Hats off

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.