Android壳的Proc Maps和LD分析

简介

在Android开发中,经常会遇到需要分析apk文件中的代码逻辑或者加固措施的需求。而在进行这些分析之前,我们首先需要了解apk文件的结构以及其中的壳机制。本文将介绍如何使用proc mapsld命令来分析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 mapsld命令来分析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