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

/* 作者:老董 联系:[email protected] 成稿时间2013-02-08 */

调试分析用到的主要命令及参数
as --gstabs hello.s -o hello.o
ld hello.o -o hello.bin
gdb hello.bin
objdump -dS hello.bin

0x01探索汇编错误处理
为调试方便,对程序2简单修改,见以下程序清单注释;
程序3:
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()
9       pushl $len
10      pushl $msg
11      pushl $0x0a  ;将原标准输出的文件描述符$0x01改为$0x0a,故意设置一个错误点
12      pushl $0x00
13      movl $0x04,%eax
14      int $0x80
15      nop  ;加入此行,用gdb调试时,可设置断点观察
16      #exit()
17      pushl %eax
18      pushl $0x00
19      movl $01,%eax
20      int $0x80
$ as --gstabs hello.s -o hello.o
$ ld hello.o -o hello.bin
编译时该--gstabs参数是必须的,
$ man as
该参数含义为,
           Generate stabs debugging information for each assembler line.  This
           may help debugging assembler code, if the debugger can handle it.
$ ./hello.bin
$ echo $?
9
为啥返回9呢?呵呵,查看/usr/include/sys/errno.h
#define EBADF           9               /* Bad file descriptor */
代码9表示错误的文件描述符。呵呵,为了搞清楚这点,我痛苦分析了3天。
0x02 C语言是如何处理的?
程序4:
$vi helloc.c ;先写一个和程序2功能一样的C程序
1       #include <stdlib.h>
2       #include <sys/types.h>
3       #include <unistd.h>
4       #include <stdio.h>
5
6       int main()
7       {
8               int n;
  /*1表示标准输出,14为显示字符串长度*/
9               n=write(1,"hello,wrold!\n\0",14);/*man write可知,正常返回显示字符串长度,错误返回-1*/
10              printf("%i\n",n);
11  exit(n);
12      }
$ gcc -g -static helloc.c -o helloc.bin ;编译链接成可执行文件
参数 -static
           On systems that support dynamic linking, this prevents linking with
           the shared libraries.  On other systems, this option has no effect.
$ ./helloc.bin
hello,wrold!
14
$ echo $?
14

下面研究C语言错误处理,修改程序4,将行9标准输出1改为10,制造错误
程序5:
1       #include <stdlib.h>
2       #include <sys/types.h>
3       #include <unistd.h>
4       #include <stdio.h>
5
6       int main()
7       {
8               int n;
9               n=write(10,"hello,wrold!\n\0",14);
10  printf("%i\n",n);
11              exit(n);
12      }
$ gcc -static -g helloc.c -o helloc.bin
$ ./helloc.bin
-1   ;为啥是?
$ echo $?
255  ;为啥是?
$ gdb helloc.bin
(gdb) disass main ;反汇编main()主函数
0x1c0003c4 <main+0>:    lea    0x4(%esp),%ecx
0x1c0003c8 <main+4>:    and    $0xfffffff0,%esp
0x1c0003cb <main+7>:    pushl  0xfffffffc(%ecx)
0x1c0003ce <main+10>:   push   %ebp
0x1c0003cf <main+11>:   mov    %esp,%ebp
0x1c0003d1 <main+13>:   push   %ecx
0x1c0003d2 <main+14>:   sub    $0x24,%esp
0x1c0003d5 <main+17>:   movl   $0xe,0x8(%esp)
0x1c0003dd <main+25>:   movl   $0x3c000000,0x4(%esp)
0x1c0003e5 <main+33>:   movl   $0xa,(%esp)
0x1c0003ec <main+40>:   call   0x1c00041a <write> ;此处调用write()系统函数
0x1c0003f1 <main+45>:   mov    %eax,0xfffffff8(%ebp)
0x1c0003f4 <main+48>:   mov    0xfffffff8(%ebp),%eax
0x1c0003f7 <main+51>:   mov    %eax,0x4(%esp)
0x1c0003fb <main+55>:   movl   $0x3c00000f,(%esp)
0x1c000402 <main+62>:   call   0x1c000430 <printf>
0x1c000407 <main+67>:   mov    0xfffffff8(%ebp),%eax
0x1c00040a <main+70>:   mov    %eax,(%esp)
0x1c00040d <main+73>:   call   0x1c0082a0 <exit>
End of assembler dump.
(gdb) disass write ; 反汇编write()系统函数
Dump of assembler code for function write:
0x1c00041a <write+0>:   mov    $0x4,%eax
0x1c00041f <write+5>:   int    $0x80
0x1c000421 <write+7>:   jb     0x1c000414 <main+80> ;错误处理,跳转到地址0x1c000414
0x1c000423 <write+9>:   ret
(gdb) disass main+80 ;也可以用命令 disass 0x1c000414,显示指定地址的反汇编程序
0x1c000414 <main+80>:   jmp    0x1c00eeb8 <__cerror> ;跳转到__cerror
0x1c000419 <main+85>:   nop
(gdb) disass __cerror ;也可用 disass 0x1c00eeb8,显示指定地址的反汇编程序
Dump of assembler code for function __cerror:
0x1c00eeb8 <__cerror+0>:        mov    %eax,0x3c00c7cc  ;将寄存器%eax中的内容保存到0x3c00c7cc地址的内存中
       ;可在此处设置断点,观察寄存器eax中的值
0x1c00eebd <__cerror+5>:        mov    $0xffffffff,%eax ;将立即数0xffffffff存入寄存器eax中,系统函数exit()将它的低八位0xff返回给操作系统
       ;0xff作为有符号数为-1,无符号数是255
0x1c00eec2 <__cerror+10>:       mov    $0xffffffff,%edx
0x1c00eec7 <__cerror+15>:       ret ; 返回到地址0x1c0003f1处
(gdb) b *0x1c00eeb8 ;在此地址设置断点
(gdb) r
(gdb) info registers
eax            0x9      9
    呵呵,以上注释说的很清楚了,不再罗嗦了,若有问题找我[email protected]

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

你可能感兴趣的:(OpenBSD汇编)