3

I'm trying to disassembly app written in assembly. I'm on Linux, x64:

$ objdump -d my_app 

my_app:     file format elf64-x86-64

That's it. What's wrong with it? It's not a simple hello world of a few lines, it's around 200 lines of code.

The same with gbd:

$ gdb -q my_app 
Reading symbols from my_app...(no debugging symbols found)...done.
(gdb) 

And

$ radare2 my_app 
Warning: Cannot initialize section headers
Warning: Cannot initialize strings table
Warning: Cannot initialize dynamic strings
Warning: Cannot initialize dynamic section
 -- Calculate checksums for the current block with the commands starting with '#' (#md5, #crc32, #all, ..)

update:

$ objdump -D my_app 

my_app:     file format elf64-x86-64

compiling:

   $ fasm my_app.asm 
   # => my_app 

update2:

; simplified

format ELF64 executable 3

include "import64.inc"
interpreter "/lib64/ld-linux-x86-64.so.2"
needed "libc.so.6"
import printf, close

segment readable
    A equ 123
    B equ 222
    C equ 333

segment readable writeable
    struc s1 a, b, c {
      .a1 dw a
      .b1 dw b
      .c dd c
    }

    msg:
        .m1 db "aaa", 0
        .m2 db "bbb", 0
        .m3 db "ccc", 0

segment readable executable
entry $
    mov rax, 2
    mov rdi, "something.txt"
    mov rsi, 0
    syscall

    ; .............
    ; omitted
Uji
  • 33
  • 5
  • Did you try `objdump -D` to disassemble all sections? Or even `ndisasm` to disassemble the whole file as if it were a flat binary. (Default mode is 16-bit, so set it to 64-bit). – Peter Cordes Oct 18 '17 at 03:49
  • Have you tried with a simple fasm program and built it the same way to see what happens? – Michael Petch Oct 18 '17 at 03:54
  • @MichaelPetch the same thing – Uji Oct 18 '17 at 03:57
  • @PeterCordes ndisasm worked but still provided pretty complicated disasm code, way more complicated than I have in my app. Is there other way? – Uji Oct 18 '17 at 03:59
  • `ndisasm` is disassembling the ELF headers as instructions; it doesn't know about object files so it assumes everything is a flat binary. If `objdump -D` doesn't work, are you sure your app even has any machine code in its segments? Try `gdb ./my_app`, and `b *0`. You'll have to delete that breakpoint right away (because `*0` isn't a valid address), but it will stop before the first instruction of your program executes, wherever that is, so you can find the entry point. You don't need debug symbols to use gdb; it has a disassembly mode. See https://stackoverflow.com/tags/x86/info – Peter Cordes Oct 18 '17 at 04:02
  • 1
    I'd say there is something wrong with your assembly file and it is generating an unusual ELF file (ones that don't seem to have sections?). Would you humour us and post all 200 lines? Or reduce the assembly file to a minimal set of ins that still reproduces the same behavior once assembled into an executable – Michael Petch Oct 18 '17 at 04:39
  • 2
    @jww he's using fasm so there might not even be a link stage (fasm will usually allow you to go from assembly code to executable with one command) – Michael Petch Oct 18 '17 at 04:56
  • @MichaelPetch, correct – Uji Oct 18 '17 at 06:01
  • @Uji without seeing all your code or a minimal complete example that produces the same problem it is hard to tell.You could email it (your entire ASM file) to me at mpetch@gmail.com and I could take a look and may be able to complete a minimal example from it that would make this question answerable.I believe the issue lies in your actual assembly file which you just aren't showing. – Michael Petch Oct 18 '17 at 06:05
  • My main concern is that objdump with `-D` gives you one line of info `my_app: file format elf64-x86-64`. I would expect it to dump instructions from the .text segments but it isn't. It actually acts like there is some sort of problem with the sections. – Michael Petch Oct 18 '17 at 06:24
  • @Uji, Could you share the source code my_app? let me take a try to see if we have the same result. – Forward Oct 18 '17 at 07:18
  • @MichaelPetch updated – Uji Oct 18 '17 at 08:46
  • @PeterCordes updated – Uji Oct 18 '17 at 08:47
  • `readelf` says: _Number of section headers: 0_ It also tells you where the entry point is, and knowing that, `gdb` can debug it if you place a breakpoint there. – Jester Oct 18 '17 at 08:52
  • I recommend you do not create executable directly, instead use a linker. – Jester Oct 18 '17 at 09:02
  • @Jester I recommend you first try fasm yourself and then give advice. – Uji Oct 18 '17 at 09:04
  • Guess what, I have tried it. Why is everybody so rude these days? – Jester Oct 18 '17 at 09:05
  • @Jester then everyone, including its creator, do it wrong -- they don't use a linker. – Uji Oct 18 '17 at 09:06
  • @Jester why everybody is so sensitive these days so that they see rudeness everywhere? go claim your mummy – Uji Oct 18 '17 at 09:07
  • You can use fasm without a linker, I didnt't say otherwise. But using one will give you better output, you even get sections you can name. Do whatever you want but then don't come whining... – Jester Oct 18 '17 at 09:18
  • @Jester, yes, but using a linker must bring an overhead, must it not? namely, an output file will be a bit bigger and slower – Uji Oct 18 '17 at 12:15

1 Answers1

2

Asking fasm to directly produce an ELF binary without the use of a linker will only create segments but no sections in the output. This confuses some tools. In particular objdump -d is specifically documented to operate on sections. Note that gdb can still debug and disassemble it, if you give it some addresses, e.g. the entry point.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • > Note that gdb can still debug and disassemble it, if you give it some addresses, e.g. the entry point. – Uji Oct 18 '17 at 12:14
  • 2
    @Uji you can abuse the "break on any failure" mechanism of `gdb`. Use `file` to load it, then put breakpoint on invalid address like zero `b *0`, then `run` ... the `gdb` will break on first instruction because of invalid breakpoint. Delete it `d 1` (if "breakpoint 1" was added), and since here you can `stepi`/etc... – Ped7g Oct 18 '17 at 13:18
  • @Uji and Ped7g: you can also `readelf -a` and look at the "entry point" address. (The `b *0` trick is really handy, though, and also works for PIEs with ASLR.) – Peter Cordes Oct 18 '17 at 14:39
  • @PeterCordes readefl says " Entry point address: 0x40394a", what to do with that? – Uji Oct 18 '17 at 15:00
  • @Uji: `gdb ./my_app` / `b *0x40394a` to set a breakpoint there. – Peter Cordes Oct 18 '17 at 15:01
  • 2
    @PeterCordes it still sort of amazes me there's no simple way to do that from gdb directly, and some other tool must be used. Then again, the gdb is kind of shell-like tool, like old ftp, so there's maybe way to run external command from inside? I don't care, using `b *0` is for me perfect, I will not forget that so easily as anything else (`readelf` is completely off limits to my memory). – Ped7g Oct 18 '17 at 16:47
  • @Ped7g: There might be a way from within gdb, but I don't know it. It's designed primarily as a source-level debugger, not a binary-analysis tool. – Peter Cordes Oct 18 '17 at 16:50
  • At least some versions of `gdb` print the entry point if you do `info file`. Unfortunately that only works once the program has been started too. – Jester Oct 18 '17 at 17:12