| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- Rich Header
- ABI
- CodeEngn
- __vectorcall
- pe format
- 함수 호출 규약
- Reversing
- __cdecl
- Image dos header
- 리치헤더
- 리버싱
- 실행파일
- image section header
- 32bit
- 크랙미
- crackme
- x64
- 프로그래머스
- Programmers
- __fastcall
- Calling Convention
- __stdcall
- 파이썬
- RVA
- stack frame
- rev
- 코드엔진
- Python
- x32
- Dos Stub
- Today
- Total
kj0on
[Definition] VA & RVA & RAW 본문
0. 참고사항
이 글은 VA, RVA, RAW의 개념에 대한 설명이므로 스왑 메모리 방식이나 페이징 기법은 개념 설명과는 목적이 다르기 때문에 여기서는 다루지 않는다.
1. 디스크와 메모리

디스크는 비휘발성 저장장치로 전원이 꺼져도 데이터가 그대로 유지된다. HDD(하드디스크)나 SSD 같은 장치들이 여기에 해당하며 프로그램 파일이나 문서 등이 이곳에 저장된다.

반면 메모리는 휘발성 저장장치로 전원이 꺼지면 저장된 데이터가 모두 사라진다. RAM 같은 장치가 여기에 해당하며 실행 중인 프로그램이나 작업 데이터가 일시적으로 저장된다.

운영체제는 프로그램 실행 시 디스크에 있는 파일을 메모리로 불러와 실행한다. PE 파일은 디스크에 저장될 때와 메모리에 로드될 때 구조와 주소 체계가 달라진다. 디스크에서는 파일의 시작을 기준으로 한 바이트 단위 오프셋인 RAW Offset이 사용되며 이는 실제 데이터가 존재하는 물리적 위치를 나타낸다. 반면 실행 중에는 운영체제가 파일을 메모리에 매핑하면서 가상 주소(VA, Virtual Address)를 사용하고 이때 ImageBase를 기준으로 한 상대 주소인 RVA(Relative Virtual Address)가 함께 쓰인다.
2. Offset

오프셋은 기준 위치로부터 떨어진 상대적인 거리를 의미한다.
3. RAW (RAW Offset)

RAW는 PE 파일에서 데이터가 디스크에 저장된 실제 물리적 위치인 파일 내부의 오프셋(offset)을 의미한다. 이는 파일이 메모리에 로드되기 전 디스크 상에서 코드나 데이터가 존재하는 위치를 바이트 단위로 나타낸 것이다. RAW에서 오프셋의 기준은 항상 파일의 시작이다.
3-1. 절대주소가 아닌 오프셋인 이유
RAW는 기준이 0이기 때문에 절대주소처럼 보일 수 있지만 정확히는 파일 내 상대 오프셋(offset)에 해당한다. 그 이유는 RAW 값이 디스크 전체에서의 물리적 주소를 의미하지 않기 때문이다. 다르게 얘기하자면 디스크 전체에서 특정 파일에 대한 오프셋이라고 할 수 있다.
4. VA (Virtual Address)

VA는 실행 중인 프로그램이 자신의 메모리 공간에서 사용하는 주소를 의미한다. 이는 물리 메모리 주소가 아닌 운영체제가 제공하는 가상의 주소 공간으로 각 프로세스는 독립된 VA 공간을 가진다.
4-1. VA는 절대주소?
VA(Virtual Address)는 해당 프로세스 내에서 항상 동일한 위치를 가리키므로 프로세스 관점에서는 절대주소처럼 동작한다. 하지만 실제로 이 주소는 논리주소이기 때문에 실제 물리 메모리(RAM)의 주소를 의미하진 않는다. 따라서 VA는 프로세스 내부 기준으로는 절대주소고 시스템 전체 기준으로는 가상주소에 해당한다.
5. RVA (Relative Virtual Address)

RVA는 ImageBase를 기준으로 한 상대 가상 주소를 의미한다. 실행 파일이 메모리에 로드될 때 기준 주소(ImageBase) 로부터 얼마나 떨어진 위치인지를 바이트 단위로 나타낸 값이다.
5-1. IMAGE_SECTION_HEADER.VirtualAddress

IMAGE_SECTION_HEADER의 VirtualAddress와 프로세스 내부 기준 절대 주소 VA(Virtual Address)는 이름이 같아 혼동하기 쉽지만 전혀 다른 개념이다.

IMAGE_SECTION_HEADER.VirtualAddress는 실행 파일이 메모리에 로드될 때 ImageBase를 기준으로 얼마나 떨어져 있는지(RVA)의 오프셋을 의미한다. 반면 VA(VirtualAddress)는 ImageBase에 해당 RVA를 더해 계산한 실제 가상 주소다. 두 용어는 표기가 완전히 동일하지만 실제 의미는 전혀 다른 개념이다.

.text 섹션을 살펴보면 IMAGE_SECTION_HEADER.VirtualAddress(RVA) 값이 0x1000이다. 이는 프로그램을 실행했을 때 해당 섹션이 ImageBase로 부터 0x1000만큼 떨어져있다는 의미다. 그렇기 때문에 메모리에서 .text섹션은 ImageBase + 0x1000에 위치하게 된다. 그 결과 VA는 0x401000이 된다. 결과적으로 .text섹션의 VA는 VA를 의미하지 않는다.

실제 메모리에서 확인해 보면 0x401000에 .text 섹션이 위치한다는 것을 알 수 있다.
6. 관계식
VA(VitualAddress) = ImageBase + RVA(Relative Virtual Address)
RVA는 PE 파일 실행 시 메모리 상에서의 상대적 위치이며 그 기준점이 ImageBase이기 때문에 위 관계식이 성립한다. 여기서 VA는 프로세스 내부 기준 절대 주소다. IMAGE_SECTION_HEADER의 VirtualAddress(RVA)를 의미하지 않는다.
7. EntryPoint

위의 관계식을 이용하면 EP를 구하는 것 또한 가능하다. 예제 파일에서 ImageBase는 0x400000, 엔트리포인트의RVA(AddressOfEntryPoint)는 0x12AA다. 따라서 위 관계식에 따라 EntryPoint의 VA는 0x4012AA가 된다.

실제 실행한 뒤 EntryPoint를 확인해 보면 계산한 결과와 정확히 일치한다는 것을 알 수 있다. ImageBase는 실행 파일이 메모리에 로드될 기본 주소지만 이 값은 선호값이지 절대적이지 않다. ASLR, 주소 충돌, 수동 맵핑, 특수 환경 등 여러가지 요인으로 인해 실제 로딩 주소는 달라질 수 있다. 따라서 ImageBase는 기준일 뿐 실제 메모리 주소와 항상 일치하지는 않는다.
'Reversing > Definition' 카테고리의 다른 글
| [Definition] 컴파일 (Compilation) (0) | 2025.07.10 |
|---|---|
| [Definition] RVA to RAW (0) | 2025.07.07 |
| [Definition] Rich Header (3) | 2025.07.05 |
| [Definition] 64비트 윈도우 실행 파일 구조 (PE+ Format) (0) | 2025.07.04 |
| [Definition] MS-DOS Stub Program (0) | 2025.07.04 |