吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2020|回复: 17
上一主题 下一主题
收起左侧

[原创] IDA 9.0 Beta 插件兼容方案小记

  [复制链接]
跳转到指定楼层
楼主
4qwerty7 发表于 2024-8-24 04:16 回帖奖励

众所皆知,IDA 9.0 Beta 更新了插件系统,导致原来的一些插件不能用了。

那么,具体是什么部分不兼容呢?

首先,对于Python插件,用来判断当前打开文件的架构信息的 ida_idaapi.get_inf_structure() 被删掉了,这几乎是绝大多数 Python 插件不能用的唯一原因。为此,可以做这样的替换:

idaapi.cvar.inf/ida_idaapi.get_inf_structure().xx -> ida_ida_inf_get_xx
ida_idaapi.get_inf_structure().is_xx -> ida_ida_inf_is_xx
idaapi.cvar.idati -> idaapi.get_idati()

而类似 D-810 的插件依赖 z3 solver,而 z3 solver 库会优先选择 IDA 目录下的 libz3.dll(用于IDA自带的gooMBA),而这玩意与 Python3.12 版本的 z3 solver 库的 Python 代码并不兼容,为此可以在 python\3\ida_idaapi.py

import struct
import traceback
import os
import sys
import bisect

之后插入

if sys.version_info > (3, 12, 0):
    # In this case, we monkey patch CDLL for z3
    import ctypes
    cdll_func = ctypes.CDLL.__init__
    def hook_func(self, name, *args, **kwargs):
        if name == os.path.join(os.path.realpath('.'), 'libz3.dll'):
            raise FileNotFoundError(f'Could not find module {name} as compatibility forced')
        return cdll_func(self, name, *args, **kwargs)
    ctypes.CDLL.__init__ = hook_func

让 python库 z3 solver 找不到位于 IDA 根目录下的 libz3.dll,转而使用它自带的 z3。

同时 IDA 把 Strucure 和 Enum 两个 view 和对应的数据库删了,转而使用统一的 Local Types。所有依赖 ida_enum 和 ida_struct 必须改成依赖 ida_typeinf。

而 dll 格式的插件里,依赖 enum.hpp struct.hpp 同样是导致不兼容的重灾区,还好绝大多数 dll 都是开源的,因此可以稍作修改(或者直接用网友的PR)后编译,例如:

IDA_ClassInformer_PlugIn64.dll -> https://github.com/EngineLessCC/ClassInformer-IDA-90/releases
HexRaysCodeXplorer64.dll -> https://github.com/REhints/HexRaysCodeXplorer/pull/121
binexport12_ida64.dll -> https://github.com/google/binexport/pull/133

我们也可以照猫画虎,修改一些没人提交PR的插件,例如对于 https://github.com/airbus-cert/Yagi 可以做如下 patch:

diff --git a/yagi/src/idasymbol.cc b/yagi/src/idasymbol.cc
index cac4fec..aac7f1a 100644
--- a/yagi/src/idasymbol.cc
+++ b/yagi/src/idasymbol.cc
@@ -5,7 +5,7 @@
 #include "idatype.hh"
 #include <idp.hpp>
 #include <frame.hpp>
-#include <struct.hpp>
+// #include <struct.hpp>
 #include <name.hpp>
 #include <sstream>

@@ -159,17 +159,19 @@ namespace yagi
    std::optional<std::string> IdaFunctionSymbolInfo::findStackVar(uint64_t offset, uint32_t addrSize)
    {
        auto idaFunc = get_func(m_symbol->getAddress());
-       auto frame = get_frame(idaFunc);
-       if (frame == nullptr)
-       {
+       tinfo_t frame_tif;
+       if (!get_func_frame(&frame_tif, idaFunc)) {
            return std::nullopt;
        }

-       for (uint32_t i = 0; i < frame->memqty; i++)
-       {
-           auto member = frame->members[i];
-           auto name = std::string(get_struc_name(member.id, STRNFL_REGEX).c_str());
-           auto sofset = member.get_soff() - (idaFunc->frsize + idaFunc->frregs);
+       udt_type_data_t udt_data;
+       if (!frame_tif.get_udt_details(&udt_data)) {
+           return std::nullopt;
+       }
+
+       for (const udm_t& udm : udt_data) {
+           auto name = std::string(udm.name.c_str());
+           auto sofset = (udt_data.is_union ? 0 : (udm.offset / 8)) - (idaFunc->frsize + idaFunc->frregs);
            if (sofset == offset || (addrSize == 4 && ((uint32_t)sofset == (uint32_t)offset)))
            {
                auto pp = name.find(".");
@@ -180,6 +182,7 @@ namespace yagi
                return name;
            }
        }
+
        return std::nullopt;
    }

diff --git a/yagi/src/idatype.cc b/yagi/src/idatype.cc
index 1df762f..4a08900 100644
--- a/yagi/src/idatype.cc
+++ b/yagi/src/idatype.cc
@@ -130,9 +130,9 @@ namespace yagi
        m_info.m_type.get_udt_details(&attributes);
        std::vector<TypeStructField> result;

-       idatool::transform<udt_member_t, TypeStructField>(
+       idatool::transform<udm_t, TypeStructField>(
            attributes, std::back_insert_iterator(result),
-           [this](const udt_member_t& arg) -> TypeStructField
+           [this](const udm_t& arg) -> TypeStructField
            {
                return TypeStructField{ arg.offset / 8, arg.name.c_str(), std::make_unique<IdaTypeInfo>(arg.type) };
            }

剩下还有一小部分不开源/难改的插件,排除掉不需要用的,就很少了。

这时我注意到了论坛 微笑一刀 大佬写的 StrongCC 插件,我找不到源码,同时这个插件又明显不依赖 enum.hpp struct.hpp,但为什么还是不支持?

查看 idp.hpp 发现 IDP_INTERFACE_VERSION 的值从 700 更新成了 900,对应的,struct plugmod_t  的结构被小幅度修改了。

起初,我以为这样的修改只需要二进制patch一小部分代码就可以,但是结构体开头内容增加导致继承自 plugmod_t 的插件主体代码里对 this 指针的操作都要修改,特别是虚表搞得我十分头大。

那么,为什么不考虑适配器模式呢?即写一个插件,启动时它会加载老插件,而后 IDA 调用它时,他会转而使用旧版本的接口去调用老插件;而对于老插件需要的部分导出函数,替换成适配器插件上的函数,适配器做适当处理后再调用IDA。

此外,为了避免一个插件变成需要2个DLL,可以使用内存里加载DLL的方法,我使用了 https://github.com/fancycode/MemoryModule,它同时提供了自定义 GetProcAddress 能力,可以使我们轻易修改老插件需要的部分导出函数。

原理上而言,适配器插件可以实现所有 enum.hpp struct.hpp 里导出的函数,但这工作量较大且并不为我所需,因此就不写了,只写了对 struct plugmod_t 变化的支持,从而使 StrongCC 能顺利在 IDA 9.0 Beta 上运行。

具体细节见于源码,具体源码见于附件,将这些源码和 https://github.com/fancycode/MemoryModule 上提供的 MemoryModule.h 与 MemoryModule.c 以及 微笑一刀 大佬写的 StrongCC 插件,即 StrongCC_x64.dll(UPX decompress 后) 放在同一目录下,调整 build.bat 里 MSVC 和 IDA SDK 的位置后即可编译。

src.zip

3.06 KB, 下载次数: 29, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 4威望 +1 吾爱币 +23 热心值 +3 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
snowfox + 1 + 1 谢谢@Thanks!
ioyr5995 + 1 + 1 我很赞同!
crapeber + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| 4qwerty7 发表于 2024-8-26 18:48 |楼主
li513216760 发表于 2024-8-26 16:09
支持分享,挺有作用,怎么判断这个库是否不兼容?

idp.hpp 的变更导致任何原来的 dll 插件都不可能在没有修改/重新编译的前提下使用。
对于依赖已经修改的api的,需要修改相关代码重新编译(当然也可以增强帖子中的src.zip实现更强的适配器)。
对于只需要重新编译但又没源码的(看dll导入函数有哪些差异),可以用帖子中的src.zip。
沙发
justwz 发表于 2024-8-24 21:20
3#
残风逝雪夜阑天 发表于 2024-8-24 21:21
4#
Sean250mutou 发表于 2024-8-24 21:44
挺厉害的,感谢!
5#
hebingcan 发表于 2024-8-25 08:07
学习了,。。。。
6#
重命名 发表于 2024-8-25 12:30
求一份能用的IDA 9.0
7#
crapeber 发表于 2024-8-25 16:52
感谢分析DLL失效原因
8#
Hmily 发表于 2024-8-26 14:45
@微笑一刀 大佬求更新。
9#
gys19830912 发表于 2024-8-26 14:49
论坛有你很精彩,是我需要的
10#
li513216760 发表于 2024-8-26 16:09
本帖最后由 li513216760 于 2024-8-26 16:14 编辑

支持分享,挺有作用,怎么判断这个库是否不兼容?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-10-9 09:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表