用户
搜索
回帖奖励 45 魔法币 回复本帖可获得 5 魔法币奖励! 每人限 1 次
  • TA的每日心情
    慵懒
    6 天前
  • 签到天数: 117 天

    连续签到: 2 天

    [LV.6]常住居民II

    i春秋作家

    推荐小组成员

    Rank: 7Rank: 7Rank: 7

    109

    主题

    257

    帖子

    542

    魔法币
    收听
    0
    粉丝
    15
    注册时间
    2017-7-24

    幽默灌水王突出贡献春秋文阁i春秋签约作者i春秋推荐小组积极活跃奖春秋游侠秦

    HAI_ i春秋作家 推荐小组成员 幽默灌水王 突出贡献 春秋文阁 i春秋签约作者 i春秋推荐小组 积极活跃奖 春秋游侠 秦 楼主
    发表于 7 天前 13687

    如果可以,请自己编写so文件库,然后进行反编译自行学习。这样的进步是最快的。

    这篇分析仅此一份,心血付出。

    HAI_使用手册~了解一下

    0x00 前言

    说明

    1.之前学习Android逆向的时候跑的太快,很多东西没有咀嚼直接吞咽,虽然看起来有一定成果,但是很快就进入瓶颈状态。所以逆向这东西还是要慢慢静下心来搞。

    2.网上的分析文章大多都是拿来直接F5,虽然是快速解决问题,但是却不利于学习。依赖于机器终归不是一种好的学习方式,或许在工作中可以调高效率。

    3.巩固基础知识,才能爬的更高。

    4.看见汇编别怂,都是纸老虎,无非绕一点。

    内容

    1.亘古不变的HelloWord

    2.有趣的+ - * /

    3.论ARM处理%的复杂程度

    4.探讨取代%会不会提高运行效率

    4.python实现EOR逻辑的计算

    0x01 亘古不变的HelloWord

    如何搞到so文件?这个我稍微提一下。Android Studio 选c++.然后创建工程即可。不会请百度吧。有的东西不重复。

    学编程很多都是从HelloWorld开始的,逆向当然也可以从HelloWorld开始啦。当然由于太简单,会缩短篇幅。

    1. 程序代码

    不解释。

    void Hello()
    {
        printf("HelloWorld");
    }

    2. 逆向so文件

    这里写图片描述
    这个就是我们的ARM汇编文件了。

    PUSH            {R7,LR}
    MOV             R7, SP
    SUB             SP, SP, #8

    ARM准备阶段,可以选择性忽视。

    ADD             SP, SP, #8
    POP             {R7,PC}

    ARM结束字段,也可以选择性忽视。

    但是看到这里,可以简单的理解一下,就是首先开辟内存,用完之后就是释放内存。

    剩下的还有什么

    LDR             R0, =(aHelloworld - 0x430C)
    ADD             R0, PC  ; "HelloWorld"
    BLX             printf
    STR             R0, [SP,#0x10+var_C]
    LDR             R0, =(aHelloworld - 0x430C)

    LDR从存储模块拿一个数据过来。就是我们的HelloWorld字符串。

    ADD             R0, PC  ; "HelloWorld"

    这里就相当于是return

    BLX             printf

    BL: 带链接的跳转。 首先将当前指令的下一条指令地址保存在LR寄存器,然后跳转的lable。通常用于调用子程序,可通过在子程序的尾部添加mov  pc, lr 返回。
    BX: 带状态切换的跳转。最低位为1时,切换到Thumb指令执行,为0时,解释为ARM指令执行。
    BLX就是结合两者。

    STR             R0, [SP,#0x10+var_C]

    把栈4位置的东西拿出来给R0,一般R0就是需要return的数据。

    3.总结

    c代码和ARM还是有很大的差距的。这里的

    0x02 有趣的+ - * /

    1.程序代码

    void youqu()
    {
        int a,b,c,d;
        a=1+1;
        b=2-1;
        c=2*2;
        d=4/2;
    }

    简单的写一个。

    2.逆向so文件

    这里写图片描述

    这里我们来看有趣的地方。

    SUB             SP, SP, #0x10
    MOVS            R0, #2
    STR             R0, [SP,#0x10+var_4]
    MOVS            R1, #1
    STR             R1, [SP,#0x10+var_8]
    MOVS            R1, #4
    STR             R1, [SP,#0x10+var_C]
    STR             R0, [SP,#0x10+var_10]
    ADD             SP, SP, #0x10
    BX              LR
    SUB             SP, SP, #0x10

    这个就是分配一个0x10大小的栈空间,这里是16位的,所致相当于是栈16。

    MOVS            R0, #2

    把立即数2给R0

    STR             R0, [SP,#0x10+var_4]

    把R0的内容给栈C的位置

    MOVS            R1, #1

    把立即数1给R0

    STR             R1, [SP,#0x10+var_8]

    在栈8的位置存R1

    MOVS            R1, #4

    把立即数4存入R1。

    STR             R1, [SP,#0x10+var_C]

    把立即数4放在栈4的位置。

    STR             R0, [SP,#0x10+var_10]

    把立即数4放入栈0的位置。

    ADD             SP, SP, #0x10

    栈结束。

    3.总结

    看到这里有没有什么发现呢?
    为什么说他们有趣呢,是不是感觉根本没有看到ARM汇编里出现+-*/的工作,直接就是最后的结果。为什么会这样处理。
    ARM汇编会对程序进行优化,直接会变成结果。
    不会把操作放在汇编语言。

    0x03 论ARM处理%的复杂程度

    1. 程序代码

        int a,b;
        a=10;
        b=5;
        a=a%b;

    2.逆向so文件

    这里写图片描述

    .text:000042CC                 PUSH            {R7,LR}
    .text:000042CE                 MOV             R7, SP
    .text:000042D0                 SUB             SP, SP, #0x10
    .text:000042D2                 MOVS            R0, #0xA
    .text:000042D4                 STR             R0, [SP,#0x18+var_C]
    .text:000042D6                 MOVS            R0, #5
    .text:000042D8                 STR             R0, [SP,#0x18+var_10]
    .text:000042DA                 LDR             R0, [SP,#0x18+var_C]
    .text:000042DC                 LDR             R1, [SP,#0x18+var_10]
    .text:000042DE                 BL              sub_13F38
    .text:000042E2                 STR             R1, [SP,#0x18+var_C]
    .text:000042E4                 STR             R0, [SP,#0x18+var_14]
    .text:000042E6                 ADD             SP, SP, #0x10
    .text:000042E8                 POP             {R7,PC}
    .text:000042CC                 PUSH            {R7,LR}
    .text:000042CE                 MOV             R7, SP
    .text:000042D0                 SUB             SP, SP, #0x10

    ARM准备阶段。

    MOVS            R0, #0xA

    R0赋值为0xA,也就是10

    STR             R0, [SP,#0x18+var_C]

    把R0的内容放在栈C的位置。

    MOVS            R0, #5

    给R0赋值立即数5。

    STR             R0, [SP,#0x18+var_10]

    把R0的内容放在栈8的位置。

     LDR             R0, [SP,#0x18+var_C]

    把栈C里的内容拿出来R0

    LDR             R1, [SP,#0x18+var_10]

    把栈8的内容拿到R1中

    BL              sub_13F38

    跳转sub_13F38,并且存储BL。

    我们来看一下sub_13F38的内容。并且确认好,R0=10,R1=5。

    这里写图片描述

    .text:00013F38                 CMP             R1, #0
    .text:00013F3A                 BEQ             loc_13F26
    .text:00013F3C                 PUSH.W          {R0,R1,LR}
    .text:00013F40                 BL              sub_13E78
    .text:00013F44                 POP.W           {R1,R2,LR}
    .text:00013F48                 MUL.W           R3, R2, R0
    .text:00013F4C                 SUB.W           R1, R1, R3
    .text:00013F50                 BX              LR
    CMP             R1, #0

    比较R1和立即数0

    BEQ             loc_13F26

    BEQ相等或为0则跳转,这里就是若R1=0则跳转。

    PUSH.W          {R0,R1,LR}

    把R0,R1入栈。R0=10,R1=5

    BL              sub_13E78

    跳转sub_13E78,保存LR。

    我们现在来看sub_13E78的内容
    这里写图片描述

    EOR.W           R12, R0, R1

    这里就是对R0和R1进行异或操作。
    使用我们的脚本进行计算。计算结果是15。

    IT MI

    N==1,这里代表是负数。

    NEGMI           R1, R1

    对R1求补码,由于这里是MI所以是对-5进行求补码

    BEQ             loc_13EF6

    之后相同则跳转。

    。。。

    3.总结

    这里写图片描述
    这个就是%的逻辑,涉及到3个if逻辑,和一个循环逻辑。虽然只是一个简单的%运算,但是在ARM机里是要运行很多才可以处理的。运行的多了就会涉及到一个问题,损耗问题。

    0x04探讨取代%会不会提高运行效率

    首先我们写一个这样子的代码

        int a,b;
        a=10;
        b=5;
        a=a/b;
        a=a*b;
        a=10-a;

    这个是替代取余的方法。

    我原本以为这样可以提高效率的。但是。

    这里写图片描述

    这个逻辑是除法的逻辑。这个逻辑是不是看起来比取余这个算法更加复杂。所以之前我们的猜测是有问题。

    0x05 python实现EOR操作

    直接贴代码,这里没有做过滤操作,是属于初代版本,如果需要的话,可以自行改进。

    import sys
    
    def eor(a,b):
        if a==b:
            return str(0)
        else:
            return str(1)
    # Complement 8 bits
    def eight(a):
        c=""
        d=8
        if len(a)<d:
            while 1:
                c=c+str(0)
                d=d-1
    
                if d==len(a):
                    break
            a=c+a
        return a
    a=bin(int(sys.argv[1]))[2:]
    b=bin(int(sys.argv[2]))[2:]
    
    a=eight(a)
    b=eight(b)
    c=""
    for i in range(0,8):
        c=c+eor(a[i],b[i])
    print c
    
    破解的目的是为了更好的开发

    回帖奖励 +5 魔法币

    很有用的基础学习,期待大佬继续更新
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册