(一)
话说windows也有syscall,这是必须的。但是win的syscall可以直接call吗?可以是
可以但是破费周折,搞成SDT之类的复杂概念。下面看看linux是如何做的吧。
- section .data
- msg db “hello hopy!”,0x0a
- section .text
- global _start
- _start:
- mov eax,4
- mov ebx,1
- mov ecx,msg
- mov edx,12
- int0x80
- mov eax,1
- mov ebx,0
- int0x80
关键是系统调用号要知道,开始找的是usr/include/asm-gen*/unistd.h,
可是都不对。后来找的是usr/include/x86_64_linux_gnu/asm/下的头文件,
有2个,分别对应x86和x64.、编译连接指令如下:
- nasm –f elf main.asm
- ld main.o
运行,段转储错误鸟,查了一下,本猫用的是x64位的linux,所以要生成
x64位的程序,或者指明是x86的程序,我选择后者:
- ld –m elf_i386 –o main main.o
哦鸟!
(二)
我们在前一章中看到了如何仅仅用syscall做一些简单的事,现在我们看能不能直接调用
C标准库中的函数快速做一些”复杂”的事:
- section .data
- ft db “now is %d”,10
- section .text
- extern puts
- externexit
- extern sleep
- extern printf
- global main
- main:
- mov edi,11
- again:
- dec edi
- push edi
- push ft
- call printf
- push 1
- call sleep
- cmp edi,0
- jnz again
- push msg
- call puts
- push 0
- call exit
- msg:
- db “happy xxx day!”,0
以上代码功能很简单,从10倒数到0,然后打印一行,最后结束.与之前代码不同的是其中
调用了C标准库中的函数.编译和以前一样:
- nasm –e elf main.asm
我们看看怎么连接:
- gcc –m32 –o main main.o
好鸟!运行正常.
值得注意的是:我的OS是Ubuntu64,而asm代码中是32位的,如果开始用
- ld –m elf_i386 –lc –o main main.o
的方式,首先会提示找不到c库,这可以进入/usr/lib,然后使用
- sudo ln –sv /lib/i386–linux–gun/libc.so.6 libc.so
创建软连接解决.
但在运行时提示无法找到可执行文件!该文件明明在的!
遂用gcc来连接,但要将_start改为main,还要装载32库
- sudo apt–get install ia32–libs
还会提示找不到h文件,这时再装载库
- sudo apt–get install g++-multilib
还有2族库,如有必要也可加载:
- sudo apt–get install libc6:i386 libgcc1:i386 gcc–4.6–base:i386
- libstdc++5:i386 libstdc++6:i386
- sudo apt–get install libc6–i386
最后要说的是,一些C代码在用std=c99编译时会发现提示无法获取结构大小,
这时改成如下即可:
- gcc –D_GNU_SOURCE –std=c99 main.c
更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2014-06/103624p2.htm
(三)
在(二)中我们尝试使用了C库的函数完成功能,那么能不能用syscall方式
来搞呢?显然可以!
- section .data
- ft db “now is X”,10
- section .text
- global _start
- _start:
- mov edi,10
- again:
- dec edi
- mov eax,edi
- add eax,0x30
- mov byte[ft+7],al
- mov eax,4
- mov ebx,1
- mov ecx,ft
- mov edx,9
- int0x80
- mov eax,162
- push 0
- push 1
- mov ebx,esp
- mov ecx,0
- int0x80
- cmp edi,0
- jnz again
- mov eax,4
- mov ebx,1
- mov ecx,msg
- mov edx,15
- int0x80
- mov eax,1
- mov ebx,0
- int0x80
- msg:
- db “happy xxx day!”,10
—
- nasm –f elf main.asm
- ld –m elf_i386 –o main main.o
在代码中延时使用的是nanosleep,其他和第一篇一致,只不过做了一个bin->ascii的小转换.
本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-06/103624.htm