【基于Android的ARM汇编语言系列】之二:C/C++程序生成ARM汇编程序的过程分析

时间:2021-04-22 00:53:28

作者:郭嘉
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell

【基于Android的ARM汇编语言系列】章节列表

【基于Android的ARM汇编语言系列】之一:ARM汇编语言开篇
【基于Android的ARM汇编语言系列】之二:C/C++程序生成ARM汇编程序的过程分析
【基于Android的ARM汇编语言系列】之三:ARM汇编语言程序结构
【基于Android的ARM汇编语言系列】之四:ARM处理器的寻址方式
【基于Android的ARM汇编语言系列】之五:ARM指令集与Thumb指令集
【基于Android的ARM汇编语言系列】之六:NEON指令集与VFP指令集

所谓的原生程序指的是用C/C++编写的程序,下面来详细演示一下原生程序是怎么一步步生成汇编代码的。

这里编译的是一个简单的hello.c程序,如下所示:

#include <stdio.h>

int main(int argc, char* argv[]){
printf("Hello ARM!\n");
return 0;
}

一 预处理

预处理阶段会处理代码中的预处理指令,如下所示:

  • #include
  • #define
  • #if

执行以下命令进行预处理,-E可以用来查看详细输出。

gcc -E hello.c -o hello.i

成成的hello.i如下所示:

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "hello.c"
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 1
# 41 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h"
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/cdefs.h" 1
# 59 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/cdefs.h"
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/cdefs_elf.h" 1
# 60 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/cdefs.h" 2
# 42 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 2
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/_types.h" 1
# 40 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/_types.h"
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/machine/_types.h" 1
# 52 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/machine/_types.h"
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short __int16_t;
typedef unsigned short __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;

typedef long long __int64_t;

typedef unsigned long long __uint64_t;


typedef __int8_t __int_least8_t;
typedef __uint8_t __uint_least8_t;
typedef __int16_t __int_least16_t;
typedef __uint16_t __uint_least16_t;
typedef __int32_t __int_least32_t;
typedef __uint32_t __uint_least32_t;
typedef __int64_t __int_least64_t;
typedef __uint64_t __uint_least64_t;


typedef __int32_t __int_fast8_t;
typedef __uint32_t __uint_fast8_t;
typedef __int32_t __int_fast16_t;
typedef __uint32_t __uint_fast16_t;
typedef __int32_t __int_fast32_t;
typedef __uint32_t __uint_fast32_t;
typedef __int64_t __int_fast64_t;
typedef __uint64_t __uint_fast64_t;


typedef int __intptr_t;
typedef unsigned int __uintptr_t;


typedef __int64_t __intmax_t;
typedef __uint64_t __uintmax_t;


typedef __int32_t __register_t;


typedef unsigned long __vaddr_t;
typedef unsigned long __paddr_t;
typedef unsigned long __vsize_t;
typedef unsigned long __psize_t;


typedef int __clock_t;
typedef int __clockid_t;
typedef long __ptrdiff_t;
typedef int __time_t;
typedef int __timer_t;

typedef __builtin_va_list __va_list;






typedef int __wchar_t;

typedef int __wint_t;
typedef int __rune_t;
typedef void * __wctrans_t;
typedef void * __wctype_t;
# 41 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/_types.h" 2

typedef unsigned long __cpuid_t;
typedef __int32_t __dev_t;
typedef __uint32_t __fixpt_t;
typedef __uint32_t __gid_t;
typedef __uint32_t __id_t;
typedef __uint32_t __in_addr_t;
typedef __uint16_t __in_port_t;
typedef __uint32_t __ino_t;
typedef long __key_t;
typedef __uint32_t __mode_t;
typedef __uint32_t __nlink_t;
typedef __int32_t __pid_t;
typedef __uint64_t __rlim_t;
typedef __uint16_t __sa_family_t;
typedef __int32_t __segsz_t;
typedef __uint32_t __socklen_t;
typedef __int32_t __swblk_t;
typedef __uint32_t __uid_t;
typedef __uint32_t __useconds_t;
typedef __int32_t __suseconds_t;





typedef union {
char __mbstate8[128];
__int64_t __mbstateL;
} __mbstate_t;
# 43 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 2



# 1 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stdarg.h" 1 3 4
# 40 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 47 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 2



# 1 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 1 3 4
# 211 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 3 4
typedef unsigned int size_t;
# 51 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 2

# 1 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 1 3 4
# 149 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 3 4
typedef int ptrdiff_t;
# 323 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 3 4
typedef unsigned int wchar_t;
# 53 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 2


# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 1
# 33 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h"
# 1 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 1 3 4
# 34 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h" 1
# 31 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
# 1 "c:/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/stddef.h" 1 3 4
# 32 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h" 2
# 48 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef __int8_t int8_t;
typedef __uint8_t uint8_t;
typedef __int16_t int16_t;
typedef __uint16_t uint16_t;
typedef __int32_t int32_t;
typedef __uint32_t uint32_t;

typedef __int64_t int64_t;
typedef __uint64_t uint64_t;






typedef int8_t int_least8_t;
typedef int8_t int_fast8_t;

typedef uint8_t uint_least8_t;
typedef uint8_t uint_fast8_t;
# 97 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef int16_t int_least16_t;
typedef int32_t int_fast16_t;

typedef uint16_t uint_least16_t;
typedef uint32_t uint_fast16_t;
# 130 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef int32_t int_least32_t;
typedef int32_t int_fast32_t;

typedef uint32_t uint_least32_t;
typedef uint32_t uint_fast32_t;
# 163 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef int64_t int_least64_t;
typedef int64_t int_fast64_t;

typedef uint64_t uint_least64_t;
typedef uint64_t uint_fast64_t;
# 207 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef int intptr_t;
typedef unsigned int uintptr_t;
# 232 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef uint64_t uintmax_t;
typedef int64_t intmax_t;
# 268 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdint.h"
typedef long int ssize_t;
# 35 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2


# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/posix_types.h" 1
# 15 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/posix_types.h"
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/stddef.h" 1
# 15 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/stddef.h"
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/compiler.h" 1
# 16 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/stddef.h" 2
# 16 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/posix_types.h" 2
# 32 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/posix_types.h"
typedef struct {
unsigned long fds_bits [(1024/(8 * sizeof(unsigned long)))];
} __kernel_fd_set;

typedef void (*__kernel_sighandler_t)(int);

typedef int __kernel_key_t;
typedef int __kernel_mqd_t;

# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/asm/posix_types.h" 1
# 15 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/asm/posix_types.h"
typedef unsigned long __kernel_ino_t;
typedef unsigned short __kernel_mode_t;
typedef unsigned short __kernel_nlink_t;
typedef long __kernel_off_t;
typedef int __kernel_pid_t;
typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t;
typedef int __kernel_timer_t;
typedef int __kernel_clockid_t;
typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;

typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
typedef unsigned short __kernel_old_dev_t;


typedef long long __kernel_loff_t;


typedef struct {



int __val[2];

} __kernel_fsid_t;
# 42 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/posix_types.h" 2
# 38 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/asm/types.h" 1
# 17 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/asm/types.h"
typedef unsigned short umode_t;

typedef __signed__ char __s8;
typedef unsigned char __u8;

typedef __signed__ short __s16;
typedef unsigned short __u16;

typedef __signed__ int __s32;
typedef unsigned int __u32;


typedef __signed__ long long __s64;
typedef unsigned long long __u64;
# 39 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/types.h" 1
# 21 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/linux/types.h"
typedef __u16 __le16;
typedef __u16 __be16;
typedef __u32 __le32;
typedef __u32 __be32;

typedef __u64 __le64;
typedef __u64 __be64;


struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
char f_fname[6];
char f_fpack[6];
};
# 40 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2
# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/machine/kernel.h" 1
# 34 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/machine/kernel.h"
typedef unsigned long __kernel_blkcnt_t;
typedef unsigned long __kernel_blksize_t;


typedef unsigned long __kernel_fsblkcnt_t;
typedef unsigned long __kernel_fsfilcnt_t;
typedef unsigned int __kernel_id_t;
# 41 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2

typedef __u32 __kernel_dev_t;
# 52 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h"
typedef __kernel_blkcnt_t blkcnt_t;
typedef __kernel_blksize_t blksize_t;
typedef __kernel_clock_t clock_t;
typedef __kernel_clockid_t clockid_t;
typedef __kernel_dev_t dev_t;
typedef __kernel_fsblkcnt_t fsblkcnt_t;
typedef __kernel_fsfilcnt_t fsfilcnt_t;
typedef __kernel_gid32_t gid_t;
typedef __kernel_id_t id_t;
typedef __kernel_ino_t ino_t;
typedef __kernel_key_t key_t;
typedef __kernel_mode_t mode_t;
typedef __kernel_nlink_t nlink_t;


typedef __kernel_off_t off_t;

typedef __kernel_loff_t loff_t;
typedef loff_t off64_t;

typedef __kernel_pid_t pid_t;
# 99 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h"
typedef __kernel_suseconds_t suseconds_t;
typedef __kernel_time_t time_t;
typedef __kernel_uid32_t uid_t;
typedef signed long useconds_t;

typedef __kernel_daddr_t daddr_t;
typedef __kernel_timer_t timer_t;
typedef __kernel_mqd_t mqd_t;

typedef __kernel_caddr_t caddr_t;
typedef unsigned int uint_t;
typedef unsigned int uint;


# 1 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/sysmacros.h" 1
# 36 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/sysmacros.h"
static __inline__ int major(dev_t _dev)
{
return (_dev >> 8) & 0xfff;
}

static __inline__ int minor(dev_t _dev)
{
return (_dev & 0xff) | ((_dev >> 12) & 0xfff00);
}

static __inline__ dev_t makedev(int __ma, int __mi)
{
return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12);
}
# 114 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/sys/types.h" 2


typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;

typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
typedef uint64_t u_int64_t;
# 56 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h" 2
# 78 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h"
typedef off_t fpos_t;
# 87 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h"
struct __sbuf {
unsigned char *_base;
int _size;
};
# 119 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h"
typedef struct __sFILE {
unsigned char *_p;
int _r;
int _w;
short _flags;
short _file;
struct __sbuf _bf;
int _lbfsize;


void *_cookie;
int (*_close)(void *);
int (*_read)(void *, char *, int);
fpos_t (*_seek)(void *, fpos_t, int);
int (*_write)(void *, const char *, int);


struct __sbuf _ext;

unsigned char *_up;
int _ur;


unsigned char _ubuf[3];
unsigned char _nbuf[1];


struct __sbuf _lb;


int _blksize;
fpos_t _offset;
} FILE;


extern FILE __sF[];

# 223 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h"

void clearerr(FILE *);
int fclose(FILE *);
int feof(FILE *);
int ferror(FILE *);
int fflush(FILE *);
int fgetc(FILE *);
int fgetpos(FILE *, fpos_t *);
char *fgets(char *, int, FILE *);
FILE *fopen(const char *, const char *);
int fprintf(FILE *, const char *, ...);
int fputc(int, FILE *);
int fputs(const char *, FILE *);
size_t fread(void *, size_t, size_t, FILE *);
FILE *freopen(const char *, const char *, FILE *);
int fscanf(FILE *, const char *, ...);
int fseek(FILE *, long, int);
int fseeko(FILE *, off_t, int);
int fsetpos(FILE *, const fpos_t *);
long ftell(FILE *);
off_t ftello(FILE *);
size_t fwrite(const void *, size_t, size_t, FILE *);
int getc(FILE *);
int getchar(void);
char *gets(char *);



extern int sys_nerr;
extern char *sys_errlist[];

void perror(const char *);
int printf(const char *, ...);
int putc(int, FILE *);
int putchar(int);
int puts(const char *);
int remove(const char *);
int rename(const char *, const char *);
void rewind(FILE *);
int scanf(const char *, ...);
void setbuf(FILE *, char *);
int setvbuf(FILE *, char *, int, size_t);
int sprintf(char *, const char *, ...);
int sscanf(const char *, const char *, ...);
FILE *tmpfile(void);
char *tmpnam(char *);
int ungetc(int, FILE *);
int vfprintf(FILE *, const char *, __va_list);
int vprintf(const char *, __va_list);
int vsprintf(char *, const char *, __va_list);


int snprintf(char *, size_t, const char *, ...)
__attribute__((__format__ (printf, 3, 4)))
__attribute__((__nonnull__ (3)));
int vfscanf(FILE *, const char *, __va_list)
__attribute__((__format__ (scanf, 2, 0)))
__attribute__((__nonnull__ (2)));
int vscanf(const char *, __va_list)
__attribute__((__format__ (scanf, 1, 0)))
__attribute__((__nonnull__ (1)));
int vsnprintf(char *, size_t, const char *, __va_list)
__attribute__((__format__ (printf, 3, 0)))
__attribute__((__nonnull__ (3)));
int vsscanf(const char *, const char *, __va_list)
__attribute__((__format__ (scanf, 2, 0)))
__attribute__((__nonnull__ (2)));



# 302 "c:/android-ndk-r8/platforms/android-14/arch-arm/usr/include/stdio.h"





FILE *fdopen(int, const char *);
int fileno(FILE *);


int pclose(FILE *);
FILE *popen(const char *, const char *);



void flockfile(FILE *);
int ftrylockfile(FILE *);
void funlockfile(FILE *);





int getc_unlocked(FILE *);
int getchar_unlocked(void);
int putc_unlocked(int, FILE *);
int putchar_unlocked(int);



char *tempnam(const char *, const char *);










int asprintf(char **, const char *, ...)
__attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2)));
char *fgetln(FILE *, size_t *);
int fpurge(FILE *);
int getw(FILE *);
int putw(int, FILE *);
void setbuffer(FILE *, char *, int);
int setlinebuf(FILE *);
int vasprintf(char **, const char *, __va_list)
__attribute__((__format__ (printf, 2, 0)))
__attribute__((__nonnull__ (2)));






FILE *funopen(const void *,
int (*)(void *, char *, int),
int (*)(void *, const char *, int),
fpos_t (*)(void *, fpos_t, int),
int (*)(void *));









int __srget(FILE *);
int __swbuf(int, FILE *);








static __inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
# 2 "hello.c" 2

int main(int argc, char* argv[]){
printf("Hello ARM!\n");
return 0;
}

二 编译

编译阶段编译器会检查代码规范性,以及是否有语法错误等。

执行以下命令进行编译,-S可以用来查看编译器输出。

gcc -S hello.i -o hello.s

生成的hello.s文件如下所示:

    .arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file "hello.c"
.section .rodata
.align 2
.LC0:
.ascii "Hello ARM!\000"
.text
.align 2
.global main
.type main, %function
main:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {fp, lr}
add fp, sp, #4
sub sp, sp, #8
str r0, [fp, #-8]
str r1, [fp, #-12]
ldr r3, .L3
.LPIC0:
add r3, pc, r3
mov r0, r3
bl puts(PLT)
mov r3, #0
mov r0, r3
sub sp, fp, #4
ldmfd sp!, {fp, pc}
.L4:
.align 2
.L3:
.word .LC0-(.LPIC0+8)
.size main, .-main
.ident "GCC: (GNU) 4.4.3"
.section .note.GNU-stack,"",%progbits

这里便是ARM汇编代码了,后续的文章会详细介绍这些代码的具体含义。

三 汇编

汇编阶段汇编器会将汇编代码汇编成二进制目标文件。

执行以下命令进行汇编:

gcc -c hello.s -o hello.o

生成的hello.o文件,用IDAPro反汇编以后如下所示:

;
; +-------------------------------------------------------------------------+
; | This file has been generated by The Interactive Disassembler (IDA) |
; | Copyright (c) 2011 Hex-Rays, <support@hex-rays.com> |
; | License info: 48-327F-7274-B7 |
; | ESET spol. s r.o. |
; +-------------------------------------------------------------------------+
;
; Input MD5 : B0821B68099D81DC63D478051984E2D8
; Input CRC32 : 68360FC1

; File Name : C:\Users\Administrator\Desktop\【Android SDK程序逆向分析与破解系列】\相关资料\Android软件安全与逆向分析【丰生强】\Android软件安全与逆向分析【丰生强】随书光盘\chapter6\6.2\6.2.2\hello\hello.o
; Format : ELF for ARM (Relocatable)
;
; EABI version: 5
;
; Source File : 'hello.c'

; Processor : ARM
; Target assembler: Generic assembler for ARM
; Byte sex : Little endian


; Segment type: Pure code
AREA .text, CODE
CODE32


; Attributes: bp-based frame

EXPORT main
main

var_C= -0xC
var_8= -8

STMFD SP!, {R11,LR}
ADD R11, SP, #4
SUB SP, SP, #8
STR R0, [R11,#var_8]
STR R1, [R11,#var_C]
LDR R3, =(aHelloArm-0x20) ; "Hello ARM!"
ADD R3, PC, R3 ; "Hello ARM!"
MOV R0, R3 ; s
BL puts ; PIC mode
MOV R3, #0
MOV R0, R3
SUB SP, R11, #4
LDMFD SP!, {R11,PC}
; End of function main

四 链接

链接阶段会调用链接器将二进制的目标文件链接成Android平台可执行的ARM原生程序。

执行以下命令进行链接:

gcc hello.o -o hello

这个过程还需要链接其他目标文件,参数配置见以下Makefile脚本:

NDK_ROOT=c:/android-ndk-r8
TOOLCHAINS_ROOT=$(NDK_ROOT)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/4.4.3/include-fixed

PLATFORM_ROOT=$(NDK_ROOT)/platforms/android-14/arch-arm
PLATFORM_INCLUDE=$(PLATFORM_ROOT)/usr/include
PLATFORM_LIB=$(PLATFORM_ROOT)/usr/lib
SYSROOT=$(PLATFORM_ROOT)
MODULE_NAME=hello
RM=del

FLAGS=-I$(TOOLCHAINS_INCLUDE) \
-I$(PLATFORM_INCLUDE) \
-L$(PLATFORM_LIB) \

OBJS=$(MODULE_NAME).o \
$(PLATFORM_LIB)/crtbegin_dynamic.o \
$(PLATFORM_LIB)/crtend_android.o

all:
$(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -E $(MODULE_NAME).c -o $(MODULE_NAME).i
$(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -S $(MODULE_NAME).i -o $(MODULE_NAME).s
$(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -c $(MODULE_NAME).s -o $(MODULE_NAME).o
$(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -nostdlib -lgcc -Bdynamic -lc $(OBJS) -o $(MODULE_NAME)
clean:
$(RM) *.o
install:
adb push $(MODULE_NAME) /data/local/
adb shell chmod 755 /data/local/$(MODULE_NAME)

生成的可执行文件hello用IDAPro反汇编如下所示:

; Segment type: Pure code
AREA .text, CODE, ALIGN=4
; ORG 0x82E0
CODE32


; Attributes: bp-based frame

EXPORT main
main

var_C= -0xC
var_8= -8

STMFD SP!, {R11,LR}
ADD R11, SP, #4
SUB SP, SP, #8
STR R0, [R11,#var_8]
STR R1, [R11,#var_C]
LDR R3, =(aHelloArm - 0x8300)
ADD R3, PC, R3 ; "Hello ARM!"
MOV R0, R3 ; s
BL puts
MOV R3, #0
MOV R0, R3
SUB SP, R11, #4
LDMFD SP!, {R11,PC}
; End of function main

从以上过程可以看出,经过编译后C代码就转换成了汇编代码,因此可以直接编写汇编代码来开发ARM程序。Android NDK支持直接使用ARM汇编语言编写以.s结尾的文件作为程序的源文件,同时还允许使用C代码与ARM汇编代码进行混合编程。