Read/Write dynamic values to executable file from it-self


Sometimes you want to change a configuration, strings, integers or other static variable values dynamically and NOT in the building actual source process. For example:

You trying to write a client-server application and the server address can change anytime as the user needs. I know I know, we can store it in config.ini, databases (sqlite), Windows registry, etc.

But when you are writing a security tool (malware actually) you will try to touch the file-system as low as possible to avoid detection. Another example for those who don't make security tools (malwares):

You are selling an single application that you want to be portable and single file (just because you are cool) and you need to store data INSIDE your executable file, what would you do ?

Thus, I made a way for my self to store values inside my executable file and I will read them anytime I want and those values can actually change by a another application (ex. foo application builder).

I think I gave you the basic idea, lets get started how it works and how we can write it :)


Option 1:

We can use EOF (End of file) to store and read values from the arbitarry/unused bits at the end of our file. for example when you open a executable file in HxD (hex editor) at the last hex/bits of file you can see the following: 

 


Those (00, 00, 00) are unused places that you can store values to them manually and read it.

  1. Open file and reach the EOF
  2. Know the size of data you wrote
  3. Read from EOF by size of data
Simple 😏


Option 2 (The nice one, Windows Only):

The real trick is that we store data inside String Table at the executable resources file (so you HAVE TO have resources). Open a random executable from Resource Hacker:
 


WRITE:

Here is the way you can write data to your String Table (I assume you know some WinAPI/C++ to modify this by your self):

BOOL setResourceData(LPCTSTR szSSPath, LPCTSTR szSSName, int order)
	{
		HANDLE h = ::BeginUpdateResource(szSSPath, FALSE);
		if (!h)
		{
			// BeginUpdateResource failed
			return FALSE;
		}

		CString sNewString = szSSName;
		int iCharCount = sNewString.GetLength() + 1;
		LPWSTR pUnicodeString = new WCHAR[iCharCount];
		if (!pUnicodeString)
		{
			// new failed
			return FALSE;
		}

		DWORD dwUnicodeCharCount =
			MultiByteToWideChar(CP_ACP, NULL, sNewString.GetBuffer(0),
				-1, pUnicodeString, iCharCount);
		HGLOBAL hGlob =
			GlobalAlloc(GHND, (dwUnicodeCharCount + 4) * sizeof(WCHAR));
		if (!hGlob)
		{
			// GlobalAlloc failed
			delete pUnicodeString;
			return FALSE;
		}

		LPWSTR pBufStart = (LPWSTR)GlobalLock(hGlob);
		if (!pBufStart)
		{
			// GlobalLock failed
			GlobalFree(hGlob);
			delete pUnicodeString;
			return FALSE;
		}
		LPWSTR pBuf = pBufStart;
		pBuf++;
		// offset to make it string ID=1. Increment by more
		// to change to a different string ID

		// next 2 bytes is string length
		*(pBuf++) = (WCHAR)dwUnicodeCharCount - 1;
		for (int i = 0; i<(int)dwUnicodeCharCount - 1; i++)
			// remaining bytes are string in wide chars (2 bytes each)
			*(pBuf++) = pUnicodeString[i];
		delete pUnicodeString;
		if (++dwUnicodeCharCount % 1)
			// make sure we write an even number
			dwUnicodeCharCount++;
		BOOL bSuccess = TRUE;
		if (!::UpdateResource(h, RT_STRING, MAKEINTRESOURCE(order),
			MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
			pBufStart, dwUnicodeCharCount * sizeof(WCHAR)))
		{
			// UpdateResource failed
			bSuccess = FALSE;
		}

		GlobalUnlock(hGlob);
		GlobalFree(hGlob);
		::EndUpdateResource(h, FALSE); // write changes
		return bSuccess;
	}

 

Parameters: 
  • szSSPath: The executable file path
  • szSSName: The name of your variable to set
  • order: The order number (put it randomly), this value is REQUIRE later to read values


READ

 

std::string GetAddress() {
    TCHAR Connection[160];
    HINSTANCE hInstance = GetModuleHandle(NULL);
    if (LoadStringA(hInstance, ORDER, Connection, sizeof(Connection) / sizeof(TCHAR)) == 0) {
    }
    return Connection;
}

This function simply does the reading process from executable it-self. where ORDER is the order number you set before.


That's it, feel free to ask.


-Good Luck ✌






Comments

  1. nice and useful tricks.
    like the theme and these beautiful images for your posts.
    ---
    publish the link to your post in social networks (especially hackernews or reddit).

    ReplyDelete

Post a Comment