0

How can I disassemble an executable on my mac using ndisasm and reassemble and link it using nasm and ld? This is what I tried (I'm running MacOS X btw):

 *ndisasm a.out | cut -c 29- > main.asm*

this generated clean assembler code with all the processor instructions in main.asm

 *nasm -f macho main.asm*

this generated an object file main.o which I then tried to link

 *ld main.o*

... this is where I'm stuck. I don't know why it generates the following error:

ld: in section __TEXT,__text reloc 0: R_ABS reloc but no absolute symbol at target adress file 'main.o' for inferred architecture i386.

I also tried specifying the architecture (ld -arch x86_64 main.o) but that didn't work either.

My goal is to disassemble any executable, modify it and then reassemble it again.

What am I doing wrong?

  • 7
    Due to the fact that assembling and linking are performed by two different tools, getting the disassembly of a file is not enough to recreate the original binary. Furthermore, this also implies that the disassembler will pass over some binary properties that a "de-linker" should handle (do they exist?). For these reasons, people usually *patch* the binary file or edit it with a Mach-O editor to shift/grow/shrink sections around. – Margaret Bloom Dec 05 '17 at 12:25
  • It will also certainly not work for **any** executable, some may have anti-tamper or just-too-complex code which will be broken by your modification and the reassembled executable will not work correctly (correctly = as before + your modification only). For example if you have `mov edi,0x123` in executable, how can you tell if it is loading memory address of data in `.text` `0x123`, or value `0x123`? In first case the value needs patching, if your modification was not in-place, in second case the value must be kept intact. There's no way to tell except deciphering the purpose of `edi` later. – Ped7g Dec 05 '17 at 12:55
  • Plus such tool is quite useless, it's much better to checkout original source from github/etc. and modify that (so don't expect there're many people trying to solve the same thing, many people are rather developing the SW). – Ped7g Dec 05 '17 at 12:56
  • 1
    It is recommended to ask questions about Reverse Engineering in [Reverse Engineering Stack Exchange](https://reverseengineering.stackexchange.com). – Megabeets Dec 12 '17 at 09:45
  • You can emit binary from an optionally modified disassembly in `Hopper` , I recommend checking it out. – Kamil.S Dec 12 '17 at 13:18

1 Answers1

2

There is no reliable way to do this with normal assembler syntax. See How to disassemble, modify and then reassemble a Linux executable?. Section info is typically not faithfully disassembled, so you'd need a special format designed for modify and reassembling + relinking.

Also, instruction-lengths are a problem when code only works when padded by using longer encodings. (e.g. in a table of jump targets for a computed goto). See Where are GNU assembler instruction suffixes like ".s" in x86 "mov.s" documented?, but note that disassemblers don't support disassembling into that format.


ndisasm doesn't understand object file formats, so it disassembles headers as machine code!

For this to have any hope of working, use a disassembler like Agner Fog's objconv which will output asm source (NASM, MASM, or GAS AT&T) which does assemble. It might not actually work if any of the code depended on a specific longer-than-default encoding.

I'm not sure how faithful objconv is with respect to emitting section .bss, section .rodata and other directives like that to place data where it found it in the object file, but that's what you need.


Re: absolute relocations: make sure you put DEFAULT REL at the top of your file. I forget if objconv does this by default. x86-64 Mach-o only supports PC-relative relocations, so you have to create position-independent code (e.g. using RIP-relative addressing modes).

ndisasm doesn't read the symbol table, so all its operands use absolute addressing. objconv makes up label names for jump targets and static data that doesn't appear in the symbol table.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847