抖音xg03算法逆向杂谈

抖音xg03算法逆向杂谈
@[toc] # 1: 修复jni_onload不能f5 ## 1.1 jni_onload函数初探 使用ida打开libcms.so 定位到Jni_Onload函数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OE94MTXP-1600281730856)(C:\Users\hcz\AppData\Roaming\Typora\typora-user-images\image-20200917013828865.png)]
发现函数无法f5,按p创建函数,发现如下错误信息:
在这里插入图片描述

0000A86A DCW 0xB686 a886出的opcode 无法翻译成指令,竟然ida 无法翻译,那么原so的流程肯定不会经过改分支,经过的话程序会崩,修复方法是直接patch nop。 nop之后可以p键创建函数,但f5 之后又报A872: positive sp value has been found 错误,定位到0xa872,指令为 ADD SP, SP, #0xF0

改指令导致堆栈不平衡,导致ida无法f5, 原so肯定不会运行到改分支,会崩溃,所以直接nop。nop之后u键->c键->p键创建函数,AAFA: positive sp value has been found 发现同理直接nop,nop堆栈之后的f5代码如下:
在这里插入图片描述
发现代码中出现大量jmpout。

1.2 修复jmpoup

截取一块jmpout代码块
在这里插入图片描述
可以看到导致jmpoup的原因是mov pc,r1,ida不知道目的地在哪,仔细观察从0000A9D0 push {r0-r3}开始至0000AA26 POP {R0-R3}结束,寄存器的值不会发生改变,这一段可以认为是花指令,直接在0000A9D0出patch 指令为b 0x0000AA28,0000A9D0- 0x0000AA28 中间的指令用nop填充,为方便修改,编写ida python脚本,脚本内容如下:

# -*- coding:utf-8 -*-
from idc import *
from idaapi import *
from keystone import *

ks = Ks(KS_ARCH_ARM, KS_MODE_THUMB)


def ks_dis_asm(dis_str):
    global ks
    encoding, count = ks.asm(dis_str)
    return encoding


def un_junk_code(fun_start, fun_end):
    patch_start = None
    patch_end = None
    jmp_addr = []
    for i in range(fun_start, fun_end):
        # PUSH           {R0-R3}  or PUSH            {R0-R3,R7}
        # MOV            R0, PC
        # MOV            R1, PC
        buf = "".join(['%02x' % ord(j) for j in get_bytes(i, 6)]).lower()
        if buf == '0fb478467946' or buf == '8fb478467946':
            patch_start = i
        # end POP             {R0-R3}
        end_buf_one = "".join(['%02x' % ord(j) for j in get_bytes(i, 2)]).lower()
        #
        if end_buf_one == '0fbc':
            patch_end = i + 2
        # # end   POP             {R0-R2}
        # #       POP             {R3,R7}
        end_buf_two = "".join(['%02x' % ord(j) for j in get_bytes(i, 4)]).lower()
        if end_buf_two == '07bc88bc':
            patch_end = i + 4
        if patch_start != None and patch_end != None:
            for j in range(0, patch_end - patch_start, 2):
                # patch nop
                patch_byte(patch_start + j, 0x00)
                patch_byte(patch_start + j + 1, 0xbf)
            # 跳转
            dis_str = 'b #{}-{}'.format(patch_end, patch_start)
            jmp_addr.append(patch_start)
            encoding = ks_dis_asm(dis_str)
            print dis_str, encoding
            for item in encoding:
                print('{}'.format(hex(item)))
            for k in range(len(encoding)):
                patch_byte(patch_start + k, encoding[k])
            print hex(patch_start), hex(patch_end)
            patch_start = None
            patch_end = None



if __name__ == '__main__':
    # 函数开始位置与结束位置
    un_junk_code(0x000551C0, 0x00057784)

修改un_junk_code 函数的参数,即可修复这类花指令。

2、定位leviathan 函数

2.1 Jni_onload 定位法

长话短说,经过分析sub_7B10函数为RegisterNative函数的关键处。

2.2 frida hook registernative

好用的一批,强推,不多bb 直接上代码

// hook register 打印动态注册的函数地址
function hook_register(){
    // libart.so 所有导出函数表
    var symbols = Module.enumerateSymbolsSync("libart.so");
    var addr_register = null;
    for(var i = 0; i < symbols.length; i++){
        var symbol = symbols[i];
        var method_name = symbol.name;
        if(method_name.indexOf("art") >= 0){
    
            if(method_name.indexOf("_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi") >= 0){
                addr_register = symbol.address;
            }
        }
    }

    // 开始hook
    if(addr_register){
        Interceptor.attach(addr_register, {
            onEnter: function(args){
                var methods = ptr(args[2]);
                var method_count = args[3];
                console.log("[RegisterNatives] method_count:", method_count);
                for(var i = 0; i < method_count; i++){
                    var fn_ptr = methods.add(i * Process.pointerSize * 3 + Process.pointerSize * 2).readPointer();
                    var find_module = Process.findModuleByAddress(fn_ptr);
                    if(i == 0){
                        console.log("module name", find_module.name);
                        console.log("module base", find_module.base);
                    }
                    console.log("\t method_name:", methods.add(i * Process.pointerSize * 3).readPointer().readCString(), "method_sign:", methods.add(i * Process.pointerSize * 3 + Process.pointerSize).readPointer().readCString(), "method_fnPtr:", fn_ptr, "method offset:", fn_ptr.sub(find_module.base));
                }
            }, onLeave(retval){

            }
        })
    }

}

function main(){
    hook_register();
}

setImmediate(main);

3、算法还原:

1、敏感话题, 不讨论。 算法的关键位置,f5之后的代码和汇编代码出入很多,要想还原得刚汇编。
附上xg03 算法的还原图:
在这里插入图片描述

成功获取数据

xg0408(最新版)算法的还原图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-teKLo5Cu-1600281730863)(C:\Users\hcz\AppData\Roaming\Typora\typora-user-images\image-20200917022336604.png)]

4注意

还原出来的xgorgon只供学习研究,切勿商业用途及非法用途

5 发现bug

这两个发现了bug,unidbg还原出来的xg0408不登录的情况下不能搜索,正常设备能搜。经过验证发现是xgorgon中有设备检测,不正常的设备搜索会需要登录。 经过一系列的奋斗,已完善。
在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值