安卓逆向_安卓逆向学习路线 - CSDN
精华内容
参与话题
  • 此篇整理了最完整的《Android逆向学习线路知识体系》。希望给迷糊的入门者指出一个明确的方向。 关于Android逆向、破解、脱壳、反逆向、反破解 等知识,网上没有完整的资料,也没有相关的课程。 完整的知识体系和...

    此篇整理了最完整的《Android逆向学习线路知识体系》。希望给迷糊的入门者指出一个明确的方向。

    关于Android逆向、破解、脱壳、反逆向、反破解 等知识,网上没有完整的资料,也没有相关的课程。

    完整的知识体系和学习大纲,都是过来人总结的经验,逆向方面没人总结,今天我来总结一下完整的知识体系框架。

    讲一下关于Android安全工程师需要具备的能力,以及想要从事Android逆向开发应该如何着手学习。

    最近我发现一些通过培训班出来面试的,纯粹的骗子,连Android工程都不会创建,有几个还没听说过RecyclerView。

    搞逆向的,你连正向开发都不会,工程源码你都看不懂,你还逆向个啥?先正向开发几年再去搞逆向吧……

    学习Android逆向之前,必备条件。【必备】

    1. 从事3-5年真实的Android开发工作,能够跟踪了解最新Android开发技术;
    2. 熟悉Android NDK开发和JNI技术,熟悉Log原理。有FrameWork开发经验;
    3. 熟悉Android虚拟机机制,打包原理,熟练使用C/C++,Java,kotlin,dart等Android开发常用语言;
    4. 了解ARM、Smali汇编语言,熟悉IPC原理,能够熟练搭建IPC框架;
    5. 熟悉Android/Linux底层框架,熟悉系统的工作原理和细节;
    6. 熟练使用Fiddler和Charles抓包工具进行抓包;
    7. 熟悉Python基础语法,并能写简单的脚本和爬虫。

    赠送源码:https://github.com/yugu88/MagicWX

    《最完整的Android逆向知识体系》-- by hao_qi 2019/10/20 


    第一阶段:

    Android 基础知识回顾:

    • 回顾Android 开发编程,深入理解Android系统原理和层次结构,深入分析Handler源码和原理;
    • 回顾Java,C/C++,Kotlin 在Android开发中必用的语言,了解几种语言的混淆后的特性;
    • 回顾Android IPC和JNI的底层原理和热更新技术
    • 回顾Native开发要点,使用C++结合NDK完成Android Native开发;
    • 回顾Android开发中常用的 AMS、PMS、WMS原理;
    • 回顾Android开发中 Google的MVVM框架:DataBinding+LiveData+ViewModel;
    • 回顾Android开发中 Google的MVP框架:Dagger2;
    • 回顾Android开发网络架构:Okhttp3+RxJava2+Retrofit2+Rxdownload4+Rxcache+Glide;

    Android 逆向基础知识:

    • 熟悉Android逆向工具的使用,如apktool,IDA,dex2jar,JEB,AndroidKiller,Androguard等;
    • 深入分析APK中包含的各文件格式,分析Android系统源码中解析APK的相关代码;
    • 学习和熟悉smali语言(重点);
    • 仿微信写一个APP,并利用工具逆向出apk内的代码,并对比源码分析。

    入门知识总结和实战(逆向入门):

    • 知识梳理,常用工具安装,adb命令与Linux常用命令,常见登录逻辑分析;
    • 分析ELF可执行程序,调式ELF可执行程序;
    • ARM汇编与寄存器,ARM反汇编速成,ARM指令机器码,常用ARM指令集;
    • 反编译ELF文件与ObjDump,ELF文件解析与readelf,ELF文件解析与010Editor,深入分析ELF文件结构;
    • IDA静态分析,IDA动态调式;
    • 简易计算器实现及分析(练习);
    • 字符串加密与解密,冒泡排序算法分析;
    • 关键android_server文件检测,IDA调试端口检测;
    • ELF可执行程序加载so库,DEX解析与dexDump,DEX解析与010Editor;
    • 实现自己的Dex解析工具与GDA(练习);
    • Androidkiller动态调试smali代码插件,AS+smalidea调式smali代码;
    • Log注入实现免注册,如何定位关键代码,去除java层签名验证,去除广告和弹窗(实战);
    • 推荐阅读《Android系统源代码情景分析》;

    Android 基础算法和安全协议:

    • 密码学,对称加密算法,非对称加密算法,散列函数;
    • 数字签名,数字证书,SSL证书检测,协议与安全协议;
    • 了解服务器端与客户端通信协议分析;
    • 使用Charles抓登录封包和验证码,协议构造与Java层MD5算法,动态调式smali代码与sign字段;
    • 协议构造类与SO层DESCBC算法,协议关键字段SIGN与SO层MD5算法,动态调试协议字段,动态调式协议关键字段SIGN;
    • 协议关键字段pwad和sign,动态调式协议字段拼接与MD5加密,分析so层OpenSSLSHA1算法;
    • 封包加密与反编译失败,使用方法跟踪分析加密;
    • java层逆向分析,分析so层TEA算法;
    • 练习:抓取验证码和登录封包,分析协议关键字段与RSA算法,证书与RSA原理及源码分析;
    • 对称加密AES、PBE与CRC算法,数字签名RSA、DSA算法;

    第二阶段:

    Android 逆向进阶学习:

    • Android 系统结构深入分析,自定义 ClassLoader,自定义注解和元注解原理分析;
    • 了解AndroidNDK,静态注册,动态注册,SO加载分析,App保护策略
    • 去除霸哥磁力搜素APK签名验证,一键去除签名验证,静态代理,动态代理
    • Hook Activity启动函数,Hook签名验证函数
    • 介绍xposed框架:
    • Xposed框架:绕过验证码注册
    • Xposed框架:登陆劫持
    • Xposed框架:篡改IMEI信息
    • 介绍CydiaSubstrate框架:
    • Java层Hook:篡改系统文字颜色
    • Java层Hook:修改方法返回值绕过登录
    • Java层Hook:篡改游戏金币
    • Java层Hook:篡改主机名和端口号
    • Native层Hook:
    • ADBI框架:
    • ELFARMHOOK框架
    • 内存抠取Dex文件
    • 过反调试技巧
    • C++游戏逆向
    • 练习:动态调试2048纯算法游戏,Zygote+Hook使2048游戏秒过关;

    Android NDK与JNI全面剖析:

    • so动态库的介绍
    • JNI动态注册和静态注册
    • NDK Build 工具介绍
    • Cmake工具介绍
    • JNI.h 介绍
    • Android 源码工具和技巧
    • ijkplayer 源码分析及原理讲解
    • AndFix 源码分析及原理讲解
    • Java调用so库的动态流程解析
    • NDK实现增量更新案例
    • NDK实现换脸等工业级图像识别案例
    • NDK文件实现拆分和加密处理

    Android 加固防护和脱壳简介:

    • DEX文件、ODEX文件与OAT文件;
    • XML文件与ARSC文件;
    • 分析App加固的产生及背景,最初加固方式,加固技术的发展;
    • HOOK制作脱壳机,定制自己的脱壳系统;
    • DexClassLoader动态加载分析,DEX自解析重构技术;
    • 三代梆梆加固原理分析;
    • 爱加密加固原理分析;
    • 360加固与脱壳机,360加固VM与置换表;
    • 辅助脱壳机,IDA动态调式脱爱加密壳;
    • IDA动态调式脱360壳,IDA动态调式脱SO壳;
    • 脱360壳-dex2oat,脱360壳-drizzleDumper;
    • 百度加固DD大法,百度加固VM与置换表;
    • 阿里加固与脱壳机,腾讯乐固;
    • ARSC资源保护与注解;
    • 脱壳神器ZjDroid:捕鱼达3
    • 加固技术总结;

    Android 脱壳与反脱壳分析:

    • Android脱壳中的思路,技巧
    • elf结构详解:动态运行库so文件的文件组成结构
    • elf结构详解:加载so文件的流程
    • elf文件变形与保护,elf文件修复分析,so加壳文件修复
    • 常用调试检测方法与过检测方法
    • Android源码定制添加反反调试机制
    • Android dvm 脱壳,Dalvik dex处理分析
    • IDA脱壳脚本编写,Odex修复方法,IDAOdex修复脚本编写

    进阶知识总结和企业级实战(逆向进阶):

    • 病毒分析与脱壳学习,用Ransomware类和木马类进行学习;
    • 手动脱壳《王者荣耀》练习;
    • 从0开始打造自己的破解代码库;

    第三阶段:

    Android 漏洞分析和挖掘:

    • 学习常见的漏洞类型和原理。例如堆溢出,栈溢出,UAF等,可以参考漏洞分析相关书籍;
    • 关注Android Security Bulletin,根据提供的diff分析漏洞成因;
    • 学习并调试以前的经典漏洞;
    • 学习漏洞挖掘fuzzing思路,参考书籍推荐《Android安全攻防权威指南》;
    • 病毒分析与病毒脱壳实战;

    Android 虚拟机技术、系统源码分析、刷机机制介绍、制作ROM刷机包:

    • ASP代码注入式写法;
    • Android 免root进行hook;
    • Android虚拟机原理,Android多开原理讲解;
    • 在apk内部写一个虚拟机,在apk内安装apk;虚拟机适配Android 10和64位系统;
    • 从0开始开发自己的虚拟机库;
    • 最完善的刷机工具 :魔趣 ROM:www.mokeedev.com
    • 最完善的刷机工具 :Devices - TWRP:https://twrp.me/Devices/
    • 略…………

    大型企业级项目讲解(五个项目):

    • ……

    第四阶段:

    ………………



     

     

     

    展开全文
  • Android逆向系列(一):初探Android逆向

    万次阅读 多人点赞 2019-04-16 11:00:32
    谨此以本文开始记录我的Android逆向之旅吧。 总述 习惯于应用层开发的我们都知道,在应用上架的时候都需要程序经过编译、签名 、生成一个后缀为apk的文件才能发布到应用市场,而我认识的逆向就从这个ap...

    这段时间因为某些业务驱动,开始研究一些逆向相关的东西,浏览了下其所包含的大致内容,发现真是一个新大陆,跟之前耳听目染过的一些门面介绍完全不是一个层级的,真正的印证了下手难这一说法。

        谨此以本文开始记录我的Android逆向之旅吧。
    

    总述

    习惯于应用层开发的我们都知道,在应用上架的时候都需要程序经过编译、签名 、生成一个后缀为apk的文件才能发布到应用市场,而我认识的逆向就从这个apk开始(逆向分为多种逆向,为了避免混淆概念这里的逆向暂且就特指apk的逆向)。

    工具准备

    工欲善其身,必先利其器。这句话放到逆向对工具的描述上来说再适合不过。
    这里写图片描述

    反编译代码的工具下载:

    反编译资源的工具:

    • APKTool: 本文重要工具,APK逆向工具,使用简单下载地址: http://ibotpeaches.github.io/Apktool/install/
      这里简单介绍下大概流程,首先把后缀为.apk的文件改为.zip的一个压缩文件,方便解压。dex2jar和jd-gui配套使用,用于逆向代码部分,APKTool用于逆向res文件夹下的图片布局等部分。
      .apk 修改成.zip文件解压后的目录树长这样:
      这里写图片描述
      这里也贴上源码,很简单就一个输入框和一个按钮,输入框内输入“2018”点击按钮即可跳转到另外一个界面,否则提示一个Toast “验证码错误!”,而我们要做的就是突破这个“2018”,绕过验证。
      这里写图片描述

    反编译代码部分

    需要用到的是dex2jar包里面的三个文件(当前是在windows环境下,Mac环境用对应的.sh文件):

    • d2j_invoke.bat
    • d2j-dex2jar.bat
    • lib
      将这三个文件复制到一个空的文件夹内,将刚才.apk解压后的classes.dex文件也一起复制到这里。如图:
      这里写图片描述
      Windows cmd到这个文件夹下 输入:d2j-dex2jar.bat classes.dex
      Mac 到这个文件夹下 输入:sh d2j-dex2jar.sh classes.dex
      如此之后在这个目录里会生成一个classes-dex2jar.jar文件。如图:
      这里写图片描述
      这个时候就轮到JD-GUI工具出手了,运行jd-gui.exe File–OpenFile–classes-dex2jar.jar 打开刚才生成的jar文件。就能很清晰的看到我们想要的代码了,如图。
      这里写图片描述
      对照上面发过的主要代码,已经差不离十了,对于想要代码思路的我们来说,到这里已经基本可以摸透他的逻辑了。

    反编译res资源部分

    apktool下载后会有两个文件,一个.jar(例如apktool_2.3.3.jar 需要把名字改成apktool.jar) 一个apktool.bat 。(这两个文件在这里下载,如图:)
    这里写图片描述
    同刚才一样在cmd命令下进入刚才文件夹(同样可以新建一个),连同我们刚才那个后缀为apk的安装包一起放入,输入如下命令:

    apktool d app-release.apk   此处app-release为apk名称
    

    得到一个新的app-release(对应apk名称)文件夹。流程如图:
    这里写图片描述
    这里写图片描述
    这个app-release文件夹下会得到若干文件,主要内容介绍如下:

    • AndroidManifest.xml:描述文件
    • res:资源文件
    • smail:反编译出来的所有代码,语法与java不同,类似汇编,是Android虚拟机所使用的寄存器语言

    到此我们想要的都有了。下一步就是实现我们想法的时候了。

    修改原代码逻辑

    在刚才的JD-GUI中可以看到跳转的逻辑判断如下:

     public void onClick(View paramAnonymousView)
          {
            if (MainActivity.this.code.getText().toString().trim().equals("2018"))
            {
              paramAnonymousView = new Intent(MainActivity.this, SuccessActivity.class);
              MainActivity.this.startActivity(paramAnonymousView);
              return;
            }
            Toast.makeText(MainActivity.this, "验证码错误!", 0).show();
          }
    

    我们只需要修改if后面的判断条件,设置为否即可if (!MainActivity.this.code.…),这样就成功绕过了条件约束。

    Δ 接下来还有一部很重要那就是修改smali文件,找到MainActivity$1.smali这个文件用代码查看工具打开,如图:

    这里写图片描述
    找到这个if-eqz 修改成if-nez (nez对应为非,符号“!”),到这里要修改的部分都成功了,最后一步要做的就是重新打包了。当然对smali语法感兴趣的可以到我群里索取免费的pdf资料(415974495),大家可以一起探讨学习一下。

    重新打包

    在apktool文件夹路径的cmd下输入:

    apktool b [文件夹] -o test2.apk   (test2为新apk名称,[文件夹]为对应的有修改需要打包的文件夹)
    例如:我当前就可以这样写  apktool b [F:\tools\apktool\app-release] -o test2.apk
    

    这里写图片描述
    至此,我们的目标apk文件已经生成,当然如果你想装到你自己手机上还需要重新签名一下。

    重新签名

    首先我们需要一个用于签名的.keystore文件,生成命令如下(这里我们假设生成的是demo.keystore)。

    keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore
    (cmd到apktool文件夹下跟待签名的apk放同个文件夹内便于操作)
    

    这里我们利用Java JDK提供的一个jarsigner进行签名,在刚才的cmd下继续操作,输入:

    jarsigner -verbose -keystore demo.keystore test2.apk demo.keystore
    

    这里写图片描述
    以上。我们目的apk已经可以投入使用,如果需要更快更好的体验还需要进行一次字节对齐的操作(后续分析)。

    展开全文
  • 吾爱破解安卓逆向入门教程

    万次阅读 多人点赞 2017-03-18 11:56:56
    一、环境配置安装 java jdk,并设置好环境变量。测试: java -version二、初识 APK、Dalvik字节码以及Smali1. apk是什么?apk实质上是一个zip压缩包,将apk后缀修改为zip,解压之后可以看到其内部结构:2....

    来源:吾爱破解安卓逆向入门教程(1-5)笔记

    作者:加菲猫

    一、环境配置

    安装 java jdk,并设置好环境变量。

    测试: java -version

    二、初识 APK、Dalvik字节码以及Smali

    1. apk是什么?

    apk实质上是一个zip压缩包,将apk后缀修改为zip,解压之后可以看到其内部结构:

    2. apk 的组成

    assets: 资源目录1,assets 和 res 都是资源目录但有所区别:

    res 目录下的资源文件在编译时会自动生成索引文件(R.java),在Java代码中勇R.xxx.yyy来引用;而asset 目录下的资源文件不需要生成索引,在Java 代码中需要用AssetManager来访问;

    一般来说,除了音频和视频资源(需要放在raw或asset下),使用Java开发的Android工程使用到的资源文件都会放在res下;使用C++游戏引擎(或使用 Lua Unity3D等)的资源文件均需要放在 assets 下。

    lib: so 库存放位置,一般由NDK编译得到,常见于使用游戏引擎或 JNI native调用的工程中

    META-INF: 存放工程一些属性文件,例如 Manifest.MF

    res: 资源目录2,

    AndroidManifest.xml: Android工程的基础配置属性文件

    classes.dex: Java代码编译得到的 Dalvik VM 能直接执行的文件

    resources.arsc: 对res 目录下的资源的一个索引文件,保存了原工程中 strings.xml等文件内容

    其他文件夹等

    3. Dalvik字节码(学习破解的基础)

    • Dalvik 是 google 专门为 Android 操作系统设计的一个虚拟机,经过深度优化。虽然 Android 上的程序是使用 java 来开发的,但是 Dalvik 和标准的 java 虚拟机 JVM 还是两回事。Dalvik VM 是基于寄存器的,而 JVM 是基于栈的;Dalvik有专属的文件执行格式 dex (dalvik executable),而 JVM 则执行的是 java 字节码。Dalvik VM 比 JVM 速度更快,占用空间更少。

    • 通过 Dalvik 的字节码我们不能直接看到原来的逻辑代码,这时需要借助如 Apktool 或 dex2jar+jd-gui 工具来帮助查看。但是,我们最终修改 APK 需要操作的文件是 .smali 文件,而不是导出来的 Java 文件重新编译。

    4. Smali(破解的重中之重)

    • Smali,Baksmali 分别是指安卓系统里的 Java 虚拟机(Dalvik)所使用的一种 dex 格式文件的汇编器,反汇编器。其语法是一种宽松式的 Jasmin/dedexer 语法,而且它实现了 .dex 格式所有功能(注解,调试信息,线路信息等)

    • 当我们对 APK 文件进行反编译后,便会生成此类文件。在Davlik字节码中,寄存器都是32位的,能够支持任何类型,64位类型(Long/Double)用2个寄存器表示;Dalvik字节码有两种类型:原始类型;引用类型(包括对象和数组)

    • 原始类型:

    • B—byte
    • C—char
    • D—double
    • F—float
    • I—int
    • J—long
    • S—short
    • V—void
    • Z—boolean
    • [XXX—array
    • Lxxx/yyy—object

    这里解析下最后两项,数组的表示方式是:在基本类型前加上前中括号“[”,例如 int 数组和 float 数组分别表示为:[I、[F;对象的表示则以 L 作为开头,格式是 LpackageName/objectName;(注意必须有个分号跟在最后),例如 String 对象在 smali 中为:Ljava/lang/String;,其中 java/lang 对应 java.lang 包,String 就是定义在该包中的一个对象。

    或许有人问,既然类是用 LpackageName/objectName; 来表示,那类里面的内部类又如何在 smali 中引用呢?答案是:LpackageName/objectNamesubObjectName;”符号,关于“$”符号更多的规则将在后面谈到.

    • 方法的定义

    Func-Name (Para-Type1Para-Type2Para-Type3…)Return-Type

    注意参数与参数之间没有任何分隔符,举例如下:

    hello ()V

    没错,这就是void hello()。

    hello (III)Z

    这个则是boolean hello(int, int, int)。

    hello (Z[I[ILjava/lang/String;J)Ljava/lang/String;

    看出来这是String hello (boolean, int[], int[], String, long) 了吗?

    • Smali基本语法
    • .field private isFlag:z  定义变量
    • .method  方法
    • .parameter  方法参数
    • .prologue  方法开始
    • .line 123  此方法位于第123行
    • invoke-super  调用父函数
    • const/high16 v0, 0x7fo3  把0x7fo3赋值给v0
    • invoke-direct  调用函数
    • return-void  函数返回void
    • .end method  函数结束
    • new-instance  创建实例
    • iput-object  对象赋值
    • iget-object  调用对象
    • invoke-static  调用静态函数
    • 条件跳转分支
     "if-eq vA, vB, :cond_**"   如果vA等于vB则跳转到:cond_**
     "if-ne vA, vB, :cond_**"   如果vA不等于vB则跳转到:cond_**
     "if-lt vA, vB, :cond_**"   如果vA小于vB则跳转到:cond_**
     "if-ge vA, vB, :cond_**"   如果vA大于等于vB则跳转到:cond_**
     "if-gt vA, vB, :cond_**"   如果vA大于vB则跳转到:cond_**
     "if-le vA, vB, :cond_**"   如果vA小于等于vB则跳转到:cond_**
     "if-eqz vA, :cond_**"      如果vA等于0则跳转到:cond_**
     "if-nez vA, :cond_**"      如果vA不等于0则跳转到:cond_**
     "if-ltz vA, :cond_**"      如果vA小于0则跳转到:cond_**
     "if-gez vA, :cond_**"      如果vA大于等于0则跳转到:cond_**
     "if-gtz vA, :cond_**"      如果vA大于0则跳转到:cond_**
     "if-lez vA, :cond_**"      如果vA小于等于0则跳转到:cond_**

    三、深入 Smali 文件

    1. Smali中的包信息

    • .class public Lcom/aaaaa; (它是com.aaaaa这个package下的一个类)
    • .super Lcom/bbbbb; (继承自com.bbbbb这个类)
    • .source “ccccc.java” (一个由ccccc.java编译得到的smali文件)

    2. Smali中的声明

    一般来说,在Smali文件中声明如下:

    # annotations
    
    .annotation system Ldalvik/annotation/MemberClasses;
    value = {
    Lcom/aaa$qqq;,
    Lcom/aaa$www;
    }
    .end annotation
    
    //这个声明是内部类的声明:aaa这个类它有两个成员内部类——qqq和www,内部类将在后面小节中会有提及。

    3. 关于寄存器的知识补充

    • 寄存器是什么意思呢?在 smali 里的所有操作都必须经过寄存器来进行:本地寄存器用 v 开头,数字结尾的符号来表示,如v0、v1、v2、…参数寄存器则使用 p 开头,数字结尾的符号来表示,如p0、p1、p2、…特别注意的是,p0 不一定是函数中的第一个参数,在非 static 函数中,p0 代指“this”,p1 表示函数的第一个参数,p2 代表函数中的第二个参数…而在 static 函数中 p0 才对应第一个参数(因为 Java 的 static 方法中没有 this 方法。

    4. 寄存器简单实例分析

    const/4 v0, 0x1
    iput-boolean v0, p0, Lcom/aaa;->IsRegistered:Z
    • 我们来分析一下上面的两句 smali 代码,首先它使用了 v0 本地寄存器,并把值 0x1 存到 v0 中,然后第二句用 iput-boolean 这个指令把 v0 中的值存放到 com.aaa.IsRegistered 这个成员变量中。
    • 即相当于:this.IsRegistered= true;(上面说过,在非static函数中p0代表的是“this”,在这里就是 com.aaa 实例)。

    5. Smali中的成员变量

    • 成员变量格式是:.field public/private [static] [final] varName:<类型>。

    • 对于不同的成员变量也有不同的指令。

    • 一般来说,获取的指令有:iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等。

    • 操作的指令有:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等。

    • 没有“-object”后缀的表示操作的成员变量对象是基本数据类型,带“-object”表示操作的成员变量是对象类型,特别地,boolean 类型则使用带“-boolean”的指令操作。

    6. Smali成员变量指令简析

    (1) 简析一

    sget-object v0, Lcom/aaa;->ID:Ljava/lang/String;
    • sget-object就是用来获取变量值并保存到紧接着的参数的寄存器中,本例中,它获取ID这个String类型的成员变量并放到v0这个寄存器中。

    • 注意:前面需要该变量所属的类的类型,后面需要加一个冒号和该成员变量的类型,中间是“->”表示所属关系。

    (2) 简析二

    iget-object v0, p0, Lcom/aaa;->view:Lcom/aaa/view;
    • 可以看到iget-object指令比sget-object多了一个参数,就是该变量所在类的实例,在这里就是p0即“this”。

    • 获取array的话我们用aget和aget-object,指令使用和上述一致

    (3) 简析三(put指令的使用和get指令是统一的)

    const/4 v3, 0x0
    sput-object v3, Lcom/aaa;->timer:Lcom/aaa/timer;
    • 相当于:this.timer= null;

    • 注意,这里因为是赋值object 所以是null,若是boolean的话,大家想应该相当于什么呢?

    (4) 简析四

    .local v0, args:Landroid/os/Message;
    const/4 v1, 0x12
    iput v1, v0, Landroid/os/Message;->what:I
    • 相当于:args.what = 18;(args 是 Message 的实例)

    四、Smali函数分析

    1. Smali中函数的调用

    • smali中的函数和成员变量一样也分为两种类型,分别为direct和virtual之分。那么direct method和virtual method有什么区别呢?

    • 简单来说,direct method 就是 private 函数,其余的 public 和 protected 函数都属于 virtual method。所以在调用函数时,有invoke-direct,invoke-virtual,另外还有invoke-static、invoke-super以及invoke-interface等几种不同的指令。当然其实还有invoke-XXX/range 指令的,这是参数多于4个的时候调用的指令,比较少见,了解下即可。

    • (1).invoke-static:用于调用static函数,例如:

    invoke-static {}, Lcom/aaa;->CheckSignature()Z 

    这里注意到 invoke-static 后面有一对大括号“{}”,其实是调用该方法的实例+参数列表,由于这个方法既不需参数也是static的,所以{}内为空,再看一个:

    const-string v0, "NDKLIB"  
    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

    这个是调用 static void System.loadLibrary(String) 来加载 NDK 编译的 so 库用的方法,同样也是这里 v0 就是参数”NDKLIB”了。

    • (2).invoke-super:调用父类方法用的指令,一般用于调用onCreate、onDestroy等方法。

    • (3).invoke-direct:调用private函数:

    invoke-direct {p0}, Landroid/app/TabActivity;-><init>()V

    这里init()就是定义在TabActivity中的一个private函数

    • (4).invoke-virtual:用于调用 protected 或 public 函数,同样注意修改smali时不要错用 invoke-direct 或 invoke-static:
    sget-object v0, Lcom/dddd;->bbb:Lcom/ccc;
    invoke-virtual {v0, v1}, Lcom/ccc;->Messages(Ljava/lang/Object;)V

    这里相信大家都已经很清楚了:

    v0是bbb:Lcom/ccc

    v1是传递给Messages方法的Ljava/lang/Object参数。

    • (5).invoke-xxxxx/range:当方法的参数多于5个时(含5个),不能直接使用以上的指令,而是在后面加上“/range”,range表示范围,使用方法也有所不同:
    invoke-direct/range {v0 .. v5}, Lcmb/pb/ui/PBContainerActivity;->h(ILjava/lang/CharSequence;Ljava/lang/String;Landroid/content/Intent;I)Z

    需要传递v0到v5一共6个参数,这时候大括号内的参数采用省略形式,且需要连续。

    2. Smali中函数返回结果操作

    • 在Java代码中调用函数和返回函数结果可以用一条语句完成,而在Smali里则需要分开来完成,在使用上述指令后,如果调用的函数返回非void,那么还需要用到move-result(返回基本数据类型)和move-result-object(返回对象)指令:
    const-string v0, "Eric"
    invoke-static {v0}, Lcmb/pbi;->t(Ljava/lang/String;)Ljava/lang/String;
    move-result-object v2

    v2保存的就是调用t方法返回的String字符串。

    3. Smali中函数实体分析–if函数分析

    • .method private ifRegistered()Z
    • .locals 2 //在这个函数中本地寄存器的个数
    • .prologue
    • const/4 v0, 0x1 // v0赋值为1
    • .local v0, tempFlag:Z
    • if-eqz v0, :cond_0 // 判断v0是否等于0,等于0则跳到cond_0执行
    • const/4 v1, 0x1 // 符合条件分支
    • :goto_0 //标签
    • return v1 //返回v1的值
    • :cond_0 //标签
    • const/4 v1, 0x0 // cond_0分支
    • goto :goto_0 //跳到goto_0执行 即返回v1的值 这里可以改成return v1 也是一样的
    • .end method

    附加知识:

    1. Smali中函数实体分析–if函数分析

    const/4 v0, 0x0   //vo =0;
    
    .local v0, i:I
    
    :goto_0
    
    if-lt v0, v3, :cond_0     //  v0小于v3 则跳到cond_0并执行分支 :cond_0
    
    return-void
        :cond_0                // 标签
    
    iget-object v1, p0, Lcom/aaa/MainActivity;->listStrings:Ljava/util/List;        // 引用对象
    
    const-string v2, "Eric"
    
    invoke-interface {v1, v2}, Ljava/util/List;->add(Ljava/lang/Object;)Z    // List是接口, 执行接口方法add
    
    add-int/lit8 v0, v0, 0x1  // 将第二个v0寄存器中的值,加上0x1的值放入第一个寄存器中, 实现自增长
    
    goto :goto_0                // 回去:goto_0标签
    

    2. Smali课后习题,翻译成Java代码

    .locals 4
    
    const/4 v2, 0x1
    
    const/16 v1, 0x10
    
    .local v1, "length":I
    
    if-nez v1, :cond_1
    
    :cond_0
    
    :goto_0
    
    return v2
    
    :cond_1
    
    const/4 v0, 0x0
    
    .local v0, "i":I
    
    :goto_1
    
    if-lt v0, v1, :cond_2
    
    const/16 v3, 0x28
    
    if-le v1, v3, :cond_0
    
    const/4 v2, 0x0
    
    goto :goto_0
    
    :cond_2
    
    xor-int/lit8 v1, v1, 0x3b
    
    add-int/lit8 v0, v0, 0x1
    
    goto :goto_1
    

    五、实战

    笔记内容略

    参考:

    [1] 吾爱破解安卓逆向入门教程(五)—Smali实战分析

    [2] 第五课所讲的目标软件原版,“求破”,欢迎分享各种破解手段

    展开全文
  • 教我兄弟学安卓逆向1~12+番外全部教程, 安卓逆向的经典教程之一, 本人认为讲的非常好, 大家可以学习一下
  • 阅读本文之前,建议阅读Android逆向实战篇(Https抓包)。 1. 实战背景 由于工作需要,要爬取某款App的数据,App的具体名称此处不便透露,避免他们发现并修改加密逻辑我就得重新破解了。 爬取这款App时发现,抓包...

    目录

    1. 实战背景

    2. 问题分析

    3. 实战记录

    1) 脱壳

    2) 找到解密函数

    3) 重现

    4. 总结


    阅读本文之前,建议阅读Android逆向实战篇(Https抓包)。

    1. 实战背景

    由于工作需要,要爬取某款App的数据,App的具体名称此处不便透露,避免他们发现并修改加密逻辑我就得重新破解了。

    爬取这款App时发现,抓包抓到的数据是加密过的,如图1所示(原数据较长,图中有省略),可以看到这个超长的data1字段,而且是加密过的。显然,对方不想让我们直接拿到它的信息,选择传过来一个加密的字段,而我们要做的,就是解密这个字段。

                                                                        

                                                                                              图1  数据包截图

    2. 问题分析

    既然服务器返回了一段无法阅读的加密数据,那么必然,这段数据是在客户端进行解密的。因此,我们要做的就是找出解密代码,重现它,从而来破解这段加密数据。

    所以,我们要做的,就是逆向App→找到解密函数→重现。就这么简单。

    3. 实战记录

    1) 脱壳

    拿到APK后,要做的第一件是就是查壳。如果你第一件事就是用jadx、AndroidKiller、APKTool等各种工具怼的话,那你一定是个愣头青,铁头娃,石乐志。如图2所示,可以看到这个App是经过腾讯加固的,需要费一番功夫才能拿到源码。

                                                                     

                                                                                                图2  查壳

    脱壳是一项比较麻烦的工作,脱壳大神可以直接进入下一步,像我一样的小菜鸡建议转去阅读《Android逆向基础篇(脱壳机)》,拥有一部脱壳机可以助你轻松无脑的脱去市面上大多数的壳。

    2) 找到解密函数

    找源码是有技巧的,一行一行阅读的话头都秃了源码还没读完,因此需要巧用搜索功能。

    对于搜索功能,个人十分推荐jadx,它的搜索功能十分强大,但随之而来的是它对内存的巨大需求。可以看到图3中,它占了1600多MB内存。

                                                                   

                                                                                        图3  jadx占用内存

    这里分享一下我对于代码搜索的一些拙见。想破解请求中的加密字段,首先肯定是搜索加密的字段名,但有时候这些字段叫做“token”、“key”等随便搜搜几千个的名字,那就很难从几千个中找出来了。这种情况,可以搜索请求的URL,然后一步步findusage,找出用这个URL的代码,慢慢抽丝剥茧总能找到的,个人感觉效率直接搜字段名要高。使用URL搜索时不建议输入整个URL,大多数情况下都会拼接的,找几个有特征的词去搜就行了。

    对于返回的加密数据,上面这种搜URL的方法就不好使了。图1中可以看到加密字段叫data1,幸好它不叫data,如果它叫data,那就得从5000多个data中把它挖出来。而源码中的data1,只有52个,瞬间筛掉了99%的无关代码。

    搜索结果如图4所示。截全图的话看不清,因此这里只截取部分。相信有视力5.3英语16级的小伙伴已经发现了,几个闪亮的、引人注目的“Decode”,decode data1,那还有疑问吗?肯定是它干的好事呀。

                                               

                                                                                          图4  “data1”搜索结果

    在上面随便找个decode双击,然后按住ctrl点击函数名,就能看到这个decode函数的源码了,如图5所示,这个名为eee3DecodeECB的函数,八成就是我们想要找到的解密函数了。

                                               

                                                                                          图5  decode函数源码

    3) 重现

    直接把这段代码复制进Intellij中,效果如图6所示。

                  

                                                                                      图6  Intellij截图(1)

    图6红的仿佛梦中的A股,股市越红越好,而代码则是越红越不好。我们需要处理这些cannot resolve的东西。

    缺啥补啥,先看变量,需要ENCODING,f224IV,SECRET_KEY,不出所料,这几个都是类中定义的静态变量,顺便把开头的import也一起复制过来,现在的效果就好多了。

                                 

                                                                                    图7  Intellij截图(2)

    这里的Base64这个包原本是android.util.Base64,在开发安卓时,在Android Studio中直接import就可以了,但在Intellij中直接import是不行的,需要自己把这个包下载一下。

    不报错了,那就写个main函数解密试试。把抓包抓到的巨长无比的data1复制到main中的data1,然后调用一下刚才重现的解密函数。因为data1实在是长,这里就不复制进去的,请自行脑补。还有,记得一定要写try。

                                                                    

                                                                                           图8  main函数

    从头到尾再看一遍我们重现的解密代码,一切都很perfect,运行走起。看一下运行结果,是一段Json格式的数据,找一个json在线格式化的网站把运行结果复制进行,结果如图9所示,显然,完成了对加密数据包的解密

                                      

                                                                                             图9  运行结果

    可以看到,经过上述操作,完成了对加密数据包的解密。

    4. 总结

    上述过程并不复杂,也几乎没有任何难点,因此这种加密方式可以说并不合格,甚至可以说有些自欺欺人。加密的本意显然是为了增加一点破解难度,但我这样的菜鸡也只花了不到半小时就完成了破解,何况专业的逆向大神呢。讲真,哪怕把data1这个名字改成data也能增加一些破解的时间成本。

    单纯的Java代码加密太容易破解了,建议此类场景还是用So加密更好,毕竟想要把so文件执行起来还是得费一番功夫的。

    展开全文
  • 安卓从开发到逆向(一)java转换为smali对比分析 简单的认识了java代码和smali代码之间的对应关系,本文我们结合相关知识点,进行一次实战,逆向破解简单安卓手游,让无限生命称为可能。 安卓手游apk及逆向破解工具...
  • 26款优秀的Android逆向工程工具

    千次阅读 2019-09-23 10:56:36
    工欲善其事必先利其器,好的Android逆向工程工具在逆向破解工程中起到事半功倍的作用。 1. SMALI/BAKSMALI SMALI/BAKSMALI是一个强大的apk文件编辑工具,用于Dalvik虚拟机(Google公司自己设计用于Android平台的...
  • 学习逆向的初衷是想系统学习Android下的hook技术和工具, 想系统学习Android的hook技术和工具是因为Android移动性能实战这本书. 这本书里用hook技术hook一些关键函数来计算关键函数的调用参数和调用时长, 从而确定...
  • Android逆向-Android基础逆向(1)

    万次阅读 多人点赞 2018-01-24 19:35:52
    0x01 Android helloworld 第一步 第二步 第三步 第四步 第五步 第六步 第七步 0x02 Android APK分析 神器android Analyzer APK实质 APK内容分析 1签名文件 2资源文件 3资源索引文件 4classesdex 5AndroidManifestxml...
  • Android逆向助手

    2020-07-30 23:30:21
    Android逆向助手
  • 最近一周时间,在学习和研究Android逆向,接下来一段时间,写一系列Android逆向的博客,来总结和记录自己所掌握的知识,也希望为正在学习Android逆向的朋友带来一点帮助。 首先,简单说一下自己对Android逆向的...
  • Android逆向分析概述

    千次阅读 2018-06-04 20:35:19
    学习逆向的初衷是想系统学习Android下的hook技术和工具, 想系统学习Android的hook技术和工具是因为Android移动性能实战这本书. 这本书里用hook技术hook一些关键函数来计算关键函数的调用参数和调用时长, 从而确定...
  • 阿里android逆向面试题crackme
  • 初探android逆向

    千次阅读 2019-01-17 09:38:21
    原创地址 最近看了一点有关于逆向的文章,...最近突然对逆向萌生了一点点兴趣,关于逆向的东西依旧有很多,很多apk对进行加固,加壳等等,这里的入门仅仅是对于没有加密等操作的apk进行逆向,对初学者可以更快的知道...
  • 安卓逆向视频教程

    2019-09-24 14:11:48
    擅长逆向分析,也是编程高手,多次参加国内安全大比武,取得骄人成绩,熟人间戏称F8LEFT为“老师”。于2015年参加阿里举办《2015移动安全挑战赛MSC第二届》获得Android精英奖+学生潜力奖并前往阿里总部领奖。 01.An....
  • android逆向工程教程

    千次阅读 2018-11-26 14:00:02
    很多时候老板会要求我们开发的android软件要进行加固和混淆的,混淆可以使用android原生的build.gradle下的代码实现, buildTypes { release { minifyEnabled false multiDexEnabled true proguar...
  • 安卓逆向协议分析全套视频完整版
  • Android逆向面试题汇总

    千次阅读 2019-09-10 18:36:33
    UC-Android逆向工程师 面试题1的分析 UC-Android逆向工程师面试第2题分析
  • CTF-安卓逆向入门题目

    千次阅读 2019-10-13 17:01:10
    以下题目都是比较简单的安卓逆向题目,主要训练目的是熟悉安卓逆向的一些基础题目,如果是第一次接触安卓逆向,建议先去学一点安卓开发的相关知识,这样做题目就更快一些,当然题目做多了自然也就熟悉了,题目我都...
  • android逆向助手v2.2

    2020-07-18 23:31:08
    android逆向助手v2.2,需要就下载,需要安装jdk,具体jdk配置自行百度
1 2 3 4 5 ... 20
收藏数 19,038
精华内容 7,615
关键字:

安卓逆向