8a425344dac7d9dae04bc59b7ab26a317fb41e23
code.md
... | ... | @@ -4,7 +4,8 @@ |
4 | 4 | |
5 | 5 | * [liner (intro template)](https://github.com/shizmob/liner) |
6 | 6 | * [more GL init stuff](https://github.com/blackle/Linux-OpenGL-Examples/) |
7 | -* [even smaller GL init if you only need a single fullscreen fragment shader, still works with default Ubuntu](https://github.com/blackle/Clutter-1k/) |
|
7 | +* [even smaller GL init if you only need a single fullscreen fragment shader, |
|
8 | + still works with default Ubuntu](https://github.com/blackle/Clutter-1k/) |
|
8 | 9 | |
9 | 10 | ### Basic synth setup |
10 | 11 | |
... | ... | @@ -30,4 +31,4 @@ |
30 | 31 | |
31 | 32 | ### Other stuff |
32 | 33 | |
33 | -* [Tetris clone, in 2k](https://github.com/donnerbrenn/Tetris2k) |
|
... | ... | \ No newline at end of file |
0 | +* [Tetris clone, in 2k](https://github.com/donnerbrenn/Tetris2k) |
explain-dot-md.md
... | ... | @@ -4,7 +4,8 @@ |
4 | 4 | |
5 | 5 | * [Syscalls](/explain/syscalls) |
6 | 6 | * [Creating small static binaries, ELF header |
7 | - hacks](https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) ([notes on doing the same, on ARM](/explain/tinyelf-arm)) |
|
7 | + hacks](https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) |
|
8 | + ([notes on doing the same, on ARM](/explain/tinyelf-arm)) |
|
8 | 9 | * [Process creation](/explain/proc) |
9 | 10 | * [Dynamic linking](/explain/rtld) |
10 | 11 | * [C runtime](/explain/crt) |
explain/crt.md
... | ... | @@ -10,9 +10,12 @@ function: |
10 | 10 | |
11 | 11 | 1. aligns the stack |
12 | 12 | 2. reads `argc`, `argv`, `environ` and [the auxiliary vector |
13 | - ](https://refspecs.linuxfoundation.org/LSB_1.3.0/IA64/spec/auxiliaryvector.html) from the stack (see the links to LWN in [Process creation](https://linux.weeaboo.software/explain/proc) for stack content details) |
|
13 | + ](https://refspecs.linuxfoundation.org/LSB_1.3.0/IA64/spec/auxiliaryvector.html) |
|
14 | + from the stack (see the links to LWN in [Process creation](/explain/proc) |
|
15 | + for stack content details) |
|
14 | 16 | 3. sets up TLS, locales, and other crap |
15 | -4. calls `__libc_start_user`, which first calls the constructors of all global (C++) variables, then calls `main`, and `exit` automatically as |
|
17 | +4. calls `__libc_start_user`, which first calls the constructors of all global |
|
18 | + (C++) variables, then calls `main`, and `exit` automatically as |
|
16 | 19 | well. |
17 | 20 | |
18 | 21 | Of course, it's huge, but we can provide our own: step 3 can be skipped, 1 and 2 |
explain/rtld.md
... | ... | @@ -4,11 +4,14 @@ |
4 | 4 | Dynamic linking is the process of loading code and data from shared libraries. |
5 | 5 | For an overview, see [this |
6 | 6 | ](https://0x00sec.org/t/linux-internals-dynamic-linking-wizardry/1082) and [ |
7 | -this page](https://0x00sec.org/t/linux-internals-the-art-of-symbol-resolution/1488), or [this talk by Matt Godbolt](https://www.youtube.com/watch?v=dOfucXtyEsU). |
|
7 | +this page](https://0x00sec.org/t/linux-internals-the-art-of-symbol-resolution/1488), |
|
8 | +or [this talk by Matt Godbolt](https://www.youtube.com/watch?v=dOfucXtyEsU). |
|
8 | 9 | For a series of very in-depth articles, see [this page |
9 | 10 | ](https://www.airs.com/blog/archives/38) etc. |
10 | 11 | |
11 | -[Here](https://sourceware.org/glibc/wiki/Debugging/Loader_Debugging)'s a page on how to debug ld.so, and [here](https://www.gnu.org/software/hurd/glibc/startup.html)'s one on the glibc startup process (GNU Hurd, but mostly applicable to Linux as well). |
|
12 | +[Here](https://sourceware.org/glibc/wiki/Debugging/Loader_Debugging)'s a page |
|
13 | +on how to debug ld.so, and [here](https://www.gnu.org/software/hurd/glibc/startup.html)'s |
|
14 | +one on the glibc startup process (GNU Hurd, but mostly applicable to Linux as well). |
|
12 | 15 | |
13 | 16 | ### The interesting bits |
14 | 17 | |
... | ... | @@ -36,8 +39,8 @@ symbols, and performs the required relocations to glue all code together. |
36 | 39 | However, there's one entry, `DT_DEBUG`, which isn't documented (the docs say |
37 | 40 | "for debugging purposes"). What it actually does, is that the dynamic linker |
38 | 41 | places a pointer to its `r_debug` struct in the value field. This behavior |
39 | -is mostly portable (as in, it works on at least glibc, musl, bionic and FreeBSD). If |
|
40 | -you look at your system's `link.h` file (eg. in `/usr/include`), you can see |
|
42 | +is mostly portable (as in, it works on at least glibc, musl, bionic and FreeBSD). |
|
43 | +If you look at your system's `link.h` file (eg. in `/usr/include`), you can see |
|
41 | 44 | the contents of this struct. The second field is a pointer to the root |
42 | 45 | `link_map`. More about this one later. |
43 | 46 | |
... | ... | @@ -58,7 +61,7 @@ phdr. We can use the latter to traverse all the symbol tables and figure out |
58 | 61 | what the address of every symbol is. This is what **bold** and **dnload** do, |
59 | 62 | except they save a hash of the names of the required symbols, instead of the |
60 | 63 | symbol names themselves, computes the hashes of the symbol names from the |
61 | -`link_map`, and compare thise. |
|
64 | +`link_map`, and compare those. |
|
62 | 65 | |
63 | 66 | However, there are a few ways to save even more bytes: |
64 | 67 |
explain/tinyelf-arm.md
... | ... | @@ -1,30 +1,50 @@ |
1 | 1 | # Tiny ELF binaries on ARM |
2 | 2 | |
3 | -Looks like breadbox didn't want to go down *this* rabbithole. So we'll have to do it instead. |
|
3 | +Looks like breadbox didn't want to go down *this* rabbithole. So we'll have to |
|
4 | +do it instead. |
|
4 | 5 | |
5 | -* Target platform: OABI is dead, so EABI it is. Anything running Linux seems to support `thumb`, `half` and `fastmult`, and usually `edsp` as well. |
|
6 | +* Target platform: OABI is dead, so EABI it is. Anything running Linux seems to |
|
7 | + support `thumb`, `half` and `fastmult`, and usually `edsp` as well. |
|
6 | 8 | * So what will the minimum target CPU be? ARMv6T (RPI1)? ARMv5TE? |
7 | 9 | * All ARM instructions are 4 bytes wide |
8 | -* There's a "Thumb" mode, with reduced instructions (eg. no free shifts, no 3-operand instructions) where all instructions are 2 bytes wide |
|
10 | +* There's a "Thumb" mode, with reduced instructions (eg. no free shifts, no |
|
11 | + 3-operand instructions) where all instructions are 2 bytes wide |
|
9 | 12 | * Switch to Thumb like this: `add lr, pc, #1; bx lr` |
10 | - * On older ARMs, it was possible to directly write to `pc` and switch mode, but this doesn't seem to be possible on ARMv6 anymore. |
|
11 | -* The `mov` opcode doesn't accept arbitrary immediate values, so you sometimes have to spill values to a "constant pool", or be creative with assignments and register write-backs in load/store ops |
|
12 | -* Null bytes decode to `andeq r0, r0` in ARM mode, or to `movs r0, r0` in Thumb mode, both are no-ops, unlike in x86 where null bytes cause a segfault. |
|
13 | - * Instruction encoding is relatively sane, so you can predict what low-value 32-bit ints will decode to so you can treat them as (almost-)no-ops. |
|
14 | -* It's a RISC, so you don't have one-byte-instructions, flexible addressing modes or stringops, but there are a few useful parts in ARM: |
|
13 | + * On older ARMs, it was possible to directly write to `pc` and switch mode, |
|
14 | + but this doesn't seem to be possible on ARMv6 anymore. |
|
15 | +* The `mov` opcode doesn't accept arbitrary immediate values, so you sometimes |
|
16 | + have to spill values to a "constant pool", or be creative with assignments and |
|
17 | + register write-backs in load/store ops |
|
18 | +* Null bytes decode to `andeq r0, r0` in ARM mode, or to `movs r0, r0` in Thumb |
|
19 | + mode, both are no-ops, unlike in x86 where null bytes cause a segfault. |
|
20 | + * Instruction encoding is relatively sane, so you can predict what low-value |
|
21 | + 32-bit ints will decode to so you can treat them as (almost-)no-ops. |
|
22 | +* It's a RISC, so you don't have one-byte-instructions, flexible addressing |
|
23 | + modes or stringops, but there are a few useful parts in ARM: |
|
15 | 24 | * `pc`, `sp` etc. behave as regular registers |
16 | - * You can shift one operand of an instruction by a constant value for free, it doesn't cost any bytes. (ARM mode only) This can also be used to do fixed-point multiplications etc. (eg. `add r0, r0, lsr #1` for `r0*1.5`) |
|
25 | + * You can shift one operand of an instruction by a constant value for free, |
|
26 | + it doesn't cost any bytes. (ARM mode only) This can also be used to do |
|
27 | + fixed-point multiplications etc. (eg. `add r0, r0, lsr #1` for `r0*1.5`) |
|
17 | 28 | * `ldmia`/`stmia` are great for copying stuff around |
18 | -* [`e_machine` (and `e_type`) seem to be the only checked header fields](https://code.woboq.org/linux/linux/arch/arm/kernel/elf.c.html) (`e_entry` alignment checks are normal, because if it wouldn't be aligned, the code would segfault on entry.) |
|
19 | - * Of course, `e_entry`, `e_phoff`, `e_phnum` need to contain the right values, and `e_phentsize` and `e_ehsize` need to be correct as well. |
|
20 | -* `phdr` parsing etc. is done architecture-independently, so the same tricks should be usable here as well. |
|
21 | - * Turns out it's even more relaxed than x86 when messing with `p_paddr`, `p_padding` and `p_flags`. It seems to be the case that the kernel & CPU will happily let you execute code in read-write pages. |
|
22 | -* Apparently the kernel doesn't look at the immediate field of `swi` and `bkpt` instructions __if it's configured as EABI-only__ (which we assume). |
|
23 | -* [Dynamic linking stuff](https://linux.weeaboo.software/explain/rtld#dynamic-linking_arm) |
|
29 | +* [`e_machine` (and `e_type`) seem to be the only checked header fields |
|
30 | + ](https://code.woboq.org/linux/linux/arch/arm/kernel/elf.c.html) (`e_entry` |
|
31 | + alignment checks are normal, because if it wouldn't be aligned, the code |
|
32 | + would segfault on entry.) |
|
33 | + * Of course, `e_entry`, `e_phoff`, `e_phnum` need to contain the right |
|
34 | + values, and `e_phentsize` and `e_ehsize` need to be correct as well. |
|
35 | +* `phdr` parsing etc. is done architecture-independently, so the same tricks |
|
36 | + should be usable here as well. |
|
37 | + * Turns out it's even more relaxed than x86 when messing with `p_paddr`, |
|
38 | + `p_padding` and `p_flags`. It seems to be the case that the kernel & CPU |
|
39 | + will happily let you execute code in read-write pages. |
|
40 | +* Apparently the kernel doesn't look at the immediate field of `swi` and |
|
41 | + `bkpt` instructions __if it's configured as EABI-only__ (which we assume). |
|
42 | +* [Dynamic linking stuff](/explain/rtld#dynamic-linking_arm) |
|
24 | 43 | |
25 | 44 | ### Minimal ELF Poc |
26 | 45 | |
27 | -Not *that* minimal :) (But it should be able to show you which fields can be bogus quite clearly.) |
|
46 | +Not *that* minimal :) (But it should be able to show you which fields can be |
|
47 | +bogus quite clearly.) |
|
28 | 48 | |
29 | 49 | ``` |
30 | 50 | gcc -c -o tiny.o tiny.S |
tools.md
... | ... | @@ -10,10 +10,15 @@ |
10 | 10 | |
11 | 11 | * shell dropping: `cp $0 /tmp/M;(sed 1d $0|lzcat)>$_;exec $_;` |
12 | 12 | * ~~[fishypack |
13 | - ](https://bitbucket.org/blackle_mori/cenotaph4soda/src/master/packer/?at=master): In-memory `memfd`/`execveat`-based decompressor~~ (Deprecated in favor of vondehi) |
|
14 | -* [vondehi](https://gitlab.com/PoroCYon/vondehi): Next-generation in-memory `memfd`/`execveat`-based decompressor (See list of known bugs) |
|
15 | - * [autovndh](https://gitlab.com/snippets/1800243): script that bruteforces all possible gzip/lzma/xz/... options and automatically places a vondehi decompression stub at the beginning |
|
16 | -* [oneKpaq](https://github.com/temisu/oneKpaq): Generic PAQ-based (de)compressor for 32-bit x86 |
|
13 | + ](https://bitbucket.org/blackle_mori/cenotaph4soda/src/master/packer/?at=master): |
|
14 | + In-memory `memfd`/`execveat`-based decompressor~~ (Deprecated in favor of vondehi) |
|
15 | +* [vondehi](https://gitlab.com/PoroCYon/vondehi): Next-generation in-memory |
|
16 | + `memfd`/`execveat`-based decompressor (See list of known bugs) |
|
17 | + * [autovndh](https://gitlab.com/snippets/1800243): script that bruteforces |
|
18 | + all possible gzip/lzma/xz/... options and automatically places a vondehi |
|
19 | + decompression stub at the beginning |
|
20 | +* [oneKpaq](https://github.com/temisu/oneKpaq): Generic PAQ-based (de)compressor |
|
21 | + for 32-bit x86 |
|
17 | 22 | |
18 | 23 | ### synths |
19 | 24 | |
... | ... | @@ -21,8 +26,12 @@ |
21 | 26 | * [4klang](https://www.pouet.net/prod.php?which=53398), [ForkedKlang |
22 | 27 | ](https://www.pouet.net/topic.php?which=11312). Note that the replayer code |
23 | 28 | is 32-bit only! You'll need some hacks to make it work on 64-bit. |
24 | -* [Clinkster](https://www.pouet.net/prod.php?which=61592), replayer is 32-bit only as well. |
|
25 | -* [Oidos](https://www.pouet.net/prod.php?which=69524), replayer is once more 32-bit only. |
|
29 | +* [Clinkster](https://www.pouet.net/prod.php?which=61592), replayer is 32-bit |
|
30 | + only as well. |
|
31 | +* [Oidos](https://www.pouet.net/prod.php?which=69524), replayer is once more |
|
32 | + 32-bit only. |
|
26 | 33 | * [Axiom](https://github.com/monadgroup/axiom/) is "supposed" to work |
27 | 34 | |
28 | -See [here](/code#example-code_basic-synth-setup) for some synth example setup code, together with some Linux-specific patches to get some of the replayers to work. |
|
35 | +See [here](/code#example-code_basic-synth-setup) for some |
|
36 | +synth example setup code, together with some Linux-specific patches to get some |
|
37 | +of the replayers to work. |