BLOG
Tracefield · 02
Tracefield · 01
블로그 · 14
Vibe Audit · 04
Vibe Audit · 03
Vibe Audit · 02
Vibe Audit · 01
출판편집자 · 01
StudyTree · 01
SecurityOps · 02
SecurityOps · 01
AI챗봇 · 04
AI챗봇 · 03
AI챗봇 · 02
AI챗봇 · 01
퍼플심 · 04
퍼플심 · 03
퍼플심 · 02
퍼플심 · 01
블로그 · 13
rootscan · 07
rootscan · 06
블로그 · 12
블로그 · 11
블로그 · 10
블로그 · 09
블로그 · 08
블로그 · 07
블로그 · 06
블로그 · 05
블로그 · 04
블로그 · 03
블로그 · 02
블로그 · 01
rootscan · 05
rootscan · 04
rootscan · 03
asmspeak · 03
asmspeak · 02
rootscan · 02
asmspeak · 01
rootscan · 01
웹보안도구 · 02
웹보안도구 · 01
루트캠프 · 02
루트캠프 · 01
All notes 167
기드라를 이용한 PE 분석 기초
1. 기초 단계의 리버싱 실습
이 문서는 학습용 PE 샘플을 기준으로, 기드라에서 PE 악성코드 분석을 어떻게 시작하는지 정리한 메모다.
정보보안기사 실기 기출문제
윈도우 PE(Portable Executable) 파일은 윈도우 7과 같은 NT 계열 운영체제에서 실행되는 파일 포맷이다. 실행 코드, 데이터, 리소스, 메타데이터를 함께 담고 있으며 보통
.exe,.dll,.sys확장자를 쓴다. 악성 파일도 윈도우에서 실행되려면 PE 포맷을 사용한다. 그래서 공격자는 PE 헤더나 섹션 정보를 변형하거나, 파일을 난독화해서 디버깅과 분석을 어렵게 만든다.
1.1. 학습용 PE 제작
실습에 쓴 샘플은 실제 악성 행위는 하지 않는다. 대신 로그를 남기고 메시지 박스를 띄워서 분석 대상처럼 보이게 만든 예제다.
// training_sample.c
#include <windows.h>
#include <stdio.h>
void write_log() {
HANDLE hFile;
DWORD written;
const char *msg = "[TRAINING] sample log entry\r\n";
// C:\temp가 없으면 실패할 수 있으니 미리 폴더 만들어 두기
hFile = CreateFileA(
"C:\\temp\\training_sample.log",
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
return;
}
// 파일 끝으로 이동 후 로그 추가
SetFilePointer(hFile, 0, NULL, FILE_END);
WriteFile(hFile, msg, (DWORD)lstrlenA(msg), &written, NULL);
CloseHandle(hFile);
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
) {
// 콘솔 생성해서 디버깅 메시지 확인 가능하게
AllocConsole();
FILE *fp;
freopen_s(&fp, "CONOUT$", "w", stdout);
printf("[TRAINING] sample started.\n");
DWORD start = GetTickCount();
write_log();
MessageBoxA(
NULL,
"This is a harmless training sample.\nYou can analyze this in Ghidra.",
"Training Sample",
MB_OK | MB_ICONINFORMATION
);
// 조금 대기
Sleep(5000);
printf("[TRAINING] exiting after %lu ms.\n", GetTickCount() - start);
FreeConsole();
return 0;
}
빌드 후 실행하면 콘솔과 경고창이 나타나고, Temp 폴더에 로그가 남는다.


1.2. 기드라로 불러오기
기드라로 불러오면 PE64를 자동 감지하고 기본 분석을 진행한다.


2. 기드라 분석 시작
2.1. 엔트리 포인트 확인

일반적으로 기드라가 자동으로 엔트리 포인트를 잡아주지만, Symbol Tree -> Functions -> Entry를 따라가면서 직접 확인할 수도 있다.
악성코드는 이 지점을 숨기는 경우가 많다. 대표적으로 아래 방식이 자주 쓰인다.
- 패킹(UPX, Themida 등): 압축되거나 암호화된 더미 코드가 엔트리처럼 보이게 만든다.
- DLL 분리:
exe는 껍데기만 두고, 실제 동작은dll에서 실행하게 만든다. - Obfuscated Entry Block: 쓰레기 코드와
JMP를 섞어 진입 지점을 일부러 복잡하게 만든다. - Dynamic Code Unpack: 실행 중 메모리에 실제 코드를 풀어놓고 진행한다.
- 특히 Shellcode Loader처럼 Entry에서 쉘코드만 호출하고 곧바로 종료되는 경우는 분석 난도가 높다.
2.2. Import Table 분석

Import Table은 프로그램이 실행될 때 외부 DLL에서 가져오는 윈도우 API 목록이다. 악성코드 분석에서는 이 부분이 사실상 첫 관문이다.
이번 샘플에서는 Kernel32.dll, User32.dll 쪽 API를 먼저 보면 된다.
CreateFileA: 파일 생성 또는 열기WriteFile: 파일 기록. 로그 저장이나 키로깅 흔적을 볼 때 자주 확인한다.SetFilePointer: 파일 끝에 이어쓰기 가능Sleep: 일정 시간 잠복하거나 타이밍을 조절한다.MessageBoxA: 사용자 인터페이스 조작. 여기서는 가짜 경고창 역할이다.
2.3. 디컴파일하여 로직 이해하기

엔트리에서 호출하는 함수들을 따라가면 실제 로직이 있는 위치를 좁힐 수 있다.
FUN_140001808: 보안 쿠키를 초기화하는 함수FUN_1400012c4: CRT 초기화 함수- 내부 함수를 계속 따라가면서, 앞에서 본 Import Table API를 실제로 쓰는 지점을 찾는다.
- 대부분 핵심 동작은
WinMain쪽에 모여 있다. iVar3 = FUN_140001070();호출을 찾으면, 이 함수가 실질적인 분석 지점이다.

void FUN_140001070(void)
{
DWORD DVar1;
DWORD DVar2;
FILE *_OldFile;
HANDLE hFile;
char *pcVar3;
undefined *puVar4;
undefined8 uVar5;
undefined1 auStackY_68 [32];
FILE *local_28;
DWORD local_20 [2];
ulonglong local_18;
// 스택 쿠키: 런타임 보안용 → 악성 행위 아님
local_18 = DAT_140005000 ^ (ulonglong)auStackY_68;
// 콘솔 창을 생성 (UI 동작)
AllocConsole();
// stdout 핸들 가져오기 → 콘솔로 리다이렉션 준비
_OldFile = (FILE *)__acrt_iob_func(1);
puVar4 = &DAT_1400032ec;
pcVar3 = "CONOUT$";
// 출력 스트림을 콘솔로 연결
freopen_s(&local_28,"CONOUT$","w",_OldFile);
// 시작 메시지 출력
FUN_140001010("[TRAINING] sample started.\n",pcVar3,puVar4,_OldFile);
// 실행 시작 시간 기록
DVar1 = GetTickCount();
// 로그 파일 생성/열기
hFile = CreateFileA("C:\\temp\\training_sample.log"
,0x40000000,
1,
(LPSECURITY_ATTRIBUTES)0x0,
4,
0x80
,(HANDLE)0x0);
if (hFile != (HANDLE)0xffffffffffffffff) {
// 파일 끝으로 이동 → Append 방식
SetFilePointer(hFile,0,(PLONG)0x0,2);
// 로그 텍스트 길이 구하기
DVar2 = lstrlenA("[TRAINING] sample log entry\r\n");
// 로그 내용을 파일에 기록
WriteFile(hFile,"[TRAINING] sample log entry\r\n",DVar2,local_20,(LPOVERLAPPED)0x0);
// 파일 핸들 닫기
CloseHandle(hFile);
}
// 메시지 박스 표시 (UI 동작)
uVar5 = 0x40;
pcVar3 = "Training Sample";
MessageBoxA((HWND)0x0,
"This is a harmless training sample.\nYou can analyze this in Ghidra.",
"Training Sample",
0x40);
// 대기 (행위 지연/탐지 우회 가능)
Sleep(5000);
DVar2 = GetTickCount();
// 종료 시간 측정
FUN_140001010("[TRAINING] exiting after %lu ms.\n",(ulonglong)(DVar2 - DVar1),pcVar3,uVar5);
// 콘솔 닫기
FreeConsole();
// 스택 쿠키 검증 (정상 종료 확인)
FUN_1400011c0(local_18 ^ (ulonglong)auStackY_68);
return;
}
3. 분석 보고서 샘플
자세한 보고서 형식은 악성코드_02_기드라 PE 분석 보고서 샘플 문서를 참고하면 된다.

