作者:郭嘉
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell
所谓的原生程序指的是用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 - 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, <[email protected]> |
; | 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汇编代码进行混合编程。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 02:45:09