Android逆向入门之常见Davlik字节码解析

目录
  • 破解流程
  • 相关知识
    • 寄存器
    • 复杂指令集和精简指令集
    • jvm和davlik的一些区别
  • 常见Davlik字节码解释
  • 破解程序
    • 分析修改smail文件
    • 重新签名

破解流程

破解Android程序流程:反编译—>分析–>修改–>回编译–>签名,这些都是在命令行中操作,当然也有集成了这些操作的工具:

macos:Android-Crack-Tool

Windows:Android Killer

相关知识

寄存器

这里解释下寄存器的概念,寄存器是用来存储

寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。也就是存储来存储数据的。现在所有手机都是用的arm芯片

这里说一些题外话:比较常见的CPU有intel的X86架构的CPU的还有arm架构的CPU,其中intel的X86架构的cpu指令集有复杂指令集和精简指令集,arm中只有精简指令集。

复杂指令集和精简指令集

所谓复杂和简单就是根据是否要根据程序来设计指令来提高计算机的性能,复杂指令集会根据应用程序来增加一些复杂功能的指令集,这样也就导致CPU的指令越来越多越设计越复杂造价也越高,而精简指令集则不会根据程序来设计指令集,那么怎么提高性能?

jvm和davlik的一些区别

翻译成机器码的工作就是由高级语言的编译器来做的,把这些工作交给了编译器。所以两种区别就是复杂指令集会根据程序来增加自己的指令集达到提高计算机性能的作用,精简指令集则是交给了编译器去做指令转换的工作。由于加入了编译器的转换所以运行速度会慢,而且占用的内存也会变多,同样的程序在arm芯片的手机上和intel芯片的电脑上,手机上占用的空间更多。精简指令集的arm架构还有一个特点是其寄存器特别多,而davlik虚拟机利用这个特性对原本java虚拟机进行了改动:

java虚拟机中每个线程都会有一个PC计数器和一个java栈,PC计数器用于记录程序执行到哪个地方,java栈中用来记录java方法的调用记录叫做栈帧,每调用一个方法就会分配一个新栈并压入java栈,每个栈帧都包含局部变量区,求值栈(jvm叫做操作数栈),局部变量区用来存储方法的参数和局部变量,求值栈用于保存求值的中间结果及调用其他方法的参数。方法运算时从栈中的局部变量区取数据进行运算将结果存放在操作数栈中,最后返回的时候从操作数栈中弹出结果

而davlik虚拟机运行时中也为每一个线程维护了一个PC计数器和一个调用栈,不同的是这个调用栈中维护了一个寄存器列表,至于虚拟寄存器分配多少个是根据方法结构体中的registers字段给出,davlik虚拟机根据这个字段创建一份虚拟的寄存器列表。将java栈帧中的局部变量区和操作数栈换成了寄存器列表来存储。所以java虚拟机是基于栈架构,而davlik虚拟机基于寄存器架构

常见Davlik字节码解释

1.常见Davlik字节码:

定义字段类型:

check-cast 寄存器(操作数),定义的类型;
举例:
check-cast v0,Lcom/android/Launcher2/launcherApplication;

代表定义v0的类型为LauncherApplication
字段写入字段读取(通用解释)

总结:指令 目的操作数 源操作数前面代表指令 寄存器中的值(操作数) 所属类 变量名 变量属性本质上指令操作的还是操作数,根据指令变量是读取还是被赋值读取get:读取变量赋值给操作数赋值set:赋值变量的值为操作数的值

静态字段写入:

const 寄存器 ,值所对应的ID(0X0代表为null)
sput-object 寄存器,字段所属的类;->字段名字:字段类型

const/4 v3, 0x0
sput-object v3, Lcom/disney/Class1;->globalIapHandler:Lcom/disney/config/GlobalPurchaseHandler;
将0x00(代表null)存入v3寄存器中
将v3寄存器中的值写入Class1中的globalIapHandler变量,该变量类型为GlobalPurchaseHandler,
也就是Class1.globalIapHandler = null;

静态字段读取:

sget -object 寄存器, 字段所属的类;->字段名称:字段类型
举例:
sget-object v0, Lcom/disney/Class1;->PREFS_INSTALLATION_ID:Ljava/lang/String;
读取Class1中的PREFS_INSTALLATION_ID变量,该变量类型为String

普通字段写入:

.local v0, args:Landroid/os/Message;
const/4 v1, 0x12
iput v1, v0, Landroid/os/Message;->what:I
将args变量存入v0寄存器中
将0X12传入到v1寄存器中
设置Message中的what变量为v1的值
相当于 args.what=18;

普通字段读取:

iget-object 寄存器 p0(代表该变量所在类的示例即this), 字段所属的类;->字段名字:zidaun1:字段类型
举例:
iget-object v0, p0, Lcom/disney/Class1;->_view:Lcom/disney/Class2;
从v0寄存器中拿Class1中的_view变量,这个变量类型为Class2

调用方法:

invoke-virtual {寄存器:调用者(p0代表this)和方法参数信息}, 方法所在的类;->方法名(参数) 返回值

举例:
invoke-virtual {p0},Lcom/android/Launcher2/Launcher;_>getApplication()L android/app/Application;
java实现代码为:(this.)getApplication();

调用父类方法:

invoke-super {寄存器 :代表调用者和参数},方法所属的类;->方法名称(参数类型)返回值【V代表无返回值】

invoke-super {p0,p1},Landroid/app/ActivityGroup;->onCreate(Landroid/os/Bundle;)V

调用接口:

invoke-interface {寄存器【和方法一样也是调用者和方法参数信息】}, 方法所属的接口全名;->方法名(参数类型)返回值

invoke-interface {v3,v6,v9},Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z
java实现代码为:v3.getBoolean(v6,v9);

判断语句:

一,if-nez(与if-eqz相反)
if-nez 寄存器(里面存储的是操作数), :标号处
如果操作数不为null或者不为0或者不相等就跳转到标号处执行代码
举例:
move resule v0 (将上一条命令的结果赋值给v0)
if-nez v0, :cond_0
(判断其值不为0【条件为真】就跳转到cond_0标号处,反之程序继续执行直到执行到return-void指令处)

二,if-eqz
表示在结果为0或者相等时跳转(与if-nez相反)

方法返回:

return-void 没有返回值

破解程序

分析修改smail文件

1.修改完smali文件安装到手机上

重新编译,回编译命令为

apktool b 文件地址

回编译中常见的错误:
1.提示"at brut.androlib.Androlib.buildResourcesFull(Androlib.java:477)"
解释:该问题为打包资源出错,程序使用的的API版本号和apkool中framework-res.apk基于Android的版本不一致导致
举例:程序使用的API版本号为25;而apkttol版本号为2.2.2其对应的framework-res.apk的版本是基于Android6.0的,
其API为23。两者不一致
解决方法为:找一台API和程序使用的API版本号一致的android设备,从中获取framework-res.apk,并把这个apk安装到本地
使用命令:
(1.)获取android设备中的framework-res.apk:
adb pull /system/framework/framework-res.apk
(2.)安装到本地apktool中
apktool if ./framework-res.apk

重新签名

编译完生成的APK文件是没有进行签名的,所以不能安装。

通过signapk对APK文件进行签名
使用命令:
cat /User/android/Program/signapk
#!/bin/sh
java -jar ~/Program/signapk_jar/signapk.jar ~/Program/signapk_jar/testkey.x509.pem ~/Program/signapk_jar/testkey.pk8 $1 signed.apk
这些文件都可以从android源码中提取。
接着完成apk的签名操作:
signapk 编译后未签名的apk文件地址
签名后完成后会在上面的文件地址里面生成sign.apk文件

到此这篇关于Android逆向入门之常见Davlik字节码解析的文章就介绍到这了,更多相关Android Davlik 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-11-25

Android逆向技巧——去除开屏广告

相信不少网友都有相似的经历:很多app刚开始用的时候很清爽,没啥广告:等用了一段时间后厂家就开始大量上广告的了,我个人觉得这是典型的利用大数据杀熟:厂家看到用户的月活.日活都挺高的,说明用户对自己的app已经产生依赖,此时可以开始"杀猪吃肉"了!开屏广告是我最讨厌的一种:点开app就被逼着看,而且非会员一般要5秒后才能跳过,不想被逼着看广告的就花钱充会员:怎么才能不花钱去掉app的开屏广告了? 先简单回顾一下windows下PE文件的执行原理:PE文件的文件头有个字段叫AddressO

Android逆向之dex2oat的实现解析

目录 简介 dex2oat介绍 为什么要使用dex2oat进行转换 dex2oat代码 1.dex2oat类定义 2.OpenDexFiles函数定义 3.dex2oat入口函数定义 总结 简介 在Android系统5.0及以上系统开始逐渐丢弃Dalvik虚拟机,由于ART虚拟机对内存分配和回收都做了算法优化,降低了内存碎片化程度,回收时间也得以缩短,所有android系统5.0及以上都在主推ART虚拟机.在ART虚拟机中ART则会将Dex通过dex2oat工具编译得到一个ELF文件,它是一个可

使用android-apktool来逆向(反编译)APK包方法介绍

谷歌官方提供了apktool可以逆向已经发布出去的APK应用,即反编译已经打包成功的APK文件,使用它可以将其反编译成非常接近打包前的原始格式,对于APK来说,可以具体的逆向AndroidManifest.xml.资源文件resources.arsc以及将dex文件反编译成可以调试的smali文件. Warnning 但apktool并不等于是可以用来侵犯前作者的作品的工具,所以使用apktool工具的用户千万不用用其来进行不正当.非法的使用. It is NOT intended for pi

Android 逆向学习详解及实例

断断续续的总算的把android开发和逆向的这两本书看完了,虽然没有java,和android开发的基础,但总体感觉起来还是比较能接收的,毕竟都是触类旁通的.当然要深入的话还需要对这门语言的细节特性和奇技淫巧进行挖掘. 这里推荐2本书,个人觉得对android开发入门和android逆向入门比较好的教材: <google android 开发入门与实战> <android 软件安全与逆向分析> 1. 我对android逆向的认识 因为之前有一些windows逆向的基础,在看andr

Android 单线程模型详解及实例

Android 单线程模型详解及实例 我们今天将会在这篇文章中为大家详细介绍有关Android单线程模型的相关内容.希望初学者们可以通过本文介绍的内容对这一概念有一个充分的认识,并从中对这一系统有一个深刻的认识. 当第一次启动一个Android程序时,Android会自动创建一个称为"main"主线程的线程.这个主线程(也称为UI线程)很重要,因为它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与Andriod控件交互的线程.比如,当你在屏幕上按下一个按钮后,UI线程

Android 自定义阴影效果详解及实例

Android 自定义阴影效果详解及实例 Android5.X中,Google为其增加了两个属性 android:elevation=" " 与 android:translationZ=" ",对应垂直方向上的高度变化.系统会自动增加阴影效果. 在TabLayout中增加android:elevation=" 8dp" ,效果如下: 箭头指向的就是系统为我们默认提供,结果差强人意.那我们是不是可以自定义阴影,不使用系统提供的. 自定义阴影效果

Android ViewFlipper的详解及实例

Android ViewFlipper的详解 前言: View Flipper,是ViewAnimator的子类,而ViewAnimator又是继承自FrameLayout,而FrameLayout就是平时基本上只显示一个子视图的布局,由于FrameLayout下不好确定子视图的位置,所以很多情况下子视图之前存在相互遮挡,这样就造成了很多时候我们基本上只要求FrameLayout显示一个子视图,然后通过某些控制来实现切换.正好,ViewFlipper帮我们实现了这个工作,我们需要做的就是,选择恰

Android WebView的详解及实例

Android WebView的详解       Android WebView在android平台上是一个特殊的View, 他能用来显示网页,这个类可以被用来在你的app中仅仅显示一张在线的网页,还可以用来开发浏览器. 在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件.WebKit是Mac OS X v10.3及以上版本所包含的软件框 架(对v10.2.7及以上版本也可通过软件更新获取). 同时,WebKit也是Mac OS X的Safa

Android Handler的详解及实例

Android Handler的详解 Handler我们常常用于通知主线程做相对应的操作,但是如果使用不但的话就会造成内存泄露,所以记录写正确的Handler写法. Handler handler = new Handler() { public void handleMessage(Message msg) { //do something }; }; handler.sendEmptyMessageDelayed(0, 100 * 1000); 像上面的代码片段,就会存在内存泄露的风险,因为

android 通知Notification详解及实例代码

android Notification实例详解 1.使用Builder模式来创建 2.必须要设置一个smallIcon,还可以设置setTicker 3.可以设置 setContentTitle,setContentInfo,setContentText,setWhen 4.可以设置setDefaults(闪屏,声音,震动),通过Notification设置flags(能不能被清除) 5.发送需要获取一个NotificationManager(getSystemService来获取);noti

Android GPS定位详解及实例代码

GPS定位是智能手机上一个比较有意思的功能,LBS等服务都有效的利用了GPS定位功能.本文就跟大家分享下Android开发中的GPS定位知识.      一.Android基础知识准备 1.Activity类 每一种移动开发环境都有自己的基类.如J2ME应用程序的基类是midlets,BREW的基类是applets,而Android程序的基类是Activity.这个activity为我们提供了对移动操作系统的基本功能和事件的访问.这个类包含了基本的构造方法,键盘处理,挂起来恢复功能,以及其他底层

Android 图片选择详解及实例代码

 Android 图片选择 可以达到的效果: 1.第一个图片的位置放照相机,点击打开照相机 2.其余的是显示全部存储的图片,点击一次是查看大图,长按则是每张图片出现一个checkBox,可以进行选择 下面是实例效果图 MainActivity 类 public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickLis

Android 文件选择器详解及实例代码

本文给大家讲解下Android文件选择器的使用.实际上就是获取用户在SD卡中选择的文件或文件夹的路径,这很像C#中的OpenFileDialog控件. 此实例的实现过程很简单,这样可以让大家快速的熟悉Android文件选择器,提高开发效率. 网上曾经见到过一个关于文件选择器的实例,很多人都看过,本实例是根据它修改而成的,但更容易理解,效率也更高,另外,本实例有自己的特点:   1.监听了用户按下Back键的事件,使其返回上一层目录.        2.针对不同的文件类型(文件vs文件夹 , 目标