Skip to content

Commit 9897ba0

Browse files
dancinlifedancinlifeclaude
authored
feat(F-NSWINDOW-E5 r7): bind 3 CRT imports + IMUL/CPUID/RDTSC decode + security-cookie arithmetic (#29)
Cross the r6 wall (unbound IAT call @0x5392D4, insns=30) and run deeper into __scrt_common_main CRT init. native/i386_cpu.{c,h}: 3 more kernel32 shims โ€” GetStartupInfoW (buffer-write STARTUPINFOW, cb=0x44), GetSystemInfo (bounded-synthetic SYSTEM_INFO), and GetProcAddress (โ†’ synthetic in-image stub). IAT now binds 11 slots (0x538000..0x538028). Synthetic monotonic TSC field + I386_TSC_STEP added. native/i386_decode.{c,h} + byte-equal .hexa mirror (RUNEQ): new opcodes IMUL_R_RM (0F AF), IMUL_R_RM_IMM (69 id / 6B ib), CPUID (0F A2), RDTSC (0F 31). Interpreter: IMUL 32-bit signed (lowโ†’dst, CF/OF on int32 overflow); CPUID writes a synthetic GenuineIntel feature set; RDTSC writes a synthetic monotonic edx:eax. native/i386_cpu_test.c: hermetic prologue extended with the 3 binds + the __security_init_cookie shape (load FILETIME entropy โ†’ xor โ†’ imul โ†’ store a non-default cookie to a global slot) + cpuid + rdtsc. Run A advances insns 30โ†’44, halt 0x5392D4โ†’0x539318 (UNBOUND_IMPORT slot 0x53802C, bound=11, last=GetProcAddress); cookie/cpuid/rdtsc all asserted. B/D sentinel 0F A2โ†’0F A3 (bt, next decoder gap). __SHIM_TEST__ PASS, clang -Wall -Wextra -Wpedantic clean. main/WinMain NOT reached โ€” still CRT-init (import binding); the hermetic prologue is a documented SHAPE, not the real binary, so there is no real `call main` yet. own1: loading our own kernel32 imports; CPUID/RDTSC are plain CPU ops; the cookie is our arithmetic over our buffers. No Wine, no protection. validated_manjeom=0. Co-authored-by: dancinlife <mk55911@proton.me> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5fe4868 commit 9897ba0

7 files changed

Lines changed: 382 additions & 45 deletions

File tree

โ€ŽCHANGELOG.mdโ€Ž

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,44 @@ All notable changes to `gamebox` are documented in this file.
66

77
### Added
88

9+
- feat(F-NSWINDOW-E5 r7): **CRT import 3๊ฐœ ์ถ”๊ฐ€ ๋ฐ”์ธ๋”ฉ + IMUL/CPUID/RDTSC ๋””์ฝ”๋”
10+
๊ฐญ ์ข…๊ฒฐ + `__security_init_cookie` ์‚ฐ์ˆ  ์‹คํ–‰** โ€” r6 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT ํ˜ธ์ถœ
11+
@`0x5392D4`, insns=30)์„ **๋„˜๋Š”๋‹ค**. (1) `native/i386_cpu.{c,h}` ์— ์„ธ ๊ฐœ์˜
12+
kernel32 ์…ฐ์ž„ ์ถ”๊ฐ€: `GetStartupInfoW(LPSTARTUPINFOW)`(1-arg ptr, push ๋œ ํฌ์ธํ„ฐ
13+
`[esp]` ์˜ STARTUPINFOW 0x44B ๋ฅผ 0 ์œผ๋กœ + `cb=0x44` ์Šคํƒฌํ”„ โ€” ๋ฒ„ํผ-์“ฐ๊ธฐ),
14+
`GetSystemInfo(LPSYSTEM_INFO)`(1-arg ptr, **bounded-synthetic** SYSTEM_INFO
15+
0x24B โ€” dwPageSize=0x1000ยทnCPU=4ยทarch=INTEL, ๋‚˜๋จธ์ง€ 0), `GetProcAddress(HMODULE,
16+
LPCSTR)`(2-arg โ†’ **ํ•ฉ์„ฑ in-image ์Šคํ… ์ฃผ์†Œ** `base+0x1FF0`). IAT ๋“ฑ๋ก ์Šฌ๋กฏ
17+
`0x538000..0x538028` ๋กœ 11๊ฐœ(count=11). (2) `native/i386_decode.{c,h}` +
18+
byte-equal `.hexa` ๋ฏธ๋Ÿฌ: enum `I386_OP_IMUL_R_RM`(57, `0F AF`)/`_IMM`(58, `69 id`/
19+
`6B ib`)/`I386_OP_CPUID`(59, `0F A2`)/`I386_OP_RDTSC`(60, `0F 31`) + ๋””์ฝ”๋“œ
20+
๋ถ„๊ธฐ ์ถ”๊ฐ€, op_name="imul"/"cpuid"/"rdtsc". ์ธํ„ฐํ”„๋ฆฌํ„ฐ: **IMUL** ์€ 32-bit signed
21+
๊ณฑ์˜ ํ•˜์œ„ 32-bit ๋ฅผ dst(ModR/M.reg)์—, int32 ์˜ค๋ฒ„ํ”Œ๋กœ๋ฉด CF=OF=1(SDM Vol.2);
22+
**CPUID** ๋Š” leaf(eax)๋ณ„ **ํ•ฉ์„ฑ** ํ”ผ์ฒ˜์…‹(leaf0 vendor "GenuineIntel"ยทmax-leaf,
23+
leaf1 family/feature) ์„ eax/ebx/ecx/edx ์—; **RDTSC** ๋Š” `cpu->tsc += step` ํ•ฉ์„ฑ
24+
๋‹จ์กฐ ์นด์šดํ„ฐ๋ฅผ edx:eax ์— ๊ธฐ๋ก. CPUID/RDTSC ๋Š” ํ‰๋ฒ”ํ•œ CPU ๋ช…๋ น(๋ณดํ˜ธ ์•„๋‹˜). (3)
25+
**๋ณด์•ˆ์ฟ ํ‚ค ์‚ฐ์ˆ **: hermetic ํ”„๋กค๋กœ๊ทธ๊ฐ€ FILETIME ์—”ํŠธ๋กœํ”ผ ๋กœ๋“œ โ†’ `xor` โ†’
26+
`imul eax,eax,0x01000193`(์‹ ๊ทœ 0x69 IMUL) โ†’ ๊ธ€๋กœ๋ฒŒ ์Šฌ๋กฏ์— **๋น„๊ธฐ๋ณธ ์ฟ ํ‚ค** ์ €์žฅ โ†’
27+
`cpuid`(GenuineIntel) โ†’ `rdtsc`. (4) hermetic ํ…Œ์ŠคํŠธ(`native/i386_cpu_test.c`)
28+
Run A ๋Š” r6 ์ฒด์ธ ๋’ค์— `call GetStartupInfoW`(cb=0x44 ๊ฒ€์ฆ) / `call GetSystemInfo`
29+
(page=0x1000ยทnCPU=4 ๊ฒ€์ฆ) / `pushร—2; call GetProcAddress` / ์ฟ ํ‚ค `mov/xor/imul/mov`
30+
(์ฟ ํ‚ค == `(FT_lo^FT_hi)*0x01000193` ์žฌ์œ ๋„ ๊ฒ€์ฆ, โ‰ 0) / `cpuid`(ebx="Genu"ยท
31+
ecx="ntel" ๊ฒ€์ฆ) / `rdtsc`(edx:eax ํ•ฉ์„ฑ ๊ฒ€์ฆ) / ๋ฏธ๋“ฑ๋ก `call` ์„ ์ด์–ด ๋ถ™์—ฌ ๊ฒฝ๊ณ„
32+
ํ†ต๊ณผ๋ฅผ ์ฆ๋ช…: **insns 30โ†’44, halt `0x5392D4`โ†’`0x539318`**(reason=UNBOUND_IMPORT,
33+
slot `0x53802C`), bound=11, last=GetProcAddress. B/D sentinel ์€ `0F A2`(์ด์ œ ์‹คํ–‰๋จ)
34+
โ†’ `0F A3`(BT, ๋‹ค์Œ ์ง„์งœ ๋””์ฝ”๋” ๊ฐญ) ์œผ๋กœ ๊ต์ฒด. ์ธก์ • ๋ผ์ธ `__SHIM__ PARTIAL
35+
phase=e4_crt_security_cookie insns=44 bound=11 last=GetProcAddress
36+
halt_va=0x539318 halt=unbound_import halt_op=call unbound_slot=0x53802C`,
37+
`__SHIM_TEST__ PASS`(CI ๊ฒŒ์ดํŠธ, Run A 18 checks ์ „๋ถ€ green, ๋กœ์ปฌ clang
38+
`-Wall -Wextra -Wpedantic -std=c11` ์ฒญ์ •). **own1**: ๋กœ๋”๊ฐ€ ์ž๊ธฐ ํ”„๋กœ์„ธ์Šค์˜ **์ž๊ธฐ
39+
import**(kernel32 OS API)๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๊ตฌํ˜„์— ๋ฌถ๋Š” **๋กœ๋”ฉ** โ€” ์šฐํšŒ ์•„๋‹˜; CPUID/RDTSC
40+
๋Š” ํ‰๋ฒ”ํ•œ CPU ๋ช…๋ น, ์ฟ ํ‚ค๋Š” **์ž๊ธฐ ๋ฒ„ํผ ์œ„์˜ ์ž๊ธฐ ์‚ฐ์ˆ **, ํ•ฉ์„ฑ SYSTEM_INFO/์Šคํ…์€
41+
์ •์ง ๋ผ๋ฒจ. **`main`/`WinMain` ๋ฏธ๋„๋‹ฌ**: ์•„์ง CRT-init(import ๋ฐ”์ธ๋”ฉ) ๋‹จ๊ณ„์ด๋ฉฐ
42+
hermetic ํ”„๋กค๋กœ๊ทธ๋Š” ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์•„๋‹Œ ๋ฌธ์„œํ™”๋œ SHAPE ๋ผ ์ง„์งœ `call main` ์€
43+
์—†์Œ โ€” ๋‚จ์€ CRT ๋‹จ๊ณ„(์ถ”๊ฐ€ import + `__scrt_common_main_seh` โ†’ user entry). `validated_manjeom`
44+
์€ ์—ฌ์ „ํžˆ **0**(๋กœ๋” ์ง„์ฒ™์ด์ง€ ๋ Œ๋”๋œ ํ”„๋ ˆ์ž„ ์•„๋‹˜). ๋‹ค์Œ r8: ๋ฏธ๋“ฑ๋ก slot `0x53802C`
45+
๋ฐ”์ธ๋”ฉ + `0F A3` BT ๋””์ฝ”๋” ๊ฐญ + ์‹ค์ œ ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ `mainCRTStartupโ†’main` ๊ฑฐ๋ฆฌ ์ธก์ •.
46+
947
- feat(F-NSWINDOW-E5 r6): **CRT-security import 3๊ฐœ ์ถ”๊ฐ€ ๋ฐ”์ธ๋”ฉ + 0F B6/B7/BE/BF
1048
MOVZX/MOVSX ๋””์ฝ”๋” ๊ฐญ ์ข…๊ฒฐ + ํ•ฉ์„ฑ TEBโ†’PEBโ†’ImageBase ์ฒด์ธ** โ€” r5 ์˜ ๋ฒฝ(๋ฏธ๋“ฑ๋ก IAT
1149
ํ˜ธ์ถœ @`0x5392A1`, insns=18)์„ **๋„˜๋Š”๋‹ค**. (1) `native/i386_cpu.{c,h}` ์— ์„ธ ๊ฐœ์˜

โ€Žnative/i386_cpu.cโ€Ž

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,45 @@ uint32_t i386_shim_GetModuleHandleW(i386_cpu_t *cpu, const struct i386_image *im
109109
return img->base; // HMODULE == loaded image base
110110
}
111111

112+
// GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo) โ€” WINAPI/stdcall, 1 ptr arg,
113+
// returns void. Buffer-writing: zeroes a STARTUPINFOW (0x44 bytes on x86) in
114+
// image memory at the pushed pointer ([esp]) and stamps cb = 0x44 at offset 0.
115+
// own1: a CRT-startup OS-API call filling the program's OWN buffer โ€” loading.
116+
uint32_t i386_shim_GetStartupInfoW(i386_cpu_t *cpu, const struct i386_image *img) {
117+
uint32_t psi; // LPSTARTUPINFOW arg
118+
if (!i386_mem_read32(img, cpu->gpr[I386_REG_ESP], &psi)) return 0;
119+
for (uint32_t o = 0; o < 0x44u; o += 4) i386_mem_write32(img, psi + o, 0u);
120+
i386_mem_write32(img, psi + 0x00u, 0x44u); // cb = sizeof(STARTUPINFOW) (x86)
121+
return 0; // void โ†’ EAX irrelevant
122+
}
123+
124+
// GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) โ€” WINAPI/stdcall, 1 ptr arg, void.
125+
// Buffer-writing: a BOUNDED-SYNTHETIC SYSTEM_INFO (0x24 bytes on x86) โ€” a few
126+
// plausible fields (page size / processor count / type), the rest zeroed.
127+
// own1: native re-impl of the OS API filling the program's OWN buffer โ€” loading.
128+
uint32_t i386_shim_GetSystemInfo(i386_cpu_t *cpu, const struct i386_image *img) {
129+
uint32_t psi; // LPSYSTEM_INFO arg
130+
if (!i386_mem_read32(img, cpu->gpr[I386_REG_ESP], &psi)) return 0;
131+
for (uint32_t o = 0; o < 0x24u; o += 4) i386_mem_write32(img, psi + o, 0u);
132+
i386_mem_write32(img, psi + 0x00u, 0x00000000u);// wProcessorArchitecture = INTEL(0)
133+
i386_mem_write32(img, psi + 0x04u, 0x00001000u);// dwPageSize = 4096
134+
i386_mem_write32(img, psi + 0x14u, 0x00000004u);// dwNumberOfProcessors = 4 (synthetic)
135+
i386_mem_write32(img, psi + 0x18u, 0x000006F0u);// dwProcessorType (synthetic)
136+
return 0; // void โ†’ EAX irrelevant
137+
}
138+
139+
// GetProcAddress(HMODULE hModule, LPCSTR lpProcName) โ€” WINAPI/stdcall, 2 args,
140+
// returns FARPROC. own1: the LOADER hands back a SYNTHETIC in-image stub address
141+
// (we never resolve to a real OS export here); a later round can bind it. Not a
142+
// bypass โ€” this is import resolution, exactly what a loader does.
143+
uint32_t i386_shim_GetProcAddress(i386_cpu_t *cpu, const struct i386_image *img) {
144+
uint32_t hmod = 0, pname = 0;
145+
i386_mem_read32(img, cpu->gpr[I386_REG_ESP] + 0, &hmod); // arg1 hModule
146+
i386_mem_read32(img, cpu->gpr[I386_REG_ESP] + 4, &pname); // arg2 lpProcName
147+
(void)hmod; (void)pname;
148+
return img->base + 0x1FF0u; // synthetic in-image stub addr
149+
}
150+
112151
const i386_import_t *i386_iat_lookup(const i386_iat_t *iat, uint32_t slot_va) {
113152
if (!iat || !iat->imports) return NULL;
114153
for (uint32_t i = 0; i < iat->count; i++) {
@@ -614,6 +653,66 @@ void i386_cpu_run(i386_cpu_t *cpu, const i386_image_t *img,
614653
cpu->gpr[(insn.modrm >> 3) & 7] = v;
615654
break;
616655
}
656+
// โ”€โ”€ IMUL r32, r/m32[, imm] (E5 r7) โ€” 0F AF ยท 69 /r id ยท 6B /r ib โ”€
657+
// 32-bit signed multiply. Low 32 bits of the product โ†’ dst register
658+
// (ModR/M.reg). CF=OF=1 if the full signed product does not fit in a
659+
// sign-extended 32-bit result (per SDM Vol.2 IMUL); SF/ZF/AF/PF
660+
// undefined (left unchanged). own1: a plain CPU multiply.
661+
case I386_OP_IMUL_R_RM:
662+
case I386_OP_IMUL_R_RM_IMM: {
663+
int dst = (insn.modrm >> 3) & 7;
664+
i386_halt_t why = I386_HALT_UNSUPPORTED;
665+
uint32_t rm_v;
666+
if (!rm_get32(cpu, img, &insn, &rm_v, &why)) {
667+
res->halt = why; res->halt_va = eip; res->halt_op = insn.op; return;
668+
}
669+
int64_t a = (insn.op == I386_OP_IMUL_R_RM_IMM)
670+
? (int64_t)(int32_t)rm_v // src1 = r/m32
671+
: (int64_t)(int32_t)cpu->gpr[dst];
672+
int64_t b = (insn.op == I386_OP_IMUL_R_RM_IMM)
673+
? (int64_t)(int32_t)insn.imm // src2 = imm
674+
: (int64_t)(int32_t)rm_v; // src2 = r/m32
675+
int64_t prod = a * b;
676+
uint32_t low = (uint32_t)prod;
677+
cpu->gpr[dst] = low;
678+
int ovf = (prod != (int64_t)(int32_t)low);
679+
set_flag(&cpu->eflags, EFL_CF, ovf);
680+
set_flag(&cpu->eflags, EFL_OF, ovf);
681+
break;
682+
}
683+
// โ”€โ”€ CPUID (E5 r7) โ€” 0F A2 โ€” SYNTHETIC CPU-identity / feature set โ”€
684+
// Leaf in EAX selects the result. We return a plausible synthetic
685+
// set (vendor "GenuineIntel" + a max-leaf for leaf 0; family/feature
686+
// bits for leaf 1). own1: CPUID is a plain CPU instruction โ€” the CRT
687+
// probes it to pick code paths; NOT a protection mechanism.
688+
case I386_OP_CPUID: {
689+
uint32_t leaf = cpu->gpr[I386_REG_EAX];
690+
if (leaf == 0) {
691+
cpu->gpr[I386_REG_EAX] = 0x00000016u; // max basic leaf (synthetic)
692+
cpu->gpr[I386_REG_EBX] = 0x756E6547u; // "Genu"
693+
cpu->gpr[I386_REG_EDX] = 0x49656E69u; // "ineI"
694+
cpu->gpr[I386_REG_ECX] = 0x6C65746Eu; // "ntel" โ†’ "GenuineIntel"
695+
} else if (leaf == 1) {
696+
cpu->gpr[I386_REG_EAX] = 0x000006F0u; // family/model/stepping (synthetic)
697+
cpu->gpr[I386_REG_EBX] = 0x00000000u;
698+
cpu->gpr[I386_REG_ECX] = 0x00000201u; // a couple ECX feature bits (synthetic)
699+
cpu->gpr[I386_REG_EDX] = 0x078BFBFFu; // common base EDX feature bits (synthetic)
700+
} else {
701+
cpu->gpr[I386_REG_EAX] = 0u; cpu->gpr[I386_REG_EBX] = 0u;
702+
cpu->gpr[I386_REG_ECX] = 0u; cpu->gpr[I386_REG_EDX] = 0u;
703+
}
704+
break;
705+
}
706+
// โ”€โ”€ RDTSC (E5 r7) โ€” 0F 31 โ€” SYNTHETIC monotonic timestamp counter โ”€
707+
// Each rdtsc advances cpu->tsc by a fixed step and returns the running
708+
// 64-bit count in edx:eax. own1: a deterministic synthetic counter,
709+
// NOT the host TSC and NOT a protection clock.
710+
case I386_OP_RDTSC: {
711+
cpu->tsc += I386_TSC_STEP;
712+
cpu->gpr[I386_REG_EAX] = (uint32_t)cpu->tsc;
713+
cpu->gpr[I386_REG_EDX] = (uint32_t)(cpu->tsc >> 32);
714+
break;
715+
}
617716
// โ”€โ”€ E4 kernel32 boundary โ€” indirect IAT call / jump โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
618717
case I386_OP_CALL_RM: // FF /2 [..]
619718
case I386_OP_JMP_RM: { // FF /4 [..]

โ€Žnative/i386_cpu.hโ€Ž

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@
4343
// address into a few-field synthetic TEB/PEB (teb_base; self@+0x18, PEB@+0x30,
4444
// ImageBase@PEB+8) so the security-cookie / CRT-startup `fs:[..]` chain runs.
4545
// own1: synthetic block, NOT the OS TEB and NOT a protection structure.
46+
//
47+
// Coverage (E5 r7 โ€” security cookie + CPU-identity ops, deeper into CRT init):
48+
// IMUL r32,r/m32 (0F AF) + IMUL r32,r/m32,imm (69 id / 6B ib) โ€” 32-bit signed
49+
// multiply, low result to dst, CF/OF set if it overflows int32 ยท
50+
// CPUID (0F A2) โ€” writes a SYNTHETIC feature set (leaf 0 vendor "GenuineIntel"
51+
// + max-leaf; leaf 1 family/feature bits) into eax/ebx/ecx/edx ยท
52+
// RDTSC (0F 31) โ€” writes a SYNTHETIC monotonic counter (cpu->tsc += step) into
53+
// edx:eax ยท three more kernel32 shims (GetStartupInfoW [buffer-write cb=0x44] /
54+
// GetSystemInfo [bounded-synthetic SYSTEM_INFO] / GetProcAddress [โ†’ synthetic
55+
// in-image stub addr]). The prologue now runs the MSVC __security_init_cookie
56+
// shape: load the FILETIME entropy, xor, imul-mix, and store a non-default
57+
// cookie to a global slot. own1: CPUID/RDTSC are plain CPU instructions (no
58+
// protection); the cookie is OUR arithmetic over OUR buffers; no Wine.
4659

4760
#ifndef GAMEBOX_I386_CPU_H
4861
#define GAMEBOX_I386_CPU_H
@@ -100,8 +113,16 @@ struct i386_cpu {
100113
// and NOT a protection structure โ€” just enough for the cookie math to run.
101114
// 0 โ†’ no TEB modeled (an fs: access then halts OOB honestly).
102115
uint32_t teb_base;
116+
// โ”€โ”€ E5 r7 SYNTHETIC timestamp counter (NOT the real CPU TSC) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
117+
// RDTSC (0F 31) returns a deterministic monotonic value: each rdtsc adds
118+
// I386_TSC_STEP and writes the running 64-bit count to edx:eax. own1: a
119+
// plausible synthetic counter, NOT the host TSC and NOT a protection clock.
120+
uint64_t tsc;
103121
};
104122

123+
// Per-rdtsc increment for the synthetic timestamp counter (plausible, fixed).
124+
#define I386_TSC_STEP 0x000000178B4D159EULL
125+
105126
// Native kernel32 shim โ€” GetCurrentThreadId (WINAPI/stdcall, 0 args, โ†’ DWORD).
106127
// own1: returns a deterministic plausible thread id. This is the OS API
107128
// surface bound to a native impl (loading), not a protection bypass.
@@ -130,6 +151,18 @@ uint32_t i386_shim_IsProcessorFeaturePresent(i386_cpu_t *cpu, const struct i386_
130151
uint32_t i386_shim_InitializeSListHead(i386_cpu_t *cpu, const struct i386_image *img);
131152
uint32_t i386_shim_GetModuleHandleW(i386_cpu_t *cpu, const struct i386_image *img);
132153

154+
// CRT-startup kernel32 shims (E5 r7). own1: native re-impls of the OS API
155+
// surface bound to the program's OWN imports โ€” loading, not a bypass.
156+
// GetStartupInfoW(LPSTARTUPINFOW) โ€” 1 ptr arg, void; zeroes a STARTUPINFOW
157+
// and stamps cb = 0x44 (sizeof) at image memory at the pushed pointer.
158+
// GetSystemInfo(LPSYSTEM_INFO) โ€” 1 ptr arg, void; writes a BOUNDED-
159+
// SYNTHETIC SYSTEM_INFO (page size / processor count / arch) buffer.
160+
// GetProcAddress(HMODULE,LPCSTR) โ€” 2 ptr/str args, returns a synthetic
161+
// in-image stub address (the loader hands back its own thunk).
162+
uint32_t i386_shim_GetStartupInfoW(i386_cpu_t *cpu, const struct i386_image *img);
163+
uint32_t i386_shim_GetSystemInfo(i386_cpu_t *cpu, const struct i386_image *img);
164+
uint32_t i386_shim_GetProcAddress(i386_cpu_t *cpu, const struct i386_image *img);
165+
133166
// Look up an IAT slot VA in the registry. Returns NULL if `iat` is NULL or
134167
// the slot is not bound (โ†’ the caller halts UNBOUND_IMPORT honestly).
135168
const i386_import_t *i386_iat_lookup(const i386_iat_t *iat, uint32_t slot_va);

0 commit comments

Comments
ย (0)