Android壳的Proc Maps和LD分析
简介
在Android开发中,经常会遇到需要分析apk文件中的代码逻辑或者加固措施的需求。而在进行这些分析之前,我们首先需要了解apk文件的结构以及其中的壳机制。本文将介绍如何使用proc maps
和ld
命令来分析Android壳,以及相关的代码示例和实践经验。
APK文件结构
APK文件是Android应用程序的安装包,它是一个压缩文件,包含了应用程序的所有资源和代码文件。APK文件的基本结构如下:
APK
├── AndroidManifest.xml
├── classes.dex
├── resources.arsc
├── lib
│ ├── arm64-v8a
│ ├── armeabi-v7a
│ ├── x86
│ └── x86_64
└── assets
其中,AndroidManifest.xml
是Android应用程序的配置文件;classes.dex
是Dalvik虚拟机的可执行文件;resources.arsc
是包含了应用程序的资源信息;lib
目录下存放了不同架构的动态链接库;assets
目录下存放了应用程序的其他资源文件。
Proc Maps
proc maps
是一个Linux命令,用于显示进程的内存映射表。在Android系统中,每个进程都有自己的内存映射表,该表记录了进程的虚拟地址空间和物理内存的映射关系。通过分析进程的内存映射表,我们可以获取到应用程序的加载地址、动态链接库的加载地址等信息。
要查看Android应用程序的内存映射表,可以使用以下命令:
adb shell cat /proc/{PID}/maps
其中,{PID}
为应用程序的进程ID。通过分析内存映射表,我们可以找到应用程序加载的基地址、动态链接库加载的基地址,以及其他内存映射信息。
LD命令
ld
命令是GNU链接器,用于将多个目标文件和库文件链接成一个可执行文件。在Android系统中,ld
命令也被用于加载动态链接库。通过分析ld
命令的输出,我们可以获取到动态链接库的加载地址、符号表等信息。
要查看Android应用程序加载的动态链接库信息,可以使用以下命令:
adb shell LD_DEBUG=libs am start -n com.example.app/.MainActivity
其中,com.example.app
为应用程序的包名,MainActivity
为应用程序的入口Activity。通过分析ld
命令的输出,我们可以找到动态链接库的加载地址、符号表等信息。
示例分析
下面通过一个示例来演示如何使用proc maps
和ld
命令来分析Android壳。
示例代码
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String hello = NativeLib.hello();
TextView textView = findViewById(R.id.textView);
textView.setText(hello);
}
}
上述代码中,MainActivity
的静态代码块中加载了名为hello
的动态链接库。在onCreate
方法中,调用了动态链接库中的hello
函数,并将其结果显示在textView
中。
内存映射表分析
首先,我们需要获取应用程序的进程ID。可以使用以下命令:
adb shell ps | grep com.example.app
假设我们得到的进程ID为12345
,然后我们可以通过proc maps
命令查看该进程的内存映射表:
adb shell cat /proc/12345/maps
输出的结果类似于以下内容:
5630e3f2c000-5630e3f2f000 r--p 00000000 fe:00 11062 /system/lib64/libz.so
5630e3f2f000-5630e3f30000 r-xp 00003000 fe:00 11062 /system/lib64/lib