nx_pe_thunk_dump.nx source
↩ module page · 63 lines · 2407 B
1// nx_pe_thunk_dump.nx -- SOVEREIGN PE troubleshooting organ (replaces the python oracle). Reads a built
2// PE, locates the CreateFileA thunk by its `mov edx,0x80000000` signature (BA 00 00 00 80), and prints
3// the emitted thunk bytes as hex -- so "is the emitted thunk what the organ intended" is one step, in Nishi.
4import "nx_syscalls.nx"
5
6func d_putc(ch: i64) -> i64 { let t: *u8 = sys_mmap(1); t[0] = ch as u8; sys_write(1, t, 1); return 0 }
7func d_hexbyte(v: i64) -> i64 {
8 let hi: i64 = (v / 16) & 15
9 let lo: i64 = v & 15
10 if hi < 10 { d_putc(48 + hi) } else { d_putc(87 + hi) }
11 if lo < 10 { d_putc(48 + lo) } else { d_putc(87 + lo) }
12 d_putc(32)
13 return 0
14}
15func d_u16(b: *u8, o: i64) -> i64 { return (b[o] as i64) | ((b[o+1] as i64) << 8) }
16func d_u32(b: *u8, o: i64) -> i64 { return (b[o] as i64) | ((b[o+1] as i64) << 8) | ((b[o+2] as i64) << 16) | ((b[o+3] as i64) << 24) }
17
18func main() -> i64 {
19 let lenp: *i64 = sys_mmap(8) as *i64
20 let b: *u8 = sys_read_file("_offc/nx_win_uiserve.exe\x00" as *u8, lenp)
21 if (b as i64) == 0 { sys_write(1, "DUMP: no exe\n" as *u8, 13); return 1 }
22 let e: i64 = d_u32(b, 0x3C)
23 let sopt: i64 = d_u16(b, e + 20)
24 let nsec: i64 = d_u16(b, e + 6)
25 let st: i64 = e + 24 + sopt
26 var tro: i64 = 0
27 var trs: i64 = 0
28 var i: i64 = 0
29 while i < nsec {
30 let o: i64 = st + i * 40
31 if b[o] == (46 as u8) {
32 if b[o+1] == (116 as u8) {
33 if b[o+2] == (101 as u8) {
34 if b[o+3] == (120 as u8) {
35 if b[o+4] == (116 as u8) { trs = d_u32(b, o+16); tro = d_u32(b, o+20) }
36 }
37 }
38 }
39 }
40 i = i + 1
41 }
42 var idx: i64 = 0 - 1
43 var j: i64 = tro
44 while j < tro + trs - 5 {
45 if b[j] == (0xBA as u8) {
46 if b[j+1] == (0 as u8) {
47 if b[j+2] == (0 as u8) {
48 if b[j+3] == (0 as u8) {
49 if b[j+4] == (0x80 as u8) { idx = j; break }
50 }
51 }
52 }
53 }
54 j = j + 1
55 }
56 if idx < 0 { sys_write(1, "DUMP: fopen sig not found\n" as *u8, 26); return 2 }
57 sys_write(1, "fopen thunk (60 bytes from sub rsp):\n" as *u8, 37)
58 var k: i64 = idx - 7
59 let stop: i64 = idx + 53
60 while k < stop { d_hexbyte(b[k] as i64); k = k + 1 }
61 d_putc(10)
62 return 0
63}