首页
社区
课程
招聘
[原创] 自动化提取protobuf结构体
发表于: 2025-3-11 20:16 5260

[原创] 自动化提取protobuf结构体

2025-3-11 20:16
5260

众所周知,国赛非常喜欢在题目中塞进protobuf来????人,所以简单搓了个脚本来梭哈proto

以2024年华北国赛半决赛的proc为例,简单复习一下

图片描述

程序是个heap菜单题,输入会经过sub_1AA5函数进行处理

图片描述

这是一个protobuf的反序列化函数,proto的结构体在unk_3C60

图片描述

简单对应一下,可知name short_name c_name都是unk_2260,即Msgpackage_name则为空

其字段内容在values,即off_3B80

图片描述

只要把每个字段的name type找到,就可以复原出proto文件了

项目地址在此~

github

struct ProtobufCEnumDescriptor {
    /** Magic value checked to ensure that the API is used correctly. */
    uint32_t            magic;
 
    /** The qualified name (e.g., "namespace.Type"). */
    const char          *name;
    /** The unqualified name as given in the .proto file (e.g., "Type"). */
    const char          *short_name;
    /** Identifier used in generated C code. */
    const char          *c_name;
    /** The dot-separated namespace. */
    const char          *package_name;
 
    /** Number elements in `values`. */
    unsigned            n_values;
    /** Array of distinct values, sorted by numeric value. */
    const ProtobufCEnumValue    *values;
 
    /** Number of elements in `values_by_name`. */
    unsigned            n_value_names;
    /** Array of named values, including aliases, sorted by name. */
    const ProtobufCEnumValueIndex   *values_by_name;
 
    /** Number of elements in `value_ranges`. */
    unsigned            n_value_ranges;
    /** Value ranges, for faster lookups by numeric value. */
    const ProtobufCIntRange     *value_ranges;
 
    /** Reserved for future use. */
    void                *reserved1;
    /** Reserved for future use. */
    void                *reserved2;
    /** Reserved for future use. */
    void                *reserved3;
    /** Reserved for future use. */
    void                *reserved4;
};
struct ProtobufCEnumDescriptor {
    /** Magic value checked to ensure that the API is used correctly. */
    uint32_t            magic;
 
    /** The qualified name (e.g., "namespace.Type"). */
    const char          *name;
    /** The unqualified name as given in the .proto file (e.g., "Type"). */
    const char          *short_name;
    /** Identifier used in generated C code. */
    const char          *c_name;
    /** The dot-separated namespace. */
    const char          *package_name;
 
    /** Number elements in `values`. */
    unsigned            n_values;
    /** Array of distinct values, sorted by numeric value. */
    const ProtobufCEnumValue    *values;
 
    /** Number of elements in `values_by_name`. */
    unsigned            n_value_names;
    /** Array of named values, including aliases, sorted by name. */
    const ProtobufCEnumValueIndex   *values_by_name;
 
    /** Number of elements in `value_ranges`. */
    unsigned            n_value_ranges;
    /** Value ranges, for faster lookups by numeric value. */
    const ProtobufCIntRange     *value_ranges;
 
    /** Reserved for future use. */
    void                *reserved1;
    /** Reserved for future use. */
    void                *reserved2;
    /** Reserved for future use. */
    void                *reserved3;
    /** Reserved for future use. */
    void                *reserved4;
};
struct ProtobufCFieldDescriptor {
    /** Name of the field as given in the .proto file. */
    const char      *name;
 
    /** Tag value of the field as given in the .proto file. */
    uint32_t        id;
 
    /** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
    ProtobufCLabel      label;
 
    /** The type of the field. */
    ProtobufCType       type;
 
    /**
     * The offset in bytes of the message's C structure's quantifier field
     * (the `has_MEMBER` field for optional members or the `n_MEMBER` field
     * for repeated members or the case enum for oneofs).
     */
    unsigned        quantifier_offset;
 
    /**
     * The offset in bytes into the message's C structure for the member
     * itself.
     */
    unsigned        offset;
 
    /**
     * A type-specific descriptor.
     *
     * If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the
     * corresponding `ProtobufCEnumDescriptor`.
     *
     * If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to
     * the corresponding `ProtobufCMessageDescriptor`.
     *
     * Otherwise this field is NULL.
     */
    const void      *descriptor; /* for MESSAGE and ENUM types */
 
    /** The default value for this field, if defined. May be NULL. */
    const void      *default_value;
 
    /**
     * A flag word. Zero or more of the bits defined in the
     * `ProtobufCFieldFlag` enum may be set.
     */
    uint32_t        flags;
 
    /** Reserved for future use. */
    unsigned        reserved_flags;
    /** Reserved for future use. */
    void            *reserved2;
    /** Reserved for future use. */
    void            *reserved3;
};
struct ProtobufCFieldDescriptor {
    /** Name of the field as given in the .proto file. */
    const char      *name;
 
    /** Tag value of the field as given in the .proto file. */
    uint32_t        id;
 
    /** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
项目地址好像打不开了
2025-4-28 22:38
0
游客
登录 | 注册 方可回帖
返回