【逆向分析】静态分析_Navtive_ISCC_2017

文章详细展示了对Java层Native函数的静态分析过程,通过反编译和汇编代码解析,重点讨论了内存分配、字符串处理及位操作等技术,包括malloc、memset、memcpy和strcmp函数的使用,以及如何通过位移和比较操作实现特定的字符串操作。最终,文章给出了一个基于分析结果的解密示例,涉及字符串首位互换和比较的逻辑。

【逆向分析】静态分析_Navtive_ISCC_2017

分析

Java层jadx反编译
在这里插入图片描述

目标函数是native函数,所以这里需要静态分析native
直接搜目标函数
在这里插入图片描述
开始读汇编


        ; ================ B E G I N N I N G   O F   P R O C E D U R E ================

        ; Variables:
        ;    var_1C: int32_t, -28
        ;    var_28: int32_t, -40

native_checkFlag:
push       {r4, r5, r6, r7, lr}
sub        sp, #0x14
adds       r6, r0, #0x0
adds       r0, r3, #0x0 ; argument "__size" for method malloc@PLT
adds       r5, r3, #0x0
str        r2, [sp, #0x28 + var_1C] (r2存下来)
blx        malloc@PLT   ; malloc (创建空间)
ldr        r2, [r6] (r2 = r6)
movs       r3, #0xc8 (r3 = 200)
str        r0, [sp, #0x28 + var_28] (r0 存下来)
lsls       r3, r3, #0x2 (r3 = r3 左移两位)
ldr        r4, [r2, r3] (r4 = r2 + r3 )
ldr        r1, [sp, #0x28 + var_1C]
adds       r3, r5, #0x0
movs       r2, #0x0
adds       r7, r0, #0x0
adds       r0, r6, #0x0
blx        r4
adds       r4, r5, #0x1
adds       r0, r4, #0x0 ; argument "__size" for method malloc@PLT
blx        malloc@PLT   ; malloc
movs       r1, #0x0     ; argument "__c" for method memset@PLT
adds       r6, r0, #0x0
adds       r2, r4, #0x0 ; argument "__n" for method memset@PLT
blx        memset@PLT   ; memset
adds       r2, r5, #0x0 ; argument "__n" for method memcpy@PLT
adds       r0, r6, #0x0 ; argument "__dest" for method memcpy@PLT
adds       r1, r7, #0x0 ; argument "__src" for method memcpy@PLT
blx        memcpy@PLT   ; memcpy
lsrs       r0, r5, #0x1f
adds       r0, r0, r5
asrs       r0, r0, #0x1
movs       r2, #0x0
str        r0, [sp, #0x28 + var_1C]
adds       r3, r2, #0x0 (r3 = r2 + 0)
b          loc_d5a
loc_d5a:
ldr        r1, [sp, #0x28 + var_1C] ; CODE XREF=native_checkFlag+78
subs       r2, #0x1 (r2 = r2 -1 ,这里就是r3 一开始和 r2 相同然后一个+1 一个 -1)
cmp        r3, r1 (r3 和 r1比较)
blt        loc_d4c (小于就跳loc_d4c)
loc_d4c:
ldrb       r4, [r6, r3] ; CODE XREF=native_checkFlag+100 (r4 = r6 + r3)
adds       r1, r6, r5 ( r1 = r6 + r5)
ldrb       r0, [r1, r2] (r0 = r1 + r2)
subs       r4, #0x5(r4 = r4 - 5)
strb       r0, [r6, r3] ( r6+ r3 = r0)
strb       r4, [r1, r2] (r1 + r2 = r4 ) (也就是r1 + r2 的值放到了r6 + r3上面,r6 + r3的值-5放到了r1+r2的位置)
adds       r3, #0x1 (r3  = r3+1)
ldr        r1, =0x15f8  ; 0xd88,0x15f8
movs       r3, #0x0
strb       r3, [r6, r5]
add        r1, pc       ; argument "__s2" for method strcmp@PLT, "=0HWYl1SE5UQWFfN?I+PEo.UcshU"
adds       r0, r6, #0x0 ; argument "__s1" for method strcmp@PLT
blx        strcmp@PLT   ; strcmp
adds       r4, r0, #0x0
adds       r0, r6, #0x0 ; argument "__ptr" for method free@PLT
blx        free@PLT     ; free
adds       r0, r7, #0x0 ; argument "__ptr" for method free@PLT
blx        free@PLT     ; free
add        sp, #0x14
rsbs       r0, r4, #0x0
adcs       r0, r4
pop        {r4, r5, r6, r7, pc}

转成C语言来看看

int native_checkFlag(int arg0, int arg1, int arg2, int arg3) {
    r4 = arg3;
    r0 = malloc(arg3);(内存分配arg3大小)
    r5 = r0;(r5新开辟了一个空间)
    (*(*arg0 + 0x320))(arg0, arg2, 0x0, r4, r0);
    r0 = malloc(r4 + 0x1);
    r6 = r0;(r6新开辟了一个空间)
    memset(r0, 0x0, r4 + 0x1);(将新开辟的空间填充字符0x0memcpy(r6, r5, r4);(从r5复制东西到r6,也就是r0呗,也就是都变成了0x0,长度是r4和r4+1,可以理解r0,r5,r6都是装满0的空间)
    r2 = 0x0;
    r1 = r6 + r4;
    r0 = SAR(r4 + r4 / 0x80000000, 0x1); (看汇编:asrs       r0, r0, #0x1 就是r0 = r0 >> 1 也就是 r0 = r0/2 )
    r3 = r2;
    do {
            r2 = r2 - 0x1; (r2从0开始-1)
            if (r3 >= r0) {(此时的r0是原来的一半)
                break;
            }
            lr = *(int8_t *)(r1 + r2);(r6+r4-r3)(r6是起点,r4是终点)
            r7 = *(int8_t *)(r6 + r3);(r6+r3)
            *(int8_t *)(r6 + r3) = lr;
            r3 = r3 + 0x1;(r3从0开始+1*(int8_t *)(r1 + r2) = r7 - 0x5;(互换位置,并且后面的换到前面还-5} while (true);
    *(int8_t *)(r6 + r4) = 0x0; 直到首位碰头
    r4 = strcmp(r6, "=0HWYl1SE5UQWFfN?I+PEo.UcshU");(将我们的r6和这个字符串进行比较)
    free(r6);
    free(r5);
    r0 = 0x1 - r4;(
    这里来看汇编吧:
             rsbs.w     r0, r4, #0x1 (逆向减法 r0 = 1 - r4)
00000d80         it         lo (如果小于)
00000d82         movslo     r0, #0x0 (没懂)
00000d84         pop.w      {r2, r3, r4, r5, r6, r7, r8, pc}if (r0 < 0x0) {
            asm { movslo     r0, #0x0 };
    }
    return r0;
}

虽然有些细节没明白,大概意思是一个字符串首位互换,并且尾换到首时-5 和指定字符串比较就行,可以逆推回去原始字符串。

import base64

ans = '=0HWYl1SE5UQWFfN?I+PEo.UcshU'
length = len(ans)
flag_suf = []
flag_pre = []

for i in range(length//2):
    flag_suf.append(ans[i])
    flag_pre.append(chr(ord(ans[(i+1)*(-1)]) + 5))
print(base64.b64decode("".join(flag_pre + flag_suf[::-1])))

在这里插入图片描述

flag{ISCCJAVANDKYXX}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值