dz0212 发表于 2013-03-01 15:11

openbsd源码情景分析 一 汇编程序的编写

    openbsd方面的资料很少,汇编的资料就更少了,这篇文章的每前进一步都是一个痛苦探索的过程,看OpenBSD源码(sys.tar.gz和src.tar.gz),学习linux此类书籍的分析方法,再利用gdb和objdump工具反复调试。
0x01 编译器和链接器
    默认的编译器为AS(AS - the portable GNU assembler)。x86汇编一直存在两种语法intel语法和AT&A语法。Unix平台一直使用AT&A语法,本文也使用此语法。
    链接器ld(ld - Using LD, the GNU linker)
0x02 最简单的汇编程序
首先来看c语言
$vi exit.c
#include <stdlib.h>
int main(void)
{
      exit(5);/*退出并返回状态码5*/
}
$ gcc exit.c -o exit.bin
$ ./exit.bin
$ echo $?
5
$ls -l
-rwxr-xr-x1 walkmanwalkman6696 Jan 29 02:55 exit.bin
汇编语言实现,程序1:
$ vi exit.s
.globl _start
_start:
#将系统调用exit的返回值5,压入栈
pushl $0x5
#将系统调用参数结束标志,压入栈
pushl $0x0
#将系统调用exit的系统调用号1传入寄存器eax
movl $0x01,%eax
int    $0x80
$ as exit.s -o exit.o   ;编译
$ ld exit.o -o exit.bin ;链接
$ ./exit.bin            ;运行
$ echo $?               ;显示返回码
5 ls -l
-rwxr-xr-x1 walkmanwalkman4843 Jan 29 02:52 exit.bin
-rw-r--r--1 walkmanwalkman   476 Jan 29 02:52 exit.o
-rw-r--r--1 walkmanwalkman    89 Jan 29 02:49 exit.s
0x03 汇编程序的基本框架
#数据段
.section .data
......
#代码段
.section .text
#定义入口标签_start
.globl _start
_start:
#代码开始
......

0x04 函数调用的规则
1)参数压栈传递,参数从右向左依次压栈;
2)ebp总是指向当前栈的栈底。
3)返回值通过eax寄存器传递;
0x05 Hello World
c语言实现
$ vi hello.c
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
      int n;
      n=write(1,"hello,wrold!\n\0",14);
      exit(n);
}
$ gcc hello.c -o hello.bin
$ ./hello.bin
hello,wrold!
$ echo $?
14
汇编实现,程序2:
$ vi hello.s

1       .section .data
2       msg:
3       .ascii "hello world!\n\0"
4       .set len,.-msg
5       .section .text
6       .globl _start
7       _start:
8       #write()
#write(int d, const void *buf, size_t nbytes);
#从右向左依次将参数压入栈
9       pushl $len ;显示字符串的长度
10      pushl $msg ;显示字符串的地址
11      pushl $0x01 ;文件描述符,0标准输入,1标准输出,2标准错误
#将参数结束标志压入栈
12      pushl $0x00
#将系统调用write的系统调用号4传入寄存器eax,其返还值仍保存在eax中,
#正常结束返回显示字符串的长度(本例为14),如异常结束返回错误码
13      movl $0x04,%eax
14      int $0x80
15      #exit()
#将系统调用write的返回值压入栈,作为exit的返回值
16      pushl %eax
17      pushl $0x00
18      movl $01,%eax
19      int $0x80

$ as hello.s -o hello.o
$ ld hello.o -o hello.bin
$ ./hello.bin
hello world!
$ echo $?
14
注:系统函数的调用号及参数,可在以下文件查得
$ more /usr/include/sys/syscall.h

/*
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
* created from;      OpenBSD: syscalls.master,v 1.124 2012/06/21 00:56:59 guenther Exp
*/

/* syscall: "syscall" ret: "int" args: "int" "..." */
#define SYS_syscall   0

/* syscall: "exit" ret: "void" args: "int" */
#define SYS_exit      1

/* syscall: "fork" ret: "int" args: */
#define SYS_fork      2

/* syscall: "read" ret: "ssize_t" args: "int" "void *" "size_t" */
#define SYS_read      3

/* syscall: "write" ret: "ssize_t" args: "int" "const void *" "size_t" */
#define SYS_write       4

--------------------------------------------

gvim 发表于 2013-03-07 13:02

好啊,多分享点:mrgreen:

gvim 发表于 2013-03-07 13:02

好啊,多分享点:mrgreen:
页: [1]
查看完整版本: openbsd源码情景分析 一 汇编程序的编写