기초 분석에서 파일의 겉모습을 확인했다면, 이제 파일 안쪽을 들여다볼 차례다.
이번 편에서는 정적 분석 단계에서 사용하는 BinText와 PEview를 정리했다.
기초 분석에서 파일의 겉(파일 정보, 패킹 여부)을 확인했다면, 정적 분석에서는 파일의 속을 들여다본다. 파일을 실행하지 않고, 파일 안에 담긴 문자열이나 내부 구조를 직접 살펴보는 방법이다.
정적 분석에는 두 가지 장점이 있다. 실행하지 않기 때문에 안전하다는 점, 그리고 파일 안에 고정되어 있는 정보를 보기 때문에 언제 분석하든 같은 결과를 얻을 수 있다는 점이다. 동적 분석은 실행 환경에 따라 결과가 달라질 수 있지만, 정적 분석에서 발견한 문자열이나 함수 목록은 변하지 않는다.
이 단계에서 찾는 건 "이 파일이 뭘 하려는 놈인지"에 대한 힌트다. 파일 안에 어떤 주소가 적혀 있는지, 어떤 기능을 쓰려고 준비해뒀는지 같은 단서들을 찾을 수 있다. 이번 편에서 다룰 도구는 두 가지다. BinText는 파일 안의 문자열을, PEview는 파일의 내부 구조를 본다.
⚠️ 패킹된 파일은 문자열도 구조도 제대로 안 보일 수 있다. 기초 분석에서 패킹 여부를 먼저 확인한 뒤 진행하는 게 좋다.
파일 안에 포함된 문자열을 전부 뽑아주는 도구다. 실행 파일 안에는 개발자가 코드에 직접 적어넣은 주소, 경로, DLL 이름 같은 텍스트가 남아 있는 경우가 많다. BinText는 이런 문자열을 한꺼번에 보여준다.
프로그램을 실행한 뒤 Browse 또는 드래그앤드롭으로 파일을 불러오고, Go 버튼을 누르면 문자열 목록이 출력된다.

문자열이 수천 개씩 나오기 때문에 그대로 전부 보기는 어렵다. Filter 탭에서 포함할 문자 종류, 최소 길이, 필수 키워드 같은 조건을 설정하면 범위를 좁힐 수 있다. 다만 필터를 걸어도 양이 많을 수 있다. 어떤 문자열이 중요한지 빠르게 판단하는 건 경험이 쌓이면서 감이 잡히는 부분이다.

하단 상태바에는 추출된 문자열 수가 표시된다. AN은 아스키 문자열, UN은 유니코드 문자열, RS는 리소스 스트링 수를 뜻한다.
💡 필터 설정 방법이나 실제 분석에서 문자열을 읽는 팁은 별도 글에서 정리할 예정이다.
처음에는 문자열이 많아서 뭘 봐야 할지 막막할 수 있다. 우선 아래 다섯 가지를 먼저 찾아보면 방향이 잡힌다.
① 네트워크 주소
IP 주소, 도메인, URL이 보이면 악성코드가 통신하려는 서버 주소일 수 있다. IOC 후보로 따로 메모해두면 이후 분석에서 활용할 수 있다.
② 시스템 경로
C:\Windows\... 같은 파일 경로가 보이면 파일을 어디에 만들거나 접근하려는지 힌트가 된다. HKLM\SOFTWARE\... 같은 레지스트리 경로가 보이면 시스템 설정을 바꾸려는 흔적이다.
③ DLL 이름이나 함수 이름
kernel32.dll, ws2_32.dll 같은 DLL 이름이 보이면 어떤 기능을 쓰려는지 힌트가 된다. CreateProcess, URLDownloadToFile 같은 함수 이름이 직접 보이기도 한다.
④ 실행파일 관련 문자열
.exe, .dll, .bat 같은 확장자가 포함된 문자열이 있으면, 다른 파일을 실행하거나 생성하려는 흔적일 수 있다. 예를 들어 update.exe나 config.bat 같은 이름이 보인다면, 이 파일이 실행되면서 추가 파일을 만들거나 실행할 가능성이 있다.
⑤ 수상한 명령어 패턴
문자열 중에 명령어처럼 보이는 텍스트가 있으면 주의해서 봐야 한다. 실제 분석에서 이런 문자열이 발견된 적이 있다.
cmd.exe /c — 명령 프롬프트를 열어서 다른 명령을 실행하려는 흔적ping 127.0.0.1 -n 2 — 실제 통신이 아니라 시간을 지연시키려는 목적으로 쓰인다. 백신 탐지를 피하거나 다른 작업이 끝나길 기다릴 때 사용하는 트릭이다if exist "%s" goto Repeat — 특정 파일이 생길 때까지 반복 확인하려는 패턴이런 문자열은 정상 프로그램에서는 보기 어려운 패턴이다. 하나라도 보인다면 이 파일이 단순한 프로그램이 아닐 가능성이 높다. 이 외에도 악성코드에서 자주 발견되는 명령어 패턴이 있는데, 더 자세한 내용은 별도 글에서 정리할 예정이다.
⚠️ 문자열이 있다고 해서 반드시 그 동작을 한다는 뜻은 아니다. "이런 걸 하려는 것 같다"는 힌트 정도로 보는 게 맞다.
PE 파일의 내부 구조를 트리 형태로 보여주는 도구다. 헤더, 섹션, 함수 목록 등 파일이 어떻게 구성되어 있는지 한눈에 확인할 수 있다.
💡 PE 파일이란 윈도우에서 실행되는 파일 형식(.exe, .dll 등)을 말한다.
프로그램을 실행한 뒤 분석할 파일을 불러오면, 왼쪽에 트리 구조, 오른쪽에 상세 정보가 나온다. 제일 먼저 보이는 IMAGE_DOS_HEADER에서 Value 항목에 MZ가 표시되어 있으면, 이 파일이 윈도우에서 실행 가능한 PE 파일이라는 뜻이다.

💡 MZ는 DOS 시대부터 쓰이던 실행 파일 표시다. PE 파일이라면 항상 MZ로 시작한다.
MZ가 확인되면 트리를 따라 내려가면서 아래 항목들을 확인하면 된다.
① 기본 정보 (IMAGE_FILE_HEADER)

| 항목 | 설명 |
|---|---|
| Machine | 32비트(I386)인지 64비트인지 |
| Number of Sections | 섹션이 몇 개인지 |
| Time Date Stamp | 컴파일된 시간. 날짜가 너무 오래됐거나 미래로 되어 있으면 조작됐을 가능성이 있다 |
| Characteristics | 파일의 성격. 실행 가능 여부, 32비트 여부 같은 플래그가 표시된다 |
Characteristics에는 여러 플래그가 나열되는데, IMAGE_FILE_EXECUTABLE_IMAGE(실행 가능한 파일)와 IMAGE_FILE_32BIT_MACHINE(32비트) 정도만 확인하면 충분하다.
② 섹션 구성과 권한
트리에서 IMAGE_SECTION_HEADER 항목들을 확인한다. 섹션에서 볼 건 이름, 권한, 크기 세 가지다.
이름 — 일반적인 프로그램은 .text, .data, .rdata, .rsrc 같은 이름을 쓴다. .UPX0, .aspack 같은 이름이 보이면 패킹된 흔적이다. 기초 분석에서 확인한 패킹 결과와 크로스체크할 수 있는 포인트다.
권한 — 각 섹션에는 읽기(R), 쓰기(W), 실행(E) 권한이 있다. 정상적인 프로그램이라면 코드 섹션(.text)은 읽기+실행, 데이터 섹션(.data)은 읽기+쓰기가 일반적이다. 코드 섹션에 쓰기 권한이 있거나, 데이터 섹션에 실행 권한이 있으면 비정상적이다. 실행 중에 코드를 스스로 수정하려는 의도일 수 있다.
크기 비교 — 각 섹션에는 Virtual Size(메모리에서의 크기)와 Size of Raw Data(파일에서의 크기)가 있다. Virtual Size가 Size of Raw Data보다 확연히 크면 패킹되어 있을 가능성이 있다. 패킹된 파일은 디스크에는 압축된 상태로 저장되어 있다가, 실행 시 메모리에서 압축을 풀기 때문에 Virtual Size가 커진다.

③ 가져다 쓰는 함수와 라이브러리 (IAT)
SECTION .rsrc 아래 IMPORT 항목에서 확인한다. 이 파일이 윈도우에서 어떤 기능을 빌려 쓰려는지 보여주는 목록이다.

💡 IAT(Import Address Table)란 프로그램이 사용하려는 외부 기능 목록이다. DLL(라이브러리)은 기능이 담긴 공구함이고, 함수는 그 안의 개별 공구라고 보면 된다.
여기서는 어떤 DLL에서 어떤 함수를 가져오는지를 함께 본다.
| DLL 이름 | 역할 | 이런 함수가 보이면 |
|---|---|---|
kernel32.dll | 파일, 프로세스 등 기본 기능 | CreateProcessW(프로세스 실행), WriteFile(파일 쓰기) |
ws2_32.dll | 네트워크 통신 | connect, send(외부 서버 연결) |
advapi32.dll | 레지스트리, 보안 관련 | RegSetValueExA(레지스트리 수정) |
urlmon.dll | 인터넷 다운로드 | URLDownloadToFileA(파일 다운로드) |
GDI32.dll | 화면 표시 관련 | SetTextColor, SelectObject |
이 목록을 조합해보면 파일이 어떤 동작을 하려는지 윤곽이 잡힌다.
예를 들어 ws2_32.dll과 urlmon.dll이 함께 보인다면 "외부에서 뭔가를 받아오는 파일"이라는 방향이 잡힌다. advapi32.dll의 레지스트리 함수와 \CurrentVersion\Run 경로가 같이 보인다면 "시스템에 자기 자신을 등록하려는 파일"이라는 윤곽이 그려진다.
⚠️ 패킹된 파일은 IAT가 거의 비어 있거나
kernel32.dll정도만 보일 수 있다. 함수 목록이 비정상적으로 적다면 패킹을 의심해볼 수 있다.
정적 분석은 파일을 실행하지 않고 안을 들여다봐서, "이 파일이 뭘 하려는 놈인지" 힌트를 찾는 단계다.
BinText에서 문자열을 뽑아 네트워크 주소, 경로, 수상한 명령어 같은 단서를 찾고, PEview에서 파일 구조와 함수 목록을 확인하면 파일의 의도가 어느 정도 윤곽이 잡힌다.
다만 정적 분석에서 나온 건 가능성이지 확정이 아니다. 실제로 어떻게 동작하는지는 실행해봐야 알 수 있다. 그래도 정적 분석에서 발견한 문자열, 함수 목록, 섹션 구조 같은 건 파일 안에 고정된 정보이기 때문에 변하지 않는 증거로 남는다. 이 단계에서 힌트를 잡아두면, 이후 분석에서 뭘 집중해서 봐야 할지 방향이 잡힌다.