IDA 反编译之创建结构体分析调用的API某硬编码项

        在逆向分析某mqtt client软件的时候,由于调用了“Paho Asynchronous MQTT C Client Library”,为了分析获得某硬编码的API参数值,需要在IDA工具里构造struct。下面是分析的过程

1.定位到API结构体的位置

        在某次逆向分析某mqtt client软件的时候,我对此处的v17的值很感兴趣,我怀疑是某重要信息的硬编码,我想知道这串字符串到底是用做什么的?

 

        全局搜索v17出现的地方,第一个搜到的是它的定义。

        由于结构体地址空间是连续的,我们是可以轻易大胆猜测v16-v22几个命名很可能是结构体的相邻项。

        v16很显然是第一个结构体第一个地址,搜索v16出现的地方,试图推测它的结构体名字

        从日志中,我们认为推断结构体名字叫MQTTAsync * connect *的可能性比较大。

2.通过查阅资料创建API结构体

        前期通过IDA对所有可读字符串的分析知道,本代码调用了“Paho Asynchronous MQTT C Client Library”库,找到库文档,查找名字相似的API介绍。

Paho Asynchronous MQTT C Client Library: MQTTAsync.h File Reference (eclipse.org)

        找到了一个很相似的 data struct,“MQTTAsync_connectOptions Struct”。

        初步分析了结构体前几项占用空间大小,觉得挺像的。

        打开IDA的struct窗口(view-opensubviews-structures),按照库文档里的结构体描述信息,创建struct。

        自己构建的struct如下:

        最后几项不重要,直接省略了。

        这里要注意字节对齐,64位IDA里结构体指针是占用8个字节,因此在will前要自己添加四个字节以对齐。

附:结构体内容解释

typedef struct
{
    char struct_id[4]; //MQTC 

    /** 这个参数必须是  0, 1, 2, 3 4 5 or 6.
          * 0 表示不使用SSL,也不使用serverURIs
          * 1 表示不使用serverURIs
          * 2 表示没有设置版本信息
          * 3 表示不使用自动重连
          * 4 表示不使用二进制密码,即不设置binarypwd
          * 5 表示没有MQTTV5的属性
          默认设置这个值为6
    */
    int struct_version; 

    //保活时间间隔
    int keepAliveInterval;

   //1 丢失连接时清楚所有这个连接的信息,包括订阅等,0与之相反,使用非5.0的时候设置这个参数
    int cleansession;

    int maxInflight; //这个值设置最大的在飞行中的消息数量 
    MQTTAsync_willOptions* will; //这个参数设置断开连接时的临终遗嘱消息,断开连接时发送消息到LWP topic
    const char* username;  //用户名
    const char* password; //密码
    int connectTimeout; //连接超时时间
    int retryInterval; //重发未发送的消息的时间间隔,以秒为单位的内部时钟间隔
    MQTTAsync_SSLOptions* ssl; //指向ssl设置参数的结构体指针,为NULL时表示不使用SSL
    MQTTAsync_onSuccess* onSuccess; //连接成功时调用
    MQTTAsync_onFailure* onFailure; //连接失败时调用
    void* context; //赋值为client
    int serverURIcount; //serverURIs数组大小
    char* const* serverURIs; //服务器url数组,null结尾的字符串数组,地址格式为protocol://host:port。protocol可以是tcp或者ssl,host可以是ip地址或者域名
    int MQTTVersion; //MQTT版本信息
    int automaticReconnect; //自动重连
    int minRetryInterval; //最小的重试间隔,以秒为单位,没失败一次,值增加一倍
    int maxRetryInterval; //最大的重连时间间隔,最小重连时间间隔超过这个值时停止
    struct {
        int len;            /**< binary password length */
        const void* data;  /**< binary password data */
    } binarypwd; //二进制密码设置,目前没去了解
    int cleanstart; //使用5.0的时候设置这个参数

    //MQTTV5的一些属性设置
    MQTTProperties *connectProperties;
    MQTTProperties *willProperties;
    MQTTAsync_onSuccess5* onSuccess5;
    MQTTAsync_onFailure5* onFailure5;
} MQTTAsync_connectOptions;

3.关联自己定义的结构体并成功得到API的关键项的值

        通过前面分析已经知道v16是结构体的第一项,现在修改v16定义为刚创建的结构体

        按F5刷新页面,可以看到我们感兴趣的字符串已经显示出它本来的含义了。

        这是一个硬编码的username,这个发现对我们接下来继续逆向分析很有意义。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值