0
点赞
收藏
分享

微信扫一扫

Frida和IDA分析OLLVM控制流程平坦化


OLLVM控制流程平坦化

简介:​​https://github.com/obfuscator-llvm/obfuscator/wiki/Control-Flow-Flattening​​

特征:常量很多,用来根据常量跳转到正确的位置。
分析控制流程平坦化,主要是分析交叉引用,关注两种数据,一种从输入参数开始分析交叉引用,一种是从输出结果分析交叉引用。

把能使用输入参数的地址都Hook一下。

Java反编译

package com.example.hellojni;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.hellojni_sign2.R;
import org.apache.commons.lang3.RandomStringUtils;

public class HelloJni extends AppCompatActivity {
TextView tv;

public native String sign1(String str);

public native String sign2(String str, String str2);

public native String stringFromJNI();

/* access modifiers changed from: protected */
@Override // android.support.v7.app.AppCompatActivity, android.support.v4.app.SupportActivity, android.support.v4.app.FragmentActivity
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_hello_jni);
this.tv = (TextView) findViewById(R.id.hello_textview);
this.tv.setText(stringFromJNI());
((Button) findViewById(R.id.button_sign2)).setOnClickListener(new View.OnClickListener() {
/* class com.example.hellojni.HelloJni.AnonymousClass1 */

public void onClick(View view) {
HelloJni.this.tv.setText(HelloJni.this.sign2(RandomStringUtils.randomAlphabetic(15), RandomStringUtils.randomAlphabetic(16)));
}
});
}

static {
System.loadLibrary("hello-jni");
}
}

分析SO

找到Native函数sign2:

Frida和IDA分析OLLVM控制流程平坦化_java

加载Android ARM库

Frida和IDA分析OLLVM控制流程平坦化_IDA_02


打开sign2,并重命名第一个参数为​​env​​​,类型为​​JNIEnv*​​。第3个、第4个参数对应Java层的str1和str2,所以也重命名为str1和str2。前两个是编译时自带的。

Frida和IDA分析OLLVM控制流程平坦化_java_03


从输入str1开始分析,交叉引用:

Frida和IDA分析OLLVM控制流程平坦化_IDA_04


重命名v5为_str1, ​​ReleaseStringUTFChars​​右键Force Call Type,查看参数:

Frida和IDA分析OLLVM控制流程平坦化_frida_05


​​GetStringUTFChars函数原型​​:

const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);

返回char*

Frida和IDA分析OLLVM控制流程平坦化_android_06


其中v10是字符长度。

查看sub_13558:

Frida和IDA分析OLLVM控制流程平坦化_frida_07


查看v28交叉引用:

Frida和IDA分析OLLVM控制流程平坦化_llvm_08


把v3赋值给了v28.

Frida和IDA分析OLLVM控制流程平坦化_android_09


Frida和IDA分析OLLVM控制流程平坦化_IDA_10


接下来要Hook偏移量为13558的函数:

Frida和IDA分析OLLVM控制流程平坦化_java_11


Frida和IDA分析OLLVM控制流程平坦化_IDA_12


Frida和IDA分析OLLVM控制流程平坦化_java_13


Frida和IDA分析OLLVM控制流程平坦化_frida_14


说明a2是​​字符串的长度 * 2​​。

然后查一下​​sub_13558((unsigned __int64 *)&v45, (__int64)lp_str1, v10);​​中v45的交叉引用:

Frida和IDA分析OLLVM控制流程平坦化_frida_15


查看函数sub_12D70:

Frida和IDA分析OLLVM控制流程平坦化_IDA_16


Frida和IDA分析OLLVM控制流程平坦化_llvm_17


Esc返回到sub_12D70,查看参数v46:

Frida和IDA分析OLLVM控制流程平坦化_java_18

Frida和IDA分析OLLVM控制流程平坦化_java_19

Hook找到的这几个未知函数:

function hex_dump(p) {
try {
return hexdump(p) + "\r\n";
} catch (error) {
return ptr(p) + "\r\n";
}

}

function hook_native_addr(addr, idb_addr) {
var base_hello_jni = Module.findBaseAddress("libhello-jni.so");
Interceptor.attach(addr, {
onEnter: function (args) {
this.arg0 = args[0];
this.arg1 = args[1];
this.arg2 = args[2];
this.arg3 = args[3];

// 调用地址(LR寄存器)
this.lr = this.context.lr;
}, onLeave: function (retval) {
console.log("ptr:" + ptr(addr) + "idb_addr:" + ptr(idb_addr) + " LR:" + ptr(this.lr).sub(base_hello_jni) + " \r\n",
"this.arg0:\r\n", hex_dump(this.arg0),
"this.arg1:\r\n", hex_dump(this.arg1),
"this.arg2:\r\n", hex_dump(this.arg2),
"this.arg3:\r\n", hex_dump(this.arg3),
"retval:\r\n", hex_dump(retval));
}
})

}

function hook_native() {
// 基地址
var base_hello_jni = Module.findBaseAddress("libhello-jni.so");
// 加上偏移,获取到虚拟地址
// console.log(hexdump(base_hello_jni.add(0x3E070)));
var sub_13558 = base_hello_jni.add(0x13558);
// Interceptor.attach(sub_13558, {
// onEnter: function (args) {
// this.arg0 = args[0];
// this.arg1 = args[1];
// this.arg2 = args[2];
// }, onLeave: function (retval) {
// console.log("sub_13558:", hexdump(this.arg0), "\r\n",
// hexdump(this.arg1, { length: parseInt(this.arg2) }));
// }
// })

// hook_native_addr(base_hello_jni.add(0x12D70), 0x12D70);
// hook_native_addr(base_hello_jni.add(0x13558), 0x13558);
// hook_native_addr(base_hello_jni.add(0x162B8), 0x162B8);
// hook_native_addr(base_hello_jni.add(0x130F0), 0x130F0);
hook_native_addr(base_hello_jni.add(0x15F1C), 0x15F1C);
// hook_native_addr(base_hello_jni.add(0x154D4), 0x154D4);
// hook_native_addr(base_hello_jni.add(0x158AC), 0x158AC);
Interceptor.attach(base_hello_jni.add(0x154D4), {
onEnter: function (args) {
this.arg0 = args[0];
this.arg1 = args[1];
this.arg2 = args[2];
}, onLeave: function (retval) {
console.log("0x154D4:",
hexdump(this.arg1, { length: parseInt(this.arg2) }));
}
})

}

function hook_java() {
Java.perform(function () {
// 首先把随机数固定一下
var HelloJni = Java.use("com.example.hellojni.HelloJni");
HelloJni.sign2.implementation = function (str, str2) {
var result = this.sign2("0123456789abcde", "fedcba9876543210");
console.log("Java sign2 result:", result);
return result;
}
})
}

function main() {
hook_native();
hook_java();
}

setImmediate(main);

通过分析输出结果,可知​​sub_15F1C(v33, v34, &v51);​​​是关键函数。
查看sub_130F0函数:

Frida和IDA分析OLLVM控制流程平坦化_llvm_20


查看sub_162B8:

Frida和IDA分析OLLVM控制流程平坦化_IDA_21


Frida和IDA分析OLLVM控制流程平坦化_frida_22


Frida和IDA分析OLLVM控制流程平坦化_android_23


Frida和IDA分析OLLVM控制流程平坦化_android_24


打开aAbcdefghijklmn:

Frida和IDA分析OLLVM控制流程平坦化_frida_25


找到Base64编码函数特征。

调用aAbcdefghijklmn的函数即Base编码函数:

Frida和IDA分析OLLVM控制流程平坦化_java_26


查看交叉引用:

Frida和IDA分析OLLVM控制流程平坦化_android_27


然后查看sub_15F1C:

Frida和IDA分析OLLVM控制流程平坦化_llvm_28


改名:

Frida和IDA分析OLLVM控制流程平坦化_java_29


进去sub_15F1C查看:

Frida和IDA分析OLLVM控制流程平坦化_llvm_30


Frida和IDA分析OLLVM控制流程平坦化_llvm_31


Frida和IDA分析OLLVM控制流程平坦化_android_32


Frida和IDA分析OLLVM控制流程平坦化_IDA_33

查看sub_154D4、sub_158AC函数。

Frida和IDA分析OLLVM控制流程平坦化_IDA_34


Frida和IDA分析OLLVM控制流程平坦化_java_35


Frida和IDA分析OLLVM控制流程平坦化_java_36


Frida和IDA分析OLLVM控制流程平坦化_java_37


Frida和IDA分析OLLVM控制流程平坦化_frida_38


Frida和IDA分析OLLVM控制流程平坦化_android_39


找到md5特征:​​https://github.com/Zunawe/md5-c/blob/main/md5.c​​​​ https://code.woboq.org/linux/linux/crypto/md5.c.html​​Frida和IDA分析OLLVM控制流程平坦化_llvm_40

重命名md5_transform:

Frida和IDA分析OLLVM控制流程平坦化_frida_41


Frida和IDA分析OLLVM控制流程平坦化_llvm_42


md5_update调用的md5_transform:

Frida和IDA分析OLLVM控制流程平坦化_llvm_43


Frida和IDA分析OLLVM控制流程平坦化_llvm_44

Frida和IDA分析OLLVM控制流程平坦化_frida_45


md5特征:

Frida和IDA分析OLLVM控制流程平坦化_java_46

Frida和IDA分析OLLVM控制流程平坦化_android_47

Frida和IDA分析OLLVM控制流程平坦化_java_48


找到md5函数:

Frida和IDA分析OLLVM控制流程平坦化_android_49


举报

相关推荐

0 条评论