draugr.git


draugr

~ single ELF file analysis tool
git clone https://github.com/djnnvx/draugr.git
log | files | refs | archive | README

README.md (2951B)

      1 # draugr
      2 
      3 ELF mapping and analysis tool. Written in Odin with no third-party dependencies.
      4 
      5 ## Build
      6 
      7 ```sh
      8 asdf install
      9 odin build . -out:draugr
     10 ```
     11 
     12 ## Usage
     13 
     14 ```
     15 draugr <elf-path> [flags]
     16 ```
     17 
     18 | Flag | Description |
     19 | --- | --- |
     20 | `--info` | ELF summary only (class, type, machine, entry, PIE, dynamic, counts) |
     21 | `--sections` | Section header table |
     22 | `--segments` | Program header table, objdump -p style |
     23 | `--symbols` | Symbol table, nm style, static and dynamic |
     24 | `--map` | Visual memory layout |
     25 | `--entropy` | Shannon entropy, 256-byte blocks, bits per byte |
     26 | `--hexdump` | Hex dump the whole file |
     27 | `--checksec` | Hardening report: RELRO, NX, canary, PIE, RPATH, FORTIFY |
     28 | `--relocs` | Relocation table and PLT/GOT map |
     29 | `--code` | Code regions: executable sections with entropy, entry point, function starts |
     30 | `--call-function <sym>` | Load the file from memory and call one symbol |
     31 | `--call-args <list>` | Arguments for `--call-function` |
     32 | `--patch <list>` | In-memory patches applied before `--call-function` (x86-64). `;`-separated: `sym=ret:N`, `sym=jmp:target`, `got:sym=target` |
     33 | `--bin-diff <file>` | Diff this binary's layout against a reference ELF |
     34 | `--json` | Full structured dump: header, segments, sections, dynamic, symbols, relocations, GOT, checksec |
     35 | `--verbose` | Verbose output |
     36 
     37 `--hexdump`, `--entropy` and `--code` each have an `--<name>-out <file>` variant that
     38 writes to a file instead of stdout. Flags combine, so `--sections --symbols` prints both.
     39 
     40 `--json` covers the whole structured dump on its own and ignores the selector flags. It is
     41 rejected alongside `--hexdump`, `--entropy`, `--code`, `--map`, `--bin-diff` and
     42 `--call-function`, which are visualizations or actions with no JSON form.
     43 
     44 Both `--flag value` and `--flag=value` work, and a single dash is accepted.
     45 
     46 ### Simple examples
     47 
     48 ```sh
     49 draugr --json /bin/ls | jq .needed
     50 draugr --json /bin/ls | jq .checksec
     51 draugr --json /bin/ls | jq .got.fclose       # GOT slot address, pwntools style
     52 draugr --json /bin/ls | jq '.dynamic_entries[] | select(.tag == "RUNPATH")'
     53 draugr --sections /bin/ls | awk '$3 == "PROGBITS"'
     54 draugr --symbols /bin/ls | grep ' U '        # undefined imports
     55 draugr --bin-diff v1.4.2/httpd v1.4.3/httpd  # what changed between firmware builds
     56 ```
     57 
     58 ### Calling a function
     59 
     60 `--call-function` loads the file through a `memfd` and calls a single symbol, without the
     61 linked object ever reaching disk. A `.o` is linked first with `ld -shared` writing straight
     62 into the memfd; a `.so` is written to the memfd as-is.
     63 
     64 ```sh
     65 draugr --call-function alpha --call-args 21 ./thing.o
     66 draugr --call-function parse --call-args s:AAAA,64 ./libvendor.so
     67 ```
     68 
     69 Arguments are comma-separated: integers (decimal or `0x`), or `s:text` to pass a pointer to
     70 a NULL-terminated string. Up to six, matching the integer argument registers. Floats and
     71 structs are not supported, and the return value is read as a 64-bit integer.