【问题标题】:C++ Writing Binary Dump and Writing to Binary from DumpC++编写二进制转储和从转储写入二进制
【发布时间】:2017-06-05 00:24:37
【问题描述】:

我很困惑,需要一些帮助。 在我的一个程序中,我正在实现一些代码,以便我可以在 Windows 上运行一个程序并基本上执行 hexdump(您在 hex 编辑器中看到的),我将其转换为二进制文件并将其写入 .txt 文档。我最近才弄明白了一半。另一半代码是将已转储为 .txt 文件中的二进制文件的对象重建为原始对象。这应该适用于所有对象,而不仅仅是重建某个对象。

转储部分的部分代码:

//Rip Program to Binary

streampos size; //Declare size variable
unsigned char* memblock; //Holds input
ifstream input; //Declare ifstream
ofstream output("output.txt", ios::out|ios::binary); //Specify ofstream
input.open("sparktools.bin", ios::in|ios::binary|ios::ate); //Open input file and move to the end of it

size = input.tellg(); //Store current location as file length
memblock = new unsigned char [size]; //Declare the input holder with array size as length of file
input.seekg (0, ios::beg); //Return to beginning of file

input.read((char*)memblock, size); //Read each character of the input file until end of file

for (int i=0; i<size; i++) //For each character until end of file:
{   
    std::bitset<sizeof(char) * CHAR_BIT> binary(memblock[i]); //Set bitset<1> to essentially convert to a binary char array
    output << binary; //Output from binary variable created
}

input.close();
output.close();
delete[] memblock;

重建零件的部分代码:

//Restore Ripped Binary To Program

int size; //Holds length of input document
unsigned char* memblock; //Holds input
ifstream input; //Declare ifstream
ofstream output("Binary.bin", ios::out|ios::binary); //Specify ofstream
input.open("Binary.txt", ios::in|ios::binary|ios::ate); //Open input file and move to the end of it

size = input.tellg(); //Store current location as file length
input.seekg(0, ios::beg); //Return to beginning of file
memblock = new unsigned char [size]; //Declare the input holder with array size as length of file
input.read((char*)memblock, size); //Read each character of the input file until end of file

for (int i=0; i<size; i++) //For each character until end of file:
{
    output.write((char*) &memblock[i], size); //Write each char from the input array one at a time until end of file to the output binary

}

input.close();
output.close();
delete[] memblock;

我正在测试图像的功能。原始文件大小为 10 KB。转储后,.txt 文件为 76 KB,内容与十六进制编辑器中显示的内容相匹配。

当我从二进制转储中重建时,文件大小不会回到 10 KB。当我增加位集数时,文件大小会增加。但是,在 bitset 处,它保持在 76 KB。根据我的结论,我基本上需要 bitset 将文件大小从 76KB 减少到 10 KB,并且数字应该匹配,并且可以简单地从 .bin 重命名为 .whatever-it-originally-was 并正常运行。但是我认为 bitset 不会低于 1。

我尝试过的代码:

43555 KB: output.write((char*)&memblock[i], size);
0 KB: output.write((char*)memblock[i], size);
43555 KB: output.write((const char*)&memblock[i], size);
43555 KB: output.write(reinterpret_cast<const char*>(&memblock[i]), size);
43555 KB: output.write(reinterpret_cast<char*>(&memblock[i]), size);
76 KB: output << memblock[i];

当我做这些简单的检查时:

cout << memblock[i];
cout << size;

我看到所有输入都已读入,并且与文件中的内容相同。大小变量在 77296 处是正确的。

通过做一些猜测,我认为我需要对 bitset 做一些事情,或者手动将位转换回字节,转换,然后传递该值来完成此操作。我是在正确的道路上还是我的代码中有更好/更简单的方法/有问题?提前感谢您的帮助!

【问题讨论】:

    标签: c++ binary dump rebuild


    【解决方案1】:

    据我所知,问题是位集转储中的位顺序,磁盘转储来自第一个代码片段:

    11001010

    表示第一位是字节的最高有效位,因此要对其进行解码,您应该在循环中执行以下操作(已测试):

    unsigned char *p = memblock;
    //For each character until end of file:
    for (int i=0; i<size/8; i++)  
    {
        uint8_t byte = 0;
        for (int j = 7; j >= 0; j--) 
            if (*p++ == '1')
                byte |= (1 << j);
    
        output.write((char*) &byte, 1);
    }
    

    请注意,您循环 size/8 因为每 8 个字符编码一个字节,并且内部循环从 7 迭代到 0 以反映第一位更重要的事实。

    【讨论】:

    • 非常感谢您的回复!我有一种感觉,我必须手动将位转换回字节,但之前没有使用过。当我用你的代码代替我尝试的 for 循环时,程序运行良好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 2014-01-24
    • 2020-11-06
    • 2014-10-30
    • 2011-12-08
    • 1970-01-01
    相关资源
    最近更新 更多