Repository navigation
v0.0.150
rePIU v0.0.150
이전 릴리스 v0.0.149 이후의 변경입니다. 이번 릴리스는 실행 probe에 게스트 메모리 구간
dump 진단을 추가하고, 그 진단으로 확정한 원인에 따라 DOS 저메모리 읽기 대행을 문자열 명령까지
확장해 pumpit8의 배경 로딩 중 종료를 제거합니다.
실행 probe 메모리 구간 dump
REPIU_EXECUTION_PROBE_DUMP_*로 probe first-hit 시점의 게스트 메모리 구간을 파일에
보존합니다. 기준은 레지스터 이름 또는 절대 주소이며, 구조체 안의 포인터를 따라가는 간접
역참조와 최대 1 MiB 복사를 지원합니다.- 복사 buffer는 실행 시작 전에 한 번 할당해, first-hit recorder가 예외 처리 중 할당하지
않습니다. 파일 기록은 게스트 스레드가 멈춘 뒤 수행하며 VEH 안에서 파일 I/O를 하지 않습니다. - 바이트는 telemetry snapshot을 거치지 않고, snapshot에는 포착·기록 상태와 주소만 전달합니다.
- 전체 구간이 게스트 arena 안에서 읽을 수 있을 때만 복사하고, 부분 범위나 host 임의 주소는
읽지 않습니다. 환경 변수가 없으면 기존 실행 경로가 변하지 않습니다. - 반복 수행 절차는
docs/guides/execution-probe-memory-dump.md에 있습니다.
DOS 저메모리 문자열 명령 대행
HandleGuestLowMemoryReadFault는MOV,MOVZX,MOVSX만 처리하고 나머지 mnemonic을
거부해, 저메모리를 읽는 문자열 명령의 접근 위반이 처리되지 않았습니다.SCAS,LODS,CMPS의 저메모리 읽기를 대행하는 전용 모듈을 추가했습니다.MOVS는 기존
전담 handler가 있어 제외하고,STOS는 쓰기이므로 이 읽기 대행 범위에서 제외했습니다.REP계열이 반복 사이에서 재개 가능하다는 성질을 이용해, 반복이 끝났을 때만EIP를
전진시키고 남았으면 그대로 둡니다. 따라서 handler가 저메모리 경계를 추적하지 않습니다.- 폭은 operand width가 아니라 mnemonic에서 얻습니다.
66hprefix가 mnemonic 자체를 바꾸므로
매핑이 정확합니다. SSEcmpsd와 문자열CMPSD가 mnemonic을 공유하므로
ZYDIS_CATEGORY_STRINGOP으로 먼저 거릅니다. SetCompareFlags8을 폭 인자를 받는SetCompareFlags로 일반화하고 기존 함수는 이를
호출하도록 바꿨습니다. 8-bit 결과는 이전과 같습니다.- address size가 32-bit가 아니거나, 접근이 저메모리 경계를 걸치거나,
CMPS반대편이 게스트
범위 검사를 통과하지 못하거나,REP인데ECX가 이미 0이면 대행하지 않고 기존 진단이
원인을 그대로 보고하게 둡니다. - 특정 target이나 실행 파일 주소에 대한 동작 우회는 추가하지 않았습니다.
pumpit8 배경 로딩 종료 해소
BGA/083.DAT의BR01_01.tga(실제 PNG)를 읽던 중 발생하던0xC0000005종료가
사라졌습니다.- 원인은 자산의
iCCPchunk에 있는 zlib datastream이 4바이트 adler32 없이 작성된 것이며,
chunk CRC32가 저장값과 계산값 모두0x8FC1BA08로 일치해 원본 그대로 메모리에 도달했음을
확인했습니다. rePIU의 파일 I/O, RES 복호화, PNG 전달에는 결함이 없습니다. - 원본 libpng
1.0.6은png_decompress_chunk의 null 반환을 검사하지 않고 prefix0x17을
더해repne scasb로 역참조합니다. 정적 역어셈블로call과 fault 사이에 조건 분기가 없음을
확인했습니다. - 분석은
docs/analysis/pumpit8-bga-iccp-crash.md에 누적했습니다.
검증
- Win32 x86 Debug 빌드와 Release 빌드가 성공했습니다.
- Debug
pumpit8실행에서 문자열 대행 2,522회, 반복 2,522회, 마지막 EIP0x040E5D0D,
주소0x00000017, mnemonicSCASB, 예외 0건을 기록했습니다. - 같은 실행이
BGA/083.DAT를 지나AUDIO/004.AUD까지 진행했고 약 6.9 FPS로 렌더링했습니다.
종료는 접근 위반이 아니라 관측 종료를 위한 SDL 종료 요청입니다. - OpenWatcom 샘플 819개를 빌드하고 baseline과 같은 Release 구성으로 suite를 재측정해
RunPassed 528, 회귀 0건, 신규 통과 0건을 확인했습니다.
알려진 제한
pumpit8은 이 지점만 통과했을 뿐 완주를 확인한 것이 아니며, 이후 구간은 별도 관측
대상입니다.- DOS/4GW에서 linear
0x17이 실제로 읽힌다는 것은 보호 모드 익스텐더의 표준 동작에서 온
추정이며, 원본 환경에서 직접 관측하지 않았습니다. - 저메모리 대행은 읽기에 한정합니다.
STOS처럼 저메모리에 쓰는 경로는 아직 대행하지
않습니다. 67hprefix가 붙은 16-bit address size 문자열 명령은 관측된 바 없어 구현하지 않았습니다.- 샘플 suite는 저메모리 문자열 읽기 경로에 도달하지 않으므로, 회귀 0건은 영향이 없음을
확인한 것이지 이 경로를 검증한 것이 아닙니다.
rePIU v0.0.150
Everything since the previous release, v0.0.149. This release adds a guest memory-range dump
diagnostic to the execution probe and, acting on the cause that diagnostic established, extends DOS
low-memory read servicing to string instructions, removing the pumpit8 termination during
background loading.
Execution probe memory-range dump
REPIU_EXECUTION_PROBE_DUMP_*preserves a guest memory range to a file at the probe's first hit.
The base is a register name or an absolute address, with optional indirect dereference to follow a
pointer inside a structure and up to 1 MiB copied.- The capture buffer is allocated once before execution starts, so the first-hit recorder never
allocates during exception handling. The file is written after the guest thread stops, and no file
I/O happens inside the VEH. - The bytes never travel through the telemetry snapshot, which carries only capture and write status
with the addresses. - The copy happens only when the complete range is readable inside the guest arena; no partial range
or arbitrary host address is read. Without the environment variables the existing execution path
is unchanged. - The repeatable procedure is in
docs/guides/execution-probe-memory-dump.md.
DOS low-memory string instruction servicing
HandleGuestLowMemoryReadFaultaccepted onlyMOV,MOVZX, andMOVSXand rejected every other
mnemonic, leaving access violations from string instructions reading low memory unserviced.- Added a dedicated module servicing
SCAS,LODS, andCMPSreads of low memory.MOVSis
excluded because a dedicated handler already owns it, andSTOSis excluded because it writes and
falls outside this read facility. - Using the restartability of
REPforms between iterations,EIPadvances only when the
repetition finished and is otherwise left in place, so the handler never tracks where low memory
ends. - Width comes from the mnemonic rather than the operand width, since a
66hprefix changes the
mnemonic itself and makes the mapping exact.ZYDIS_CATEGORY_STRINGOPgates first because the SSE
cmpsdshares its mnemonic with the string form. SetCompareFlags8is generalized into a width-takingSetCompareFlagswith the original
delegating to it; 8-bit results are unchanged.- Servicing declines, leaving the existing diagnostics to report the cause, when the address size is
not 32-bit, the access straddles the low-memory boundary, theCMPScounterpart fails the
guest-range check, or aREPhasECXalready zero. - No target-specific or executable-address behavior bypass was added.
pumpit8 background-loading termination resolved
- The
0xC0000005termination while readingBR01_01.tga— actually a PNG — fromBGA/083.DATis
gone. - The cause is that the asset's
iCCPchunk carries a zlib datastream written without its four-byte
adler32. The chunk CRC32 is0x8FC1BA08both stored and computed, confirming the chunk reached
memory exactly as authored, so rePIU's file I/O, RES decryption, and PNG delivery are sound. - The original libpng
1.0.6does not check the null return frompng_decompress_chunkbefore
adding the prefix0x17and dereferencing it withrepne scasb. Static disassembly confirms no
conditional branch separates the call from the fault. - The analysis is accumulated in
docs/analysis/pumpit8-bga-iccp-crash.md.
Verification
- Win32 x86 Debug and Release builds passed.
- A Debug
pumpit8run recorded 2,522 string services over 2,522 iterations, last EIP
0x040E5D0D, address0x00000017, mnemonicSCASB, and zero exceptions. - The same run proceeded past
BGA/083.DATtoAUDIO/004.AUD, rendering at roughly 6.9 FPS. It
ended on an SDL exit request issued to stop the observation, not on an access violation. - All 819 OpenWatcom samples were built and the suite re-measured in the baseline's Release
configuration, giving RunPassed 528 with zero regressions and zero new passes.
Known limitations
pumpit8only passes this site; completion is not verified, and later stages remain separate
observation targets.- That linear
0x17is actually readable under DOS/4GW is inferred from standard protected-mode
extender behavior and was not observed directly in the original environment. - Low-memory servicing covers reads only. Paths that write to low memory, such as
STOS, are not
serviced yet. - No
67h-prefixed 16-bit address-size string instruction has been observed, so that form is not
implemented. - The sample suite never reaches a low-memory string read, so zero regressions confirms the absence
of impact rather than validating this path.