Объединить блоки памяти в C ++ - PullRequest
0 голосов
/ 31 января 2020

Я сделал 10 фрагментов двоичного исполняемого файла и сохранил их в отдельных блоках памяти. Я использовал setter вот так.

  void SetCDataStream(u_char* _cDataStream, size_t _sizeData)
    {
        cDataStream = new u_char [_sizeData]; 
        memmove(cDataStream,_cDataStream, _sizeData);
    }

И я получаю эти блоки, используя вот так getter

u_char *GetCDataStream()
{
    return cDataStream;
}

И помещаю их в вектор в правильном порядке от начала до конца содержимого файла.

std::vector<u_char*> vecCDataStream;

Я хочу объединить каждую запись вектора для формирования исходного файла и должен иметь возможность его выполнить. Есть ли лучший способ сделать это?

Ответы [ 2 ]

2 голосов
/ 31 января 2020

Если я правильно понимаю, вам вообще не нужно ручное управление памятью, и вам не нужно сохранять исходные позиции блоков памяти в памяти. В этом случае вы можете использовать std::vector для хранения блоков - и складывать sh их в один большой блок, если вы будете sh.

Пример:

#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <vector>

// A class to keep a number of blocks
class BlockMaster {
public:
    using block_t = std::vector<uint8_t>;

    explicit BlockMaster(size_t init_size = 0) : blocks{init_size} {}

    // Add a new block
    void AddDataStream(const uint8_t* begin, const uint8_t* end) {
        blocks.emplace_back(begin, end);
    }

    size_t size() const noexcept { return blocks.size(); }

    // random access to the stored blocks
    block_t& operator[](size_t block_number) noexcept {
        return blocks[block_number];
    }
    const block_t& operator[](size_t block_number) const noexcept {
        return blocks[block_number];
    }

    // support for iterating over the stored blocks
    auto cbegin() const noexcept { return blocks.cbegin(); }
    auto cend() const noexcept { return blocks.cend(); }
    auto begin() const noexcept { return cbegin(); }
    auto end() const noexcept { return cend(); }
    auto begin() noexcept { return blocks.begin(); }
    auto end() noexcept { return blocks.end(); }

    // create a BlockMaster with one huge block from the stored blocks
    BlockMaster GetSquashedBlocks() {
        BlockMaster result(1);
        for(const block_t& block : *this) {
            result[0].insert(result[0].end(), block.begin(), block.end());
        }
        return result;
    }

private:
    std::vector<block_t> blocks;
};

// stream all the stored blocks to a file (as if they were one big block, so
// you don't need to squash them for this)
std::ofstream& operator<<(std::ofstream& ofs, const BlockMaster& bm) {
    for(const auto& block : bm)
        ofs.write(reinterpret_cast<const char*>(block.data()),
                  static_cast<std::streamsize>(block.size()));
    return ofs;
}

int main() {
    unsigned char memory[]{1, 2, 3, 4, 5, 6, 7, 8, 9};

    BlockMaster bm;
    bm.AddDataStream(memory + 0, memory + 3);
    bm.AddDataStream(memory + 4, memory + 8);

    std::cout << bm.size() << "\n--\n";

    for(const auto& block : bm) {
        std::cout << ' ' << block.size() << '\n';
    }

    bm = bm.GetSquashedBlocks();

    std::cout << "--\n";

    std::cout << bm.size() << "\n--\n";
    for(const auto& block : bm) {
        std::cout << ' ' << block.size() << '\n';
    }
}

Вывод :

2    // blockmasters number of stored blocks
--
 3   // first blocks size
 4   // second blocks size
--
1    // blockmasters number of stored blocks after squashing
--
 7   // size of the one block after squashing
2 голосов
/ 31 января 2020

Предполагая, что каждый Block имеет GetSize() член и GetCDataStream() член, вы можете просто создать std::ofstream объект и записать каждый блок, используя метод std::ofstream::write:

std::ofstream out("test.bin", std::ios::binary | std::ios::out);
for (Block& b : blocks) {
    out.write(b.GetCDataStream(), b.GetSize());
}
out.close();

Обратите внимание, что вам решать, что объединение всех блоков является допустимым исполняемым файлом для вашей платформы (PE на Windows, ELF на Linux, Mach-O на macOS).

...