一、目标

一、目标

我们的目标是:没有蛀牙。哦不,是 还原算法。还原算法最佳的伙伴当然是IDA的F5了,不过这个哥们偶尔会闹点小脾气

idafailure
1:idafailure

手撕汇编是不可能,这辈子都不想手撕汇编。男人嘛一个怎么够呢。

二、介绍

RetDec是基于LLVM的开源机器代码反编译器。可以反汇编不限于任何特定的目标体系结构,操作系统或可执行文件格式。这是机翻的,说人话就是支持多种平台的反汇编,重要的还是开源的,有理想的小伙伴可以研究研究他的代码。

源码 https://github.com/avast/retdec

奋飞目前还没有那么远大的理想,就不下载代码编译了,目前Release出来的是V4.0版本,奋飞的开发平台是Mac 10.14.6。所以下载他的 retdec-v4.0-macos-64b.tar.xz

解压完把我惊到了, 5个多G。果然是大块头有大智慧。就拿之前的 libnative-lib.so 来练练手。

python3 retdec-decompiler.py libnative-lib.so

一共生成了4个文件

retdec
1:idafailure

我们最关心的就是 libnative-lib.so.c 文件了,打开对比下:

// 源代码
static int registerNativeMethods(JNIEnv* env, const char* className,
        JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;
    clazz = env->FindClass(className);
    if (clazz == NULL) {
        return JNI_FALSE;
    }
    if ( env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
        return JNI_FALSE;
    }

    return JNI_TRUE;
}


// retdec 反编译出来的
// From module:   /Users/fenfei/Desktop/myndk/app/src/main/cpp/native-lib.cpp
// Address range: 0x8f48 - 0x8f94
// Line range:    32 - 45
// Demangled:     registerNativeMethods(_JNIEnv*, char const*, JNINativeMethod*, int)
int32_t _ZL21registerNativeMethodsP7_JNIEnvPKcP15JNINativeMethodi(int32_t * a1, char * a2, int32_t * a3, int32_t a4) {
    int32_t v1 = (int32_t)a1;
    int32_t v2 = function_889c(v1, (int32_t)a2); // 0x8f5a
    int32_t result = 0; // 0x8f64
    if (v2 != 0) {
        // 0x8f6e
        result = function_88a8(v1, v2, (int32_t)a3, a4) > -1;
    }
    // 0x8f8e
    return result;
}

// 源代码
extern "C" JNIEXPORT jstring JNICALL
Java_com_fenfei_myndk_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

// retdec 反编译出来的
// From module:   /Users/fenfei/Desktop/myndk/app/src/main/cpp/native-lib.cpp
// Address range: 0x8de4 - 0x8e54
// Line range:    5 - 0
int32_t Java_com_fenfei_myndk_MainActivity_stringFromJNI(int32_t env, int32_t a1) {
    // 0x8de4
    int32_t hello; // bp-24, 0x8de4
    function_883c(&hello, 0x15e06);
    int32_t v1 = _ZNKSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv(&hello); // 0x8e0c
    int32_t result = function_8848(env, v1); // 0x8e18
    function_8854(&hello);
    if (*(int32_t *)g261 == *(int32_t *)g261) {
        // 0x8e36
        return result;
    }
    // 0x8e4e
    __stack_chk_fail();
    return &g335;
}

怎么说呢,可读性也就那么回事吧,还是IDA的F5真香。不过在IDA闹脾气的时候,retdec 也是可以顶一顶的,奋飞感觉用retdec指定反编译某个函数还是有实用价值的,不过目前还没有研究出来用哪个参数,等搞明白了再来更新吧。

retdec也有ida的插件,可以直接支持函数级反汇编,不过目前只支持 IDA 7.5,土豪专用。

三、总结

教员说过,朋友要搞到多多的。东边不亮西边亮。做逆向不要死磕,毕竟我们的目的仅仅是学习下关键算法,而不是把整个工程还原出来。所以多几款工具交叉对比还是有必要的。

100

关注微信公众号,最新技术干货实时推送

100