• ARM汇编学习录 3 - 调试/编译


    概述

    在学习ARM汇编的时候,我们往往需要将汇编生成为可执行程序以及调试运行。这里使用Android手机作为运行环境。

    前置准备:

    1. NDK安装

    高版本NDK使用clang套件已经不在提供GUN GCC/GDB

    编译

    NDK相关编译命令

    在学习Thumb/ARM32指令时clang传入tartget armv7a-linux-androideabi${API}

    如果只需只要生成thumb代码给clang传入 -mthumb参数。
    为方便学习这里给出一个示例脚本方便大家学习

    #!/bin/zsh
    # https://clang.llvm.org/docs/ClangCommandLineReference.html
    #指定NDK目录
    export NDK_PATH="/Users/fanjack/Library/Android/sdk/ndk/25.2.9519653"
    export API=21
    # 需要Thumb/ARM32请使用armv7
    #export TARGET="armv7a-linux-androideabi${API}"
    # 学习ARM64
    export TARGET="aarch64-linux-android21"
    # export ccOps="-S"
    export COMPILER="$NDK_PATH/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang"
    export CC="$COMPILER -target  ${TARGET} "
    # 仅生成 thumb指令
    #$CC  -mthumb  hello.c  -o hello.out
    # 生成汇编文件
    #$CC  -S  hello.c  -o hello.S
    # 汇编生成可执行文件
    #$CC  hello.S  -o hello.out
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在学习的时候想直接编写汇编文件,然后不知道语法的时候可以按照以下技巧学习。

    #include 
    int main(int argc,char ** args){
        printf("hello world %d\r\n",argc);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // 如果想学习thumb指令添加-mthumb 
    $CC  -S  hello.c  -o hello.S
    
    • 1
    • 2

    生成的文件如下:

    	.text
    	.syntax unified
    	.eabi_attribute	67, "2.09"	@ Tag_conformance
    	.eabi_attribute	6, 10	@ Tag_CPU_arch
    	.eabi_attribute	7, 65	@ Tag_CPU_arch_profile
    	.eabi_attribute	8, 1	@ Tag_ARM_ISA_use
    	.eabi_attribute	9, 2	@ Tag_THUMB_ISA_use
    	.fpu	neon
    	.eabi_attribute	34, 1	@ Tag_CPU_unaligned_access
    	.eabi_attribute	15, 1	@ Tag_ABI_PCS_RW_data
    	.eabi_attribute	16, 1	@ Tag_ABI_PCS_RO_data
    	.eabi_attribute	17, 2	@ Tag_ABI_PCS_GOT_use
    	.eabi_attribute	20, 1	@ Tag_ABI_FP_denormal
    	.eabi_attribute	21, 0	@ Tag_ABI_FP_exceptions
    	.eabi_attribute	23, 3	@ Tag_ABI_FP_number_model
    	.eabi_attribute	24, 1	@ Tag_ABI_align_needed
    	.eabi_attribute	25, 1	@ Tag_ABI_align_preserved
    	.eabi_attribute	38, 1	@ Tag_ABI_FP_16bit_format
    	.eabi_attribute	18, 4	@ Tag_ABI_PCS_wchar_t
    	.eabi_attribute	26, 2	@ Tag_ABI_enum_size
    	.eabi_attribute	14, 0	@ Tag_ABI_PCS_R9_use
    	.file	"hello.c"
    	.globl	main                            @ -- Begin function main
    	.p2align	2
    	.type	main,%function
    	.code	16                              @ @main
    	.thumb_func
    main:
    	.fnstart
    @ %bb.0:
    	.save	{r7, lr}
    	push	{r7, lr}
    	.setfp	r7, sp
    	mov	r7, sp
    	.pad	#16
    	sub	r1, #16
    	movs	r2, #0
    	str	r2, [sp]                        @ 4-byte Spill
    	str	r2, [sp, #12]
    	str	r0, [sp, #8]
    	str	r1, [sp, #4]
    	ldr	r1, [sp, #8]
    	ldr	r0, .LCPI0_0
    .LPC0_0:
    	add	r0, pc
    	bl	printf
                                            @ kill: def $r1 killed $r0
    	ldr	r0, [sp]                        @ 4-byte Reload
    	add	sp, #16
    	pop	{r7, pc}
    	.p2align	2
    @ %bb.1:
    .LCPI0_0:
    	.long	.L.str-(.LPC0_0+4)
    .Lfunc_end0:
    	.size	main, .Lfunc_end0-main
    	.cantunwind
    	.fnend
                                            @ -- End function
    	.type	.L.str,%object                  @ @.str
    	.section	.rodata.str1.1,"aMS",%progbits,1
    .L.str:
    	.asciz	"hello world %d\r\n"
    	.size	.L.str, 17
    
    	.ident	"Android (9352603, based on r450784d1) clang version 14.0.7 (https://android.googlesource.com/toolchain/llvm-project 4c603efb0cca074e9238af8b4106c30add4418f6)"
    	.section	".note.GNU-stack","",%progbits
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    你可以修改上面的代码编写相关兴趣汇编语句。(.code 16 指示代码是16位的,.p2align 2表示对齐大小。在学习的时候需要注意你学习的指令集,其他direction 你可以执行查阅文档)

    在你修改汇编文件将其编译成可执行文件

    CC  hello.S  -o hello.out
    
    • 1

    接着push到手机运行即可

    #!bin/zsh
    adb push hello.out /data/local/tmp
    adb shell "/data/local/tmp/hello.out"
    
    • 1
    • 2
    • 3

    如果在Mac下学习可能需要调用binutils工具可通过homebrew安装.
    以下是一些常用命令

    #输出二进制节信息
    readElf -S hello.out
    
    • 1
    • 2

    输出结果:

    There are 27 section headers, starting at offset 0xfe0:
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .interp           PROGBITS         00000000000002a8  000002a8
           0000000000000015  0000000000000000   A       0     0     1
      [ 2] .note.androi[...] NOTE             00000000000002c0  000002c0
           0000000000000098  0000000000000000   A       0     0     4
      [ 3] .dynsym           DYNSYM           0000000000000358  00000358
           0000000000000060  0000000000000018   A       8     1     8
      [ 4] .gnu.version      VERSYM           00000000000003b8  000003b8
           0000000000000008  0000000000000002   A       3     0     2
      [ 5] .gnu.version_r    VERNEED          00000000000003c0  000003c0
           0000000000000020  0000000000000000   A       8     1     4
      [ 6] .gnu.hash         GNU_HASH         00000000000003e0  000003e0
           000000000000001c  0000000000000000   A       3     0     8
      [ 7] .hash             HASH             00000000000003fc  000003fc
           0000000000000028  0000000000000004   A       3     0     4
      [ 8] .dynstr           STRTAB           0000000000000424  00000424
           0000000000000037  0000000000000000   A       0     0     1
      [ 9] .rela.dyn         RELA             0000000000000460  00000460
           0000000000000060  0000000000000018   A       3     0     8
      [10] .rela.plt         RELA             00000000000004c0  000004c0
           0000000000000048  0000000000000018  AI       3    21     8
      [11] .rodata           PROGBITS         0000000000000508  00000508
           0000000000000011  0000000000000001 AMS       0     0     1
      [12] .eh_frame_hdr     PROGBITS         000000000000051c  0000051c
           000000000000002c  0000000000000000   A       0     0     4
      [13] .eh_frame         PROGBITS         0000000000000548  00000548
           000000000000008c  0000000000000000   A       0     0     8
      [14] .text             PROGBITS         00000000000015d4  000005d4
           00000000000000c8  0000000000000000  AX       0     0     4
      [15] .plt              PROGBITS         00000000000016a0  000006a0
           0000000000000050  0000000000000000  AX       0     0     16
      [16] .preinit_array    PREINIT_ARRAY    00000000000026f0  000006f0
           0000000000000010  0000000000000000  WA       0     0     8
      [17] .init_array       INIT_ARRAY       0000000000002700  00000700
           0000000000000010  0000000000000000  WA       0     0     8
      [18] .fini_array       FINI_ARRAY       0000000000002710  00000710
           0000000000000010  0000000000000000  WA       0     0     8
      [19] .dynamic          DYNAMIC          0000000000002720  00000720
           00000000000001d0  0000000000000010  WA       8     0     8
      [20] .got              PROGBITS         00000000000028f0  000008f0
           0000000000000020  0000000000000000  WA       0     0     8
      [21] .got.plt          PROGBITS         0000000000002910  00000910
           0000000000000030  0000000000000000  WA       0     0     8
      [22] .bss              NOBITS           0000000000003940  00000940
           0000000000000008  0000000000000000  WA       0     0     8
      [23] .comment          PROGBITS         0000000000000000  00000940
           00000000000000b2  0000000000000001  MS       0     0     1
      [24] .symtab           SYMTAB           0000000000000000  000009f8
           00000000000003a8  0000000000000018          26    31     8
      [25] .shstrtab         STRTAB           0000000000000000  00000da0
           00000000000000fe  0000000000000000           0     0     1
      [26] .strtab           STRTAB           0000000000000000  00000e9e
           000000000000013f  0000000000000000           0     0     1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      D (mbind), p (processor specific)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    # 输出反汇编
    objdump -d hello.out
    
    • 1
    • 2
    hello.out:     file format elf64-littleaarch64
    
    
    Disassembly of section .text:
    
    00000000000015d4 <_start>:
        15d4:       d503249f        bti     j
        15d8:       d280001d        mov     x29, #0x0                       // #0
        15dc:       d280001e        mov     x30, #0x0                       // #0
        15e0:       910003e0        mov     x0, sp
        15e4:       14000001        b       15e8 <_start_main>
    
    00000000000015e8 <_start_main>:
        15e8:       d503233f        paciasp
        15ec:       d100c3ff        sub     sp, sp, #0x30
        15f0:       a9027bfd        stp     x29, x30, [sp, #32]
        15f4:       910083fd        add     x29, sp, #0x20
        15f8:       b0000008        adrp    x8, 2000 <printf@plt+0x920>
        15fc:       b0000009        adrp    x9, 2000 <printf@plt+0x920>
        1600:       b000000a        adrp    x10, 2000 <printf@plt+0x920>
        1604:       b0000002        adrp    x2, 2000 <printf@plt+0x920>
        1608:       910023e3        add     x3, sp, #0x8
        160c:       aa1f03e1        mov     x1, xzr
        1610:       f9447908        ldr     x8, [x8, #2288]
        1614:       f9447d29        ldr     x9, [x9, #2296]
        1618:       f944814a        ldr     x10, [x10, #2304]
        161c:       a900a7e8        stp     x8, x9, [sp, #8]
        1620:       f9000fea        str     x10, [sp, #24]
        1624:       f9448442        ldr     x2, [x2, #2312]
        1628:       94000026        bl      16c0 <__libc_init@plt>
    
    000000000000162c <__atexit_handler_wrapper>:
        162c:       d503245f        bti     c
        1630:       b4000060        cbz     x0, 163c <__atexit_handler_wrapper+0x10>
        1634:       aa0003f0        mov     x16, x0
        1638:       d61f0200        br      x16
        163c:       d65f03c0        ret
    
    0000000000001640 <atexit>:
        1640:       d503245f        bti     c
        1644:       aa0003e1        mov     x1, x0
        1648:       90000000        adrp    x0, 1000 <__FRAME_END__+0xab8>
        164c:       d0000002        adrp    x2, 3000 <_DYNAMIC+0x8e0>
        1650:       9118b000        add     x0, x0, #0x62c
        1654:       91250042        add     x2, x2, #0x940
        1658:       1400001e        b       16d0 <__cxa_atexit@plt>
    
    000000000000165c <main>:
        165c:       d100c3ff        sub     sp, sp, #0x30
        1660:       a9027bfd        stp     x29, x30, [sp, #32]
        1664:       910083fd        add     x29, sp, #0x20
        1668:       2a1f03e8        mov     w8, wzr
        166c:       b9000fe8        str     w8, [sp, #12]
        1670:       b81fc3bf        stur    wzr, [x29, #-4]
        1674:       b81f83a0        stur    w0, [x29, #-8]
        1678:       f9000be1        str     x1, [sp, #16]
        167c:       b85f83a1        ldur    w1, [x29, #-8]
        1680:       f0ffffe0        adrp    x0, 0 <note_android_ident-0x2c0>
        1684:       91142000        add     x0, x0, #0x508
        1688:       94000016        bl      16e0 <printf@plt>
        168c:       b9400fe0        ldr     w0, [sp, #12]
        1690:       a9427bfd        ldp     x29, x30, [sp, #32]
        1694:       9100c3ff        add     sp, sp, #0x30
        1698:       d65f03c0        ret
    
    Disassembly of section .plt:
    
    00000000000016a0 <__libc_init@plt-0x20>:
        16a0:       a9bf7bf0        stp     x16, x30, [sp, #-16]!
        16a4:       b0000010        adrp    x16, 2000 <printf@plt+0x920>
        16a8:       f9449211        ldr     x17, [x16, #2336]
        16ac:       91248210        add     x16, x16, #0x920
        16b0:       d61f0220        br      x17
        16b4:       d503201f        nop
        16b8:       d503201f        nop
        16bc:       d503201f        nop
    
    00000000000016c0 <__libc_init@plt>:
        16c0:       b0000010        adrp    x16, 2000 <printf@plt+0x920>
        16c4:       f9449611        ldr     x17, [x16, #2344]
        16c8:       9124a210        add     x16, x16, #0x928
        16cc:       d61f0220        br      x17
    
    00000000000016d0 <__cxa_atexit@plt>:
        16d0:       b0000010        adrp    x16, 2000 <printf@plt+0x920>
        16d4:       f9449a11        ldr     x17, [x16, #2352]
        16d8:       9124c210        add     x16, x16, #0x930
        16dc:       d61f0220        br      x17
    
    00000000000016e0 <printf@plt>:
        16e0:       b0000010        adrp    x16, 2000 <printf@plt+0x920>
        16e4:       f9449e11        ldr     x17, [x16, #2360]
        16e8:       9124e210        add     x16, x16, #0x938
        16ec:       d61f0220        br      x17
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    调试

    由于NDK已经放弃GDB的套件改用LLDB,所以本文将使用远程调试方式。

    由于参考链接链接写的过于详细,这里不在说明。

    LLDB-remote
    How do I use lldb to debug C++ code on Android on command line

  • 相关阅读:
    JVM 性能监控与故障处理工具
    渗透测试工程师(NISP-PT)
    大前端CPU优化技术--NEON指令介绍
    docker制作镜像
    计算机网络:数据链路层功能
    day33 文件上传&中间件解析漏洞&编辑器安全
    电机行业mes系统解决方案
    本地缓存 guava
    第四节 基本运算符和变量,数组切片
    Kerberos
  • 原文地址:https://blog.csdn.net/qfanmingyiq/article/details/133856678