当前位置: 首页 > news >正文

android-ndk开发(6): 查看反汇编

android-ndk开发(6): 查看反汇编

2025/05/05

1. 概要

android-ndk 是基于 clang 的工具链, clang 则保持了和 gcc 的高度兼容。 在 Linux 开发机上, GCC 套件里的 objdump 提供了反汇编的功能。 实际上 android-ndk 也提供了一份 objdump, 用它可以反汇编 android 平台的二进制文件。

使用调试器带来的交互式体验, 在 android-ndk 这一交叉编译 - 连接到设备上运行和调试的场景下, 卡顿感比较明显; 相比之下, 查看反汇编代码来辅助 crash 分析, 是 android-ndk 开发过程中会使用到的一个技能。 不求精通汇编, 反正可以问 AI; 而具备查看反汇编的思维则显得更加重要。

2. 查看反汇编

2.1 查看可执行文件的反汇编

还记得上一篇我们搭建的 hello-world 工程吗?

#include <stdio.h>
int main() {printf("hello, world!\n");
}
#!/bin/bash
NDK=~/soft/android-ndk/r21e
HOST_TAG=darwin-x86_64
$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/clang \-target aarch64-linux-android21 hello.c \-o helloadb push hello /data/local/tmp/hello
adb shell "cd /data/local/tmp; chmod +x ./hello; ./hello"

编译后会在当前目录得到 hello 可执行文件。 查看它的反汇编:

/<path/to>/aarch64-linux-android-objdump -d hello

例如我的路径是:

/Users/zz/soft/android-ndk/r21e/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-objdump -d hello

反汇编结果如下:

hello:     file format elf64-littleaarch64Disassembly of section .plt:0000000000000560 <printf@plt-0x20>:560:   a9bf7bf0    stp x16, x30, [sp,#-16]!564:   b0000010    adrp    x16, 1000 <main+0x9d8>568:   f947de11    ldr x17, [x16,#4024]56c:   913ee210    add x16, x16, #0xfb8570:   d61f0220    br  x17574:   d503201f    nop578:   d503201f    nop57c:   d503201f    nop0000000000000580 <printf@plt>:580:   b0000010    adrp    x16, 1000 <main+0x9d8>584:   f947e211    ldr x17, [x16,#4032]588:   913f0210    add x16, x16, #0xfc058c:   d61f0220    br  x170000000000000590 <__libc_init@plt>:590:   b0000010    adrp    x16, 1000 <main+0x9d8>594:   f947e611    ldr x17, [x16,#4040]598:   913f2210    add x16, x16, #0xfc859c:   d61f0220    br  x1700000000000005a0 <__cxa_atexit@plt>:5a0:   b0000010    adrp    x16, 1000 <main+0x9d8>5a4:   f947ea11    ldr x17, [x16,#4048]5a8:   913f4210    add x16, x16, #0xfd05ac:   d61f0220    br  x17Disassembly of section .text:00000000000005b0 <_start>:5b0:   910003e0    mov x0, sp5b4:   14000001    b   5b8 <_start_main>00000000000005b8 <_start_main>:5b8:   d100c3ff    sub sp, sp, #0x305bc:   a9027bfd    stp x29, x30, [sp,#32]5c0:   b0000008    adrp    x8, 1000 <main+0x9d8>5c4:   f947f508    ldr x8, [x8,#4072]5c8:   b0000009    adrp    x9, 1000 <main+0x9d8>5cc:   f947fd29    ldr x9, [x9,#4088]5d0:   b000000a    adrp    x10, 1000 <main+0x9d8>5d4:   f947f94a    ldr x10, [x10,#4080]5d8:   9e670100    fmov    d0, x85dc:   4e181d20    mov v0.d[1], x95e0:   3d8003e0    str q0, [sp]5e4:   f9000bea    str x10, [sp,#16]5e8:   b0000002    adrp    x2, 1000 <main+0x9d8>5ec:   f947f042    ldr x2, [x2,#4064]5f0:   910003e3    mov x3, sp5f4:   aa1f03e1    mov x1, xzr5f8:   910083fd    add x29, sp, #0x205fc:   97ffffe5    bl  590 <__libc_init@plt>0000000000000600 <__atexit_handler_wrapper>:600:   b4000040    cbz x0, 608 <__atexit_handler_wrapper+0x8>604:   d61f0000    br  x0608:   d65f03c0    ret000000000000060c <atexit>:60c:   90000008    adrp    x8, 0 <note_android_ident-0x218>610:   91180108    add x8, x8, #0x600614:   d0000002    adrp    x2, 2000 <__bss_start>618:   91000042    add x2, x2, #0x061c:   aa0003e1    mov x1, x0620:   aa0803e0    mov x0, x8624:   17ffffdf    b   5a0 <__cxa_atexit@plt>0000000000000628 <main>:628:   d10083ff    sub sp, sp, #0x2062c:   a9017bfd    stp x29, x30, [sp,#16]630:   910043fd    add x29, sp, #0x10634:   90000000    adrp    x0, 0 <note_android_ident-0x218>638:   91197000    add x0, x0, #0x65c63c:   52800008    mov w8, #0x0                    // #0640:   b81fc3a8    stur    w8, [x29,#-4]644:   97ffffcf    bl  580 <printf@plt>648:   b85fc3a8    ldur    w8, [x29,#-4]64c:   2a0803e0    mov w0, w8650:   a9417bfd    ldp x29, x30, [sp,#16]654:   910083ff    add sp, sp, #0x20658:   d65f03c0    ret

也可以封装为脚本: disassemble.sh:

#!/bin/bash
NDK=~/soft/android-ndk/r21e
HOST_TAG=darwin-x86_64
$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/aarch64-linux-android-objdump -d hello

3.2 查看单个 .c/.cpp 文件的反汇编

对于 hello-world 工程, 可执行文件对应到唯一的源代码文件 hello.c。

对于稍微有点内容的工程, 不止一个源代码文件。 拿我本地的 ncv 工程来说, 有5个源文件:

  • color.c
  • io.c
  • main.c
  • thread.c
  • timer.c

这对应两个事情:

  • 使用 cmake 构建比较方便, 使用纯粹的命令行也行, 但是有点麻烦
  • 查看反汇编时, 分别对每个 .c 对应的 .o 反汇编, 内容比较清晰; 所有文件编译出的可执行文件 test_ncv 的反汇编, 内容太多, 看不过来

我的 CMakeLists.txt 为:

cmake_minimum_required(VERSION 3.10)
project(ncv C)
add_library(ncv STATIC color.c io.c)
add_executable(test_ncv main.c)
target_link_libraries(test_ncv PUBLIC ncv)

对应的 cmake 构建输出, build/CMakeFiles 目录下的文件:

➜  ncv git:(main) ✗ tree build/CMakeFiles
build/CMakeFiles
├── 3.31.6
│             ├── CMakeCCompiler.cmake
│             ├── CMakeDetermineCompilerABI_C.bin
│             └── CMakeSystem.cmake
├── CMakeConfigureLog.yaml
├── TargetDirectories.txt
├── cmake.check_cache
├── ncv.dir
│             ├── color.c.o
│             └── io.c.o
├── pkgRedirects
├── rules.ninja
└── test_ncv.dir└── main.c.o5 directories, 10 files

我们感兴趣的 ncv.dir/color.c.oncv.dir/io.c.o. 他们是库目标 ncv 对应的源代码们, 对应的 .o 文件。

执行反汇编:

/Users/zz/soft/android-ndk/r21e/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-objdump -d build/CMakeFiles/ncv.dir/color.c.o

一些反汇编结果:

Disassembly of section .text.nv21_to_rgb_worker:0000000000000000 <nv21_to_rgb_worker>:0:   a9bf4ff4    stp x20, x19, [sp,#-16]!4:   69402408    ldpsw   x8, x9, [x0]8:   6b09011f    cmp w8, w9c:   540014aa    b.ge    2a0 <nv21_to_rgb_worker+0x2a0>10:   f940040a    ldr x10, [x0,#8]14:   9000000b    adrp    x11, 0 <nv21_to_rgb_worker>18:   9000000c    adrp    x12, 0 <nv21_to_rgb_worker>1c:   fd400160    ldr d0, [x11]20:   fd400181    ldr d1, [x12]24:   a940314b    ldp x11, x12, [x10]28:   9000000d    adrp    x13, 0 <nv21_to_rgb_worker>2c:   9000000e    adrp    x14, 0 <nv21_to_rgb_worker>30:   fd4001a2    ldr d2, [x13]34:   fd4001c3    ldr d3, [x14]38:   a941396d    ldp x13, x14, [x11,#16]3c:   f9400990    ldr x16, [x12,#16]40:   69462971    ldpsw   x17, x10, [x11,#48]44:   b9803180    ldrsw   x0, [x12,#48]48:   b940056b    ldr w11, [x11,#4]4c:   9100050f    add x15, x8, #0x150:   9b113501    madd    x1, x8, x17, x1354:   d37ffa2c    lsl x12, x17, #158:   9b1135f1    madd    x17, x15, x17, x135c:   910005cd    add x13, x14, #0x160:   9b004102    madd    x2, x8, x0, x1664:   d37ff80e    lsl x14, x0, #168:   9b0041e0    madd    x0, x15, x0, x166c:   9100042f    add x15, x1, #0x170:   91000630    add x16, x17, #0x174:   91000851    add x17, x2, #0x278:   91000800    add x0, x0, #0x27c:   52801fe1    mov w1, #0xff                   // #25580:   7100057f    cmp w11, #0x184:   5400014a    b.ge    ac <nv21_to_rgb_worker+0xac>88:   91000908    add x8, x8, #0x28c:   8b0c01ef    add x15, x15, x1290:   8b0c0210    add x16, x16, x1294:   8b0e0231    add x17, x17, x1498:   eb09011f    cmp x8, x99c:   8b0e0000    add x0, x0, x14a0:   5400100a    b.ge    2a0 <nv21_to_rgb_worker+0x2a0>a4:   7100057f    cmp w11, #0x1a8:   54ffff0b    b.lt    88 <nv21_to_rgb_worker+0x88>ac:   93417d02    sbfx    x2, x8, #1, #31b0:   9b0a3442    madd    x2, x2, x10, x13b4:   aa0003e3    mov x3, x0b8:   aa1103e4    mov x4, x17bc:   aa1003e5    mov x5, x16c0:   aa0f03e6    mov x6, x15c4:   2a0b03e7    mov w7, w11c8:   385ff053    ldurb   w19, [x2,#-1]cc:   3c5ff0c4    ldur    b4, [x6,#-1]d0:   38402454    ldrb    w20, [x2],#2d4:   510008e7    sub w7, w7, #0x2d8:   51020273    sub w19, w19, #0x80dc:   1e620265    scvtf   d5, w19e0:   7e61d884    ucvtf   d4, d4e4:   1e6008a7    fmul    d7, d5, d0e8:   1e6428e4    fadd    d4, d7, d4ec:   1e780093    fcvtzs  w19, d4f0:   7103fe7f    cmp w19, #0xfff4:   1a81b273    csel    w19, w19, w1, ltf8:   0ab37e73    bic w19, w19, w19, asr #31fc:   381fe093    sturb   w19, [x4,#-2]100:   3c5ff0c6    ldur    b6, [x6,#-1]104:   51020294    sub w20, w20, #0x80108:   1e620290    scvtf   d16, w2010c:   1e610a04    fmul    d4, d16, d1110:   7e61d8c6    ucvtf   d6, d6114:   1e6208a5    fmul    d5, d5, d2118:   1e6438c6    fsub    d6, d6, d411c:   1e6538c6    fsub    d6, d6, d5120:   1e7800d3    fcvtzs  w19, d6124:   7103fe7f    cmp w19, #0xff128:   1a81b273    csel    w19, w19, w1, lt12c:   0ab37e73    bic w19, w19, w19, asr #31130:   381ff093    sturb   w19, [x4,#-1]134:   3c5ff0d1    ldur    b17, [x6,#-1]138:   1e630a06    fmul    d6, d16, d313c:   7e61da30    ucvtf   d16, d17140:   1e7028d0    fadd    d16, d6, d16144:   1e780213    fcvtzs  w19, d16148:   7103fe7f    cmp w19, #0xff14c:   1a81b273    csel    w19, w19, w1, lt150:   0ab37e73    bic w19, w19, w19, asr #31154:   39000093    strb    w19, [x4]158:   3d4000d0    ldr b16, [x6]15c:   7e61da10    ucvtf   d16, d16160:   1e7028f0    fadd    d16, d7, d16164:   1e780213    fcvtzs  w19, d16168:   7103fe7f    cmp w19, #0xff16c:   1a81b273    csel    w19, w19, w1, lt170:   0ab37e73    bic w19, w19, w19, asr #31174:   39000493    strb    w19, [x4,#1]178:   3d4000d0    ldr b16, [x6]17c:   7e61da10    ucvtf   d16, d16180:   1e643a10    fsub    d16, d16, d4184:   1e653a10    fsub    d16, d16, d5188:   1e780213    fcvtzs  w19, d1618c:   7103fe7f    cmp w19, #0xff190:   1a81b273    csel    w19, w19, w1, lt194:   0ab37e73    bic w19, w19, w19, asr #31198:   39000893    strb    w19, [x4,#2]19c:   3d4000d0    ldr b16, [x6]1a0:   910008c6    add x6, x6, #0x21a4:   7e61da10    ucvtf   d16, d161a8:   1e7028d0    fadd    d16, d6, d161ac:   1e780213    fcvtzs  w19, d161b0:   7103fe7f    cmp w19, #0xff1b4:   1a81b273    csel    w19, w19, w1, lt1b8:   0ab37e73    bic w19, w19, w19, asr #311bc:   39000c93    strb    w19, [x4,#3]1c0:   3c5ff0b0    ldur    b16, [x5,#-1]1c4:   91001884    add x4, x4, #0x61c8:   7e61da10    ucvtf   d16, d161cc:   1e7028f0    fadd    d16, d7, d161d0:   1e780213    fcvtzs  w19, d161d4:   7103fe7f    cmp w19, #0xff1d8:   1a81b273    csel    w19, w19, w1, lt1dc:   0ab37e73    bic w19, w19, w19, asr #311e0:   381fe073    sturb   w19, [x3,#-2]1e4:   3c5ff0b0    ldur    b16, [x5,#-1]1e8:   7e61da10    ucvtf   d16, d161ec:   1e643a10    fsub    d16, d16, d41f0:   1e653a10    fsub    d16, d16, d51f4:   1e780213    fcvtzs  w19, d161f8:   7103fe7f    cmp w19, #0xff1fc:   1a81b273    csel    w19, w19, w1, lt200:   0ab37e73    bic w19, w19, w19, asr #31204:   381ff073    sturb   w19, [x3,#-1]208:   3c5ff0b0    ldur    b16, [x5,#-1]20c:   7e61da10    ucvtf   d16, d16210:   1e7028d0    fadd    d16, d6, d16214:   1e780213    fcvtzs  w19, d16218:   7103fe7f    cmp w19, #0xff21c:   1a81b273    csel    w19, w19, w1, lt220:   0ab37e73    bic w19, w19, w19, asr #31224:   39000073    strb    w19, [x3]228:   3d4000b0    ldr b16, [x5]22c:   7e61da10    ucvtf   d16, d16230:   1e7028e7    fadd    d7, d7, d16234:   1e7800f3    fcvtzs  w19, d7238:   7103fe7f    cmp w19, #0xff23c:   1a81b273    csel    w19, w19, w1, lt240:   0ab37e73    bic w19, w19, w19, asr #31244:   39000473    strb    w19, [x3,#1]248:   3d4000a7    ldr b7, [x5]24c:   7e61d8e7    ucvtf   d7, d7250:   1e6438e4    fsub    d4, d7, d4254:   1e653884    fsub    d4, d4, d5258:   1e780093    fcvtzs  w19, d425c:   7103fe7f    cmp w19, #0xff260:   1a81b273    csel    w19, w19, w1, lt264:   0ab37e73    bic w19, w19, w19, asr #31268:   39000873    strb    w19, [x3,#2]26c:   3d4000a4    ldr b4, [x5]270:   910008a5    add x5, x5, #0x2274:   7e61d884    ucvtf   d4, d4278:   1e6428c4    fadd    d4, d6, d427c:   1e780093    fcvtzs  w19, d4280:   7103fe7f    cmp w19, #0xff284:   1a81b273    csel    w19, w19, w1, lt288:   0ab37e73    bic w19, w19, w19, asr #3128c:   710000ff    cmp w7, #0x0290:   39000c73    strb    w19, [x3,#3]294:   91001863    add x3, x3, #0x6298:   54fff18c    b.gt    c8 <nv21_to_rgb_worker+0xc8>29c:   17ffff7b    b   88 <nv21_to_rgb_worker+0x88>2a0:   aa1f03e0    mov x0, xzr2a4:   a8c14ff4    ldp x20, x19, [sp],#162a8:   d65f03c0    retDisassembly of section .text.ncv_color_cvt:0000000000000000 <ncv_color_cvt>:0:   d10143ff    sub sp, sp, #0x504:   f9001bf3    str x19, [sp,#48]8:   a9047bfd    stp x29, x30, [sp,#64]c:   910103fd    add x29, sp, #0x4010:   d53bd053    mrs x19, tpidr_el014:   f9401669    ldr x9, [x19,#40]18:   aa0003e8    mov x8, x01c:   52800020    mov w0, #0x1                    // #120:   f81e83a9    stur    x9, [x29,#-24]24:   b4000668    cbz x8, f0 <ncv_color_cvt+0xf0>28:   b4000641    cbz x1, f0 <ncv_color_cvt+0xf0>2c:   b940010a    ldr w10, [x8]30:   b9400029    ldr w9, [x1]34:   7108055f    cmp w10, #0x20138:   54000321    b.ne    9c <ncv_color_cvt+0x9c>3c:   711c053f    cmp w9, #0x70140:   540002e1    b.ne    9c <ncv_color_cvt+0x9c>44:   b9400509    ldr w9, [x8,#4]48:   b940042a    ldr w10, [x1,#4]4c:   6b0a013f    cmp w9, w1050:   540004e1    b.ne    ec <ncv_color_cvt+0xec>54:   b9400909    ldr w9, [x8,#8]58:   b940082a    ldr w10, [x1,#8]5c:   6b0a013f    cmp w9, w1060:   54000461    b.ne    ec <ncv_color_cvt+0xec>64:   f940090a    ldr x10, [x8,#16]68:   b400054a    cbz x10, 110 <ncv_color_cvt+0x110>6c:   f940082a    ldr x10, [x1,#16]70:   b400050a    cbz x10, 110 <ncv_color_cvt+0x110>74:   90000000    adrp    x0, 0 <ncv_color_cvt>78:   a90187e8    stp x8, x1, [sp,#24]7c:   910063e8    add x8, sp, #0x1880:   91000000    add x0, x0, #0x084:   910023e1    add x1, sp, #0x888:   290127ff    stp wzr, w9, [sp,#8]8c:   f9000be8    str x8, [sp,#16]90:   94000000    bl  0 <ncv_parallel_for>94:   2a1f03e0    mov w0, wzr98:   14000016    b   f0 <ncv_color_cvt+0xf0>9c:   7108055f    cmp w10, #0x201a0:   2a1f03e0    mov w0, wzra4:   54000261    b.ne    f0 <ncv_color_cvt+0xf0>a8:   7108053f    cmp w9, #0x201ac:   54000221    b.ne    f0 <ncv_color_cvt+0xf0>b0:   b9400509    ldr w9, [x8,#4]b4:   b940042a    ldr w10, [x1,#4]b8:   6b0a013f    cmp w9, w10bc:   54000181    b.ne    ec <ncv_color_cvt+0xec>c0:   b9400909    ldr w9, [x8,#8]c4:   b940082a    ldr w10, [x1,#8]c8:   6b0a013f    cmp w9, w10cc:   54000101    b.ne    ec <ncv_color_cvt+0xec>d0:   f9400908    ldr x8, [x8,#16]d4:   528000a0    mov w0, #0x5                    // #5d8:   b40000c8    cbz x8, f0 <ncv_color_cvt+0xf0>dc:   f9400828    ldr x8, [x1,#16]e0:   f100011f    cmp x8, #0x0e4:   1a9f0000    csel    w0, w0, wzr, eqe8:   14000002    b   f0 <ncv_color_cvt+0xf0>ec:   52800080    mov w0, #0x4                    // #4f0:   f9401668    ldr x8, [x19,#40]f4:   f85e83a9    ldur    x9, [x29,#-24]f8:   eb09011f    cmp x8, x9fc:   540000e1    b.ne    118 <ncv_color_cvt+0x118>100:   a9447bfd    ldp x29, x30, [sp,#64]104:   f9401bf3    ldr x19, [sp,#48]108:   910143ff    add sp, sp, #0x5010c:   d65f03c0    ret110:   528000a0    mov w0, #0x5                    // #5114:   17fffff7    b   f0 <ncv_color_cvt+0xf0>118:   94000000    bl  0 <__stack_chk_fail>

4. 反汇编有什么用处?

当发生 crash 时, 当程序耗时超出预期时, 都可以从汇编代码进一步分析。

举例: 对于一个C/C++函数,返回值类型不是 void; 如果缺失返回值,可能会在 Debug 模式发生 TRAP(crash,信号为TRAP), 在 Release 模式能运行而不会 Trap。 这时候可以从反汇编分析。

再举例: 对于 rgb 到 gray 的颜色空间转换, 在 Release 模式下的程序运行的很快, 在 Debug 模式下运行的稍慢, 并且如果手写了 arm neon (intrinsics)优化, 仍然和 Release 模式差不多快。 那么检查 Release 下的反汇编代码, 大概率是生成了 neon intrinsics 指令, 并且可能还把流水排布做了优化。

5. 搞一个网站查看反汇编呗!

很可惜, godbolt.org 目前还不支持 android-ndk 作为编译器。

对于 infra 比较到位的公司, 应该可以自行搭建一个在线网站来查看反汇编, 以及根据 crash 堆栈自动做分析等 (比如腾讯)。

6. 总结

给出了 android-ndk 程序查看反汇编代码的方法, 包括单个可执行文件、 基于 cmake 构建时的每个源代码文件。 简要提及了反汇编典型使用场景: crash 分析、 性能分析.

http://www.xdnf.cn/news/290413.html

相关文章:

  • 《算法导论(第4版)》阅读笔记:p7-p8
  • 售前赢单评分是越权吗?
  • 第二章-猜数游戏
  • 数据集-目标检测系列- 牙刷 检测数据集 toothbrush >> DataBall
  • 分析strtol(),strtoul()和strtod()三个函数的功能
  • 字符串哈希专题
  • 架构进阶:什么是数据架构,如何理解数据架构?(华为)
  • 从0开始学习大模型--Day01--大模型是什么
  • 什么是开放数据湖(Open Data Lake)?
  • 十大排序算法全面解析(Java实现)及优化策略
  • Kotlin 作用域函数全解析:let、run、with、apply、also 应该怎么选?
  • C++演讲比赛案例代码
  • [人机交互]理解与概念化交互
  • 小工具功能强大,非常优秀!​
  • 「Mac畅玩AIGC与多模态20」开发篇16 - 使用结构化输出字段控制后续流程示例
  • 基于STM32F103C8T6驱动WS2812彩灯模块点亮RGB灯
  • 布隆过滤器
  • Qt学习笔记
  • SVD降维详解
  • 领略算法真谛: 多源bfs
  • 设一个测试情境,新用户注册后显示的名字不完整,测试思路是怎么样的?
  • 项目实战-基于信号处理与SVM机器学习的声音情感识别系统
  • 【Bootstrap V4系列】学习入门教程之 组件-按钮组(Button group)
  • MAC地址与帧结构
  • ICLR2024 | GNS-HFA | 通过梯度归一化缩放和高频适应增强视觉Transformer的可迁移对抗攻击
  • WMS仓库管理系统:Java+Vue,含源码及文档,集成仓储全流程管控,实现库存精准、作业高效、数据透明
  • Visual Studio 项目转Qt项目
  • 用网页显示工控仪表
  • Barrett Reduction算法优化:更紧的界限消除冗余的减法
  • 迅睿CMS导入别站数据库