首页
论坛
课程
招聘
[原创] 某类抽取加固APP的脱壳与修复
2020-3-31 00:46 8544

[原创] 某类抽取加固APP的脱壳与修复

2020-3-31 00:46
8544
  • 写在前面
    APP来自看雪安卓2w班3月份题目,题目主要关键点在于dex的dump和恢复,但是实际上由于这个APP的壳保护较弱,实际上如果脱壳点时机稍微晚一点,就可以完全dump下来,也不需要修复。不过为了应对其他无法完整dump下来的APP,解题时还是采用了较为一般的方法。

    描述

    使用至少两种方法完成对dex的dump和修复

    解题过程

    脱壳

    选取脱壳点

    这里选取我之前总结的调用图中的DexFileVerifier::VerifyDexFileVerifier以及OpenFile函数与DexFile::DexFile函数作为脱壳点,
    在函数中插入以下dump dex的代码

    char dexfilepath[100]={0};
    int pid=getpid();
    sprintf(dexfilepath,"/sdcard/%d_%d_OpenFile.dex",(int)(size),pid);
    //fopen
    int fd=open(dexfilepath,O_CREAT|O_RDWR,0666);
    if(fd>0)
    {
        write(fd,base,size);
        close(fd);
    }
    

    编译源码,刷机,
    刷机成功后,安装并给予应用存储权限,然后运行app,并在sdcard目录下使用grep命令过滤dex,最终得到脱壳后的文件如下

修复

dump下来之后就是修复,使用FART确认是否有抽取的dex,

修复方式1:

fart.py,然后一一分析想要分析的方法
最终修复效果

修复方式2:

我自己写了一个脚本,关键代码如下

# -*- coding: utf-8 -*-

def delblankline():
    global insfilename
    infopen = open(insfilename, 'r',encoding="utf-8")
    outfopen = open(insfilename + '_out', 'w',encoding="utf-8")
    db = infopen.read()
    outfopen.write(db.replace(';','\n'))
    outfopen.close()
    infopen.close()
    f.close()

def read_one_line(line):
    #print(line)
    frags = line.split(',')
    if len(frags) == 5:
        _name = frags[0].split(':')[1]
        _method_idx = int(frags[1].split(':')[1])
        _offset =  int(frags[2].split(':')[1])
        _code_item_len = int(frags[3].split(':')[1])
        _ins = frags[4].split(':')[1].replace("}\n", "")
        return _name,_method_idx,_offset,_code_item_len,_ins
    else:
        return '',-1,-1,-1,''   
    #print(dex.base64_decode())
    #data = json.loads(line,encoding = 'utf-8')
    #print(data)

class dex_method:
    name = ''
    method_idx = 0
    offset = 0
    code_item_len = 0
    ins_raw = ''
    ins = b''
    def __init__(self,_name,_method_idx,_offset,_code_item_len,_ins):
        self.ins_raw = _ins
        self.name,self.method_idx,self.offset,self.code_item_len,self.ins = _name,_method_idx,_offset,_code_item_len,base64.b64decode(_ins)
        #print(_name,_method_idx,_offset,_code_item_len,self.ins_raw)

    def repair_dex(self,fd):
        if self.offset > 0:
            fd.seek(self.offset, 0)
            if len(self.ins) == self.code_item_len:
                #print('reapir method = ',self.name,'repair code = ',self.ins_raw)
                fd.write(self.ins)  

def main():
    init()
    global filename
    global insfilename
    global method_name
    global all_methods
    delblankline()
    dex_file = open(filename,'rb+')         
    #bin_file = 
    if all_methods:
        with open(insfilename + '_out',encoding='utf-8') as f:
            for line in f:
                _name,_method_idx,_offset,_code_item_len,_ins = read_one_line(line)
                method = dex_method(_name, _method_idx, _offset, _code_item_len, _ins)
                method.repair_dex(dex_file)
    else:
        found = False
        with open(insfilename + '_out',encoding='utf-8') as f:
            for line in f:
                _name,_method_idx,_offset,_code_item_len,_ins = read_one_line(line)
                if method_name in _name:
                    found = True
                    method = dex_method(_name, _method_idx, _offset, _code_item_len, _ins)
                    print('find method = ' + method.name)
                    method.repair_dex(dex_file)
                else:
                    pass
        if found == False:
            print('don\'t find method = ',method_name)      
                #break


if __name__ == '__main__':
    main()

这个脚本是实现的抽取壳中空间不变的情况,使用方法和完整代码见here,程序个人完成,如果有bug,欢迎指摘。最终修复效果如下:

 

与@hanbingle师傅的修复脚本修复后的一致。

 

最后,题目见附件


[2022冬季班]《安卓高级研修班(网课)》月薪三万班招生中~

最后于 2020-4-1 12:00 被Simp1er编辑 ,原因:
上传的附件:
收藏
点赞4
打赏
分享
最新回复 (5)
雪    币: 5437
活跃值: 活跃值 (4434)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
GitRoy 活跃值 3 2020-4-3 09:45
2
0
不错
雪    币: 14617
活跃值: 活跃值 (4130)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
浅笑不语 活跃值 2020-4-7 13:26
3
0
谢谢楼主先收藏起来
雪    币: 222
活跃值: 活跃值 (270)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_yvvzfcdo 活跃值 2021-4-1 15:28
4
0
感谢大牛
雪    币: 222
活跃值: 活跃值 (270)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_yvvzfcdo 活跃值 2021-4-1 15:32
5
0

大牛,这个错误是啥原因

雪    币: 3610
活跃值: 活跃值 (4315)
能力值: ( LV10,RANK:177 )
在线值:
发帖
回帖
粉丝
YenKoc 活跃值 2 2021-4-1 15:36
6
0
mark了,感谢simple哥
游客
登录 | 注册 方可回帖
返回