当试图在汇编代码( yasm
)上调用c函数时,它无法执行。
function_call_c.asm:
x86-64
编译:
; yasm assembly program, instruction - call c function
; compile: yasm -f elf64 function_call_c.asm -g dwarf2 && ld function_call_c.o -lc
; execute: ./a.out
section .data
msg_format db "hello"
section .text
extern printf
global _start
_start:
lea rdi, [msg_format]
call printf
_exit:
; exit
mov eax,1
mov ebx,5
int 0x80
执行时:
提示:
bash:./ a.out:没有这样的文件或目录
但yasm -f elf64 function_call_c.asm -g dwarf2 && ld function_call_c.o -lc
确实存在,并具有执行权限。
使用 objdump ,获取可执行文件的信息:
a.out
使用 readelf ,获取可执行文件的信息:
a.out: file format elf64-x86-64
Disassembly of section .interp:
0000000000400158 <.interp>:
400158: 2f (bad)
400159: 6c insb (%dx),%es:(%rdi)
40015a: 69 62 2f 6c 64 36 34 imul $0x3436646c,0x2f(%rdx),%esp
400161: 2e 73 6f jae,pn 4001d3 <printf@plt-0x4d>
400164: 2e 31 00 xor %eax,%cs:(%rax)
Disassembly of section .hash:
0000000000400168 <.hash>:
400168: 01 00 add %eax,(%rax)
40016a: 00 00 add %al,(%rax)
40016c: 02 00 add (%rax),%al
40016e: 00 00 add %al,(%rax)
400170: 01 00 add %eax,(%rax)
...
Disassembly of section .dynsym:
0000000000400180 <.dynsym>:
...
400198: 0b 00 or (%rax),%eax
40019a: 00 00 add %al,(%rax)
40019c: 12 00 adc (%rax),%al
...
Disassembly of section .dynstr:
00000000004001b0 <.dynstr>:
4001b0: 00 6c 69 62 add %ch,0x62(%rcx,%rbp,2)
4001b4: 63 2e movslq (%rsi),%ebp
4001b6: 73 6f jae 400227 <printf@plt+0x7>
4001b8: 2e 36 00 70 72 cs add %dh,%cs:%ss:0x72(%rax)
4001bd: 69 6e 74 66 00 47 4c imul $0x4c470066,0x74(%rsi),%ebp
4001c4: 49 rex.WB
4001c5: 42 rex.X
4001c6: 43 5f rex.XB pop %r15
4001c8: 32 2e xor (%rsi),%ch
4001ca: 32 2e xor (%rsi),%ch
4001cc: 35 .byte 0x35
...
Disassembly of section .gnu.version:
00000000004001ce <.gnu.version>:
4001ce: 00 00 add %al,(%rax)
4001d0: 02 00 add (%rax),%al
Disassembly of section .gnu.version_r:
00000000004001d8 <.gnu.version_r>:
4001d8: 01 00 add %eax,(%rax)
4001da: 01 00 add %eax,(%rax)
4001dc: 01 00 add %eax,(%rax)
4001de: 00 00 add %al,(%rax)
4001e0: 10 00 adc %al,(%rax)
4001e2: 00 00 add %al,(%rax)
4001e4: 00 00 add %al,(%rax)
4001e6: 00 00 add %al,(%rax)
4001e8: 75 1a jne 400204 <printf@plt-0x1c>
4001ea: 69 09 00 00 02 00 imul $0x20000,(%rcx),%ecx
4001f0: 12 00 adc (%rax),%al
4001f2: 00 00 add %al,(%rax)
4001f4: 00 00 add %al,(%rax)
...
Disassembly of section .rela.plt:
00000000004001f8 <.rela.plt>:
4001f8: a8 03 test $0x3,%al
4001fa: 60 (bad)
4001fb: 00 00 add %al,(%rax)
4001fd: 00 00 add %al,(%rax)
4001ff: 00 07 add %al,(%rdi)
400201: 00 00 add %al,(%rax)
400203: 00 01 add %al,(%rcx)
...
Disassembly of section .plt:
0000000000400210 <printf@plt-0x10>:
400210: ff 35 82 01 20 00 pushq 0x200182(%rip) # 600398 <_GLOBAL_OFFSET_TABLE_+0x8>
400216: ff 25 84 01 20 00 jmpq *0x200184(%rip) # 6003a0 <_GLOBAL_OFFSET_TABLE_+0x10>
40021c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400220 <printf@plt>:
400220: ff 25 82 01 20 00 jmpq *0x200182(%rip) # 6003a8 <_GLOBAL_OFFSET_TABLE_+0x18>
400226: 68 00 00 00 00 pushq $0x0
40022b: e9 e0 ff ff ff jmpq 400210 <printf@plt-0x10>
Disassembly of section .text:
0000000000400230 <_start>:
400230: 48 8d 3c 25 b0 03 60 lea 0x6003b0,%rdi
400237: 00
400238: e8 e3 ff ff ff callq 400220 <printf@plt>
000000000040023d <_exit>:
40023d: b8 01 00 00 00 mov $0x1,%eax
400242: bb 05 00 00 00 mov $0x5,%ebx
400247: cd 80 int $0x80
Disassembly of section .dynamic:
0000000000600250 <_DYNAMIC>:
600250: 01 00 add %eax,(%rax)
600252: 00 00 add %al,(%rax)
600254: 00 00 add %al,(%rax)
600256: 00 00 add %al,(%rax)
600258: 01 00 add %eax,(%rax)
60025a: 00 00 add %al,(%rax)
60025c: 00 00 add %al,(%rax)
60025e: 00 00 add %al,(%rax)
600260: 04 00 add $0x0,%al
600262: 00 00 add %al,(%rax)
600264: 00 00 add %al,(%rax)
600266: 00 00 add %al,(%rax)
600268: 68 01 40 00 00 pushq $0x4001
60026d: 00 00 add %al,(%rax)
60026f: 00 05 00 00 00 00 add %al,0x0(%rip) # 600275 <_DYNAMIC+0x25>
600275: 00 00 add %al,(%rax)
600277: 00 b0 01 40 00 00 add %dh,0x4001(%rax)
60027d: 00 00 add %al,(%rax)
60027f: 00 06 add %al,(%rsi)
600281: 00 00 add %al,(%rax)
600283: 00 00 add %al,(%rax)
600285: 00 00 add %al,(%rax)
600287: 00 80 01 40 00 00 add %al,0x4001(%rax)
60028d: 00 00 add %al,(%rax)
60028f: 00 0a add %cl,(%rdx)
600291: 00 00 add %al,(%rax)
600293: 00 00 add %al,(%rax)
600295: 00 00 add %al,(%rax)
600297: 00 1e add %bl,(%rsi)
600299: 00 00 add %al,(%rax)
60029b: 00 00 add %al,(%rax)
60029d: 00 00 add %al,(%rax)
60029f: 00 0b add %cl,(%rbx)
6002a1: 00 00 add %al,(%rax)
6002a3: 00 00 add %al,(%rax)
6002a5: 00 00 add %al,(%rax)
6002a7: 00 18 add %bl,(%rax)
6002a9: 00 00 add %al,(%rax)
6002ab: 00 00 add %al,(%rax)
6002ad: 00 00 add %al,(%rax)
6002af: 00 15 00 00 00 00 add %dl,0x0(%rip) # 6002b5 <_DYNAMIC+0x65>
...
6002bd: 00 00 add %al,(%rax)
6002bf: 00 03 add %al,(%rbx)
6002c1: 00 00 add %al,(%rax)
6002c3: 00 00 add %al,(%rax)
6002c5: 00 00 add %al,(%rax)
6002c7: 00 90 03 60 00 00 add %dl,0x6003(%rax)
6002cd: 00 00 add %al,(%rax)
6002cf: 00 02 add %al,(%rdx)
6002d1: 00 00 add %al,(%rax)
6002d3: 00 00 add %al,(%rax)
6002d5: 00 00 add %al,(%rax)
6002d7: 00 18 add %bl,(%rax)
6002d9: 00 00 add %al,(%rax)
6002db: 00 00 add %al,(%rax)
6002dd: 00 00 add %al,(%rax)
6002df: 00 14 00 add %dl,(%rax,%rax,1)
6002e2: 00 00 add %al,(%rax)
6002e4: 00 00 add %al,(%rax)
6002e6: 00 00 add %al,(%rax)
6002e8: 07 (bad)
6002e9: 00 00 add %al,(%rax)
6002eb: 00 00 add %al,(%rax)
6002ed: 00 00 add %al,(%rax)
6002ef: 00 17 add %dl,(%rdi)
6002f1: 00 00 add %al,(%rax)
6002f3: 00 00 add %al,(%rax)
6002f5: 00 00 add %al,(%rax)
6002f7: 00 f8 add %bh,%al
6002f9: 01 40 00 add %eax,0x0(%rax)
6002fc: 00 00 add %al,(%rax)
6002fe: 00 00 add %al,(%rax)
600300: fe (bad)
600301: ff (bad)
600302: ff 6f 00 ljmpq *0x0(%rdi)
600305: 00 00 add %al,(%rax)
600307: 00 d8 add %bl,%al
600309: 01 40 00 add %eax,0x0(%rax)
60030c: 00 00 add %al,(%rax)
60030e: 00 00 add %al,(%rax)
600310: ff (bad)
600311: ff (bad)
600312: ff 6f 00 ljmpq *0x0(%rdi)
600315: 00 00 add %al,(%rax)
600317: 00 01 add %al,(%rcx)
600319: 00 00 add %al,(%rax)
60031b: 00 00 add %al,(%rax)
60031d: 00 00 add %al,(%rax)
60031f: 00 f0 add %dh,%al
600321: ff (bad)
600322: ff 6f 00 ljmpq *0x0(%rdi)
600325: 00 00 add %al,(%rax)
600327: 00 ce add %cl,%dh
600329: 01 40 00 add %eax,0x0(%rax)
...
Disassembly of section .got.plt:
0000000000600390 <_GLOBAL_OFFSET_TABLE_>:
600390: 50 push %rax
600391: 02 60 00 add 0x0(%rax),%ah
...
6003a8: 26 02 40 00 add %es:0x0(%rax),%al
6003ac: 00 00 add %al,(%rax)
...
Disassembly of section .data:
00000000006003b0 <msg_format>:
6003b0: 68 65 6c 6c 6f pushq $0x6f6c6c65
Disassembly of section .debug_aranges:
0000000000000000 <.debug_aranges>:
0: 2c 00 sub $0x0,%al
2: 00 00 add %al,(%rax)
4: 02 00 add (%rax),%al
6: 00 00 add %al,(%rax)
8: 00 00 add %al,(%rax)
a: 08 00 or %al,(%rax)
c: 00 00 add %al,(%rax)
e: 00 00 add %al,(%rax)
10: 30 02 xor %al,(%rdx)
12: 40 00 00 add %al,(%rax)
15: 00 00 add %al,(%rax)
17: 00 19 add %bl,(%rcx)
...
Disassembly of section .debug_info:
0000000000000000 <.debug_info>:
0: 85 00 test %eax,(%rax)
2: 00 00 add %al,(%rax)
4: 02 00 add (%rax),%al
6: 00 00 add %al,(%rax)
8: 00 00 add %al,(%rax)
a: 08 01 or %al,(%rcx)
c: 00 00 add %al,(%rax)
e: 00 00 add %al,(%rax)
10: 30 02 xor %al,(%rdx)
12: 40 00 00 add %al,(%rax)
15: 00 00 add %al,(%rax)
17: 00 49 02 add %cl,0x2(%rcx)
1a: 40 00 00 add %al,(%rax)
1d: 00 00 add %al,(%rax)
1f: 00 66 75 add %ah,0x75(%rsi)
22: 6e outsb %ds:(%rsi),(%dx)
23: 63 74 69 6f movslq 0x6f(%rcx,%rbp,2),%esi
27: 6e outsb %ds:(%rsi),(%dx)
28: 5f pop %rdi
29: 63 61 6c movslq 0x6c(%rcx),%esp
2c: 6c insb (%dx),%es:(%rdi)
2d: 5f pop %rdi
2e: 63 2e movslq (%rsi),%ebp
30: 61 (bad)
31: 73 6d jae a0 <printf@plt-0x400180>
33: 00 2f add %ch,(%rdi)
35: 6d insl (%dx),%es:(%rdi)
36: 6e outsb %ds:(%rsi),(%dx)
37: 74 2f je 68 <printf@plt-0x4001b8>
39: 73 74 jae af <printf@plt-0x400171>
3b: 61 (bad)
3c: 72 2f jb 6d <printf@plt-0x4001b3>
3e: 67 69 74 5f 72 65 70 imul $0x736f7065,0x72(%edi,%ebx,2),%esi
45: 6f 73
47: 69 74 6f 72 79 2f 77 imul $0x6f772f79,0x72(%rdi,%rbp,2),%esi
4e: 6f
4f: 72 6b jb bc <printf@plt-0x400164>
51: 73 70 jae c3 <printf@plt-0x40015d>
53: 61 (bad)
54: 63 65 2f movslq 0x2f(%rbp),%esp
57: 61 (bad)
58: 73 73 jae cd <printf@plt-0x400153>
5a: 65 gs
5b: 6d insl (%dx),%es:(%rdi)
5c: 62 (bad)
5d: 6c insb (%dx),%es:(%rdi)
5e: 79 5f jns bf <printf@plt-0x400161>
60: 77 6f ja d1 <printf@plt-0x40014f>
62: 72 6b jb cf <printf@plt-0x400151>
64: 70 6c jo d2 <printf@plt-0x40014e>
66: 61 (bad)
67: 63 65 2f movslq 0x2f(%rbp),%esp
6a: 79 61 jns cd <printf@plt-0x400153>
6c: 73 6d jae db <printf@plt-0x400145>
6e: 2f (bad)
6f: 69 6e 73 74 72 75 63 imul $0x63757274,0x73(%rsi),%ebp
76: 74 69 je e1 <printf@plt-0x40013f>
78: 6f outsl %ds:(%rsi),(%dx)
79: 6e outsb %ds:(%rsi),(%dx)
7a: 2f (bad)
7b: 00 79 61 add %bh,0x61(%rcx)
7e: 73 6d jae ed <printf@plt-0x400133>
80: 20 31 and %dh,(%rcx)
82: 2e 32 2e xor %cs:(%rsi),%ch
85: 30 00 xor %al,(%rax)
87: 01 .byte 0x1
88: 80 .byte 0x80
Disassembly of section .debug_abbrev:
0000000000000000 <.debug_abbrev>:
0: 01 11 add %edx,(%rcx)
2: 00 10 add %dl,(%rax)
4: 06 (bad)
5: 11 01 adc %eax,(%rcx)
7: 12 01 adc (%rcx),%al
9: 03 08 add (%rax),%ecx
b: 1b 08 sbb (%rax),%ecx
d: 25 08 13 05 00 and $0x51308,%eax
...
Disassembly of section .debug_line:
0000000000000000 <.debug_line>:
0: 47 00 00 rex.RXB add %r8b,(%r8)
3: 00 02 add %al,(%rdx)
5: 00 2a add %ch,(%rdx)
7: 00 00 add %al,(%rax)
9: 00 01 add %al,(%rcx)
b: 01 fb add %edi,%ebx
d: 0e (bad)
e: 0d 00 01 01 01 or $0x1010100,%eax
13: 01 00 add %eax,(%rax)
15: 00 00 add %al,(%rax)
17: 01 00 add %eax,(%rax)
19: 00 01 add %al,(%rcx)
1b: 00 66 75 add %ah,0x75(%rsi)
1e: 6e outsb %ds:(%rsi),(%dx)
1f: 63 74 69 6f movslq 0x6f(%rcx,%rbp,2),%esi
23: 6e outsb %ds:(%rsi),(%dx)
24: 5f pop %rdi
25: 63 61 6c movslq 0x6c(%rcx),%esp
28: 6c insb (%dx),%es:(%rdi)
29: 5f pop %rdi
2a: 63 2e movslq (%rsi),%ebp
2c: 61 (bad)
2d: 73 6d jae 9c <printf@plt-0x400184>
2f: 00 00 add %al,(%rax)
31: 00 00 add %al,(%rax)
33: 00 00 add %al,(%rax)
35: 09 02 or %eax,(%rdx)
37: 30 02 xor %al,(%rdx)
39: 40 00 00 add %al,(%rax)
3c: 00 00 add %al,(%rax)
3e: 00 03 add %al,(%rbx)
40: 0c 01 or $0x1,%al
42: 83 5d 59 59 sbbl $0x59,0x59(%rbp)
46: 02 02 add (%rdx),%al
48: 00 01 add %al,(%rcx)
4a: 01 .byte 0x1
问题是:
答案 0 :(得分:2)
刚刚运行你的例子并遇到了同样的问题
原因是我的情况是一个不正确的动态链接器(ELF解释器)
要验证这是问题,请键入file ./a.out
,您应该获得与以下输出类似的内容:
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld64.so.1, not stripped
ld
默认选择动态链接器(/lib/ld64.so.1
)并不存在于大多数Linux系统上,因此存在问题。您可以使用patchelf(apt-get install patchelf)和以下命令来纠正此问题:
patchelf --set-interpreter [path_to_interpreter] ./a.out
通过键入file /bin/ls
,您可以获得应该用作ELF解释器的正确路径 - 将打印标准动态链接器路径。 (另外,readelf
可以打印出更多内容。)
最好的方法是使用ld
&#39; -dynamic-linker
标记首先正确设置elf标题中的INTERP部分。
有关使用或不使用libc将asm构建/链接到静态或动态二进制文件的更多详细信息,另请参阅this answer。
答案 1 :(得分:2)
(正如@Peter Cordes所建议的那样,我想提出一个答案,总结所提出的评论和其他答案,以便让未来的搜索者更清楚。)< / p>
原始代码中的问题&amp;编译/链接策略:
更好地使用main
代替_start
。原因:因为(最初在@Michael Petch&#39;评论中提到),C运行时包含_start
标签,这是冲突,当使用gcc
链接时。即使这可以通过在链接时向gcc添加-nostartfiles
选项来修复,但简单的gcc xxx.o
更简单。因此,只需使用main
代替_start
。
通过ret
而非int 0x80
退出。原因:因为(最初在@Michael Petch&#39;评论中提到),ret
将有助于刷新标准输出,而int 0x80
赢了,所以使用int 0x80
无法在控制台中看到hello world
。调用C函数exit
是另一种解决方案,但它是对c的额外函数调用,因此使用ret
更有效,它将从c运行时返回_start
。 / p>
通过gcc
代替ld
更好地链接。原因:因为(如@Peter Cordes和@Michael Petch&#39; 中提到的),默认情况下在gcc中包含C运行时,因此您不需要添加类似的选项使用gcc时-lc
。但ld
不包含C运行时。因此,再次使用gcc
会使其更简单。
有关详细信息,请参阅相关评论及其他答案。
(因此,根据以上解释。)
解决问题的步骤:
_start
更改为main
ret
而不是int 0x80
退出计划。yasm
进行编译,例如yasm -f elf64 function_call_c.asm -g dwarf2
gcc
链接,例如gcc function_call_c.o
(这是新版本的代码。)
<强> function_call_c.asm:强>
; yasm assembly program, instruction - call c function
; compile: yasm -f elf64 function_call_c.asm -g dwarf2 && gcc function_call_c.o
; execute: ./a.out
; check printed char count (immediately after execution): echo $?
section .data
msg_format db 'hello world',0x0A,0
section .text
extern printf
extern exit
global main
main:
mov rax, 0
lea rdi, [msg_format]
call printf
_exit:
; eax now contains count of chars printed, due to previous 'printf' call,
ret; return from main, this will flush the output,