8月份课时1

  1. 虚拟机安装
  2. 下载kali-linux:https://github.com/r0ysue/AndroidSecurityStudy/tree/master/FART
  3. wifi adb:https://www.apkmirror.com/apk/metactrl/wifi-adb-debug-over-air/wifi-adb-debug-over-air-3-0-6-release/wifi-adb-debug-over-air-3-0-6-android-apk-download/download/
  4. vmware配置kali-linux

解压
vmware打开解压后的文件
编辑虚拟机-》内存4096,显示器3d加速不选,其他不改
开机-》账号root,密码toor
如果虚拟机时间不对改时区:终端-》dpkg-reconfigure tzdata-》Asia/shanghai-》apt update
显示中文字符(系统不要切换成中文):apt install xfonts-intl-chinese、apt install ttf-wqy-microhei
如果上面的命令执行失败就执行apt update,如果还失败:https://wochinijiamile.blog.csdn.net/article/details/79275944?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_paycolumn_v3&utm_relevant_index=1
分别运行命令安装软件:apt install htop、apt-get install tmux jnettop
apt install neofetch:用来看系统的工具

  1. 软件安装

(1)as:
下载:wget https://redirector.gvt1.com/edgedl/android/studio/ide-zips/4.0.1.0/android-studio-ide-193.6626763-linux.tar.gz
解压:tar -zxvf 文件名
运行:./studio.sh
一路next和finish完成下载
(2) genymotion
https://www.genymotion.com/download/选大的
安装genymotion,安装时不要改genymotion和virtualBox默认安装路径,不然可能启动不了
注册账号
加虚拟机-》搜索5x-》选择8.0
配置其他不变,最后选bridge
模拟器配置:adb shell-》uname -a查看架构,i686代表是x86,arm是手机
有些app是arm会导致模拟器无法安装,要搭arm桥:把压缩包直接拖入模拟器
模拟器wifi有×,root下执行:
settings put global captive_portal_http_url https://www.google.cn/generate_204
settings put global captive_portal_https_url https://www.google.cn/generate_204
settings put global ntp_server 1.hk.pool.ntp.org
reboot重启×消失

8月份课时5

  1. jeb,java反编译工具,根jadx作用差不多

下载地址:http://www.itmop.com/downinfo/214119.html

8月份课时6

apktool下载地址:https://www.jb51.net/softs/644481.html

  1. objection

objection安装:pip3 install objection
objection -g 包名 explore:打开应用,如objection -g com.android.settings explore打开设置
如果运行objection报(Pygments 2.11.2 (d:\python\python3.7\lib\site-packages), Requirement.parse(‘Pygments<=2.11.1,>=1.6’)类似的错误,那就是版本问题,要降objection版本
android hooking list classes:列出所有的类

  1. 内存漫游

获取内存中的对象、调用栈等
env:常用命令,显示包的缓存、主要文件、源app位置
memory list modules:显示当前在内存中的so
memory list exports so名:hook指定so
memory list exports so名 —json c:/Users/hw/Desktop/1.json:把hook结果输出到文件
android hooking list activities:列出所有activity
android intent launch_activity activity名:跳到指定的activity
android hooking watch class 类的全限定类名:hook监视类,可以查看那些方法有没有执行
android hooking search classes 类名:搜索一个类
jobs list:查看监视的对象
jobs kill 对象id:解除监视
android hooking watch class_method 类的全限定类名.方法名 —dump
-args —dump-backtrace —dump-return:监视方法的参数和返回值,并且打印调用栈。java加密常用类java.security.MessageDigest

8月份课时7

  1. 去升级

升级弹窗常用方法:activity、Dialog、PopupWindow
activity:可以直接用activity跳转直接绕过
dialog:Android dialog常用实例https://www.jianshu.com/p/4712652fb313

8月份课时9

安卓常用反爬
代码混淆:把类名、常量、参数变成没有意义的字符串
类动态加载:运行时加载类
云加载:核心逻辑放到服务器上
类动态加载
hook安卓的DexClassLoader

9月份课时1

xpose安装
原版xpose已经停止更新,最高支持安卓7,可使用衍生版本:太极、virtualxpose等
模块安装
GravityBox[N]:调整手机设置

9月份课时2

jeb3.0
smail调试(类似于直接调试程序)
https://down.52pojie.cn/Tools/Android_Tools/
tab:切换代码显示
双击:进入方法
调试:装xdebug插件,手机打开app,jeb调试器-》开始-》选择进程,app必须要支持调试(Manileft下有android:debuggable=”true”)
DDMS动态调试
android studio的sdk安装目录下有monitor.exe
手机运行app-》找到对应的包名-》点上面的dump
Hierarchy View:DDMS旁边的图标点一下出来,可以查看继承关系图
mothod Profiling:查看运行的方法,可以搜关键方法进行定位

9月份课时3

frida
frida-ps -U:查看本机连的手机的进程
frida -U -F:查看前台应用
开发环境搭建
git clone https://github.com/oleavr/frida-agent-example.git
cd frida-agent-example
npm install
用vscode等软件打开工程会有代码提示
npm run watch:监控代码修改自动编译成js文件
frida -U -f com.android.settings —no-pause -l_agent.js

9月份课时4

常用抓包方式
设置代理抓包:手机设置wifi,电脑用fiddler、charles
vpn抓包:有些app会有检测,导致app抓不到包或app无网络,这时要手机配置vpn抓包

9月份课时6

基于hook的抓包
安卓网络请求常用框架:com.android.okhttp、java.net.HttpURLConnection、org.apache.http
用objection来hook网络请求常用框架看调用栈,反编译软件直接定位方法,如果包的子包多用*
混淆
1.app有混淆无法用直接搜索
2.apktool d app名:解包app,如果有加固就不能解
3.搜索被混淆的类,如okhttpclient,可以用工具:https://www.greenxf.com/soft/270951.html
4.找到可疑文件,打开可疑文件找.source就可以看到混淆前的类
网上脚本
git clone https://github.com/siyujie/OkHttpLogger-Frida.git
push文件:adb push okhttpfind.dex /data/local/tmp
赋权
运行脚本:frida -U -l okhttp_poker.js -f 包名 —no-pause

9月份课时7

两种方法:命令行、RPC

  1. 命令行

frida -UF -l js脚本:获取最前台的app并加载脚本
-U:获取usb,-F:获取最前台app,-l:加载脚本

  1. RPC
    1. Java.perform(function(){
    2. console.log('2222222222222222')
    3. })
    1. import frida
    2. # 连接手机
    3. device=frida.get_remote_device()
    4. # 获取最前的app
    5. print(device.get_frontmost_application())
    6. # 获取所有进程
    7. print(device.enumerate_applications())
    8. # 获取pid
    9. pid=device.get_frontmost_application().pid
    10. # 根据pid获取进程
    11. session=device.attach(pid)
    12. with open('hello world\helloworld.js') as f:
    13. script=session.create_script(f.read())
    14. # 执行脚本
    15. script.load()
    ```python import os

import frida, sys

def on_message(message, data): if message[‘type’] == ‘send’: print(“[*] {0}”.format(message[‘payload’])) else: print(message)

jscode = ‘’’ Java.perform(function () { Java.use(‘tencent.go.c’).c.implementation = function() { send(1) var res=this.c() return res; } }); ‘’’

jscode=open(‘./test.js’,encoding=’utf-8’).read()

process = frida.get_remote_device().attach(‘com.example.seccon2015.rock_paper_scissors’)

os.system(“adb forward tcp:27042 tcp:27042”) os.system(“adb forward tcp:27043 tcp:27043”)

session = frida.get_remote_device()

根据包名启动app,用于启动时hook

pid=session.spawn([‘com.wzyk.zgyjb’]) session.resume(pid) session=session.attach(pid)

script = session.create_script(jscode) script.on(‘message’, on_message) print(‘[*] Running CTF’) script.load() sys.stdin.read()

  1. 3. frida两种操作app方式
  2. spawn:应用加载时就hook,有壳就不行<br />attach:运行时hook,有壳也可以
  3. <a name="TUgxi"></a>
  4. ### 9月份课时8
  5. 1. 壳的分类
  6. 一代壳:脱壳之后拿到完整源码<br />二代壳:脱壳后源码不全,比如函数体没有,只有函数名<br />frida-dexdump github:[https://github.com/hluwa/FRIDA-DEXDump](https://github.com/hluwa/FRIDA-DEXDump)<br />脱壳:frida-dexdump -U -f com.app.pkgname
  7. 2. 跳过升级案例
  8. 启动时hook类:objection -g 包名 --startup-command "android hooking watch class 类全限定名"<br />如:objection -g com.wzyk.zgyjb explore --startup-command "android hooking watch class android.view.Window"<br />常用类:android.view.Windowandroid.app.Dialogandroid.widget.PopupWindowandroid.app.AlertDialog<br />如果弹框使用android.app.Dialoghook方法android.app.Dialog.setCancelable查看调用栈,查看调用此方法的方法
  9. <a name="SLKRK"></a>
  10. ### 9月份课时9
  11. 1. frida主动调用
  12. 类静态变量可以直接访问:对象.变量名.value<br />成员变量不能直接访问,需要使用choose
  13. ```javascript
  14. Java.choose("com.wzyk.zgyjb.bean.PageInfo",{
  15. // instance:固定,current_page_num:变量名,value:获取值
  16. onMatch:function(instance){
  17. // 操作执行函数
  18. console.log(instance);
  19. console.log(instance.current_page_num.value);
  20. // 直接修改
  21. instance.current_page_num.value=5
  22. },onComplete:function(){
  23. // 操作完成函数
  24. send("完成")
  25. }
  26. })

调用构造方法创建对象:Java.use(类全限定类名).$new(参数),如Java.use(“java.lang.String”).$new(“2”)
调用静态方法:对象.方法名(参数)
调用普通方法:跟调用成员变量同理,instance.方法名(参数)

  1. nps

内网穿透工具,github:https://github.com/ehang-io/nps

10月份课时1

案例项目:https://github.com/aqi00/android2,模块network
hooking类java.net.URL和它的构造函数
hooking构造函数:java.net.URL.$init

  1. import frida, sys,os
  2. def on_message(message, data):
  3. if message['type'] == 'send':
  4. print("{0}".format(message['payload']))
  5. else:
  6. print(message)
  7. jscode = open('10月份/01.js',encoding="UTF-8").read()
  8. os.system("adb forward tcp:27042 tcp:27042")
  9. os.system("adb forward tcp:27043 tcp:27043")
  10. # 获取最前的app
  11. device=frida.get_remote_device()
  12. # 获取pid
  13. pid=device.get_frontmost_application().pid
  14. # 根据pid获取进程
  15. session=device.attach(pid)
  16. # 加载脚本
  17. script = session.create_script(jscode)
  18. # 打印日志
  19. script.on('message', on_message)
  20. # 执行脚本
  21. script.load()
  22. # 脚本执行完不直接结束
  23. sys.stdin.read()
  1. Java.perform(function(){
  2. var u=Java.use("java.net.URL");
  3. u.$init.overload('java.net.URL', 'java.lang.String').implementation=function(s1,s2){
  4. send(s1)
  5. send(s2)
  6. this.$init(s1,s2);
  7. }
  8. })

Wallbreaker插件:https://www.cnblogs.com/Fightingbirds/p/13995950.html,windows下路径~改成自定义
查看内存中的源码:plugin wallbreaker classdump —fullname 类的全限定类名

10月份课时2

plugin wallbreaker classsearch OkHttp:搜索名字包含OkHttp的类
plugin wallbreaker objectsearch okhttp3.OkHttpClient:根据搜索到的类查看相关类的内存
android hooking watch class okhttp3.OkHttpClient:hook okhttp3框架查看调用栈

11月课时1

创建c++项目报错:Failed to install the following Android SDK pac…
https://www.jianshu.com/p/560bcb5d2034
sdk:java层开发
ndk:c++层开发

  1. JNI

java本地接口,是java调用native一种特性
c++静态绑定:Java全限定类名(用分开)_方法名,如Java_com_lyf.demo_MainActivity_getSignJNI
JNI对应Java数据类型
一般是前面加一个j,jstring-》String
https://blog.csdn.net/chunleixiahe/article/details/51388577
so文件对应cpu
ARMv5-》armeabi,一般是以前32位手机
ARMv7-》armeabi-v7a,一般是以前32位手机
ARMv8-》arm64-v8a,一般是手机
x86-》x86,一般是模拟器
x86_64-》x86_64,一般是模拟器
逆向框架地址:https://pan.baidu.com/s/1dIjN3mCqL3lr7ZjkIjL_ug,提取码ytdj
启动时hook方法:objection -f 包名 explore -s “hook方法的命令”,跟命令行一致
方法静态注册和动态注册
memory list modules:查看所有内存中deso
静态注册:memory list exports so名,直接查看注册的方法
动态注册:无法直接搜索,https://github.com/lasting-yang/frida_hook_libart

11月课时7

getObjClassName(args):输出args的全限定类名
Frida JavaScript 常用 API:https://www.jianshu.com/p/2475cb4532c8

  1. 多classloader的hook

反编译可以找到类,但是用java.use的时候就报错找不到,这是该APP本身有多个classloader
Java.use的类并不在frida的默认的classFactory.loader的classloader里面
解决办法:找到类在哪个classloader,然后把classloader改成默认的

  1. Java.enumerateClassLoaders({
  2. onMatch:function(loader){
  3. try{
  4. // 查找类在哪个classloader
  5. if(loader.findClass('com.wzyk.zgyjb.api.param.ParamFactory')){
  6. console.log('找到loader:'+loader)
  7. // 把对应的classloader设置成默认
  8. Java.classFactory.loader=loader
  9. }
  10. }catch(error){
  11. console.log('error:'+error)
  12. }
  13. },
  14. onComplete:function(loader){
  15. }
  16. })
  17. // 切换后use就可以找到了
  18. Java.use('com.wzyk.zgyjb.api.param.ParamFactory')

11月课时9

  1. frida hook抓包

通杀脚本:https://github.com/r0ysue/r0capture
运行如果出现adb server version (32) doesn’t match this client (41):需要升级版本, https://blog.csdn.net/weixin_38515203/article/details/104985570
Spawn 模式:python r0capture.py -U -f app进程名
Attach 模式:python r0capture.py -U app进程名 -p zhuabao.txt,将抓包结果保存到文件

C语言简单入门

  1. 指针入门

image.png
int p:定义int类型的指针,里面只能存放地址,p=100是错误写法
p=&a:把a的地址给p
p:取出p地址的数据
int p和int p是一样

  1. 指针应用

在逆向中c函数一般不写返回值,一般加密函数是传明文和返回值的地址,然后把加密结果给传入的地址
md5(‘12345678’,接收加密结果的地址),如何根据地址去数据

  1. 指针运算image.png

数组的内存地址是连续的,数组的地址是根据第一个元素的地址
*(p+1):在数组原地址的基础上偏移1,取到第二个元素,如果是int类型就是加4个字节,根据类型占的字节

  1. 字符串

image.png
c语言没有直接的字符串,字符串是一个字符数组

  1. 多极指针

image.png
多级指针:第二个指针指向第一个指针的地址,第三个指针指向第二个指针的地址

  1. 结构体

image.png

  1. 函数指针

image.png

so层逆向网上视频笔记

案例app:川观新闻

  1. 分析

hook发现前两个参数都是空的,第三个参数是时间戳
主动调用发现传入固定时间戳返回值也是固定
可以判断时间戳是和固定字符串进行操作然后返回

  1. so分析

ide打开对应so文件找到getSign
getMD5String:c实现md5加密方法
hook可疑函数MD5Digest

  1. import frida, sys,os
  2. def on_message(message, data):
  3. if message['type'] == 'send':
  4. print("{0}".format(message['payload']))
  5. else:
  6. print(message)
  7. jscode = '''
  8. Java.perform(function () {
  9. // so文件地址,夜神模拟器可能获取不到,谷歌原生模拟器模拟器或真机可以获取到
  10. var soaddress=Module.findBaseAddress('libwtf.so');
  11. // 函数地址,CF0:ide分析的地址
  12. var funaddress=soaddress.add(0xCF0+1);
  13. // 方法2,根据注册名找地址
  14. // var funaddress=Module.findExportByName('libwtf.so','Java_com_sichuanol_cbgc_util_SignManager_getSign');
  15. Interceptor.attach(funaddress,{
  16. // 进函数前执行的方法,args:参数,hexdump:查看16进制数据,每一个16进制数对应一个字符
  17. onEnter:function(args){
  18. console.log('args1'+hexdump(args[1]));
  19. console.log('args1'+args[1].toInt32());
  20. },onLeave:function(retval){
  21. // 函数离开调用方法
  22. console.log('retval'+hexdump(retval[0]));
  23. }
  24. })
  25. })
  26. '''
  27. os.system("adb forward tcp:27042 tcp:27042")
  28. os.system("adb forward tcp:27043 tcp:27043")
  29. # 获取最前的app
  30. device=frida.get_remote_device()
  31. # 获取pid
  32. pid=device.get_frontmost_application().pid
  33. # 根据pid获取进程
  34. session=device.attach(pid)
  35. # 加载脚本
  36. script = session.create_script(jscode)
  37. print('开始')
  38. # 打印日志
  39. script.on('message', on_message)
  40. # 执行脚本
  41. script.load()
  42. # 脚本执行完不直接结束
  43. sys.stdin.read()
  1. ida动态调试

(1)汇编转伪c代码后出现很多如v10+33类似的偏移值或函数显示错乱
选中入参-》y键-》把值改成JNIEnv*,可以显示一些函数出来
工具栏view-》的一个选项-》string:查看so的字符串
(2)
把安装目录下的dbgsrv下的android_server推送到手机里,改名字可以规避一定的检测
赋权-》chmod 777 as-》./as执行
Genymotion模拟器不支持、其他如夜神模拟器会找不到so,调试一般用真机
如果执行报错可能是版本不匹配,更换其他版本的,
(3)端口转发
adb forward tcp:23946 tcp:23946:一般用默认端口23946,app有反调试就要更换
(4)调试配置
新开ida窗口不打开任何文件下-》debugger-》选项2-》Android debugger-》配置ip和端口-》找到包名-》
进入一个全新界面-》找到modules-》点击对应so-》点击函数名就会定位到对应汇编代码
general registers对应:
PC:运行到哪行就指向哪行地址
LR:保存函数返回地址
如果f9无限循环并且出现got SIGTRAP signal (Trace trap) (exc.code 5, tid 12245)类似的错误,说明有检测
(5)断点
右键-》break point
ida动态调试不会把函数名解析出来,需要开两个ida,一个动态调试,一个静态分析
方法1:工具函数前面的关键字数位置,可能是blx或call
方法2:点击可疑sub_Fxxx-》快捷键c可疑看到对应代码
(6)代码查看
hex view-1窗口右键synchronize with,r0-r2分别对应不同参数

so层逆向网上视频笔记2

案例app:喜马拉雅

  1. 程序附加

有时候程序附加找不到对应so,可能是代码执行才加载so,只加载一次,需要做对应操作再附加
附加找到对应函数方法2:
同一so同一平台下的动态调试和静态调试函数偏移是一样的
找到函数选中-》tab转到汇编看地址-》根据地址找到动态调试的函数-》双击可以看函数名-》
快捷的c转成代码
debugger-》step over:下一行代码

调试

  1. 常见反调试

(1)检测文件名,默认名字是android_server
解决办法:改文件名
(2)检测端口号,默认端口号是23946
解决办法:改端口号,./as -p23947
(3)进程名检测,进程Tracerpid不为0说明被调试
解决办法:手动值0
(4)fork一个子进程调试自己,程序只能被一个进程调试
解决办法:直接调试父进程也能达到调试子进程的效果

  1. 查看是否被调试

过滤进程:ps | grep 包名,第二栏就是pid
查看状态:cat /proc/pid(进程ID)/status,TracerPid为0代表没有被调试,不为0代表在被调试

绕过腾讯加固反调试

  1. 解壳程序入口点

AndroidManifest.xml下的application标签的android:name属性

  1. 调试分析

注入后勾选debugger下的debugger setup的library load/unload选项