Qt World Summit: Submit your Presentation

How do I utilize QDataStream to write binary to file?

  • Hello,
    right now I'm writing a function to dump a defined memory range of a foreign process into a binary file. I have allocated a new memory area depending on the dump size and successfully copied the dump over there. malloc() has returned a pointer to that memory location. Now I'd like to save all bytes situated at this pointer to file.

    QFile dump(dump_path);
        if(!dump.open(QFile::WriteOnly | QFile::Text))
            QMessageBox::warning(this, "Error", "Cannot write to file");
        unsigned __int64 dump_start = ui->lineEdit_dump_start->text().toULongLong(ok, 16);
        unsigned __int64 dump_end = ui->lineEdit_dump_end->text().toULongLong(ok, 16);
        unsigned __int64 dump_size = dump_end - dump_start;
        unsigned __int8 *byte_array = (unsigned __int8*) malloc(dump_size); // where to copy dump before exporting
        unsigned __int8 *byte_array_backup = byte_array;
        ui->lineEdit_malloc->setText(QString::number((unsigned __int64)byte_array, 16));
        for(int i = 0; i <= dump_size; i++, dump_start++, byte_array++)
            *byte_array = copy_byte(dump_start); //copy_byte() is the function that returns a byte from the foreign process
    //I'm lost here.. :(

  • Lifetime Qt Champion


    QFile file( "test.dat" );
    if( !file.open( QIODevice::WriteOnly ) )

    QDataStream stream( &file );
    // loop
    stream << "var" << realvar << what_u_like ;
    // loop end

  • thanks
    Mind explaining the following line in detail?
    @mrjj said in How do I utilize QDataStream to write binary to file?:

    stream << "var" << realvar << what_u_like ;

    It writes to a file now but only every 8th byte with 7 clear bytes in between. therefore the file is 8 times as big as defined

    writeBytes << copy_byte(dump_start);

    I have tried copying it byte wise and qword wise. the result was the same

  • Lifetime Qt Champion

    << is an operator.
    it can put known types to a stream;
    Its polymorph and can handle all build in types.
    Be vareful with pointers. it might write pointer address to stream, not what it points to unless
    you deref it with *

    for (int x=0; x < 1000 ; x++ )
    stream << x;

    will write 0 to 999 to the stream ( and hence the file)

    what does copy_byte return ?
    (type wise)

    Note: you open it as QFile::Text so it might add newlines

  • @mrjj
    The pointer is an unsigned __int64 and is converted to LPVOID to work with ReadProcessMemory()

    unsigned __int8 MainWindow::copy_byte(unsigned __int64 addr)
        val &= 0;
        hProcess = OpenProcess(PROCESS_VM_READ, 0, pid);
        ReadProcessMemory(hProcess, (LPVOID)addr, &val, 1, 0);
        return val;

    So as you can see copy_byte() returns an unsigned __int8.

    what should I use instead of QFile::Text?
    I changed it to Append and retried writing it in __int64 and the file was in BE. By returning a Byte it works!
    Is using QFile::Append an appropriate way though?
    And the dumping process is really slow.. (about 100KB/s).

    changed it to:

    QDataStream writeBytes(&dump);
        for(int i = 0; i < dump_size; i++, dump_start++, byte_array++)
            *byte_array = copy_byte(dump_start);
            //writeBytes << copy_byte(dump_start);
        writeBytes.writeRawData((const char*)byte_array_backup, (int)dump_size);

    it immediately dumps 32MB but then freezes. Might be an access violation. I wikk do some more testing

  • Lifetime Qt Champion

    QFile::Append means file will not be truncated but appended to.
    So if you re-open file for each call, it has to move to end of file to append.
    if you << a void pointer, i think it will write the value of the pointer and not what it points to.
    writeBytes might suit you better since same type.

Log in to reply