xmin. guest@xmin ~ $
~/ $
[보안 리서치] 2026년 6월 14일

IrfanView Legacy JPM.dll 분석 회고: Recursive Stack Overflow

현재 IrfanView 기본 설정 영향 항목이 아닌, 비활성화된 legacy JPM.dll 플러그인 대상 퍼징 분석 회고입니다. JPM 중첩 박스 파싱 함수들이 재귀 깊이 제한 없이 상호 호출되며 stack overflow가 발생한 케이스를 정리한 기록입니다.

irfanviewjpm.dlljpeg2000legacy-pluginstack-overflowuncontrolled-recursioncwe-674fuzzingcrash-analysisvendor-not-accepted

공개 범위 메모 : 이 글은 현재 IrfanView 기본 설정에서 악용 가능한 취약점 공개가 아닙니다. 개발자 답변에 따르면 JPM.dll 플러그인은 약 2년 전부터 기본 비활성화된 legacy plugin이며, 사용자가 수동으로 활성화하고 IrfanView의 보안 경고를 무시해야만 도달 가능한 코드입니다. 따라서 본문은 현재 제품 advisory가 아니라 WinAFL 기반 파일 포맷 파서 퍼징과 크래시 분석 과정을 정리한 연구 회고로 봐야 합니다.

개발자 답변과 현재 영향 범위

제보 후 IrfanView 개발자는 해당 JPM 플러그인이 현재 IrfanView에서 기본 활성화되어 있지 않으며, 이 문제를 현재 IrfanView의 보안 취약점으로 보지 않는다고 답변했습니다. 이 내용을 반영해 본 글에서는 해당 케이스를 비활성화된 legacy 플러그인 분석 기록 으로 정리합니다.

개요

이번 케이스는 memory corruption보다는 parser 구조 문제에 가깝다. JPM 파일의 중첩 박스 구조를 처리하는 내부 함수들이 재귀 깊이 제한 없이 서로를 호출하면서 stack overflow가 발생한다.

크래시 유형은 CWE-674, Uncontrolled Recursion으로 정리할 수 있다.

크래시 샘플: fuzzer10id00009500EXCEPTIONSTACKOVERFLOW.jpm Size: 258 bytes Exception: Stack overflow (0xc00000fd)

샘플 특징

샘플은 작은 JPM 파일이지만, 내부 박스 중첩이 parser의 상호 재귀 경로를 반복적으로 타도록 구성되어 있다.

00000000: 00 00 00 0c 6a 50 20 20 0d 0a 87 0a 00 00 00 14 00000010: 66 74 79 70 6a 70 6d 20 00 00 00 00 6a 70 6d 20 00000020: 00 00 00 1d 6d 68 64 72 00 00 00 01 01 01 00 00 00000040: 23 70 63 6f 6c ff ff ff f8 70 61 67 74 00 00 00

특히 pcol 주변에 비정상적으로 큰/음수처럼 보이는 크기 패턴이 들어가며, 이후 중첩 박스 파싱 흐름이 반복된다.

크래시

Exception: Stack overflow (0xc00000fd) Address: 0x68c0833a Module: verifier / ntdll allocation path

Crash instruction: call dword ptr [verifier!impNtAllocateVirtualMemory]

최종 크래시 지점은 heap allocation 경로처럼 보이지만, 본질은 그 전에 parser 재귀 호출로 스택이 소진된 상태라는 점이다.

호출 흐름

fuzzReadJPMW.exe JPM!ShowPlugInSaveOptionsW+0x1b29a JPM!ShowPlugInSaveOptionsW+0x30682 JPM!ShowPlugInSaveOptionsW+0x30e3b JPM!ShowPlugInSaveOptionsW+0x31107 JPM!ShowPlugInSaveOptionsW+0x30fea ... 반복 ... JPM!ShowPlugInSaveOptionsW+0x74f ntdll!RtlAllocateHeap verifier!AVrfpDphAllocateVm

보고서 기준 상호 재귀 사이클은 ShowPlugInSaveOptionsW+0x30682 , +0x30e3b , +0x31107 , +0x30fea 근처의 내부 파싱 함수 그룹이다.

원인 분석

JPM은 compound image 형식이라 박스 안에 다른 박스가 중첩될 수 있다. 이런 형식을 재귀 파서로 처리하는 것은 자연스럽지만, 반드시 깊이 제한과 진행 보장이 필요하다.

이번 케이스에서는 조작된 중첩 구조가 다음과 같은 흐름을 만든다.

parserD → parserC → parserB → parserA → parserD ...

각 함수는 하위 박스를 처리하기 위해 다시 다른 파싱 함수를 호출하고, 파일 구조가 이 사이클을 계속 유도하면서 스택 프레임이 누적된다. 재귀 깊이 제한이 없기 때문에 결국 0xc00000fd 예외가 발생한다.

영향