Prefetch
1. 프리패치 소개
윈도우 프리패치는 실행에 필요한 데이터를 미리 메모리에 로드해 실행 속도를 향상시켜주는 아티팩트로 윈도우 XP부터 사용되었다. 컴퓨터 구조에서 패치(Fetch)는 실행할 명령어를 메모리에서 프로세서로 가져오는 작업인데 프리패칭(prefetching)은 명령어를 미리(pre) 패치하여 프로세서의 대기 시간을 줄여주는 작업이다.
윈도우 프리패치는 프리패처(prefetcher)에 의해 생성되는 데이터로 명령어 프리패치와 유사하게 실행에 필요한 데이터를 저장장치에서 메모리로 미리 가져와 빠르게 실행되도록 돕는다. 프리패처는 크게 부트 프리패처와 응용프로그램 프리패처로 나눌 수 있다.
부트 프리패처는 부팅 과정 중에 접근하는 데이터를 최대 120초까지 모니터링하여 프리패치 파일로 만들어두고, 응용프로그램 프리패처는 실행 과정에서 접근하는 데이터를 10초 동안 모니터링하여 프리패치 파일로 만들어둔다. 이렇게 만들어진 프리패치 파일은 메모리에 상주하여 부팅 혹은 응용프로그램 실행 시 초기 실행 속도를 향상시킨다.
프리패치는 SysMain 서비스에 의해 동작 여부가 결정된다. SysMain 서비스는 시스템 성능을 유지하고 향상시키기 위한 서비스다. 대표적으로 메모리에 로드된 프리패치가 페이지 파일로 페이지 아웃되는 비효율적인 동작을 막기 위한 슈퍼패치(superfetch) 기능과 메모리 압축 기능을 제공한다. 프리패치가 생성되는 것을 막고 싶다면 간단히 SysMain 서비스를 중지시키고 자동 시작되지 않도록 설정하자.
프리패치 파일은 다음 폴더에 저장된다.
%SystemRoot%\Prefetch
부트 프리패치 파일은 NTOSBOOT-B00DFAAD.pf 라는 이름으로 1개의 파일이 존재했으나 윈도우 10에서는 빠른 실행(fast startup)이 도입되면서 부팅 성능 향상을 위한 부트 프리패치 파일이 사라졌다.
응용프로그램 프리패치 파일은 다음과 같은 파일 이름 형식을 갖는다.
<executable name>-<file path hash>.pf
실행파일 이름 뒤에 4바이트의 파일경로 해시값이 붙는 이유는 서로 다른 위치에서 실행된 동일한 이름의 실행파일을 구분하기 위한 용도이다. 해시값이 없으면 동일한 이름을 가진 서로 다른 실행 파일이 하나의 프리패치 파일을 공유하기 때문에 각각을 구별하기 어렵다. 이런 문제가 바로가기(Windows Shortcut, LNK) 파일에 나타나므로 바로가기 파일을 분석할 때는 주의해야 한다.
응용프로그램 프리패치 파일은 윈도우 7까지 128개가 존재하였으나 윈도우 10에서는 최대 1,024까지 존재할 수 있다(보통 200여개가 존재한다).
응용프로그램을 실행하면 그 과정에서 다수의 파일에 접근한다. 프로그램의 처리 순서로만 파일에 접근하면 디스크 헤드 움직임이 많아져 속도가 느려진다. 하지만 미리 접근하는 파일의 순서를 알고 있으면 헤드 움직임이 최소화하도록 파일의 순서를 재배치하여 실행 속도를 높일 수 있다. 이것이 프리패치 파일이 활용되는 기본 원리이다.
실제 프리패치 폴더에 존재하는 Layout.ini 파일에는 응용프로그램 실행 중 참조되는 파일이 목록화되어 있다. 운영체제는 주기적으로 이 목록화된 파일을 조각 모음하고 접근 순서대로 저장장치에 배치하여 성능 향상을 꾀한다.
디스크 형식의 저장장치에서 데이터 읽기 속도는 액추에이터 암이 데이터가 존재하는 트랙까지 이동하는 탐색시간(seek time), 디스크가 회전해 헤드가 트랙 내 데이터가 존재하는 섹터까지 도달하는 지연시간(latency), 섹터를 읽는 시간을 모두 합하여 계산된다.
데이터가 조각 나 여러 섹터에 존재한다면 섹터를 읽을 때마다 탐색시간과 지연시간이 추가로 발생한다. 이 중 성능에 가장 큰 영향을 미치는 것은 탐색시간이다. 디스크 조각 모음을 하면 추가적으로 발생하는 탐색시간은 줄일 수 있지만 최초 발생하는 탐색시간은 디스크 형식의 저장장치가 갖는 한계이다. SSD는 메모리 형식으로 데이터를 읽고 쓸 때 탐색시간이 발생하지 않는다.
2. 데이터 구조
프리패치 파일의 데이터 구조는 윈도우 XP부터 10에 이르기까지 각 운영체제마다 조금 차이가 있다. 윈도우 10의 프리패치 파일은 COMPRESSION_FORMAT_XPRESS_HUFF 압축 알고리즘에 의해 압축되어 파일을 열어보면 아래 그림과 같이 “MAM(4D414D)” 시그니처가 나타난다.
압축을 해제하면 아래 그림과 같이 프리패치의 시그니처인 “SCCA(53434341)”를 확인할 수 있다.
위 그림에서 첫 4바이트 값(0x1E)은 프리패치 파일의 포맷 버전을 나타낸다. 윈도우 10의 프리패치 파일은 아래 표와 같이 포맷 버전 30을 사용한다.
17 (0x11)
Windows XP
23 (0x17)
Windows Vista
26 (0x1A)
Windows 8.1
30 (0x1E)
Windows 10
여기서는 분석에 활용되는 주요 구조만 살펴본다. 포맷의 상세한 내용은 다음 링크에서 확인하자.
Windows Prefetch File (PF) format https://github.com/libyal/libscca/blob/master/documentation/Windows%20Prefetch%20File%20(PF)%20format.asciidoc
아래 그림은 프리패치 파일의 헤더 구조이다. 포렌식 분석 시 자주 활용되는 주요 데이터는 음영으로 표시했다.
Executable filename 실행파일의 이름이 저장된다.
Prefetch hash 프리패치 파일 이름 뒤에 붙는 4바이트 해시값과 동일하다.
Filename metrics array offset 응용프로그램을 실행할 때 처음 10초 동안 접근한 파일의 참조목록 구조가 저장된 위치의 오프셋이다.
Volume information array offset 응용프로그램을 실행할 때 처음 10초 동안 접근한 볼륨 정보 구조가 저장된 위치의 오프셋이다.
Last run time #(number) 8개의 FILETIME 형식으로 저장된 응용프로그램의 실행시간으로 숫자가 낮을수록 최근 실행한 시각이다.
Run count 응용프로그램의 실행 횟수를 나타낸다.
Executable file path offset 실행파일 경로가 저장된 위치를 가리킨다. 보통 Filename string array 구조 바로 뒤에 위치한다.
File metrics array offset을 따라가면 다음과 같은 파일 메트릭 배열을 확인할 수 있다. 배열에 속하는 파일 메트릭을 모두 해석하면 응용프로그램을 실행할 때 처음 10초 동안 참조한 파일 목록을 모두 얻을 수 있다.
Filename string offset 프리패치 파일 헤더의 Filename string array offset이 가리키는 파일이름 문자열 배열의 시작부터 계산된 상대적 오프셋이다.
File reference address MFT 레코드 번호와 순서 번호(Sequence number)가 조합된 파일 참조 주소로 순서 번호를 통해 현재 참조된 파일이 존재하는지 삭제되었는지 판단할 수 있고, MFT 레코드 번호로 레코드를 해석하면 파일의 상세 정보를 얻을 수 있다.
Volume information array offset을 따라가면 다음과 같은 구조를 확인할 수 있다. 응용프로그램이 실행되고 10초 동안 접근한 모든 볼륨의 정보가 연속적으로 기록된다. 보통 시스템 볼륨 정보만 기록되지만 프로그램의 실행 위치, 프로그램의 유형에 따라 시스템에 연결된 모든 볼륨 정보가 기록될 수도 있다.
Volume device path offset 해당 구조의 시작 오프셋을 기준으로 볼륨 GUID 저장 위치를 가리키는 상대적 오프셋이다.
Volume creation time FILETIME 형식의 볼륨 생성시각으로 볼륨의 포맷된 시간을 나타낸다. (파일시스템 메타데이터 생성시각과 동일하다.)
Volume serial number 볼륨 시리얼번호로 VBR에 저장된 값과 동일하다.
3. 분석 방안
1) 프리패치 파일 정보
데이터 구조에서 확인할 수 있듯이 프리패치 파일 분석만으로 실행한 응용프로그램과 관련하여 다음의 정보를 얻을 수 있다.
실행파일 이름
실행파일 경로
실행 횟수
최근 실행시각 (최대 8개)
응용프로그램이 접근한 볼륨 정보 (볼륨 GUID, 볼륨 생성시각, 볼륨 시리얼번호)
파일 참조목록
문서 파일은 파일을 클릭하면 바인딩된 응용프로그램이 해당 문서를 바로 프로그램에 연결시켜준다. 이 경우 응용프로그램 프리패처에 의해 실행한 문서 정보도 10초 모니터링 과정에서 식별되어 참조목록에 기록될 수 있다.
아래 그림은 “Samsung SSD 128GB.log” 파일을 윈도우 탐색기 컨텍스트 메뉴를 이용해 Notepad++ 프로그램으로 연 후 해당 프리패치 파일의 참조목록을 확인한 것이다.
하이라이트된 부분에서 확인할 수 있듯이 열어본 파일의 정보(이름, 경로)가 참조목록에 기록된다. 이처럼 응용프로그램 실행 후 10초 내에 접근하는 파일 참조목록을 이용해 다음과 같은 정보를 얻을 수 있다.
Word, Excel, Powerpoint, Hangul, PDF Reader – 열어본 문서 정보
7zip, Winzip, WinRar – 압축 해제한 파일 정보
Internet Explorer, Edge – 다운받은 캐시 파일 정보
Notepad, Notepad++, Sublime – 편집한 텍스트 파일 정보
uTorrent – 열어본 토렌트 파일 정보
2) 프리패치 파일의 파일시스템 시간 정보
프리패치 파일 헤더에 최근 프로그램 실행시각을 8개나 기록하지만 파일시스템 시간을 추가 분석하면 더 많은 정보를 얻을 수 있다. 프로그램을 처음 실행하면 프리패치 파일이 생성되는데 이때 파일의 파일시스템의 생성, 수정시각은 같다. 이후 프로그램을 다시 실행하면 프리패치 파일 내부의 최근 실행시각과 참조목록이 변경되므로 수정시각이 업데이트된다. 이에 생성, 수정시각을 다음과 같이 판단할 수 있다.
프리패치 파일의 생성시각 프로그램의 처음 실행시각이다. 프리패치 파일이 생성된 이후 오랫동안 해당 프로그램을 실행하지 않으면 프리패치 파일이 삭제되고 다시 생성될 수 있다. 따라서 생성시각은 프리패치 파일로 식별가능한 프로그램의 가장 처음 실행시각이다.
프리패치 파일의 수정시각 프로그램의 마지막 실행시각으로 프리패치 파일 내부에 기록된 마지막 실행시각과 같다. 다만, 시간을 기록하는 과정에서 지연이 발생하여 보통 두개의 시간 값은 몇 초간의 차이가 발생한다.
프로그램을 8번 실행하고 프리패치 파일 헤더를 분석하면 8로 기록된 실행 횟수와 8번의 실행시각을 모두 얻을 수 있고 추가적으로 파일시스템 생성시각을 통해 처음 실행시각을 하나 더 얻을 수 있다.
게다가 파일시스템 생성시각을 활용하면 사용자가 일별, 주별로 프로그램을 얼마나 사용하는지 빈도를 구할 수 있다. 프리패치 파일 헤더에 기록된 실행 횟수는 프리패치 파일의 생성시각과 수정시각 사이에 실행된 횟수이므로 기간별로 나누어 사용자의 실행 빈도를 알 수 있다.
3) 프리패치 파일 복구 방안
프리패치 파일은 운영체제별로 관리하는 수가 제한된다. 이 때문에 프리패치 파일이 생성된 후 오랫동안 프로그램을 실행하지 않으면 우선순위에서 밀려나 파일이 삭제된다. 프로패치 파일의 삭제 작업은 덮어쓰기 방식의 완전삭제가 아닌 일반 삭제다. SSD라면 삭제된 파일을 복구하기 어렵겠지만 디스크 형식의 저장장치인 경우 파일 데이터가 덮어써지지만 않았다면 미할당 영역에서 파일 카빙 기법을 이용해 복구할 수 있다.
프리패치 파일의 일반적인 카빙 방법은 다음과 같다. 간단한 알고리즘이지만 비교적 오탐없이 복구된다. 알려진 포렌식 아티팩트 복구 도구도 같은 원리를 사용한다.
프리패치 포맷 버전과 시그니처를 더해 8바이트의 고정된 값으로 미할당 영역을 512 바이트씩 점프하면서 일치하는지 검사한다.
8바이트 값이 일치하면 해당 시점부터 헤더에 기록된 파일 크기만큼 데이터를 읽어 파일로 저장한다.
4. 분석 도구
추천하는 프리패치 파일 분석 도구는 Eric Zimmerman이 만든 PECmd 도구로 다음 링크에서 다운받을 수 있다.
PECmd는 CLI 도구로 단일 파일 또는 디렉터리를 입력받아 분석하고 결과를 JSON, CSV, HTML 형식으로 저장한다. 분석을 목적으로 한다면 CSV 형식으로 출력한 후 동일 링크에서 제공되는 Timeline Explorer로 불러와 GUI 형태로 분석할 수 있다.
Last updated
Was this helpful?