吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2482|回复: 6
收起左侧

[Android 原创] luckfollowme arm 学习篇(3) - NDK 交叉编译

  [复制链接]
2016976438 发表于 2023-4-26 01:09

luckfollowme arm 学习篇(3) - NDK 交叉编译

之前带大伙用 cmake  配置 CMakeLists.txt

然后依然可以正常编译 window 的可执行文件

可我们的主要目标是学习 arm hook 那么只构建 windows 的可执行文件肯定是不行的。

这时候就需要我们的 ndk 的交叉编译工具

交叉编译 您可以理解成 可以在 windows 环境下构建 基于 linux 等其他平台的二进制文件。

ABI 介绍

在构建之前,我说一下 abi。

abi 个人理解就是 cpu 架构生成的指令集

我们需要在编译的时候指定下 abi (arch) 。

abi 可以指定大概4种:

x86

x86_64

armeabi-v7a

arm64-v8a

后续我们会编译可能会指定 abi 生成,稍微注意一下即可。

NDK 交叉编译工具

上一章也提到了 ndk cmake  toolchain

具体参考: https://developer.android.google.cn/ndk/guides/cmake?hl=zh-cn

要通过 ndk cmake 使用交叉工具链 参考:

https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android

在  CMake 3.21 之后,貌似内置了 NDK 交叉编译工具链的支持,所以您只需要简单的参数即可

-DCMAKE_SYSTEM_NAME=Android # 启动 android 的交叉编译环境
-DCMAKE_ANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670 #设置使用的ndk路径
-DCMAKE_ANDROID_ARCH_ABI= x86|x86_64|armeabi-v7a|arm64-v8a # 设置abi arch 
-DCMAKE_SYSTEM_VERSION=21 # 设置android api 级别 有些 api不支持 arm64 21 算是最小支持arm64版本了
-DCMAKE_BUILD_TYPE=DEBUG|RELEASE # 编译是否优化

当然,我写了个python脚本 能够快速编译 x86 x86_64 armeabi-v7a arm64-v8a 等不同 arch 的二进制文件

import os
import shutil
import subprocess

abis = ["x86", "x86_64", "armeabi-v7a", "arm64-v8a"]

class AndroidPlatformBuilder(object):
    cmake_args = list()
    cmake_build_type = "Debug"  # "Debug|Release"

    project_dir = ""

    platform = "android"
    arch = ""
    android_api_level = 21

    def __init__(self, android_nkd_dir, cmake_dir, arch, target_name ,project_dir="") -> None:
        # 如何没有写项目路径 默认上一层路径
        self.project_dir = project_dir if project_dir else os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
        self.arch = arch
        self.target_name = target_name

        self.cmake_build_dir = os.path.normpath(f"{self.project_dir}/build/cmake-build-android-{arch}")
        self.build_output_dir = os.path.normpath(f"{self.project_dir}/build/{arch}")

        self.cmake = cmake_dir

        if arch == "armeabi-v7a" or arch == "x86":
            self.android_api_level = 19

        # cmake android 构建参数
        self.cmake_args += [
            "-DCMAKE_SYSTEM_NAME=Android",      # 启用android 交叉编译
            f"-DCMAKE_C_COMPILER=clang",        # ndk 是使用 clang 进行编译的
            f"-DCMAKE_CXX_COMPILER=clang++",
            f"-DCMAKE_BUILD_TYPE={self.cmake_build_type}",  # debug 调试信息多点 不会被优化 release 是最终优化版本
            f"-DCMAKE_ANDROID_NDK={android_nkd_dir}",       # ndk 路径
            f"-DCMAKE_SYSTEM_VERSION={self.android_api_level}", # arm64 架构是在 Android 5.0 (API level 21) 开始支持的
            f"-DCMAKE_ANDROID_ARCH_ABI={self.arch}"             # android arch abi
        ]

    def build(self):
         # 0.清空缓存
        if os.path.exists(self.cmake_build_dir):
            shutil.rmtree(self.cmake_build_dir)
        # 1.构建 adnroid  cmake 项目
        cmake_cmd_options = ["-S {}".format(self.project_dir), "-B {}".format(self.cmake_build_dir)]
        cmd = [f"{self.cmake}"] + cmake_cmd_options + self.cmake_args
        # 集合转换 string 命令
        cmd = " ".join(cmd)
        print(cmd)
        os.system(cmd)

        # 2. 根据cmake 项目 构建二进制文件
        if not os.path.exists(self.build_output_dir):
            os.makedirs(self.build_output_dir)

        subprocess.run(["cmake", "--build", "."], cwd=self.cmake_build_dir,check=True)
        print("cmake --build .")
        shutil.copyfile(f"{self.cmake_build_dir}/{self.target_name}",f"{self.build_output_dir}/{self.target_name}")

if __name__ == "__main__":
    ndk_path = r"C:\Users\hp\AppData\Local\Android\Sdk\ndk\25.1.8937393".replace('\\',"/")
    cmake_path = r"F:\c++\msys2\mingw64\bin\cmake".replace('\\',"/")
    print("ndk_path:", ndk_path)
    print("cmake_path:", cmake_path)

    for abi in abis:
        # target_name 是 add_executable 中生成的执行程序名称 
        builder = AndroidPlatformBuilder(android_nkd_dir=ndk_path, cmake_dir=cmake_path, arch=abi,target_name="InlineHookPratice")
        builder.build()

您把他复制到我图中所示的地方:

</p>

01.png

</p>

修改 您的 NDK_PATH CMAKE_PATH 以及 CMakeLists 中您最终构建的可执行程序的 target_name

</p>

02.png

</p>

执行后,您的build 目录下应该会有以下文件:

</p>
03.png
</p>

浏览arm64

我们将生成的 arm64-v8a 中的文件 拖入到 ida pro 中,然后搜索 main 方法。 您应该就可以看到 对应的 hello world 字样

04.png

由于用到 std:: 里面的东西 生成的内容很多,导致我看点迷糊。

下章教程我们还是弄个简单的分析吧。

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
debug_cat + 1 + 1 谢谢@Thanks!支持支持
lxhyjr + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

bj9ye666 发表于 2023-4-26 07:12
从第一篇看到第三篇很全面虽然看不懂,但是也学习了些内容
池塘春草 发表于 2023-4-26 10:16
xhsj1997 发表于 2023-4-26 22:17
Daneellee 发表于 2023-4-27 10:39
感谢楼主分享!
帝爵 发表于 2024-6-20 10:52
不行不行不行 这样如果头文件多 就出BUG
larryliao 发表于 2024-6-20 11:17
受益匪浅,感谢楼主
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 11:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表