PE 헤더 사이즈 필드 믿을 수 있을까?

@codemaru · July 19, 2011 · 3 min read

PE 포맷의 NT 헤더에 보면 OptionalHeader에 SizeOfHeaders란 필드가 있습니다. 이 필드는 보통 파일 기반의 헤더 크기로 정의 됩니다. SizeOfImage는 반대로 파일을 로딩하기 위해서 메모리에 확보해야할 공간을 의미하죠. 그래서 SizeOfHeaders는 FileAlignment 단위로 정렬되고, SizeOfImage는 SectionAlignment 단위로 정렬됩니다.

보통의 경우 이 SizeOfHeaders 필드가 정상적입니다. 파일일 때의 크기와 일치한다는 것이죠. 그런데 얼마전에 정말 어처구니 없는 상황을 알게 되었습니다. 이 SizeOfHeaders 필드가 upx 압축이 되면 잘못될 수 있다는 것이죠. upx의 경우 소스를 보지 않아서 정확하게 왜 그러는지는 알 수 없지만 실행 파일의 SizeOfHeaders 필드를 4K로 만들어 버립니다. 더 재미난 사실은 그러고도 파일에서의 헤더 크기는 전과 똑같다는 것이죠.

즉, 문제는 upx 압축을 거치고 나면 원래 0x400이던 헤더 크기가 0x1000이 되어 버린다는 점 입니다. 그러고도 파일에서의 크기는 여전히 0x400인채 말이죠. 따라서 upx 압축을 해버린 파일의 SizeOfHeaders 필드는 믿을 수가 없습니다. 즉, SizeOfHeaders 필드로 뭔가를 해보려는 코드에게 upx 압축된 파일은 위험할 수 있습니다.

그렇다면 upx 압축된 파일의 헤더 크기를 알 수 없는 것일까요? 물론 방법이 없는 것은 아닙니다. 보통 PE 파일의 경우 헤더는 섹션이 시작되기 전까지 위치합니다. 따라서 첫 번째 섹션 헤더의 PointerToRawData 필드를 헤더 크기로 사용하면 정상적으로 처리할 수 있습니다.

시간나면 upx 소스를 한번 분석해봐야 겠네요. 버그인지 아니면 심오한 이유가 있는건지 알아봐야겠죠. *^^* PE 포맷의 SizeOfHeaders 필드로 뭔가를 해야 한다면 주의하시기 바랍니다. 여러분이 그 값을 순진하게 믿고 별 생각없이 코딩하는 순간 여러분의 프로그램이 삐걱 거릴 수 있습니다.

 0  0

 

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중