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.