首页
社区
课程
招聘
[原创][原创]第2题破解思路
2015-1-26 16:06 3821

[原创][原创]第2题破解思路

2015-1-26 16:06
3821
对dex文件进行反编译后,发现把字符串传入securityCheck函数并根据返回的boolean值判断是否验证成功。而securityCheck函数是在本机代码动态链接库libcrackme.so内。
逆向汇编libcrackme.so,会发现从地址12A8H处有securityCheck内惟一的循环,而比较字符串几乎都要使用循环。因此可以猜想此处为验证过程。

发现进行比较的2个字符串的首地址分别存在r0和r2寄存器内,而r0从函数开始处至此一直没改变(虽然和r5有一次传值,但最后油传回r0),而且r0通常用于存储首个函数参数的指针,因此可以断定传入的字符串的首地址存于r0内。而r2的内容是答案存储的首地址。因此只要把r2存储的地址所指向的字符串的字符依次作为返回值,让Java端读取并显示即可得到答案。
在Java端可以看出,函数返回值为boolean,由于boolean在JNI的类型映射为unsigned char,byte在JNI的类型映射为char,而返回值不作为函数签名,因此可以在Java端写成public native static byte securityCheck(String index);修改so,使之每次向函数传入要返回的字符在答案字符串内的序号,然后返回对应序号的字符。
然而参数类型是函数签名的一部分,因此不应更改参数类型。此时就需要把序号值用String进行封装,封装方法为:字符串封装=new String(new 

byte[]{(byte)序号&0xFF}),即传入字符串首字符的ASCII码为序号值。由于非空字符串的首字符的ASCII码不能为00,所以序号从1开始。
然后就要修改libscrackme.so。定位到12A8H,把
.text:000012A8 00 30 D2 E5                             LDRB    R3, [R2]
.text:000012AC 00 10 D0 E5                             LDRB    R1, [R0]
.text:000012B0 01 00 53 E1                             CMP     R3, R1
.text:000012B4 05 00 00 1A                             BNE     loc_12D0
改为
.text:000012A8 01 20 42 E2                             SUB     R2, R2, #1 ;序号从1开始,因此先把指针减1 
.text:000012AC 00 10 D0 E5                             LDRB    R1, [R0]   ;字符串首字符为序号
.text:000012B0 01 20 82 E0                             ADD     R2, R2, R1 ;答案指针加上序号
.text:000012B4 00 10 D2 E5                             LDRB    R1, [R2]   ;获取指针所指向的值
.text:000012B8 05 00 00 EA                             B       loc_12D4    ;跳到函数返回部分
然后新建一个ANDROID项目,引用该库,并添加如下函数
    public native static byte securityCheck(String index);
    public void onClick(View view) { //点击按键显示答案
        final byte 结束符 = (byte)0;
        final int 最大长度 = 256;
        StringBuffer 答案 = new StringBuffer();
        for(int 序号=1;序号<=最大长度;++序号){
            String 序号的字符串封装 = new String(new byte[]{(byte)(序号&0xFF)});
            byte 字符 = securityCheck(序号的字符串封装);
            if(结束符==字符)  break;
            答案.append((char) 字符);
        }
        ((TextView)findViewById(R.id.textView)).setText(答案.toString());
    }
点击按键,即可显示答案。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (3)
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hahads 2015-2-3 20:56
2
0
思路不错,谢楼主分享!
雪    币: 163
活跃值: (1233)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
学编程 1 2015-2-4 11:06
3
0
然后就要修改libscrackme.so。定位到12A8H,把
.text:000012A8 00 30 D2 E5                             LDRB    R3, [R2]
.text:000012AC 00 10 D0 E5                             LDRB    R1, [R0]
.text:000012B0 01 00 53 E1                             CMP     R3, R1
.text:000012B4 05 00 00 1A                             BNE     loc_12D0
改为
.text:000012A8 01 20 42 E2                             SUB     R2, R2, #1 ;序号从1开始,因此先把指针减1
.text:000012AC 00 10 D0 E5                             LDRB    R1, [R0]   ;字符串首字符为序号
.text:000012B0 01 20 82 E0                             ADD     R2, R2, R1 ;答案指针加上序号
.text:000012B4 00 10 D2 E5                             LDRB    R1, [R2]   ;获取指针所指向的值
.text:000012B8 05 00 00 EA                             B       loc_12D4    ;跳到函数返回部分

是否有工具可以直接填写ARM汇编,然后得到二机制的机器码?
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hmbhmb 2015-2-7 22:22
4
0
LZ一看就知道是程序员,而且能力还蛮强
游客
登录 | 注册 方可回帖
返回