首页
社区
课程
招聘
[转帖]在新版IDA中使用旧版本反编译插件
2023-12-1 12:03 10231

[转帖]在新版IDA中使用旧版本反编译插件

2023-12-1 12:03
10231

转载自微信公众号宜到家尝菜
原文链接https://mp.weixin.qq.com/s/aqmwaCIOKzKfrGFfhRXBPQ
试了一下确实可以解决部分arm64程序反编译卡死的问题,但如作者所说,可能会引起其他bug,我试了下,ida8.3的"de-obfuscate"功能不能乱点,否则直接interr。
下面是原文


众所周知,上周末IDA Pro最新的8.3版本泄漏了,自带x86和x86_64的反编译插件。

看雪和吾爱上不少网友都提到没有hexarm和hexarm64,那么我们能不能直接在8.3版本上直接使用7.7的反编译插件呢?

搜索类似“ida old version hexrays decompiler github”的关键词,很快能找到别人提供的一个开源解决方案ida_dll_shim[1]

粗略浏览代码可知,这个dll会提供一些ida.dll和ida64.dll不再导出的API给旧版本插件使用。

下载代码然后自行编译,装上之后发现确实可以加载hexarm.dll以及hexarm64.dll了。

但是有的函数点进去IDA就会卡死,估计是啥地方死循环了。

windbg附加上去,切换到0号线程上,观察栈回溯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
0:000> k
 # Child-SP          RetAddr               Call Site
00 0000001c`8dbf9c50 00000000`6eae826e     hexarm64+0xbcc61
01 0000001c`8dbf9cb0 00000000`6ec1347e     hexarm64+0xc826e
02 0000001c`8dbf9ce0 00000000`6ec136f1     hexarm64+0x1f347e
03 0000001c`8dbf9d10 00000000`6ec136f1     hexarm64+0x1f36f1
04 0000001c`8dbf9d40 00000000`6ec135a3     hexarm64+0x1f36f1
05 0000001c`8dbf9d70 00000000`6ec135a3     hexarm64+0x1f35a3
06 0000001c`8dbf9da0 00000000`6ec190e1     hexarm64+0x1f35a3
07 0000001c`8dbf9dd0 00000000`6ec1347e     hexarm64+0x1f90e1
08 0000001c`8dbf9e00 00000000`6ec136f1     hexarm64+0x1f347e
09 0000001c`8dbf9e30 00000000`6ec135df     hexarm64+0x1f36f1
0a 0000001c`8dbf9e60 00000000`6ec1380b     hexarm64+0x1f35df
0b 0000001c`8dbf9e90 00000000`6ead8142     hexarm64+0x1f380b
0c 0000001c`8dbf9ef0 00000000`6ec141e9     hexarm64+0xb8142
0d 0000001c`8dbf9fa0 00000000`6ec2534f     hexarm64+0x1f41e9
0e 0000001c`8dbfa050 00000000`6eb65977     hexarm64+0x20534f
0f 0000001c`8dbfa260 00000000`6eb64bf4     hexarm64+0x145977
10 0000001c`8dbfa450 00000000`6ebd6d46     hexarm64+0x144bf4
11 0000001c`8dbfa4a0 00000000`6ebd48b7     hexarm64+0x1b6d46
12 0000001c`8dbfa630 00000000`6ebd4787     hexarm64+0x1b48b7
13 0000001c`8dbfa6c0 00007ff7`807da0d3     hexarm64+0x1b4787
14 0000001c`8dbfa790 00007ffd`b1df7848     ida64_exe+0x6a0d3
15 0000001c`8dbfa830 00007ffd`b1e986f0     Qt5Widgets!QT::QWidget::event+0x148
16 0000001c`8dbfa8c0 00007ffd`b130501c     Qt5Widgets!QT::QFrame::event+0x30
17 0000001c`8dbfa8f0 00007ffd`b1dd483d     Qt5Core!QT::QCoreApplicationPrivate::sendThroughObjectEventFilters+0xdc
18 0000001c`8dbfa950 00007ffd`b1dd28a0     Qt5Widgets!QT::QApplicationPrivate::notify_helper+0xfd
19 0000001c`8dbfa980 00007ff7`8088aead     Qt5Widgets!QT::QApplication::notify+0x750
1a 0000001c`8dbfaec0 00007ff7`8092d5a5     ida64_exe+0x11aead
1b 0000001c`8dbfaf20 00007ffd`b1302f5b     ida64_exe+0x1bd5a5
1c 0000001c`8dbfb0b0 00007ffd`b1dd5ba5     Qt5Core!QT::QCoreApplication::notifyInternal2+0xbb
1d 0000001c`8dbfb120 00007ffd`b1e20252     Qt5Widgets!QT::QApplicationPrivate::sendMouseEvent+0x3c5
1e 0000001c`8dbfb1e0 00007ffd`b1e1e1ee     Qt5Widgets!QT::QSizePolicy::QSizePolicy+0x2d22
1f 0000001c`8dbfb570 00007ffd`b1dd4851     Qt5Widgets!QT::QSizePolicy::QSizePolicy+0xcbe
20 0000001c`8dbfb640 00007ffd`b1dd3a03     Qt5Widgets!QT::QApplicationPrivate::notify_helper+0x111
21 0000001c`8dbfb670 00007ff7`8088aead     Qt5Widgets!QT::QApplication::notify+0x18b3
22 0000001c`8dbfbbb0 00007ff7`8092d5a5     ida64_exe+0x11aead
23 0000001c`8dbfbc10 00007ffd`b1302f5b     ida64_exe+0x1bd5a5
24 0000001c`8dbfbda0 00007ffd`b1764cc5     Qt5Core!QT::QCoreApplication::notifyInternal2+0xbb
25 0000001c`8dbfbe10 00007ffd`b174ecd0     Qt5Gui!QT::QGuiApplicationPrivate::processMouseEvent+0xef5
26 0000001c`8dbfc2c0 00007ffd`b134bb2a     Qt5Gui!QT::QWindowSystemInterface::sendWindowSystemEvents+0x90
27 0000001c`8dbfc2f0 00007ffd`b544d9f9     Qt5Core!QT::QEventDispatcherWin32::processEvents+0x6a
28 0000001c`8dbff410 00007ffd`b12ff3af     qwindows!qt_plugin_query_metadata+0x1f99
29 0000001c`8dbff440 00007ffd`b1301f25     Qt5Core!QT::QEventLoop::exec+0x1bf
2a 0000001c`8dbff4a0 00007ff7`8088e88c     Qt5Core!QT::QCoreApplication::exec+0x155
2b 0000001c`8dbff500 00007ff7`8088e8bc     ida64_exe+0x11e88c
2c 0000001c`8dbff540 00007ff7`8088ff0a     ida64_exe+0x11e8bc
2d 0000001c`8dbff580 00007ff7`8088ffc6     ida64_exe+0x11ff0a
2e 0000001c`8dbffac0 00007ff7`809adbea     ida64_exe+0x11ffc6
2f 0000001c`8dbffb20 00007ffd`f4dc7604     ida64_exe+0x23dbea
30 0000001c`8dbffb60 00007ffd`f4f026a1     KERNEL32!BaseThreadInitThunk+0x14
31 0000001c`8dbffb90 00000000`00000000     ntdll!RtlUserThreadStart+0x21

看到确实卡在hexarm64.dll里了。

跑几步看看具体是哪个循环卡住了:

1
2
3
4
5
6
7
8
9
10
11
12
0:000> pc
hexarm64+0xbcc6c:
00000000`6eadcc6c e83f1f0000      call    hexarm64+0xbebb0 (00000000`6eadebb0)
0:000> pc
hexarm64+0xbcc6c:
00000000`6eadcc6c e83f1f0000      call    hexarm64+0xbebb0 (00000000`6eadebb0)
0:000> pc
hexarm64+0xbcc6c:
00000000`6eadcc6c e83f1f0000      call    hexarm64+0xbebb0 (00000000`6eadebb0)
0:000> pc
hexarm64+0xbcc6c:
00000000`6eadcc6c e83f1f0000      call    hexarm64+0xbebb0 (00000000`6eadebb0)

看看这个调用是在做什么:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
char __fastcall sub_170BEBB0(__int64 a1, __int64 a2)
{
  __int64 v2; // rbp
  char v5; // r14
  unsigned __int64 v6; // rsi
  __int64 v7; // rcx
 
  v2 = *(_QWORD *)(a2 + 24);
  if ( *(_BYTE *)(v2 + 13) )
    return 0;
  v5 = 0;
  v6 = *(int *)(*(_QWORD *)(*(_QWORD *)(a1 + 16) + 8i64 * *(_QWORD *)(a1 + 24) - 8) + 8i64);
  if ( ((unsigned int)(v6 - 19) <= 2 || (_DWORD)v6 == 50)
    && (!(unsigned __int8)is_numop(*(unsigned int *)(v2 + 8), (unsigned int)*(char *)(v2 + 12))
     || (unsigned int)get_radix(*(unsigned int *)(v2 + 8), (unsigned int)*(char *)(v2 + 12)) != 16) )
  {
    v5 = 1;
    *(_DWORD *)(*(_QWORD *)(a2 + 24) + 8i64) = 0x1100000;
  }
  if ( (unsigned int)v6 > 0x3A || (v7 = 0x4003FFFFFFEFFFEi64, !_bittest64(&v7, v6)) )
  {
    if ( !**(_QWORD **)(a2 + 24) && (unsigned int)off_172AF1F0(*(unsigned int *)(a2 + 48), 3i64) == 2 )
    {
      sub_170B91F0(a2, *(_QWORD *)(a1 + 48), 1i64, 0i64);
      if ( !(unsigned __int8)sub_170BDE30(a1, *(_QWORD *)(*(_QWORD *)(a1 + 48) + 48i64)) )
        return 1;
      *(_DWORD *)(a1 + 8) |= 8u;
      return 1;
    }
  }
  if ( v5 )
    return 1;
  return 0;
}

注意到其中的is_numopget_radix

这个函数的返回值al一直是1,尝试直接修改为0,发现还是在死循环,看来是一些内部状态的修改不符合新版本要求?仔细跟一下这个函数,发现is_numop总是返回0。

对比新旧版本hexrays.dll,发现也有类似的代码,注意到新版本多了一次函数调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
char __fastcall sub_17123890(__int64 a1, __int64 a2)
{
  __int64 v2; // rbp
  char v5; // r14
  unsigned __int64 v6; // rsi
  __int64 v7; // rcx
 
  v2 = *(_QWORD *)(a2 + 16);
  if ( *(_BYTE *)(v2 + 13) )
    return 0;
  v5 = 0;
  v6 = *(int *)(*(_QWORD *)(*(_QWORD *)(a1 + 16) + 8i64 * *(_QWORD *)(a1 + 24) - 8) + 4i64);
  if ( ((unsigned int)(v6 - 19) <= 2 || (_DWORD)v6 == 50)
    && (!(unsigned __int8)is_numop(*(_QWORD *)(v2 + 40), (unsigned int)*(char *)(v2 + 12))
     || (unsigned int)get_radix(*(_QWORD *)(v2 + 40), (unsigned int)*(char *)(v2 + 12)) != 16) )
  {
    sub_171C6B60(*(_QWORD *)(a2 + 16) + 8i64, 0x11111101100000i64);
    v5 = 1;
  }
  if ( (unsigned int)v6 > 0x3A || (v7 = 0x4003FFFFFFEFFFEi64, !_bittest64(&v7, v6)) )
  {
    if ( !**(_QWORD **)(a2 + 16) && (unsigned int)off_172A42C0(*(unsigned int *)(a2 + 40), 3i64) == 2 )
    {
      sub_1711DE70(a2, *(_QWORD *)(a1 + 48), 1i64, 0i64);
      if ( !(unsigned __int8)sub_17122C40(a1, *(_QWORD *)(*(_QWORD *)(a1 + 48) + 48i64)) )
        return 1;
      *(_DWORD *)(a1 + 8) |= 8u;
      return 1;
    }
  }
  if ( v5 )
    return 1;
  return 0;
}

尝试用断电命令直接修改is_numop的返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0:000> p
hexarm64+0xbec0b:
00000000`6eadec0b 84c0            test    al,al
0:000> r rax
rax=0000000000000000
 
0:011> bp 00000000`6eadec0b "r rax=1;.echo 1;g"
breakpoint 0 redefined
0:011> g
1
1
1
1
1
1
1
1
1

断点触发多次之后,ida终于正常了。
图片描述
通过对比新旧hexrays或者hexx64插件,可以大致猜出应该是新版本要求的某些对象的保存状态相关的成员变量没有在旧版本的这个函数中设置?也不是非常确定,如果之前逆向过IDA应该能有一个比较准确的答案。

命令断点终究是不方便,还是要考虑静态patch的方案。我随便找了个is_numop0的API来替换这个is_numop的导入表项,似乎也能达到类似效果。

is_numop不是只在这一处使用,而且这么修改也不知道是否会对其他反编译过程中的状态有影响?只能说目前这么改下来还没观察到明显的副作用。

另外,微博网友沈沉舟昨天发了微博[2]来提醒大家使用这份IDA要谨慎点。

总而言之,还是尽量购买正版软件吧。

[1]
ida_dll_shim: https://github.com/x0rloser/ida_dll_shim

[2]
沈沉舟微博: https://weibo.com/1273725432/Nuv0d7nbD


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

收藏
点赞7
打赏
分享
最新回复 (23)
雪    币: 2656
活跃值: (3735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
值得怀疑 2023-12-1 12:59
2
0

这个so里的的sub_3C650 函数还是会卡死

上传的附件:
雪    币: 4857
活跃值: (2614)
能力值: ( LV15,RANK:550 )
在线值:
发帖
回帖
粉丝
diycode 5 2023-12-1 13:26
3
0
值得怀疑 这个so里的的sub_3C650 函数还是会卡死

我这里改了返回值没问题啊


最后于 2023-12-1 13:29 被diycode编辑 ,原因:
雪    币: 2656
活跃值: (3735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
值得怀疑 2023-12-1 14:06
4
0
diycode 值得怀疑 这个so里的的sub_3C650 函数还是会卡死 我这里改了返回值没问题啊
手动改的啊?不是用你发那个链接里的 ,ida.dll ida64.dll 啊?
雪    币: 1
活跃值: (146)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
妍瑷。 2023-12-1 14:16
5
0
值得怀疑 手动改的啊?不是用你发那个链接里的 ,ida.dll ida64.dll 啊?


最后于 2023-12-1 14:49 被妍瑷。编辑 ,原因:
雪    币: 2863
活跃值: (1602)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chixiaojie 2023-12-1 17:39
6
0
隔壁有19周年纪念版。
雪    币: 2656
活跃值: (3735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
值得怀疑 2023-12-1 21:20
7
0
chixiaojie 隔壁有19周年纪念版。
一样arm有问题
雪    币: 778
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_uzklxgat 2023-12-2 03:17
8
0
大佬能分享下改好的文件吗
雪    币: 31963
活跃值: (7105)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2023-12-2 07:32
9
0
不给二进制忍者方便好用,一目了然。
雪    币: 8057
活跃值: (4345)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sunsjw 1 2023-12-2 09:44
10
0
ninebell 不给二进制忍者方便好用,一目了然。
发出来共享下。
雪    币: 31963
活跃值: (7105)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ninebell 2023-12-3 11:38
11
0
sunsjw 发出来共享下。
只有3.5 demo的,没有糊嫩嬾的。
雪    币: 439
活跃值: (1479)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
绿雪羚羊 2023-12-4 23:07
12
0
感谢分享,经测试后反编译不会再出现死循环了。
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_ekvlnvmz 2023-12-4 23:24
13
0

各位大佬有没有修改好的成品插件,ARM确实卡住了,ida只能结束线程,好心大哥能分享下,成品插件么。感谢了,感谢

最后于 2023-12-4 23:26 被mb_ekvlnvmz编辑 ,原因:
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_ekvlnvmz 2023-12-4 23:27
14
0
绿雪羚羊 感谢分享,经测试后反编译不会再出现死循环了。[em_63]

大哥能分享下,你改的插件么,ARM64用了飘云的。还有网上ida64.dll,都卡了,手动改返回值的估计不会卡。

最后于 2023-12-5 02:33 被mb_ekvlnvmz编辑 ,原因:
雪    币: 439
活跃值: (1479)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
绿雪羚羊 2023-12-5 11:52
15
2

同样的,正如这篇帖子在末尾所说的那样“只能说目前这么改下来还没观察到明显的副作用”,我也只是把7.7的硬编码给搬过来,让它恰巧正常工作,仅此而已。“总而言之,还是尽量购买正版软件吧。


上传的附件:
雪    币: 702
活跃值: (3086)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
meilin 1 2023-12-22 08:53
16
1

IDA Pro 8.3 Patched Decompilers v3 by croviso


https://bbs.kanxue.com/thread-279733-1.htm#1757677 帖子的 libtolua.7z 

测试没有问题

上传的附件:
雪    币: 510
活跃值: (1285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gcodeer 2023-12-22 14:46
17
0
感谢分享,已用上
雪    币: 414
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
leave 2024-1-4 14:19
18
0
绿雪羚羊 同样的,正如这篇帖子在末尾所说的那样“只能说目前这么改下来还没观察到明显的副作用”,我也只是把7.7的硬编码给搬过来,让它恰巧正常工作,仅此而已。“总而言之,还是尽量购买正版软件吧。”
请问修改ida ida64两个文件是与ida shim类似的作用吗?改了这个可以搭配任意旧版反编译插件?
那五个插件的修改版IDA Pro 8.3 Patched Decompilers v3 by croviso与前面这两个文件的修改需要同时搭配吗?
还是说以上两个改法二选一?
雪    币: 439
活跃值: (1479)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
绿雪羚羊 2024-1-4 21:04
19
0
leave 请问修改ida ida64两个文件是与ida shim类似的作用吗?改了这个可以搭配任意旧版反编译插件? 那五个插件的修改版IDA Pro 8.3 Patched Decompilers v3 by ...

这两个文件与ida shim作用完全不同,修改仅仅是为了让arm和arm64反编译插件看起来能正常工作,在此过程中我并非完全准确且仔细的验证7.7与8.3的dll中 is_numop 函数的硬编码能得到完全相同结果。如果只是单纯的需要兼容旧版本插件,请直接使用ida shim。

至于后面的问题很遗憾我也没法给出准确的回答,抱歉啦~

最后于 2024-1-4 21:07 被绿雪羚羊编辑 ,原因:
雪    币: 414
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
leave 2024-1-8 11:02
20
0
非常感谢大佬
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_ldbucrik 2024-1-23 13:03
21
0
meilin IDA Pro 8.3 Patched Decompilers v3 by crovisohttps://bbs.kanxue.com/thread-279733-1.htm#1757677& ...
大佬,链接不能下载了呢
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_ldbucrik 2024-1-23 13:14
22
0
mb_ldbucrik 大佬,链接不能下载了呢
可以了
雪    币: 47
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
frdGo 2024-1-30 20:35
23
0
谢谢,确实可以用
雪    币: 234
活跃值: (202)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tfrist 2024-1-31 01:39
24
0
用IDA pro调试很慢吧!我还从来没有用它动态调试过!
游客
登录 | 注册 方可回帖
返回