很多朋友问我,安卓逆向好入门吗?只能这样告诉你:坑多、内容杂、容易半途而废。有些坑是可以通过百度搜索到答案的,有些坑是必须技术水平达到一定程度才能越过的,有些坑是无解的。100个人一起学习安卓逆向,最终能够坚持并有成果的,恐怕只有不到5个人。
身边太多在学习安卓逆向的过程中放弃的,或者只学到了皮毛。不管是学习安卓逆向、渗透还是其他的,如果没有基础的朋友千万不要跳着看网上的教学视频。我就是前车之鉴,因为有编程基础所以很多内容都是跳着学,但是坑还是太多了。我可以复刻视频上的操作,却无法将操作复刻到其他APK中。
那么废话不多说,这篇主要是教大家APK基础知识,了解APK包的基础结构、APP多开原理等内容。
APK 的全称是Android Package,它相当于一个压缩文件,大多数压缩软件(7z、好压)都可以直接解压:
文件 | 注释 |
assets目录 | 存放APK的静态资源文件,比如视频,音频,图片等 |
lib 目录 | armeabi-v7a基本通用所有android设备,arm64-v8a只适用于64位的android设备,x86常见用于android模拟器,其目录下的.so文件是c或c++编译的动态链接库文件 |
META-INF目录 | 保存应用的签名信息,签名信息可以验证APK文件的完整性,相当于APK的身份证(验证文件是否又被修改) |
res目录 | res目录存放资源文件,包括图片,字符串等等,APK的脸蛋由他的layout文件设计 |
AndroidManifest.xml文件 | APK的应用清单信息,它描述了应用的名字,版本,权限,引用的库文件等等信息 |
classes.dex文件 | classes.dex是java源码编译后生成的java字节码文件,APK运行的主要逻辑 |
resources.arsc文件 | resources.arsc是编译后的二进制资源文件,它是一个映射表,映射着资源和id,通过R文件中的id就可以找到对应的资源 |
assets目录 存放的都是一些静态文件,比如图片、音视频等等。
lib 目录 用来存放应用程序所依赖的native库文件,native库一般是用C/C++进行编写的,这里的lib库可能包含4种不同类型,根据CPU型号的不同,我们大体可以分为ARM,ARM-v7a,MIPS,X86,分别对应着ARM架构,ARM-V7架构,MIPS架构和X86架构。
其中,不同的CPU架构对应着不同的目录,每个目录中可以存放非常多的对应版本的so库,而且这个目录的结构固定,用户只能按照这个目录来存放自己的so库。目前市场上使用的移动终端大多是基于ARM或者ARM-v7a架构的。从厂家上来分是有三种,arm,x86,MIPS,arm 系列是绝大多数手机上使用的,x86 主要是运用在平板上,而 MIPS ,我基本上就没见过。
META-INF目录 保存应用程序的签名信息,签名信息可以验证APK文件的完整性。什么是签名呢?在android系统中,不同App之间是依靠包名、数字签名共同来进行区分的。虽然Google建议我们用自己的域名的反写作为包名的前缀来定义包名(例如com.google.),但是这并不能做到万无一失,我们不能单单利用包名来区分apk,所以提出了签名的概念。顾名思义,就是在apk上打上作者的烙印。
AndroidManifest.xml文件 他是用来告诉android系统,这里面有关于APP的配置信息,你需要根据里面的设置的配置信息来运行这个app。每个应用程序在根目录下必须包含一个AndroidManifest.xml文件,且文件名不能修改。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="webapp.wawagongju" platformBuildVersionCode="30"
platformBuildVersionName="S" android:versionCode="9" android:versionName="5.6"
android:compileSdkVersion="30" android:compileSdkVersionCodename="S">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application android:theme="@style/Theme.WebApp" android:label="蛙蛙工具"
android:icon="@drawable/icon" android:supportsRtl="true"
android:usesCleartextTraffic="true" android:appComponentFactory="androidx.core.app.CoreComponentFactory">
<activity android:name="p063cn.woobx.webapp.WebAppMainActivity" android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter><action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
package:指一个APP的包名,它也是一个应用进程的默认名称;
versionName:APP的版本号,如果微信是7.0,那么这个字段值就是7.0;
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.somnus.yunyi"
android:sharedUserId="string"
android:sharedUserLabel="string resource"
android:versionCode="integer"
android:versionName="string"
android:installLocation=["auto" | "internalOnly" | "preferExternal"] >
</manifest>
android:allowClearUserData:用户是否能选择自行清除数据,默认为true,程序管理器包含一个选择允许用户清除数据。当为true时,用户可自己清理用户数据,反之亦然;
android:hasCode:表示此APP是否包含任何的代码,默认为true,若为false,则系统在运行组件时,不会去尝试加载任何的APP代码;
<application android:allowClearUserData=["true" | "false"]
android:icon="drawable resource"
android:killAfterRestore=["true" | "false"]
android:label="string resource"
android:manageSpaceActivity="string"
android:name="string"
android:allowTaskReparenting=["true" | "false"]
android:backupAgent="string"
android:debuggable=["true" | "false"]
android:description="string resource"
android:enabled=["true" | "false"]
android:hasCode=["true" | "false"]
android:permission="string"
android:persistent=["true" | "false"]
android:process="string"
android:restoreAnyVersion=["true" | "false"]
android:taskAffinity="string"
android:theme="resource or theme" >
</application>
android:permission:属于最重要的一部分了,开发者可以声明一个可以被用来限制应用自身或者其他应用访问某些组件或者功能的安全权限。举个例子,可以设置一个“获取通讯录列表”的权限,如果你同意你的通讯录就被上传到服务器上了。
android平台上的权限许可分得很细,如果软件无法正常执行时看看是不是缺少相关的permission声明,最终我们还需要使用 android sign tools签名生成的apk文件。
classes.dex文件 是Java源码编译后生成的Java字节码文件,APK运行的主要逻辑。resources.arsc文件 是编译后的二进制资源文件,它实际上就是App的资源索引表。这两个前期先简单了解一下是什么就可以了。
在演示APK安装包和微信安装包里面多了我标记的这两个文件夹:
第一个:kotlin,Kotlin和Java是用于Android应用程序开发的两种编程语言,即使是有技术背景的人,也会混淆Kotlin和Java,更不要说那些不知道这两个词的人了。而自Google推出Kotlin作为Android应用程序开发的第二种官方编程语言以来,Java与Kotlin之战就变得更加激烈了。
那你可能要问了,微信是 kotlin 开发的吗?是的,但不完全是,部分是。没被绕晕吧?
第二个,okhttp3,OKHttp是一个当前主流的网络请求的开源框架,很多APK将其调用。
以上就是对APK基本架构的简述,通过对这些资源的一个介绍,在下一篇文章会带给大家,简易修改APK可以快速定位。比如我们要修改一个图片或音频,那我们第一时间应该直接找到 assets目录 去修改、替换。如果要修改APK的主要逻辑,就应该从 dex 文件中去修改。关注公众号,学习下一个篇章!