helloworld研究

本文研究一下输出helloworld字符串的程序。本文环境基于ubuntu 16.04 64bit。

一、源码

下载:
https://github.com/docker-library/hello-world/blob/b7a78b7ccca62cc478919b101f3ab1334899df2b/hello.asm

修改后的源码如下:

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
; this is especially thanks to:
; http://blog.markloiseau.com/2012/05/tiny-64-bit-elf-executables/

BITS 64
trueorg 0x00400000 ; Program load offset

; 64-bit ELF header
ehdr:
true; 1), 0 (ABI ver.)
truedb 0x7F, "ELF", 2, 1, 1, 0 ; e_ident
truetimes 8 db 0 ; reserved (zeroes)

truedw 2 ; e_type: Executable file
truedw 0x3e ; e_machine: AMD64
truedd 1 ; e_version: current version
truedq _start ; e_entry: program entry address (0x78)
truedq phdr - $$ ; e_phoff program header offset (0x40)
truedq 0 ; e_shoff no section headers
truedd 0 ; e_flags no flags
truedw ehdrsize ; e_ehsize: ELF header size (0x40)
truedw phdrsize ; e_phentsize: program header size (0x38)
truedw 1 ; e_phnum: one program header
truedw 0 ; e_shentsize
truedw 0 ; e_shnum
truedw 0 ; e_shstrndx

ehdrsize equ $ - ehdr

; 64-bit ELF program header
phdr:
truedd 1 ; p_type: loadable segment
truedd 5 ; p_flags read and execute
truedq 0 ; p_offset
truedq $$ ; p_vaddr: start of the current section
truedq $$ ; p_paddr: " "
truedq filesize ; p_filesz
truedq filesize ; p_memsz
truedq 0x200000 ; p_align: 2^11=200000 = section alignment

; program header size
phdrsize equ $ - phdr

; Hello World!/your program here
_start:

true; sys_write(stdout, message, length)
truemov rax, 1 ; sys_write
truemov rdi, 1 ; stdout
truemov rsi, message ; message address
truemov rdx, length ; message string length
truesyscall

true; sys_exit(return_code)
truemov rax, 60 ; sys_exit
truemov rdi, 0 ; return 0 (success)
truesyscall

truemessage:
truetruedb 'Hello world.', 0x0A
truetruedb 'This message from hello.', 0x0A
truetruedb 0x0A
truelength: equ $-message ; message length calculation

; File size calculation
filesize equ $ - $$

二、编译

安装nasm:

1
sudo apt install nasm

编译命令:

1
2
nasm hello.asm
chmod +x hello

注意,生成的hello文件没有可执行属性,要添加。

三、执行

执行结果如下:

1
2
3
$ ./hello
Hello world.
This message from hello.