[基于Android的ARM汇编语言系列]之二:原生程序的生成过程

作者:郭嘉

邮箱:[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

[基于Android的ARM汇编语言系列]之二:原生程序的生成过程的相关文章

[基于Android的ARM汇编语言系列]之一:ARM汇编语言开篇

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 这是[基于Android的ARM汇编语言系列]博文的开篇文章,这里会先介绍一下ARM处理器的大致分类和作用. 一 ARM处理器与ARM指令集 整个ARM处理器被分为三个部分: Classic Embedded Application Classic被称为经典系列. ARM1~ARM11一直都以数字来命名

[基于Android的ARM汇编语言系列]之三:ARM汇编语言程序结构

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell Android平台的ARM汇编是GNU ARM汇编格式,使用的汇编器是GAS(GNU Assembler),GAS有自己的一套语法结构.详细的内容可以查阅GAS语法结构官方手册. 我们先来看一个完整的ARM汇编程序: C代码: #include <stdio.h> int main(int argc,

[基于Android的ARM汇编语言系列]之四:ARM处理器的寻址方式

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 处理器的寻址方式是通过指令给出的地址码字段来寻找真实操作数地址的方式,ARM处理器支持9中寻址方式. 一 立即寻址 立即寻址指令后面的地址码部分为立即数(常量或常数),立即寻址多用于给寄存器赋值. 举例 MOV RO, #1234 指令执行后,R0=1234. 二 寄存器寻址 寄存器寻址中,操作数在寄存

[基于Android的ARM汇编语言系列]之五:ARM指令集与Thumb指令集

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell 写在前面:本篇文章旨在大致介绍下ARM指令集的相关内容,这里也同时提供一个有详细解释和用例的待书签的PDF版本,方便大家查阅. ARM指令集详解 指令集是处理器的核心,ARM指令的基本格式如下所示: opcode {cond}{S}{.W\.N}Rd, Rn{.operand2} S:指定是否影响CPS

[基于Android的ARM汇编语言系列]之六:NEON指令集与VFP指令集

作者:郭嘉 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell NEON指令集与VFP指令集是ARM指令集的扩展,多用于多媒体编程和浮点运算. 一 Android平台使用NEON指令集与VFP指令集 Android NDK从r3版本开始也添加了对NEON指令集与VFP指令集的支持.使用方法如下所示: 1 运行时检测处理器是否支持NEON指令集与VFP指令集 Andr

移动端--基于Android Studio的项目文件结构(二)【转】

转自[https://www.cnblogs.com/hwb04160011/p/7978816.html] Android基础--项目的文件结构(二) AndroidManifest.xml文件分析 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目中,AndroidManifest.xml文件(安卓清单文件)是整个APP的配置文件,它位于文件结构中app文件夹中,相当于根目录.四大组件都需要在AndroidManifest.xml文件

【Android Studio安装部署系列】二十八、Android Studio查看其它APP的布局结构

概述 日常使用别家的APP过程中,会遇到一些比较好看的布局,这时候我们就想学习一下别人的布局结构,以便参考. (1)手机连接电脑.设置手机为USB调试模式 参考<[Android Studio安装部署系列]七.真机运行项目> (2)运行Android Studio,打开 Tools--Android--Android Device Monitor 注意:android Studio3.1开始只能通过命令行的方式启动Android Device Monitor. 双击sdk安装目录/tools/

基于Android的计步器(Pedometer)的讲解(二)——柱状图分析

写正文之前,小小的吐槽一下,还有一个月就放假了,作业.考试.还有实习(研一,下半学期课不多,也不想在实验室)的考虑,最近基于hadoop的数据分析马上也要验收了,真的忙的"外焦里嫩"啊!目前定的方向是Android开发,所以想过年来了找一个Android的实习工作,提高一点在真正的项目中的经验. 好了,说了这么多废话,开始进入正题吧. 整个计步器的项目已经上传到github上了,感兴趣的朋友可以去看看(最好能给小弟我打颗星星哦~) https://github.com/29677751

【原创】源码角度分析Android的消息机制系列(二)——ThreadLocal的工作过程

ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一篇文章中,我们已经提到了ThreadLocal,它并非线程,而是在线程中存储数据用的.数据存储以后,只能在指定的线程中获取到数据,对于其他线程来说是无法获取到数据的,也就是说ThreadLocal可以在多个线程中互不干扰地存储和修改数据.基于ThreadLocal的这一特点,那么当我们在开发中,需要将某些数据以线程作为作用域,并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal了. Android的消息机制中也