加壳 ELF 逆向漫谈

Reading time ~1 minute

这些日子由于实验室的原因,看了几个 apk 病毒的 native so,摸索了半天终究还算有点收获。

刚看这些 so 的时候,拖进 IDA 各种报错也就算了,readelf、010 都报错,section 信息各种不正常,根本就是连个程序入口点都找不到。程序载完 so 直接结束的也有,根本没有 dump 的机会,反调也是一应俱全,只要上调试器,肯定挂不解释。

不过想来,既然程序能正常运行,那么它破坏的一定是那些不会影响运行的字段,关键的运行相关的信息,该是怎么样,还必须得是什么样。于是在网上搜集了下资料,开着 010 对比着看了下,精炼起来大概就下面几点:

  1. section 信息与运行无关,所以可以随便改甚至删除;
  2. 在 section 和 segment 中都存在一个 dynamic 段,两者为同一个,且对程序运行而言至关重要,segment 中的 dynamic 不可随便破坏,是我们分析程序的关键;
  3. so 的 entry 字段若为 0,则会被无视,否则会在 so 加载时执行;
  4. 通过 readelf -a 分析 dynamic 的结果,我们可以找到 init 函数和 init array 的地址(这其中的代码是在程序 entry 之前执行的,基本上壳都少不了要在这里面做手脚),找到 init 之后,至少我们可以下好断点挂上调试器跟踪了;

其中 dynamic 不可随便破坏不代表完全不可改,有一个 so 就通过修改了 dynamic 段导致 readelf -a 拿不到任何有用的信息,直接 readelf -a 会得到:

1
2
3
...
There are no relocations in this file.
...

010 查看一下 dynamic 段会发现 p_offset_FROM_FILE_BEGIN 为 0:

segment info

显然这个字段绝对不应该为 0,为 0 导致 readelf 读不到正确的 dynamic 段信息,而运行时既然能读到,那说明 dynamic 段还是被正常映射了。对比观察一下会发现,其实 dynamic 段跟着前面的那个 Loadable Segment 一起映射了,于是这里的 p_offset_FROM_FILE_BEGIN 可以算出来是 0x41490 - 0x00042490 + 0x00042C34,修正后 readelf 即可正常工作。

挂载网络文件夹后网络故障时文件操作命令卡死

挂载 NFS 或者 Samba 的时候,经常会由于网络故障导致挂载好的链接断掉。此时如果尝试进行 ls、cd、df 等各种命令,只要与此目录沾上边,就会卡住。如果使用了类似 oh-my-zsh 这种配置的,只要在网络目录中,弹出命令提示符前就会直接卡住。这个时候第一反应就是...… Continue reading

路由折腾记 第四弹

Published on September 02, 2017