linux简单之美

(一)

话说windows也有syscall,这是必须的。但是win的syscall可以直接call吗?可以是

可以但是破费周折,搞成SDT之类的复杂概念。下面看看linux是如何做的吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
section .data
msg db "hello hopy!",0x0a

section .text
global _start

_start:
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,12
int 0x80

mov eax,1
mov ebx,0
int 0x80

关键是系统调用号要知道,开始找的是usr/include/asm-gen*/unistd.h,

可是都不对。后来找的是usr/include/x86_64_linux_gnu/asm/下的头文件,

有2个,分别对应x86和x64.、编译连接指令如下:

1
2
nasm -f elf main.asm
ld main.o

运行,段转储错误鸟,查了一下,本猫用的是x64位的linux,所以要生成

x64位的程序,或者指明是x86的程序,我选择后者:

1
ld -m elf_i386 -o main main.o

哦鸟!

(二)

我们在前一章中看到了如何仅仅用syscall做一些简单的事,现在我们看能不能直接调用

C标准库中的函数快速做一些”复杂”的事:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
section .data
ft db "now is %d",10

section .text
extern puts
extern exit
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标准库中的函数.编译和以前一样:

1
nasm -e elf main.asm

我们看看怎么连接:

1
gcc -m32 -o main main.o

好鸟!运行正常.

值得注意的是:我的OS是ubuntu64,而asm代码中是32位的,如果开始用

1
ld -m elf_i386 -lc -o main main.o

的方式,首先会提示找不到c库,这可以进入/usr/lib,然后使用

1
sudo ln -sv /lib/i386-linux-gun/libc.so.6 libc.so

创建软连接解决.

但在运行时提示无法找到可执行文件!该文件明明在的!

遂用gcc来连接,但要将_start改为main,还要装载32库

1
sudo apt-get install ia32-libs

还会提示找不到h文件,这时再装载库

1
sudo apt-get install g++-multilib

还有2族库,如有必要也可加载:

1
2
3
4
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编译时会发现提示无法获取结构大小,

这时改成如下即可:

1
gcc -D_GNU_SOURCE -std=c99 main.c

(三)

在(二)中我们尝试使用了C库的函数完成功能,那么能不能用syscall方式

来搞呢?显然可以!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
int 0x80

mov eax,162
push 0
push 1
mov ebx,esp
mov ecx,0
int 0x80

cmp edi,0
jnz again

mov eax,4
mov ebx,1
mov ecx,msg
mov edx,15
int 0x80

mov eax,1
mov ebx,0
int 0x80

msg:
db "happy xxx day!",10

1
2
nasm -f elf main.asm
ld -m elf_i386 -o main main.o

在代码中延时使用的是nanosleep,其他和第一篇一致,只不过做了一个bin->ascii的小转换.

via: http://blog.csdn.net/mydo/article/details/8224352 http://blog.csdn.net/mydo/article/details/8452386 http://blog.csdn.net/mydo/article/details/8452417


linux简单之美
https://linuxcat.top/article-3254-1.html
作者
hopy
发布于
2014年6月24日
许可协议
CC-BY-NC