使用指针复制和重新填充结构体实例 [英] copying and repopulating a struct instance with pointers

查看:221
本文介绍了使用指针复制和重新填充结构体实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Windows中的仿真工具。

I am working on an emulation tool in windows.

截取应用程序时,我遇到了一种情况。

On intercepting an application I landed up with a situation.

我有一个c ++结构,其格式如下:

I have a c++ structure which has the following format

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

它是二进制文件的句柄。我正在做API拦截,并从应用程序进行的内部API调用获得此指针。

It is a handle to a binary file. I am doing API interception and I get this pointer from an internal API call being made by the application.

此外,上述结构中的数据字段是一个指向实例的指针两个结构连续布置。两个结构如下。

Also The data field in the structure above is a pointer to instances of two structures laid out contiguously. The two structures are as follows.

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;

我可以访问和打印数据字段,如下所示。

I am able to access and print the data field as follows.

_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;
}

我想将struct node实例写入文本文件,稍后再读回一个结构体实例。什么是最好的方法呢?我想在c ++中的答案

I want to write the struct node instance into a text file and be able to read it back into a struct instance later. What is the best way to do it? I want an answer in c++

我想要一个c ++代码,因为我工作的代码是在c ++。我在这里发布的代码有typedef因为写结构的人已经写在C。

I want a c++ code because the code I am working on is in c++. The code i posted here has typedef because people who wrote the structure has written it in C.

如果它会有帮助,我需要这个数据在结构中,所以我可以模拟因为结构的一些方面是内部的,并且对我隐藏,我最好的打赌是存储结构成员并在稍后的时间(仿真时间)重建

If it would help, I need this data in the structure so I could emulate an application with my tool.Since some aspects of the structure are internal and are hidden from me, my best bet is to store the structure members and reconstruct it at a later time (emulation time)

推荐答案

我不知道我没有得到整个问题上下文,但这里是一个基于boost序列化的设置:

I'm not sure I'm not getting the entire question context right, but here is a setup based on boost serialization:

当然我选择了C ++方式

Of course I opted for the C++ way


  • 使用std :: pair或std :: tuple连续存储的结构对(参见 element_t )。 2

  • 我真的更愿意使用 element_t element_t *

  • 为了清楚起见,我选择了XML:示例清楚地显示了序列化的内容,以及如何正确处理重复(别名)指针

  • 简单插入替换二进制序列化,而不是XML(如果优选): s / xml_ / binary_ / g 做的伎俩! 1
    也可以删除 NVL()宏,因为二进制序列化不需要命名元素:

  • using a std::pair or std::tuple to model a contiguously stored pair of structs (see element_t). 2
  • I would actually prefer using a list of element_t instead of element_t*. Regardless, it works both ways with this library
  • I chose XML for clarity: the sample clearly shows what gets serialized and how duplicate (aliased) pointers get correctly treated and restored.
  • simple drop-in replacement for binary serialization instead of XML if preferred: s/xml_/binary_/g does the trick! 1
    You could also drop the NVL() macros because binary serialization doesn't need named elements:


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

会成为

 ar & version & open & length;

b $ b

  • ,样本泄漏数据元素(只是一个演示,我在尝试几个事情;我决定使用指针只是为了更贴近你的问题)

  • as written, the sample leaks the data elements (just a demo, and I was trying several things; I decided on using pointers only to match your question more closely)

    1 糟糕,几乎忘记了std :: ios:binary on打开你的fstreams!

    2 请注意,对于特定的内存中布局,您可能需要使用 pragma 以实现正确的分配/填充。这超出了我的回答范围

    1 oops, almost forgot about std::ios:binary on opening you fstreams!
    2Note that for particular in-memory layout you may need to tinker with a struct using #pragma to achieve proper aligment/padding. That is beyond the scope of my answer

    使用

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

    已测试与升级v.1_42通过升级v.1_47

    Tested with boost v.1_42 through 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)

    Here is the sample output (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>
    

    这篇关于使用指针复制和重新填充结构体实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆