копирование и повторное заполнение экземпляра структуры с помощью указателей - PullRequest
0 голосов
/ 10 октября 2011

Я работаю над инструментом эмуляции в Windows.

При перехвате приложения я столкнулся с ситуацией.

У меня есть структура c ++, которая имеет следующий формат

typedef struct node {
  int open;
  int version;
  const unsigned long long * data;
  char* flags;
} _node;

Это дескриптор двоичного файла.Я делаю перехват API и получаю этот указатель из внутреннего вызова API, выполняемого приложением.

Также поле данных в приведенной выше структуре является указателем на экземпляры двух структур, расположенных последовательно.Две структуры:

typedef struct header{
  unsigned int open;
  unsigned int version;
  unsigned long long int length;
} _header;


typedef struct body{
  unsigned int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
  unsigned long long int ll1, ll2;
} _body;

Я могу получить доступ к полю данных и распечатать его следующим образом.

_node* First=(node *)address;//Address is a pointer that i get from intercepting an application
_header* nodeHeader=(_header*)First->data;
char *bodyPtr=(char *)(nodeHeader+1);
_body* nodeBody=(_body *)(bodyPtr);
unsigned long long int offset=0;

while(!(nodeBody->v1 & 1) && offset< nodeHeader->length)
{
 nodeBody=(_body*)(bodyPtr+offset);
 offset=nodeBody->v2+nodeBody->v3;
}

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

Я хочу код на c ++, потому что код, над которым я работаю, находится на языке c ++.Код, который я разместил здесь, имеет typedef, потому что люди, которые написали структуру, написали его на C.

Если бы это помогло, мне нужны эти данные в структуре, чтобы я мог эмулировать приложение с помощью своего инструмента.структуры являются внутренними и скрыты от меня, лучше всего хранить элементы структуры и восстанавливать их позднее (время эмуляции)

1 Ответ

0 голосов
/ 11 октября 2011

Я не уверен, что не правильно понимаю весь контекст вопроса, но вот настройка, основанная на ускоренной сериализации:

Конечно, я выбрал способ C ++

  • с использованием std :: pair или std :: tuple для моделирования непрерывно хранимой пары структур (см. element_t). 2
  • Я бы предпочел использовать список element_t вместо element_t*.Несмотря на это, она работает в обоих направлениях с этой библиотекой
  • Я выбрал XML для ясности: в примере ясно показано, что сериализуется и как дубликаты (псевдонимы) обрабатывают и восстанавливают правильно .
  • простая замена для двоичной сериализации вместо XML, если предпочтительнее: s/xml_/binary_/g добивается цели! 1 Вы также можете удалить макросы NVL(), потому что двоичная сериализация не требует именованных элементов:

     ar & NVP(version) & NVP(open) & NVP(length);
    

    станет

     ar & version & open & length;
    

  • как написано, в примере утечки элементов данных (просто демонстрация, и я пробовал несколько вещей; я решил использовать указатели только для более точного соответствия вашего вопроса)

1 упс, почти забыл про std :: ios: бинарный при открытии ваших потоков! 2 Обратите внимание, что для конкретной компоновки в памяти вам может потребоваться изменить структуру, используя #pragma для достижения правильного выравнивания / заполнения.Это выходит за рамки моего ответа

О, скомпилируйте с

g++ -O2 -g test.cpp -lboost_serialization

Проверено с boost v.1_42 через boost v.1_47


#include <boost/serialization/list.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <fstream>
#include <string>

#define NVP BOOST_SERIALIZATION_NVP // name-value pairs

struct header
{
    unsigned int open;
    unsigned int version;
    unsigned long long int length;

    header() : open(1), version(2), length(3) {} 

private:
    friend class boost::serialization::access;
    template<class Archive>
        void serialize(Archive & ar, const unsigned int archversion)
    {
        ar & NVP(version) & NVP(open) & NVP(length);
    }
};

struct body
{
    unsigned int iv[20];
    unsigned long long int ll1, ll2;

    body() : ll1(1), ll2(2)
    {
        for (int i=0; i<20; i++)
            iv[i] = i;
    }

private:
    friend class boost::serialization::access;
    template<class Archive>
        void serialize(Archive & ar, const unsigned int archversion)
    {
        ar & NVP(ll1) & NVP(ll2) & NVP(iv);
    }
};

typedef std::pair<header, body> element_t;

struct node
{
    int open;
    int version;
    std::list<element_t*> data;
    std::string flags;

    node() : open(1), version(2), flags("hello") { }

private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int archversion)
    {
        ar & NVP(version) & NVP(open) & NVP(flags) & NVP(data);
    }
};

int main()
{
    node anode;
    anode.data.push_back(new element_t(header(), body()));
    element_t* duplicated = new element_t(header(), body());
    anode.data.push_back(duplicated);
    anode.data.push_back(new element_t(header(), body()));
    anode.data.push_back(duplicated);

    {
        std::ofstream ofs("/tmp/test.xml");
        boost::archive::xml_oarchive archive(ofs);

        archive << NVP(anode);
        ofs.flush();
        ofs.close();
    }
    return 0;

    {
        std::ifstream ifs("/tmp/test.xml");
        boost::archive::xml_iarchive archive(ifs);

        node deserialized;

        archive >> NVP(deserialized);
    }

    return 0;
}

Вот пример выходных данных (test.xml)

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="9">
<anode class_id="0" tracking_level="0" version="0">
    <version>2</version>
    <open>1</open>
    <flags>hello</flags>
    <data class_id="1" tracking_level="0" version="0">
        <count>4</count>
        <item_version>0</item_version>
        <item class_id="2" tracking_level="1" version="0" object_id="_0">
            <first class_id="3" tracking_level="0" version="0">
                <version>2</version>
                <open>1</open>
                <length>3</length>
            </first>
            <second class_id="4" tracking_level="0" version="0">
                <ll1>1</ll1>
                <ll2>2</ll2>
                <iv>
                    <count>20</count>
                    <item>0</item>
                    <item>1</item>
                    <item>2</item>
                    <item>3</item>
                    <item>4</item>
                    <item>5</item>
                    <item>6</item>
                    <item>7</item>
                    <item>8</item>
                    <item>9</item>
                    <item>10</item>
                    <item>11</item>
                    <item>12</item>
                    <item>13</item>
                    <item>14</item>
                    <item>15</item>
                    <item>16</item>
                    <item>17</item>
                    <item>18</item>
                    <item>19</item>
                </iv>
            </second>
        </item>
        <item class_id_reference="2" object_id="_1">
            <first>
                <version>2</version>
                <open>1</open>
                <length>3</length>
            </first>
            <second>
                <ll1>1</ll1>
                <ll2>2</ll2>
                <iv>
                    <count>20</count>
                    <item>0</item>
                    <item>1</item>
                    <item>2</item>
                    <item>3</item>
                    <item>4</item>
                    <item>5</item>
                    <item>6</item>
                    <item>7</item>
                    <item>8</item>
                    <item>9</item>
                    <item>10</item>
                    <item>11</item>
                    <item>12</item>
                    <item>13</item>
                    <item>14</item>
                    <item>15</item>
                    <item>16</item>
                    <item>17</item>
                    <item>18</item>
                    <item>19</item>
                </iv>
            </second>
        </item>
        <item class_id_reference="2" object_id="_2">
            <first>
                <version>2</version>
                <open>1</open>
                <length>3</length>
            </first>
            <second>
                <ll1>1</ll1>
                <ll2>2</ll2>
                <iv>
                    <count>20</count>
                    <item>0</item>
                    <item>1</item>
                    <item>2</item>
                    <item>3</item>
                    <item>4</item>
                    <item>5</item>
                    <item>6</item>
                    <item>7</item>
                    <item>8</item>
                    <item>9</item>
                    <item>10</item>
                    <item>11</item>
                    <item>12</item>
                    <item>13</item>
                    <item>14</item>
                    <item>15</item>
                    <item>16</item>
                    <item>17</item>
                    <item>18</item>
                    <item>19</item>
                </iv>
            </second>
        </item>
        <item class_id_reference="2" object_id_reference="_1"></item>
    </data>
</anode>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...