4qwerty7 发表于 2024-8-24 04:16

IDA 9.0 Beta 插件兼容方案小记

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

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

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

```py
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`

```python
import struct
import traceback
import os
import sys
import bisect
```

之后插入

```python
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
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;
-                        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),
-                        (const udt_member_t& arg) -> TypeStructField
+                        (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 以及 微笑一刀 大佬写的 (https://www.52pojie.cn/forum.php?mod=viewthread&tid=1434932&extra=&highlight=StrongCC&page=1),即 StrongCC_x64.dll(UPX decompress 后) 放在同一目录下,调整 build.bat 里 MSVC 和 IDA SDK 的位置后即可编译。

微笑一刀 发表于 2024-10-20 13:34

Hmily 发表于 2024-8-26 14:45
@微笑一刀 大佬求更新。

既然有人要.那就发出来好了,加了个UPX.没功能改动.
9.0的.

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

跟着大佬学逆向

残风逝雪夜阑天 发表于 2024-8-24 21:21

感谢分享~~~~~~~~~~

Sean250mutou 发表于 2024-8-24 21:44

挺厉害的,感谢!

hebingcan 发表于 2024-8-25 08:07

学习了,。。。。

重命名 发表于 2024-8-25 12:30

求一份能用的IDA 9.0

crapeber 发表于 2024-8-25 16:52

感谢分析DLL失效原因

Hmily 发表于 2024-8-26 14:45

@微笑一刀 大佬求更新。

gys19830912 发表于 2024-8-26 14:49

论坛有你很精彩,是我需要的

li513216760 发表于 2024-8-26 16:09

本帖最后由 li513216760 于 2024-8-26 16:14 编辑

支持分享,挺有作用,怎么判断这个库是否不兼容?
页: [1] 2 3 4
查看完整版本: IDA 9.0 Beta 插件兼容方案小记