无法编译或链接调用c函数的yasm程序

时间:2016-06-21 06:48:34

标签: c linux assembly yasm

当试图在汇编代码( 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

问题是:

  • 为什么执行失败,代码错了?或者我以错误的方式编辑它?

2 个答案:

答案 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,