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

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

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

生成的文件如下:

	.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

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

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

CC  hello.S  -o hello.out

接着push到手机运行即可

#!bin/zsh
adb push hello.out /data/local/tmp
adb shell "/data/local/tmp/hello.out"

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

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

输出结果:

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)
# 输出反汇编
objdump -d hello.out
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

调试

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值