I'm writing an application to patch assembler instructions according to memory addresses. I have been using C/stdio for FILE operations (fopen, fseek, fprintf), but I would like to have a C++/fstream implementation as well (.open, .seekp, .put). I've had no problems patching file memory with stdio, but fstream/ofstream methods corrupt my executable. I've tried opening the files in multiple ios modes, but nothing's worked. Here's a simple example.

Working C Implementation

#include <stdio.h>

int main() {
    int offset[] = {0x0000082A, 0x0000082B, 0x0000082C, 0x0000082D};
    char data[] = {0x90, 0x90, 0x90, 0x90};

    FILE *faddr;
    if (((faddr=fopen("test.exe", "r+")))==NULL) return -1
    for (int i=0; i<sizeof(offset)/sizeof(int); i++) {
        fseek(faddr, offset[i], SEEK_SET);
        fprintf(faddr, "%c", data[i]);
    }

    return 0;
}

Not-Working C++ Implementation

#include <fstream>
int main() {
    ofstream f("test.exe", ios::out | ios::binary);
    if (f.fail()) return -1;
    
    int offset[] = {0x0000082A, 0x0000082B, 0x0000082C, 0x0000082D};
    char data[] = {0x90, 0x90, 0x90, 0x90};

    for (int i=0; i<sizeof(offset)/sizeof(int); i++) {
        f.seekp(offset[i], ios::beg);
        f.put(data[i]);
    }
    
    f.close();
    return 0;
}

I'm not entirely sure if put overwrites the content at the current position (although I see no reason why it shouldn't). Can you try using f.write with a size of 1 ?

Change ofstream f("test.exe", ios::out | ios::binary); To ofstream f("test.exe", ios::in | ios::out | ios::binary); The first is equivalent to the C mode string "wb", the second is equivalent to "r+b" which is what you need here.

Edited 6 Years Ago by vijayan121: n/a

Thanks, vijayan121! That fixed it. thelamb, I thought of doing that but I didn't know how to change the offset. Thanks all!

This article has been dead for over six months. Start a new discussion instead.