Instructions appended to end of assembly

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-09 09:21:25

问题


I am trying to follow this tutorial for creating a binary file, but the linker appears to be appending additional instructions at the end of the assembly. I assume this is the OS's tear-down process.


The tutorial attempts to compile a bare bones 32-bit C program on Linux:

int main() {
}

using these commands:

gcc -c test.c
ld -o test -Ttext 0x0 -e main test.o
objcopy -R .note -R .comment -S -O binary test test.bin
ndisasm -b 32 test.bin

I am running 64-bit Linux, and hence modified the compilation steps to be the following:

gcc -m32 -c test.c 
ld -m elf_i386 -o test -Ttext 0x0 -e main test.o
objcopy -R .note -R .comment -S -O binary test test.bin
ndisasm -b 32 test.bin

The expected output is:

00000000 55            push ebp
00000001 89E5          mov ebp,esp
00000003 C9            leave
00000004 C3            ret

My output is the following:

;; START expected output
00000000  55                push bp
00000001  89E5              mov bp,sp
00000003  5D                pop bp
00000004  C3                ret
;; END expected output
00000005  0000              add [eax],al
00000007  001400            add [eax+eax],dl
0000000A  0000              add [eax],al
0000000C  0000              add [eax],al
0000000E  0000              add [eax],al
00000010  017A52            add [edx+0x52],edi
00000013  0001              add [ecx],al
00000015  7C08              jl 0x1f
00000017  011B              add [ebx],ebx
00000019  0C04              or al,0x4
0000001B  0488              add al,0x88
0000001D  0100              add [eax],eax
0000001F  001C00            add [eax+eax],bl
00000022  0000              add [eax],al
00000024  1C00              sbb al,0x0
00000026  0000              add [eax],al
00000028  D8FF              fdivr st7
0000002A  FF                db 0xff
0000002B  FF0500000000      inc dword [dword 0x0]
00000031  41                inc ecx
00000032  0E                push cs
00000033  088502420D05      or [ebp+0x50d4202],al
00000039  41                inc ecx
0000003A  C50C04            lds ecx,[esp+eax]
0000003D  0400              add al,0x0
0000003F  00                db 0x00

What is the purpose of the additional instructions, and how can I strip them from the object file and binary?

EDIT:

  • Typo in objcopy args (commet -> comment). Updated disassembly output.

回答1:


Generally when you see additional data/instructions in the output file the source of the issue is probably a section that appears after your expected code. A way to deal with this is to query the ELF executable to see what sections it defines. One can query just the sections with the -x parameter to OBJDUMP. Using this command:

objdump -x test

Should produce output similar (not exact) to this in most modern versions of GCC using default parameters:

test:     file format elf32-i386
test
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000

Program Header:
    LOAD off    0x00001000 vaddr 0x00000000 paddr 0x00000000 align 2**12
         filesz 0x00000040 memsz 0x00000040 flags r-x
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
         filesz 0x00000000 memsz 0x00000000 flags rw-

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000005  00000000  00000000  00001000  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .eh_frame     00000038  00000008  00000008  00001008  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .comment      0000001d  00000000  00000000  00001040  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00000000 l    d  .text  00000000 .text
00000008 l    d  .eh_frame      00000000 .eh_frame
00000000 l    d  .comment       00000000 .comment
00000000 l    df *ABS*  00000000 test.c
00001040 g       .eh_frame      00000000 __bss_start
00000000 g     F .text  00000005 main
00001040 g       .eh_frame      00000000 _edata
00001040 g       .eh_frame      00000000 _end

One should first look for unexpected sections. Your OBJCOPY command used -R to remove sections from the ELF object before outputting to the file test.bin. You did:

objcopy -R .note -R .comment -S -O binary test test.bin

If we exclude .note and .comment sections the obvious one remaining in the OBJDUMP output above is .eh_frame. .eh_frame was placed into your file test.bin after the .text section. This contains exception unwinding information. It isn't actual instructions. NDISASM is dumping non-code as instructions because a binary file doesn't distinguish between code and data. NDISASM blindly converted all the data to instructions.

There are a couple of ways around this. You can exclude the .eh_frame section like you did with the other two. You could use:

objcopy -R .note -R .comment -R .eh_frame -S -O binary test test.bin

You could also tell GCC not to produce asynchronous exception unwinding tables in the code. This can be done with the GCC option:

gcc -m32 -c test.c -fno-asynchronous-unwind-tables  

This differs from my comment a bit, as I suggested disabling all exceptions. You just need to disable the asynchronous unwind tables to suppress the .eh_frame section. The usefulness (or lack thereof) of this section is discussed in this Stackoverflow answer. The man page (man gcc) for GCC discusses the option -fasynchronous-unwind-tables

   -fasynchronous-unwind-tables
       Generate unwind table in DWARF 2 format, if supported by target machine.  The table is exact at each
       instruction boundary, so it can be used for stack unwinding from asynchronous events (such as debugger or
       garbage collector).

This is the default on most GCCs these days. Using -fno-asynchronous-unwind-tables turns this feature off.


The tutorial you linked to was produced in 2000. GCC and its options (and the defaults used by distributions) have changed over the years. Likely when that tutorial was created the asynchronous unwind tables didn't yet exist. This would explain why your observed output differed from the tutorial.



来源:https://stackoverflow.com/questions/39456178/instructions-appended-to-end-of-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!