I'm writing a dll in 'C/C++ - Win32API' environment. I have some constant variables (all are DWORD values and LPWSTR/LPSTR strings) that I have to enable the user modify. what I'm looking for is (hopefully) a tool that enable a SAFE binary modification as described, in a way that updates all the necessary tables of the PE.
You can create a struct in a separate PE section thus:
// Create the section
#pragma section("myconst", read)
// Declare a struct to hold the constant data
typedef struct
{
DWORD a;
DWORD b;
char stringa[256];
char stringb[256];
} ConstData;
// Create an initialized instance of the struct in the new section
__declspec(allocate("myconst"))
const ConstData theData = {0xdeadbeef, 0xfeedface, "Hello", "dolly"};
Compile the code. Open a Visual Studio Command Prompt, run
dumpbin /all myexe.exe > dump.txt
notepad dump.txt
Search for the myconst
section. You should see something like:
SECTION HEADER #4
myconst name
208 virtual size
4000 virtual address (00404000 to 00404207)
400 size of raw data
2000 file pointer to raw data (00002000 to 000023FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only
RAW DATA #4
00404000: EF BE AD DE CE FA ED FE 48 65 6C 6C 6F 00 00 00 ï¾ÞÎúíþHello...
00404010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00404020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
You can see the two hex values that were initialised in the code and the first string value. You can also see that the offset of this data in the PE file - "file pointer to raw data" - is 0x2000.
Armed with that information it is very easy to construct a new data block, open the PE file and overwrite the data at 0x2000.
To determine the offset from code you need to parse the PE file header and section headers. This is fairly straightforward. Or you could grab the offset from the dumpbin output as part of your build process, and feed it into the build of the editing tool.
Note that to test this in release mode you need to actually make use of theData
or the linker will throw it away. Also note that the section only has the read
attribute so it is truly read-only. Attempting to write it will give an access violation.
And finally... This is all quite scruffy. I wouldn't bother unless you really have no alternative.