Android 应用逆向破解

合集下载

Android逆向助手使用说明

Android逆向助手使用说明

1、“源文件”处支持文件或文件夹拖放;
2、必须安装【.NET Framework2.0简体中文版】框架;
3、部份功能依赖java运行环境,因此必须安装java。
12、替换dex;
13、修复dex;
14、加密xml转txt;
15、字符串unicode编解码。
更新日志
v2.1主要修改:
1、部份功能新增错误回显;
2、修复java环境判断错误的bug;Android逆向助手是一款针对安卓平台的强大逆向辅助软件,功能涵盖apk反编译打包签名;dex/jar互转替换提取修复;so反编译;xml、txt加密;字符串编码等。支持直接将文件拖放到源和目标文件,不用每次都点浏览选择。软件暂时支持WinXP、Win7、Win2003系统。
功能介绍
1、反编译apk;
2、重新打包成apk;
3、对apk进行签名;
4、反编译dex;
5、重新打包成dex;
6、dex转jar;
7、dex转ddx;
8、dex导出成txt;
9、反编译so;
10、jar转dex;
11、提取dex;

软件逆向工程原理与实践第8章Android应用程序逆向分析

软件逆向工程原理与实践第8章Android应用程序逆向分析
(1) META-INF:存储关于签名的一些信息; (2) res:资源文件,程序本身使用的图片、颜色、配置 等信息储存于该文件夹中,其中,XML格式文件在编译过 程中由文本格式转化为二进制的AXML格式;
第8章 Android应用程序逆向分析
(3) AndroidManifest.xml:Android配置文件,编译过程 依然被转换为AXML格式;
第8章 Android应用程序逆向分析
8.2.1 APKTool APKTool是Google提供的APK反编译工具,可安装反编
译系统APK所需要的framework-res框架,能够反编译APK, 并且可以清理上次反编译文件夹。
安装和使用步骤如下: (1) 配置Java运行环境; (2) 下载并安装APKTool; (3) 打开Windows命令窗口;
APKTool的所有操作均在Windows命令窗口中输入 “apktool”命令来查看。操作完成后,可以得到应用程序的 资源文件,smali文件和Manifest.xml文件。直接点击 Manifest.xml文件可以在浏览器中查看相关信息。
第8章 Android应用程序逆向分析
8.2.2 dex2jar dex2jar也是一款开源软件。它集成了Java库,可将原本
第ali反汇编得到smali文件,阅读反汇编出 的smali文件。
(2) 使用dex2jar生成jar文件,再使用jd-gui生成Java源代 码,阅读生成的Java源代码。
(3) 使用JEB、APK Studio等高级工具。
第8章 Android应用程序逆向分析
第8章 Android应用程序逆向分析
4.反编译APK获取Java源码并分析 将应用程序反编译成可读的Java源码,然后审查该代码, 了解应用程序的所有行为。在此过程中,分析源码审查开放 的端口、共享/传输的数据,以及Socket连接等是关键的考量。 根据8.2节介绍的方法,首先对APK文件进行解压(或修改后 缀解压),从中提取出classes.dex文件;使用dex2jar工具,将 classes.dex文件转换成jar文件,如图8-11所示;然后,使用 jd-gui分析这个classes.jar文件,如图8-12所示。

Android逆向分析工具与方法

Android逆向分析工具与方法

1Android分析工具1.1分析工具经过试验,推荐的工具为:模拟器可以使用逍遥安卓;反编译,编译,smali代码注入,APK签名等等可以使用Android Killer;开发IDE可以使用Android Studio;一般的反编译和运行APK可以使用Android Killer + 逍遥安卓,注意连接逍遥安卓模拟器的方法是使用adb connect 127.0.0.1:21503,最好使用逍遥自带的adb工具。

1.APKtoola)直接编译和反编译APK文件;b)到smali语言级别;c)可以解析二进制的AndroidManifest.xml文件2.APKStudio图形界面的apktool;3.APK IDE小米出的apk反编译,打包集成工具,类似ApkStudio;集成了jd-gui,dex2jar等;4.android Killer集成了apktool,dex2jar, jd-gui等工具,同时支持搜索,类方法提取,代码插入等工具;同时支持动态连接android devices,自动编译,签名,安装,运行程序等操作。

易用性上,这几类工具的排名是:AndroidKiller> APK IDE >APKStudio>APKTool.5.JEB反编译工具,商业的,效果据说比开源的要好;6.Dex2jar可以直接把classes.dex转换成Jar包,内部是把Dalvik字节码转换成了Java字节码;7.enjarifygoogle自己出的工具,把dhttps:///google/enjarify/8.jad把某个.class文件转换成源码形式,本质是把Java字节码转换成java源码;9.jd-gui本质上和jad一样,但是是图形界面的,并且可以批量反编译整个Jar包文件;10.androguard包含了许多工具,可以对某个APK文件进行测绘,比如权限信息,函数调用图,指令级别的函数调用图,交互分析环境;11.IDEa)Eclipseb)AndroidStudioc)IDEA12.JDBa)JDK自带的调试JAVA程序的调试器,可以用来调试APK;13.IDA14.Mercury,现在改名叫Drozera)是一个渗透测试工具;15.Androguarda)一堆python脚本工具;b)有一个可以生成函数调用图;1.2分析平台系统1.2.1Santoku本质是一款Ubuntu Linux系统,上面集成了各种Android工具,包括开发,逆向,渗透测试,恶意代码分析等各个安全方向。

Android逆向工具篇—反编译工具的选择与使用

Android逆向工具篇—反编译工具的选择与使用

Android逆向⼯具篇—反编译⼯具的选择与使⽤作者 | 天天记⼩本⼦上的lilac 来源 | CSDN今天给⼤家介绍⼀下Android App 在Java层的逆向⼯具。

逆向⼯具的介绍在过去,当我们想要了解⼀个 app 内部运作细节时,往往先通过 ApkTool 反编译 APK,⽣成 smali 格式的反汇编代码[1],然后⼤佬和⽼⼿直接阅读 smali 代码,适当的进⾏修改、插桩、调试,经过⼀定的经验和猜想,理解程序的运⾏逻辑和加解密细节,⽐如如下的 smali 代码。

smail我们只要先这样,再那样,最后再这样,对对对,就这样,⼀个程序的加密就被破解出来了。

是不是迫不及待想来⼀次App的逆向之旅了?事实上,这种⽅式对⼩⽩实在不友好,有没有更加友好的⽅式呢?当然是有的,如果你百度或者 google 搜索逆向相关的教程和分享,很容易就会发现下⾯这三个⼯具。

在介绍⼯具之前,我们先补充⼀下APK结构的知识,我们以伊对这个社交 Apk 为例。

APK ⽂件其实是⼀种特殊的 zip 格式,我们可以直接⽤ 360 压缩或者别的压缩⼯具打开。

为了满⾜⾃⾝的功能和设计,⼏乎每⼀个都会在基础的⽂件结构上添加不少东西,但有六个部分是不变的,我们罗列和称述⼀下。

⽂件或⽬录作⽤META-INF/描述apk包信息的⽬录,主要存放了签名信息,配置信息,service注册信息res/存放apk资源⽂件的⽬录,⽐如图⽚、图标、字符串、样式、颜⾊assets/同样是存放apk资源⽂件的⽬录,但和res有差异,和我们关系不⼤resources.arsc资源索引,包含不同语⾔环境中res⽬录下所有资源的类型、名称与ID所对应的信息lib/存放so⽂件,越来越多的应⽤由C/C++编写核⼼代码,以SO⽂件的形式供上层JAVA代码调⽤,以保证安全性,这个⽬录是逆向解密关注的重点classes.dex(⼀个或数个)Android程序运⾏在Dalvik虚拟机上,⽽dex就是Dalvik虚拟机的可执⾏⽂件, 相当于Windows平台中的exe⽂件,通过反编译dex,可以获得apk源码(这个说法不很准确,但⽅便理解)AndroidManifest.xml清单⽂件,包含了App⼤量的的配置信息,⽐如包名、应⽤需要拥有的权限(打电话/录⾳/⽹络通信等等)、以及所有的界⾯和程序组件的信息,⽆法解压apk时直接打开,因为清单⽂件在apk打包过程中被编译成了⼆进制格式⽂件接下来我们介绍以下反编译⼯具,看⼀下反编译⼯具的作⽤⼯具作⽤ApkTool解析resources.arsc,AndroidManifest.xml等⽂件,反编译dex⽂件为smali源码Dex2jar将dex⽂件转化为jar⽂件Jd-gui反编译jar,查看java源码⽐如使⽤ Dex2jar+Jd-gui, 最终得到这样的结果。

Android逆向之dex2oat的实现解析

Android逆向之dex2oat的实现解析

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⽂件,它是⼀个可执⾏的⽂件。

所以下⾯我们就针对ART的dex2oat实现进⾏做分析。

dex2oat介绍Dex2oat的全称是:dalvik excutable file to optimized art file,它是⼀个对 android系统下的dex⽂件,进⾏编译优化的程序。

通过dex2oat的编译优化,可以⼤⼤的提⾼android系统的启动的速度和使⽤⼿机过程的的流畅度。

dex2oat在安卓⼿机环境下的存放位置为/system/bin/dex2oatdex2oat在开源系统中的路径为\art\dex2oat\。

为什么要使⽤dex2oat进⾏转换在android系统中,Android 虚拟机可以识别到的是dex⽂件,App应⽤在使⽤过程中如果每次将dex⽂件加载进⾏内存,解释性执⾏字节码,效率就会变得⾮常低,从⽽影响到⽤户在使⽤安卓⼿机的体验。

通过利⽤dex2oat进⾏优化处理,那么可以在android系统运⾏之前,利⽤合适的时机将dex⽂件字节码,提前转化为虚拟机上可以执⾏运⾏的机器码,后续直接从效率更⾼的机器码中运⾏,则运⾏阶段更加流畅,优化⽤户体验。

dex2oat代码1.dex2oat类定义class Dex2Oat {public://创建函数,返回值为bool,static bool Create(Dex2Oat** p_dex2oat,Compiler::Kind compiler_kind,InstructionSet instruction_set,InstructionSetFeatures instruction_set_features,VerificationResults* verification_results,DexFileToMethodInlinerMap* method_inliner_map,size_t thread_count)SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {//判断参数传递进来的释放为空CHECK(verification_results != nullptr);CHECK(method_inliner_map != nullptr);//⽤智能指针⽅式进⾏去实例化dex2oatstd::unique_ptr<Dex2Oat> dex2oat(new Dex2Oat(&compiler_options,compiler_kind,instruction_set,instruction_set_features,verification_results,method_inliner_map,thread_count));if (!dex2oat->CreateRuntime(runtime_options, instruction_set)) {*p_dex2oat = nullptr;return false;}*p_dex2oat = dex2oat.release();return true;}//dex2oat的虚构函数,⽤于释放操作。

android逆向奇技淫巧二:uiautomatorviewermethodprofili。。。

android逆向奇技淫巧二:uiautomatorviewermethodprofili。。。

android逆向奇技淫巧⼆:uiautomatorviewermethodprofili。

做逆向,不论是在windows还是Android,抑或是macos,都必须要⾯对的⼀个问题:找到关键的代码。

android平台下怎么找到关键的代码了?本⽂以某国民级短视频APP 为例,分享从UI界⾯定位到关键代码的链路逻辑! 1、⽼规矩,先在模拟器运⾏这款APP,然后打开ui automator viewer “截屏”(注意:要暂停短视频播放才⾏,否则截屏的时候会报错)!如下: ⽐如我们想找点赞按钮的执⾏代码(⾄于为什么要找这个按钮的执⾏代码,道上⼈⼠都懂的),光标移动到笔芯上,右边就会显⽰出笔芯的imageView,这⾥能看出其实是⼀个按钮控件;先阿敏有resource-id和class类型;接着进⼊jadx(这种apk上百兆,⽤jadx容易卡死,需要增加内存,增加的⽅法见⽂章末尾的参考1),找到resources.arsc⽂件,⽤刚才找到的id字段也就是byb作为关键词,找到点赞笔芯的id: 2131168834 然后继续搜索,发现原来是这两⾏代码引⽤了: 本想点击进⼀步查看java源码,⽆奈本机内存只有16G,⽽jadx已经消耗了9G,还是卡者不动,⽆法继续,这⾥换成android killer继续逆向分析。

把这⼀串id转成16进制,然后在android killer⾥⾯搜索:发现到处都在引⽤;后续会继续分享怎么分析这些引⽤! ⾄于这⾥为啥⽤id来检索,⽽不是控件的名称了?我个⼈理解:⼤概率是因为控件名称开发⼈员随时都可能更改,所以编译器⾃动⽣成id与之对应。

控件名称随时可以改,但是id不变,通过这种⽅式做到松耦合! 2、上⾯使⽤了这个id的地⽅还是有很多,挨个去静态分析还是耗时,怎么能快速找到点赞执⾏了哪些代码了?这⾥有个更快速的⽅法:method profiling;本质上,method profiling相当于录屏,结果如下: 因为⽤户需要⼿动点击笔芯才能点赞,所以肯定会调⽤onclick⽅法,这⾥就能根据onclick作为关键词查询:只有这两个地⽅调⽤了onclick⽅法: 接下来再去jadx或android killer找这两个⽅法分析源码,是不是简单多了?(⽤AK搜的时候注意把.改成/) ⽼规矩,最后整理⼀下常见的静态分析⽅法:注意:x⾳没登陆时点击屏幕⽤的是onClick来监听的;⼀旦登陆,⽤户点赞⽤的就是onTouch监听了,method profiling捕获到的函数调⽤如下: 代码在这:public boolean onTouchEvent(MotionEvent motionEvent) {View.OnTouchListener onTouchListener;boolean z = false;PatchProxyResult proxy = PatchProxy.proxy(new Object[]{motionEvent}, this, f173585a, false, 254253);if (proxy.isSupported) {return ((Boolean) proxy.result).booleanValue();}if (!isEnabled()) {return false;}this.j = true;int actionMasked = motionEvent.getActionMasked();if (actionMasked != 0) {if (actionMasked != 1) {if (actionMasked == 2) {this.n = motionEvent.getX();this.o = motionEvent.getY();float abs = Math.abs(this.f173586b - this.n);float abs2 = Math.abs(this.f173587c - this.o);int i2 = this.p;if (abs > ((float) i2) || abs2 > ((float) i2)) {z = true;}if (z) {com.ss.android.a.a.a.a.c(this.s);}View.OnTouchListener onTouchListener2 = this.r;if (onTouchListener2 != null) {onTouchListener2.onTouch(this, motionEvent);}} else if (actionMasked != 3) {if (actionMasked == 5) {com.ss.android.a.a.a.a.c(this.s);}}}com.ss.android.a.a.a.a.c(this.s);if (SystemClock.elapsedRealtime() - this.f173591g < ((long) this.q) && (onTouchListener = this.r) != null) { onTouchListener.onTouch(this, motionEvent);}} else {this.f173586b = motionEvent.getX();this.f173587c = motionEvent.getY();this.f173591g = SystemClock.elapsedRealtime();com.ss.android.a.a.a.a.a(this.s, this.q);View.OnTouchListener onTouchListener3 = this.r;if (onTouchListener3 != null) {onTouchListener3.onTouch(this, motionEvent);}}super.onTouchEvent(motionEvent);return true;} 这个和上⾯那个是⽗⼦关系: 继续⼀层⼀层往下拨:继续往下拨:反编译失败了:直接看smali代码或hook看看传⼊的参数是啥:直到这⾥进⼊系统函数才罢休:这⾥貌似是遍历短视频,如果还有就取出来对⽐id,看看是不是同⼀个短视频:两个参数都是float,看着像横纵坐标:仅通过静态分析也看不出啥花样来,这⾥继续⽤objection去hook上述提到的⼀些关键⽅法,看看传⼊的参数和返回值都是啥了:objection --gadget "com.ss.android.ugc.aweme" exploreandroid hooking watch class_method com.ss.android.ugc.aweme.feed.utils.m$1.onTouch --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.panel.b$10.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.panel.t.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.panel.b.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method com.ss.android.ugc.aweme.feed.story.viewmodel.b$a.a --dump-args --dump-backtrace --dump-returnandroid hooking watch class_method mon.widget.DiggLayout.a --dump-args --dump-backtrace --dump-return⼀次性hook了这么多函数,信息量最⼤的就是下⾯这个函数了,参数传⼊了⼀⼤堆,但和⽤fiddler抓的数据相差甚远,所以有两种可能:(1)java层发送数据的不是这些函数,这⾥没hook到(2)发数据的函数在so层; 下滑时调⽤了这个函数,并传⼊了MotionEvent类的参数:(agent) [763006] Called com.ss.android.ugc.aweme.feed.panel.t.a(android.view.MotionEvent, com.ss.android.ugc.aweme.feed.adapter.av, com.ss.android.ugc.aweme.feed.model.Aweme)(agent) [763006] Backtrace:com.ss.android.ugc.aweme.feed.panel.t.a(Native Method)com.ss.android.ugc.aweme.feed.panel.b.a(BaseListFragmentPanel.java:2411)com.ss.android.ugc.aweme.feed.panel.b$10.a(BaseListFragmentPanel.java:33816612)com.ss.android.ugc.aweme.feed.panel.b$10.a(Native Method)com.ss.android.ugc.aweme.feed.utils.m$1.onTouch(BaseFeedListViewUtils.java:34013410)com.ss.android.ugc.aweme.feed.ui.LongPressLayout.onTouchEvent(LongPressLayout.java:17170610)android.view.View.dispatchTouchEvent(View.java:10023)com.ss.android.ugc.aweme.feed.ui.LongPressLayout.dispatchTouchEvent(LongPressLayout.java:17039388)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)mon.widget.VerticalViewPager.dispatchTouchEvent(VerticalViewPager.java:17039392)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)com.ss.android.ugc.aweme.feed.widget.FeedSwipeRefreshLayout.dispatchTouchEvent(FeedSwipeRefreshLayout.java:17039388)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)dmt.viewpager.DmtViewPager.dispatchTouchEvent(DmtViewPager.java:17039406)com.ss.android.ugc.aweme.homepage.ui.view.MainFlippableViewPager.dispatchTouchEvent(MainFlippableViewPager.java:17170614)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)com.ss.android.ugc.aweme.feed.ui.seekbar.SupportSeekBarFrameLayout.dispatchTouchEvent(SupportSeekbarFrameLayout.kt:17236196)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)dmt.viewpager.DmtViewPager.dispatchTouchEvent(DmtViewPager.java:17039406)com.ss.android.ugc.aweme.base.ui.ScrollableViewPager.dispatchTouchEvent(ScrollableViewPager.java:17104950)com.ss.android.ugc.aweme.homepage.ui.view.MainScrollableViewPager.dispatchTouchEvent(MainScrollableViewPager.java:17104971)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2659)android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2291)com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:414)com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1808)android.app.Activity.dispatchTouchEvent(Activity.java:3080)androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:16842754)com.bytedance.a.h.dispatchTouchEvent(WindowCallback.kt:17039390)com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:376)android.view.View.dispatchPointerEvent(View.java:10243)android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4438)android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4306)android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3999)android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4056)android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3906)android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3872)android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3880)android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3853)android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6247)android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6221)android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6182)android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6350)android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)android.os.MessageQueue.nativePollOnce(Native Method)android.os.MessageQueue.next(MessageQueue.java:323)android.os.Looper.loop(Looper.java:136)android.app.ActivityThread.main(ActivityThread.java:6153)ng.reflect.Method.invoke(Native Method)com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)(agent) [763006] Arguments com.ss.android.ugc.aweme.feed.panel.t.a(MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=567.0, y[0]=1176.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edge 点赞时调⽤了同样的函数,并传⼊了videosEvent类的参数:(agent) [763006] Called com.ss.android.ugc.aweme.feed.panel.t.a(com.ss.android.ugc.aweme.feed.h.cb)(agent) [763006] Backtrace:com.ss.android.ugc.aweme.feed.panel.t.a(Native Method)com.ss.android.ugc.aweme.feed.panel.b.a(BaseListFragmentPanel.java:3594)com.ss.android.ugc.aweme.feed.adapter.VideoViewHolder.a(VideoViewHolder.java:3110)com.ss.android.ugc.aweme.feed.adapter.VideoViewHolder.a(VideoViewHolder.java:3760)com.ss.android.ugc.aweme.feed.adapter.VideoViewHolder.onChanged(VideoViewHolder.java:16842754)com.ss.android.ugc.aweme.arch.widgets.base.NextLiveData$NextObserver.onChanged(NextLiveData.java:17039395)androidx.lifecycle.LiveData.considerNotify(LiveData.java:17039389)androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:17039410)androidx.lifecycle.LiveData.setValue(LiveData.java:16973838)androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:16777216)com.ss.android.ugc.aweme.arch.widgets.base.NextLiveData.setValue(NextLiveData.java:16973849)com.ss.android.ugc.aweme.arch.widgets.base.DataCenter.a(DataCenter.java:34078842)com.ss.android.ugc.aweme.feed.quick.presenter.cb.c(FeedDiggPresenter.java:17170485)com.ss.android.ugc.aweme.feed.quick.presenter.ce.run(Unknown Source)android.os.Handler.handleCallback(Handler.java:751)android.os.Handler.dispatchMessage(Handler.java:95)android.os.Looper.loop(Looper.java:154)android.app.ActivityThread.main(ActivityThread.java:6153)ng.reflect.Method.invoke(Native Method)com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:892)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)参考:。

吾爱破解安卓逆向入门教程(五)

吾爱破解安卓逆向入门教程(五)

吾爱破解安卓逆向入门教程(五)引用: 软件:计算管家v3.4目标:破解授权会员目标软件验证方法:软件获取设备号号后调用支付宝进行付费,付费成功后会返回对应参数,点击授权按钮后即完成付费用户授权。

实战目标:点击授权按钮直接授权成功,小雨之前也做过3.3的分析,我的手段比较简单,适合新手软件界面:0x0 脱壳本软件v3.3使用的爱加密壳,v3.4使用的360壳,不过对于那些大鸟们来说,什么壳都没用,目前我们处于smali阶段,不介绍壳的脱法,不像pc破解一上来就告诉你如何脱壳,后面阶段,将会由@PoJie_小雨给大家讲述脱壳实战。

0x1 运行软件找关键点我们首先来到付费页面,如下图:开头中我已经讲过这个软件的验证流程,既然这样,我们直接点击授权按钮观察有什么关键点软件提示我们并没有获取授权,那么这类文字通常会以文本形式写在String.xml,对应的布局文件或者以unicode形式写在smali中,对于游戏来说,这类可能是以图片形式放在图片文件,或者自定义格式的文件,甚至是通过网络获取的,我们了解之后,先尝试第一种,直接搜索AndroidKiller载入apk嗯,直接搜索到了,减少了我们很多的工作量,那么,文本都有对应的id,我们再次搜索这个id,等等,我们好像发现了更重要的东西我们看到了授权成功的文字,那么我们换思路,直接搜索授权成功的id我们这里看到了这个神奇的数字,新手相信都不知道这个玩意是怎么来的,那么这里我稍微普及下,apk在编写时,开发工具都会对源代码自动编译,生成对应的标示符,通过这些标示符,来引用对应的资源,详细一点的可以阅读这篇文章/s/blog_7b83134b01016043.html0x2 尝试破解我们接着搜索0x7f080100,发现两处可疑处分别点进去看看,顺便我们也记下授权失败的标示符,0x7f080102,这里我们可以方便我们判断这里我们看到的就是授权失败时弹出的对话框,我们找到它的标签是:cond_1,接着我们向上翻,看到哪些跳转会跳到:cond_1,我们来到方法的开始这是个接收信息的方法,通常是由handler实现的,我们大体可以知道,在付费成功后,会想这个函数传递一个message,这个方法就是判断传入的message的值,通过这个值来判断是否付费成功,这里我们看到一个cond_3,我们找到:cond_3,这里我们看到,获取res资源中的0x7f08011a,并转换为string 类型,再传入到Alertdialog的message中,我们看看它到底调用了什么资源看到是这个,看来跟我们破解无关,跳过,我们就直接针对这两个跳转即可如果v1&lt;=0或者v1&gt;v2,则跳转到:cond_1,我们不让它跳,在pc破解中,我们有两种方法,一种是设置为相反的跳转,另一种就是nop 掉,lez对应的就是ge,不过这种方法不保险,我推荐第二种,不走跳转,直接向下走if函数中的代码,我们删除这两条即可,另一个smali修改方法类似,稍有出入接收传入的message,判断v0是否等于0x1b207,不等的话,跳转到:cond_2,我们观察到,如果跳转的话,就会越过成功提示的方法,我们不能让它跳,nop掉,下面一个跳转到:cond_1的判断也一并删除,保存,打包测试。

Android应用程序逆向工程和分析指南说明书

Android应用程序逆向工程和分析指南说明书
LOOK FOR MODIFIERS
RECORDS ANY “SINKS” ENCOUNTERED
REVIEW COMMS
Combines the information gathered with manifest details for later use
Examines WebView configurations and provides templated HTML files for validation of vulnerabilities
CONTACT INFO

Tony Trummer • /in/tonytrummer
@SecBro1
Tushar Dalvi • /in/tdalvi
@tushardalvi
APK Structure
Android Manifest.xml Permissions Component exporting Name, version, etc
/res Resources not in resources.arsc
Images Layouts
classes.dex Dalvik Bytecode
Service
OnCreate() OnBind()
OnStartCommand() OnUnbind() OnDestroy()
Provider
.query() .update() .delete() .insert()
Receiver
.OnReceive()
COMMUNICATION
Multiple decompilers to provide better results
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

acore.jar
ext.jar
framework.jar
service.jar
android.policy.jar
deodex
odex处理过的apk包中不包含dex文件,其对应的odex文件放在与 apk文件同一目录下,我们先把apk文件中其他的资源等文件先反编 译出来。 apktool d Calculator.apk ./Calculator 通过aapt命令获取apk使用的SDK的版本号targetSdkVersion为15。
java –jar smali.jar –o HelloWorld.dex HelloWoldOut
执行
adb push HelloWorld.dex /data/local/ adb shell dalvikvm –cp /data/local/HelloWorld.dex HelloWorld 只能汇编和反汇编DEX文件
aapt d badging Calculator.apk | grep targetSdkVersion
使用baksmali对Calculator.odex去odex并反编译成smali代码文 件, -a指明sdk版本,-x指定需deodex的odex文件,-d指明依赖的 framework目录,-o指定去输出目录。
APK编译工具

AAPT资源打包工具

Android Assets Packaging Tool 编译资源文件;生成R.java

AIDL

根据*.aidl文件自动生成java文件

Dex

将Java编译产出的*.class文件转换成dex文件

ApkBuilder APK打包工具

将前面编译产出的中间文件打包成APK
Hale Waihona Puke apktool apk解包 |-- HelloWorld/ |-- AndroidManifest.xml 被编译成二进制的配置文件 |-- class.dex Android可执行文件 |-- resources.arsc 被编译成二进制的主资源文件 |-- assets/ 不需编译的原始资源文件目录 |-- res/ 资源文件目录 |-- lib/ 库文件目录 |-- META-INF/ APK的签名信息 apk反编译 |-- out/ |-- AndroidManifest.xml 配置文件 |-- apktool.yml 反编译生成的文件,供apktool使用 |-- assets/ 不需反编译的资源文件目录 |-- lib/ 不需反编译的库文件目录 |-- res/ 反编译后的资源文件目录 |-- smali/ 反编译生成的smali源码文件目录
deodex odex?
Optimized DEX ,优化的dex文件格式 大部分厂商发布的手机上都会做odex处理 odex处理过的jar/apk包中可能不存在dex文件
odex dex
odex文件在不同的framework 上是无法被dalvik虚拟机加载的。
强依赖 odex /system/framework

JarSigner Java签名工具

使用生成的数字证书给APK签名

ZipAlign APK优化工具

优化APK,更小内存占用、更高运行效率
APK编译过程
What is smali?
Android
DEX可执行
JesusFreke Google Code开 源项目
Dalvik VM
文件格式
广告注入、去除 汉化和破解
baksmali -a 15 -x Calculator.odex –d framework -o Calculator/smali
修改相应的源码和资源后,重新编译、签名。
语法
类汇编语言、寄存器结构、可读性较高 类型 描述符 类型
基本类型:
引用类型:
V Z B S C I J F D
Smali基本原理
目录 APK组成
什么是smali 反编译、编译
语法规范、格式
修改smali代码 断点调试
APK组成

Android应用程序包文件(APK文件)其实是zip压缩包格式,使用解 压工具进行解压,可以看到其目录组成:
|-- HelloWorld/ |-- AndroidManifest.xml 被编译成二进制的配置文件 |-- class.dex Android可执行文件 |-- resources.arsc 被编译成二进制的资源索引文件 |-- assets/ 不需编译的原始资源文件目录 |-- res/ 被编译成二进制的资源文件目录 |-- lib/ 库文件目录 |-- META-INF/ APK的签名信息
apktool
Introduce
封装和改进smali工具 DEX文件的反汇编和汇编 资源文件进行反编译和编译 支持断点调试
Usage
加载framework资源包 java –jar apktool.jar if framework-res.apk 反编译 java –jar apktool.jar d HelloWorld.apk out/ 编译 java –jar apktool.jar b out/ HelloWorld.apk
smali baksmali
汇编器
ROM定制
反汇编器
smali/baksmali
smali/baksmali 反汇编(dex -> smali)
java –jar baksmali.jar –o HelloWorldOut HelloWorld.dex
修改…
汇编(smali -> dex)
void,只能用于返回值类型 boolean byte short char int long(64位) float double(64位)
对象:Lpackage/name/ObjectName; 如:Ljava/lang/String; 相当于 ng.String 数组: [I, [Ljava/lang/String; [Ljava/lang/String;表示一个String对象数组。对于多维 数组,只要增加[就行了,[[I相当于int[][]
相关文档
最新文档