App攻防技术发展

  随Smali工具(将dex反编译为smali语言的工具)以及baksmali工具(将Smali语言编译为dex二进制文件的工具)出现,Android安全起步。
  Android中的代码是运行在Dalvik或Art虚拟机中的,与ARM汇编类似,Smali语言可以当作Android虚拟机的汇编语言。
  

代码混淆

  如使用Google自带的混淆器ProGuard。ProGuard的作用是更改类名、函数名、变量名。好处就是增加攻击者在破解软件时猜到相应类的实际作用的难度;压缩文件大小。
  在Android中启用ProGuard,只需修改项目根目录下的App/build.gradle文件,将其中的buildTypes层级中的minifyEnable对应的值从false更改为true即可,这样最终编译生成的release版本便会启用代码混淆。

还有一个“代码混淆”工具——DexGuard,功能更丰富,不过它是个收费商业软件。

动态加载

  将需要保护的代码单独编译成一个二进制文件,将其进行加密后保存在一个外部的二进制文件中。在外部程序运行的过程中,再将被保护的二进制文件进行解密并使用ClassLoader类加载器来动态加载和运行被保护的代码。
  Android中每一个Java类都是由ClassLoader类加载器进行加载和运行的。
  由于Android中使用Java编写的App很容易被破解,故将所有的核心代码使用NDK套件(在Android中,NDK实际上是一个工具集,可以让开发者使用C/C++语言实现应用的各个部分)进行开发,结果就是外部的Java代码最终只是充当二进制文件装载器的角色,实际的业务逻辑都被放置在了更难破解的so文件中。甚至有的基于“放置在客户端”不可靠的原则,为了App安全,将重要功能和数据放置到云端,在客户端尽量只进行结果的展示。
  在这些保护手段下,单纯依靠apktool和Jadx这类静态反编译工具对App进行静态分析
已无法满足破解者要求,这时动态分析成为了主流。
  动态分析是通过附加调试或者注入进程来进行的分析。有Android Studio或者Jeb对App的dex进行调试,还有IDA、GDB等Native调试器对so文件进行单步调试,以及Hook和trace,也是动态分析手段。
  基于动态分析,动态加载保护就成了最脆弱的保护方式。只要通过动态分析,不管是在加载后的函数中设置断点以便从内存中dump出来被保护的内容,还是直接搜索进程的内存空间以便根据特征找到真实的dex文件并dump下来,都能应对这种保护方式。另外针对其他静态保护方式,由于动态分析是基于进程所处的运行状态,因此相比于在静态分析时得到的无意义代码而在动态分析时包含的都是真实的数据信息,使得破解者在逆向分析过程中有了很多真实数据,从而削减代码保护的作用。针对动态分析的对抗手段发展。
  在动态分析过程中,首先将调试器附加上进程或者通过注入将指令代码和数据注入目标进程中,然后才能对目标进行调试与内存监控。做到这个,最基本的方法就是调用ptrace()函数对进程进行附加或者基于二次打包的方式对程序进行修改,而对抗分两种:运行时检测和实现阻止。
  调用ptrace()函数对进程进行附加,会存在相应的特征点,比如/proc//status文件中的TracePid变量在进程被附加后,会由0变为附加进程的pid。如果此时代码本身单开一个线程对这个文件的TracePid值进行循环检测,检测到异常时就会自动退出进程,就可以做到阻止进程被破解者调试。
  App逆向分析过程中最难绕过的保护手段就是App加固。其逻辑和上面的动态加载类似,用加固厂商的壳程序包裹真实的App,在真实动态运行时再通过壳程序执行释放出来的真正App。App加固按照不同阶段加固特性重新分为三个不同阶段。
  第一阶段被认为是DEX整体加固,这是App加固初期。核心原理是将DEX整体加密后动态加载,刚开始App整体加固是需要先解密文件并在解密完成后写入到另外一个文件中,在解密完毕后调用DexClassLoader或者其他类加载器来加载解密后的文件。后来由于文件操作过于明显,进一步发展出将加密的DEX在内存中解密并直接在内存中进行加载的加固技术,这一阶段的加固技术没有明显写文件操作但同样无法阻止动态分析。后来为了防止根据特征进行内存搜索的方式,还出现了加载后抹去DEX文件头的手段,但都无法阻止设置断点和Hook的动态分析手段。DEX整体加固的致命之处在于,代码数据总是完整地存储在一段内存中,一旦反注入、反调试等措施被破解,保护就会门户洞开。
  第二阶段习惯上称为代码抽取保护。这一阶段App加固的关键在于真正的代码数据并不与DEX的整体结构数据存储在一起,就算DEX被完整地从内存中dump(转储)出来,也无法看到真正的函数代码。这种加固的核心原理是利用私有函数,通过对自身进程的Hook来拦截函数被调用时的路径,在抽取的函数被真实调用前,将无意义的代码数据填充到对应的代码区中。
  第三阶段加壳保护,将所有的Java代码变成最终的Native层代码。VMP与Dex2C。VMP加固技术最早起源于PC的虚拟机加固,其核心逻辑是将所有的代码使用自定义的解释器执行。代码不依赖于系统本身,即使获得所有的函数内容,也貌合神离,不知所云。这时唯一的解决方案可能是逆向对应解释器,找到与系统解释器的映射关系。Dex2C技术则是通过编译原理相关知识将原本的Java代码转化为native层代码,因为native层的二进制编码相比Java字节码更不容易被逆向。但实际上,具有C/C++ni’xai’g’n层的二进制编码相比Java字节码更不容易被逆向。但实际上,具有C/C++逆向经验的逆向开发和分析人员还是可以完成的。

字符串方法

str.zfill(width)

  • str是我们要操作的字符串,如果是整形浮点型等数字类型,要先通过str()转换为字符串再进行操作
  • width是补零之后的字符串长度,如果补零后的长度小于或等于原字符串的长度,那么字符串将不会产生任何的变化

示例

1
2
3
4
a = 'zfill'
print(a.zfill(10))
>>>
00000zfill
1
2
3
4
a = 'zfill'
print(a.zfill(3))
>>>
zfill

urllib

urllib.parse

urllib.parse.quote(“需要编码的字符串”)

  urllib.parse.quote() 是 Python 中用于对 URL 进行编码的函数,它可以将 URL 中的特殊字符转换为符合 URL 规范的编码形式,以便在网络传输或存储时使用。
  这个函数在处理 URL 中的特殊字符时非常有用,例如空格、斜杠、问号等。在需要将字符串作为 URL 参数发送时,通常需要使用该函数对参数进行编码,以确保 URL 的正确性和完整性。

1
2
3
4
5
6
7
8
url = "https://www.example.com/search?q="
enurl=urllib.parse.quote(url)
print(enurl)
deurl = urllib.parse.unquote(enurl)
print(deurl)
>>>
https%3A//www.example.com/search%3Fq%3D
https://www.example.com/search?q=

random

random.getrandbits(k)

这个函数用于生成一个k位的随机整数,生成的随机数介于0和2^k(不包含)之间,如果k不是0到getrandbits.max_size(包含)之间,那么将引发一个ValueError异常。
示例

1
2
3
4
5
6
7
import random

# 生成一个 5 位的随机整数
rand_int = random.getrandbits(5)
print(rand_int)
>>>
26 //0~32

函数的定义

1
2
3
def 函数名(参数):
函数体
return 返回值

注意事项:

  • 参数如果不需要,可以省略
  • 返回值如果不需要,可以省略
  • 函数必须先定义,后使用
阅读全文 »

布尔类型

布尔类型的字面量:

  • True 表示真
  • False 表示假
    定义变量存储布尔类型数据
    变量名称 = 布尔类型字面量(或返回值是布尔类型的表达式)
阅读全文 »

定位:Objection辅助定位

  Objection在逆向过程中最强大的功能是从海量的代码中定位关键的程序逻辑。Frida需要每次手动编写代码取Hook静态分析的函数,进而观察其参数和返回值是否与需求相符。,Objection将常用的一些功能集成在一起,使得逆向开发和分析人员在分析过程中不需要浪费精力在编写代码上。

阅读全文 »

apk位置在https://github.com/r0ysue/AndroidFridaBeginnersBook/tree/main/Chap04
注意:这里一定要把apk安装在模拟器上!这里一定要把apk安装在模拟器上!这里一定要把apk安装在模拟器上!

阅读全文 »

验证adb是否安装成功

adb helpadb --help

常用简单命令

命令 说明
adb version 查看adb版本
adb devices 获取设备列表和设备的状态
adb shell 进入设备的shell环境
adb -s xxx(序列号) shell 指定要进入的设备的shell环境

安装卸载软件

命令 说明
adb install apk文件路径 apk是安卓应用程序的安装包
adb install [-r] apk文件路径 -r 表示覆盖安装,保留缓存和数据处理
adb uninstall apk包名 包名是com.xxxx.xxx格式
adb push local remote 将文件从计算机复制到连接的 Android 设备
adb pull remote local 将文件从 Android 设备复制到计算机
local和remote local:计算机上的文件或目录的路径,remote:Android设备上的目的地路径。
adb shell pm list packages 列出设备中所有的App包名
adb shell pm list package -s 列出设备中系统应用所有的App包名
adb shell pm list packages -3 列出第三方应用
adb shell pm list packages -i 列出仅用户安装的应用(包括第三方应用和用户安装的系统应用)
adb shell pm list packages -f 列出所有已安装的应用程序的详细信息(包名,路径)

pm: 包管理器命令行工具,用于管理应用包。

其他命令

命令 说明
adb shell ps 查看设备所有进程,可以过滤
adb get-serialno 获取手机序列号
adb shell getprop ro.serialno 同上
adb shell getprop ro.product.cpu.abi 查看系统架构
adb shell df 获取手机存储信息
adb shell date 查看系统时间
adb logcat 查看日志,可以过滤
adb forward tcp:port tcp:port 端口转发

从手机端截图发送到电脑端

1
2
3
4
5
6
7
8
//使用以下命令截屏操作并将截图保存在手机的SD卡或内部存储中
adb shell /system/bin/screencap -p /sdcard/screenshot.png

//确认截图操作成功后,使用以下命令将截图文件从手机拉取到电脑上的指定位置:
adb pull /sdcard/screenshot.png .

//使用以下命令将手机上的截图删除以节省空间
adb shell rm /sdcard/screenshot.png