• 《CTF特训营》学习笔记——APK逆向基础


    目录

    一、Android基本架构

    1.Android操作系统基本分层

    2.Dalvik虚拟机层

    3.Native层

    二、ARM架构基础

    1.基本架构介绍

    2.工作状态

    3.函数调用和转跳指令

    4.出栈入栈指令

    5.保存/恢复寄存器的值

    三、abd

    四、APK文件格式


    一、Android基本架构

    1.Android操作系统基本分层

    一般由4层,Linux内核层,系统运行层,应用框架层和应用层,从开发人员的角度来讲,一个Android应用可以分为两个部分:一部分使用java来实现,也称为Dalvik虚拟机层,一部分使用C/C++实现,也称为Native层。

    2.Dalvik虚拟机层

    Android应用虽然可以使用Java开发,但是Android应用却不是运行在标准Java虚拟机上的,而是运行在谷歌专门为Android开发的Dalvik虚拟机上,虽然Android从5.0开始默认使用ART虚拟机,抛弃了Dalvik虚拟机,但是Dalvik虚拟机任然很重要,尤其是对DEX文件的反编译。

    Dalvik虚拟机中运行的是Dalvik字节码,并不是Java字节码,所有的Dalvik字节码均由Java字节码转换而来,并打包成一个DEX可执行文件。Dalvik虚拟机有一套自己的指令集,以及一套专门的Dalvik汇编代码。

    3.Native层

    Android既可以使用Java开发,也可以用C/C++结合,甚至可以使用纯C/C++开发,使用C/C++开发的代码会形成一个so文件,会在Android应用运行时加载到内存中。这与x86平台中Linux加载so库的方式非常独特,唯一不同的是Native蹭的函数与Dalvik层的函数进行关联,使得Native层的函数在Dalvik层中可以很方便地调用。

    二、ARM架构基础

    1.基本架构介绍

    ARM处理器一共有37个32位的寄存器,31个通用寄存器,6个为状态寄存器,共7种运行模式,除用户模式之外,其余6种称为特权模式,Android应用主要在用户模式下运行。

    用户模式下,处理器可访问寄存器为不分组寄存器R0-R7,分组寄存器R8-R14、程序计数器R15(PC)以及当前程序状态寄存器CSPSR。

    2.工作状态

    有两种,ARM状态和Thumb状态,处理器可以在这两种状态下随意切换,区别在:ARM状态下会执行32位对齐的ARM指令,而在Thumb状态时,,主要执行16位对齐的Thumb指令。处理器判断当前的状态的主要标志是程序状态寄存器CPSR中的T标志,当T位为1时,处理器处于Thumb状态,反之为ARM状态。两种状态下寄存器命名有所不同:

    ARM状态Thumb状态
    R11FP
    R12IP
    R13SP
    R14LR
    R15PC

    两种状态下的R0-R7与CPSR相同。

    通过实例来介绍一下为什么ARM有两种状态,加入有一个这样的函数:

    1. int func (int i,int j)
    2. {
    3. int x = i + j - i / j * 3;
    4. printf("%d\n",x );
    5. return x;
    6. }

    通过ARM交叉编译工具编译以后的结果:

     可以看出,ARM的汇编代码与intel x86的汇编代码非常相似,参数都是采用从目标到源的方式,汇编指令也比较相似。

    3.函数调用和转跳指令

    在ARM汇编当中,函数调用和转跳指令都可以使用b系列指令,常见的有b,bx,bl,blx,其中x的指令表示根据地址的最后一位进行Thumb模式和ARM模式的切换,当地址最后一位为1时切换至Thumb模式,为0时切换至ARM模式(9寄存器PC的值的最后一位总为0),带1的指令表示处理器跳转的时候,会将当前指令的下一条指令地址存入寄存器LR中,这样当子程序需要跳转回来时,只需要把LR的值存入PC即可。

    4.出栈入栈指令

    使用push和pop指令,不同的是ARM汇编的push和pop指令后面可以接多个单数,例如上面的push{r4,lr}

    5.保存/恢复寄存器的值

    利用LDR,STR,LDM,STM系列指令用于将寄存器的值存入内存以及将寄存器的从内存中读出,其中LDR,STR用于处理单个寄存器,LDM,STM用于一次性保存或恢复多个内存器,因此有时候我们也会看见使用LDM,STM系列指令执行出栈和入栈操作。

    三、abd

    adb是谷歌官方提供的命令行工具,用来连接真机或者模拟器,只要在相应的Android系统设置中打开USB调试,即可使用abd连接手机。abd最主要的功能是查看连接的手机,打开一个shell、查看日志、上传与下载文件,相关命令如下:

    1. 1.查看连接的手机或者模拟器
    2. adb devices
    3. 2.安装APK
    4. abd install
    5. 3.卸载APP
    6. abd uninstall
    7. 4.打开shell
    8. adb shell
    9. 5.查看日志
    10. adb logcat
    11. 6.上传文件
    12. abd push xxx/data/local/tmp
    13. 7.下载文件
    14. abd pull/data/local/tmp/some_file some_location
    15. 8.将本地端口转发到远程设备端口
    16. abd forward [--no-rebind] LOCAL REMOTE
    17. 9.列出所有的转发端口
    18. abd forward -list
    19. 10.将远程设备的端口转发到本地
    20. abd reverse [--no-rebind] REMOTE LOCAL
    21. 11.列出所有反向端口转发
    22. abd reverse --list
    23. 12.终止ADB server
    24. abd kill-server
    25. 13.启动ADB server
    26. abd start-server
    27. 14.以root权限重启ADB DAEMON
    28. abd root
    29. 15.重启设备
    30. abd reboot
    31. 16.重启并进入bootloader
    32. abd reboot bootloader
    33. 17.重启并进入recovery
    34. abd reboot recovery
    35. 18.将system分区重新挂在为可读写分区
    36. abd remount
    37. 19.通过TCP/IP连接设备(默认5555端口)
    38. abd connect HOST[:PORT]

    四、APK文件格式

    APK文件其实是一个zip压缩文件,使用unzip可以直接解压,例如

    .

    |————AndriodManifest.xml

    |————META-INF

    |————assets

    |————classes.dex

    |————libs

    |————res

    |————resources.arsc

    AndriodManifest.xml是一个APK属性文件,所有的APK都要包含这个文件,这个文件中写明了该APK所有具有的Activity、所需要的函数、启动类是哪一个等信息。打开之后一堆乱码,需要工具去解析。

    META-INF是编译过程中自动生成的一个文件夹,尽量不要手动去修改

    assets文件夹中,存放在这个文件夹里面的文件将会原封不动地打包到APK里,因为这个文件夹里经常会存放一些程序中使用的文件。

    classes.dex是存放Dalvik字节码的DEX文件

    libs文件包含Native层所需要的lib库,一般为libxxx.so格式,libs文件夹中可以包含多个lib文件

    res文件夹存放与资源相关的文件

    resources.arsc文件里存放APK中所使用资源的名字,ID,类型等信息

  • 相关阅读:
    Leetcode刷题112. 路径总和
    vim的配置及基础使用
    JUC LongAdder高性能
    C++知识点大全(第二版)
    四种常用的自动化测试框架
    基于SSM的医院门诊预约挂号系统的设计与
    向优秀的人学习
    知物由学 | Android 模拟点击研究,如何突围“黑灰产”的自动化作弊?
    computed 和 watch的区别
    爬虫基本原理
  • 原文地址:https://blog.csdn.net/qq_60503432/article/details/127539789