IDA中遇到neon加速的复现、改写

IDA中遇到neon加速的复现、改写

996.icu LICENSE

  • 问题背景
  • 复现方法
  • 改写方法
  • 总结

问题背景

使用IDA解析安卓或者iOS的app,无可避免的会遇到neon加速。
对于neon加速,通俗易懂的理解下,就是能够同时计算多个数
专业术语称之为SIMD(Single Instruction Multiple Data),也就是单指令多数据。原理则是利用了arm处理器特有的64位寄存器和128位寄存器。

通常在IDA中遇到neon加速,我们无法直接复现这些代码。但是在理解了IDA对这些neon加速的解析规则后,稍加改动即可完美复现。
更进一步,则可以把neon加速改为纯C计算,因为使用了neon加速的代码,只能在真机上编译运行,改为纯C计算就能支持通用平台了(这在复现一些加密算法的时候会很有用)。

复现方法

首先,把代码从IDA中拷贝到你的IDE(Android Studio或者 Xcode),然后在代码中包含下面这个头文件:

#include <arm_neon.h>

之后,根据IDE的错误提示,以及IDA对这些neon加速的解析规则,修正错误的代码,改写为正确的neon加速代码。
OK,大功告成!
不过有句话是这么说的:Talk is cheap, show me the code!

那么下面我们就来实际操作下!为了简单方便起见,我只给出关键代码部分,下面是IDA中解析出的代码:

uint8x16_t v19; // q1
uint16x8_t v22; // q1

v22 = vmovl_u8((uint8x8_t)v19.n128_u64[0]);

复制到Xcode中的错误提示是:


可以知道出错在“.n128_u64[0]”这个地方,根据IDA的解析规则,这代表一个128位的数据只取前64位,如果是“.n128_u64[1]”的话就是取后64位。因此修正代码如下:

uint8x16_t v19; // q1
uint16x8_t v22; // q1

v22 = vmovl_u8(*(uint8x8_t *)&v19);

因为uint8x8_t *本来就是64位数据的指针,所以我们直接去掉出错的“.n128_u64[0]”就好了,Xcode中的错误提示也就消失了。

改写方法

改写neon加速的代码为通用的代码,需要我们对代码中发生的实际数据操作有充分的理解。
但是这不需要你对neon加速有多么精通,你只需要能够查找到对应的neon指令代表的意思,然后用C语言改写出来即可。
对于neon指令,可以在armDeveloper的网站上查找到对应的意思(每一条neon指令都能查到)。
比如对复现方法中示例的改写就是:

	//uint8x16_t v19; // q1
    char v19[16];
    //uint16x8_t v22; // q1
    unsigned short v22[8];

	//v22 = vmovl_u8(*(uint8x8_t *)&v19);//by CPL 取得前8个uint8
    for(int i = 0; i < 8; i++)
		v22[i] = (short)v19[i];

总结

本篇博客的核心是:neon加速其实很简单,就是能够同时计算多个数,只需要理解IDA对neon加速的解析规则,就能改写其为正确的neon加速代码。更进一步,改为为纯C代码,则只需要理解那条neon指令实际进行的数据操作是什么就行了。

逆向经验分享不易,如果本文有帮助到你,不如请我一罐可乐吧 :honeybee:

weChatPay_l 在这里插入图片描述

2 Likes