R136A1

[WEEK2] 어셈블리 명령어 / PE Header 본문

SWING/[21-2] REVERSING

[WEEK2] 어셈블리 명령어 / PE Header

r136a1x27 2021. 9. 25. 19:32

어셈블리 명령어

참고: 최은정교수님 윈도우즈보안과운영실습

1) 데이터 이동

값을 직접 레지스터로 대입

레지스터에서 레지스터로 옮기기

값을 직접 메모리로 대입하기

레지스터에서 메모리로 또는 그 반대로 옮기기

메모리에서 메모리로 옮기기

 

MOV: move operand1 <- operand2 을 복사

MOV EAX, EBX // EBX 값을 EAX로 복사
EBP, ESP // ESP 값을 EBP로 복사
EAX, 42 // 0x42EAX로 복사
EAX, [4037C4] // 메모리주소 4037C4에 있는 4바이트 값을 EAX로 복사
EAX, [EBX] // EBX가 명시한 메모리주소의 4바이트 값을 EAX로 복사
EAX, [EBX+ESI*4] // EBX+ESI*4 연산결과가 명시한 메모리 주소의 4바이트 값을 EAX로 복사

[메모리주소값]일 경우 그곳의 값,

메모리주소가 아닐 경우 [대괄호 안에 있는 값]이 명시한 곳(=메모리주소)에 있는 값을 가리킴

 

LEA: Load Effective Address, 주소값을 저장

- LEA EAX, [EBP+8] // EBP+8에 저장된 주소를 EAX에 저장

- MOV EAX, [EBP+8] // EBP+8가 명시한 메모리주소에 있는 값을 EAX에 복사

 

PUSH: 스택을 저장 => 스택 4byte증가 == (현재 스택포인터) ESP 4byte 감소

// 스택에만 사용하는 opcode이므로 저장될 장소 operand 필요없음. operand

- PUSH EBP // 스택에 EBP 값을 push

- PUSH 5 // 스택에 5push

 

POP: 스택 끝에 저장된 값을 가져옴 => 스택 4byte감소 == (현재 스택포인터) ESP 4byte 증가

// 스택에만 사용하는 opcode이므로 가져올 장소 operand 필요없음. 저장될 operand

POP EBP // 스택이 현재 가리키는 값(=끝 값)EBP에 저장

POP ECX // 스택이 현재 가리키는 값(=끝 값)ECX에 저장

 

2) 산술연산

명령 설명 사용예
ADD 덧셈 ADD ECX, 10
SUB 뺄셈 SUB ECX, 5
INC operand 내용을 1 증가 INC ECX
DEC operand 내용을 1 감소 DEC ECX
MUL/IMUL EAXoperand를 곱셈하여 EAX에 저장 MUL EDX
DIV/IDIV EAXoperand를 나누어 EAX에 저장 DIV EDX
NEG operand 내용을 2의 보수(부호반전) NEG EAX

곱셈보다 덧셈이 빠르기 때문에 MUL 100 보다 ADD 100번 쓰는게 빠름

IMUL, IDIV는 부호가 있는 Integer 형태에서 사용됨

 

3) 비트연산

operand 2진수 형태로 연산한다

명령 설명 사용예
AND operand의 각 비트값을 AND 연산 (덧셈 느낌)
(두 비트가 모두 1이면 1, 나머지는 0)
 
OR operand의 각 비트값을 OR 연산 (곱셈 느낌)
(두 비트가 하나라도 1이면 1, 나머지는 0)
 
XOR operand의 각 비트값을 XOR 연산
(두 비트의 값이 같으면 0, 다르면 1)
 
NOT 비트 값을 반대 값(01, 10)으로 변경  
SHL 왼쪽으로 쉬프트 연산,
최하위 비트는 0으로 채워지고,
기존 값은 CF 플래그 레지스터에 저장됨
 
SHR 오른쪽으로 쉬프트 연산,
최하위 비트는 부호비트로 채워지고,
기존 값은 CF 플래그 레지스터에 저장됨
 
ROL/RCL 왼쪽으로 쉬프트 연산,
최하위 비트는 최상위 비트로 채워짐
 
ROR/RCR 오른쪽으로 쉬프트 연산,
최상위 비트는 최하위 비트로 채워짐
 

 

4) 제어

명령 설명 사용예
CMP operand 비교 (뺄셈 연산 후 플래그 설정) CMP EAX, 0 (같으면 ZF 0set)
TEST operand 비교 (AND 연산 후 플래그 설정) TEST EAX, EAX (EAX0이면 ZF 1set)
CALL 해당되는 주소의 함수를 호출하여
수행 코드 위치로 옮김
CALL 00401990 (PUSH EIP, JMP 주소)
INT 오퍼랜드로 지정된 예외 처리 수행
- 중단점으로 디버그용 소프트웨어 트랩
- 오버플로우 상황 시 발생하는 트랩
- 하드웨어 디버그 트랩
INT 3
LEAVE 함수에서 사용한 지역변수 스택을 비움 LEAVE (서브루틴보다 C핵심 main에서...)
RETN 스택에 저장된 주소로 복귀 RET
NOP 아무 동작도 수행하지 않음 (기계어코드 0x90) NOP

CMP, TEST는 주로 분기 명령어와 함께 쓰이며 NOP는 공격 코드를 삽입할 때 자주 쓰인다.

4) 분기

JMP: 무조건 EIP 주소값으로 점프

JE(Jump if Eqaul)

JNE(Jump if Not Equal)

JCC: CC(조건부코드) 값에 따라 해당 EIP 주소값으로 점프

 

E = Equal / Z = Zero / N = Not / L = Less / G = Greater

B = Bellow / A = Above / P, O, S = PF, OF, SF(플래그) / ECX = ECX(레지스터)

CC 설명 플래그값
E/Z 같은/0 ZF=1
NE/NZ 다른/0이아닌 ZF=0
L/NGE 작은 (부호 있는 연산) (SF^OF)=1 (SF != OF)
G/NLE (부호 있는 연산) ((SF^OF) | ZF)=0
GE/NL 크거나 같은 (부호 있는 연산) (SF^OF)=0
LE/NG 작거나 같은 (부호 있는 연산) ((SF^OF) | ZF)=1
B/ANE 작은 (부호 없는 연산) CF=1
AE/NB 크거나 같은 (부호 없는 연산) CF=0
P/PE PF1이면 (짝수) PF=1
NP/PO PF0이면 (홀수) PF=0
O OF1이면 OF=1
S SF1이면 SF=1
ECXZ ECX0이면 ECX=0

 

5) 반복

REP: repeat, ECX 레지스터 지정횟수만큼 또는 ZF 플래그 조건에 맞을동안 반복

REP : ECX0이 될 때까지 반복

REPE, REPZ : ECX0이거나 ZF0일 때까지 반복

REPNE, REPNZ : ECX0이 아니거나 ZF1일 때까지 반복

LOOP : LOOP 영역을 ECX 레지스터 지정 값만큼 반복

LOOP 주소 : ECX 카운터 감소시키고, 카운터가 0이 아니면 주소로 이동함

LOOPE 주소 : ECX 카운터 감소시키고, 카운터가 0이 아니고 ZF1 이면 주소로 이동함

LOOPNE 주소 : ECX 카운터 감소시키고, 카운터가 0이 아니고 ZF0 이면 주소로 이동함

 


blog.hexabrain.net/270

jmoon.co.kr/130

rninche01.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%8B%A4%ED%96%89%ED%8C%8C%EC%9D%BC-%EA%B5%AC%EC%A1%B0PE%ED%8C%8C%EC%9D%BC

Stud_PE Editing을 사용하면 구조대로 이름이 뜸 + CFF_Explorer는 구조를 아예 분석해서 보여줌

WinNT.h
0.48MB

 

PE 포맷

윈도우 운영 체제에서 사용되는, "실행 가능한 파일 형식"을 뜻함 (Linux에서는 ELF사용)

하나의 실행파일을 다양한 운영체제에서 실행할 수 있다는 의미로

"이식 가능한 실행파일" PE, Portable Executable 플랫폼에 독립적임

종류 확장자
실행파일 exe
드라이버 sys, vxd
라이브러리 dll, ocx, cpl, drv
오브젝트 obj

* exe는 직접적으로 실행 가능, obj를 제외한(?) 나머지 파일은 간접적으로 실행 가능

* 32비트 형태의 실행 파일 → PE or PE32

   64비트 형태의 실행 파일 → PE+ or PE32+

 

윈도우 Loader가 "실행가능한 코드를 관리"하는 데 필요한 정보를 캡슐화한 데이터 구조체

PE를 구성하는 요소들은 각각 구조체의 형태를 갖고있음

 

※ 아래부터 쌓이는 형태임.

 

크게 Header 부분 / Section(=Body) 부분으로 나뉨

Section은 보통 4종류로 구성되어있음(Header에서 각 Section에 대한 정보를 포함)

섹션명 용도
.text 코드, 실행, 읽기 속성을 지니며 컴파일 후의 결과가 이곳에 저장됩니다.
즉, 이 섹션은 실행되는 코드들이 들어가는 섹션
.data 초기화, 읽기, 쓰기 속성을 지니며 초기화된 전역 변수를 가집니다.
.rdata 초기화, 읽기 속성을 지니며 문자열 상수나 const로 선언된 변수처럼 읽기만 가능한
읽기 전용 데이터 섹션
.bss 비초기화, 읽기, 쓰기 속성을 지니며 초기화되지 않은 전역 변수의 섹션
.edata 초기화, 읽기 속성을 지니며 EAT와 관련된 정보가 들어가 있는 섹션
.idata 초기화, 읽기, 쓰기 속성을 지니며 IAT와 관련된 정보가 들어가 있는 섹션
.rsrc 초기화, 읽기 속성을 지니며 리소스가 저장되는 섹션

 

각 섹션은 최소 1개 이상 존재하며 각 헤더 사이에는 정렬 규칙을 사용해 패딩 영역이 있음 (크기압축 대신 처리효율을 높임)

 

파일이 메모리에 적재된 후에는 헤더는 같은데 섹션의 크기 및 형태가 달라짐

파일은 offset, 메모리에서는 address로 통칭함.


PE파일 실행 과정

1) PE 파일 실행 명령

2) PE Header 정보를 메모리에 Mapping

- 실제 프로세스를 위한 메모리 할당

- 섹션 정보를 메모리에 복사

- Import 정보 처리

- 기준 재배치 처리

3) 실제 프로그램 코드로 분기

 

VA(Virtual Address): 가상 메모리 절대 구조

RVA(Relative Virtual Address): 가상 메모리 상대 주소

- PE파일이 메모리 상의 어떤 위치에 올라갈지 알 수 없음

- ImageBase라 불리는 기준점을 놓고, 그 곳으로부터 위치를 계산

- ImageBase가 바뀌더라도 정보 접근이 가능하도록 함

 

VA = ImageBase + RVA


PE파일 구조

PEview로 확인 가능

PE 헤더 (DOS Header ~ Section Table)

파일을 실행하는 데 있어 필요한 전반적인 정보들

ex) 파일을 실행할 때 맨 처음 시작해야 할 코드의 시작 부분에 대한 정보

       프로그램이 구동 될 수 있는 플랫폼에 대한 정보

 

코드 및 데이터 영역의 위치와 크기, 운영체제, 초기 스택 크기 등

※ DWORD=4byte / WORD=2byte / LONG=4byte

1) DOS Header (4줄)

typedef struct _IMAGE_DOS_HEADER {     
    WORD   e_magic;          // 중요: DOS signature : 4D5A ("MZ")
    WORD   e_cblp;                     
    WORD   e_cp;                       
    WORD   e_crlc;                     
    WORD   e_cparhdr;                  
    WORD   e_minalloc;                 
    WORD   e_maxalloc;                 
    WORD   e_ss;                       
    WORD   e_sp;                       
    WORD   e_csum;                     
    WORD   e_ip;                       
    WORD   e_cs;                       
    WORD   e_lfarlc;                   
    WORD   e_ovno;                     
    WORD   e_res[4];                   
    WORD   e_oemid;                    
    WORD   e_oeminfo;                  
    WORD   e_res2[10];                  
    LONG   e_lfanew;         // 중요: offset to NT header 
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

WORD 16+14 / LONG 1 =64 byte

1-1. e_magic: DOS signature, PE파일의 시그니처가 저장됨 맨 처음 2byte 고정 MZ (설계자 이름 Mark Zbikowski에서 따옴)

1-2. e_lfanew: NT Header의 시작 주소(=offset)를 저장함 맨 마지막 4byte, little endian

 

2) DOS Stub (e_lfanew값 주소 이전까지)

크기가 정해져있지 않음, DOS에서 돌아가는 16bit (=2 Byte) 어셈블리어로 작성되어 있음

32bit 이상 Windows에서는 실행되지 않고 무시되어 있든 없든 상관없음

*대부분 32bit로 프로그래밍된 프로그램이 16bit DOS mode에서 실행되었을 때

여기선 돌릴 수 없다는 text를 출력하는 용도로 사용함 (하위호환성)

 

3) NT Header (e_lfanew값 주소부터)

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;                  // PE Signature : fixed 50450000 ("PE"00)
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
 
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

3-1. Signature: NT code의 시작을 알림, PE파일임을 명시, 고정적으로 50 45 00 00 (ASCII PE00) 이 들어있음 맨 처음 4byte

3-2. FileHeader: 별도의 구조체(IMAGE_FILE_HEADER) - PE의 기본적인 내용 총 20 Byte

   - 동작 가능한 cpu의 종류, 섹션의 개수, 빌드된 시간, OptionalHeader의 크기, 파일속성 ...

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

3-2-1. Machine: 동작 가능한 cpu의 종류를 상수로 담고 있음 2byte, little endian

#define IMAGE_FILE_MACHINE_(명칭)   (값)

명칭 설명
UNKNOWN 0  
I386 0x014c Intel 386
R3000 0x0162 MIPS little-endian, 0x160 big-endian
R4000 0x0166 MIPS little-endian
R10000 0x0168 MIPS little-endian
WCEMIPSV2 0x0169 MIPS little-endian WCE v2
ALPHA 0x0184 Alpha_AXP
SH3 0x01a2 SH3 little-endian
SH3DSP 0x01a3  
SH3E 0x01a4 SH3E little-endian
SH4 0x01a6 SH4 little-endian
SH5 0x01a8 SH5
ARM 0x01c0 ARM Little-Endian
THUMB 0x01c2  
AM33 0x01d3  
POWERPC 0x01F0 IBM PowerPC Little-Endian
POWERPCFP 0x01f1  
IA64 0x0200 Intel 64
MIPS16 0x0266 MIPS
ALPHA64 0x0284 ALPHA64
MIPSFPU 0x0366 MIPS
MIPSFPU16 0x0466 MIPS
AXP64 IMAGE_FILE_MACHINE_ALPHA64
TRICORE 0x0520 Infineon
CEF 0x0cef  
EBC 0x0ebc EFI Byte Code
AMD64 0x8664 AMD64 (K8)
M32R 0x9041 M32R little-endian
CEE 0xc0ee  

3-2-2. NumberOfSections: 파일이 갖고있는 Section의 개수 2byte

3-2-3. TimeDateStamp: 파일이 빌드된 시간 *변조가능, 신뢰X / 10진수값으로 바꾼 뒤 표준시작으로 바꾸면 됨 4byte

     +      PointerToSymbolTable 4byte

     +      NumberOfSymbols 4byte

3-2-4. SizeOfOptionalHeader: 다음 멤버인 Optional Header의 크기 (보통 x32: 0xE0 / x64: 0xF0 / obj: 0x00) 2byte

3-2-5. Characteristics: 파일의 속성에 대한 정보  마지막 2byte, little endian

(rwx처럼 값 중첩해서 계산=비트 플래그 형식 사용, 2진수 형식으로 증가 ex. 0102면 EXECUTABLE_IMAGE &32bit 기반)

#define IMAGE_FILE_(명칭)   (값)

명칭 설명
RELOCS_STRIPPED 0x0001 Relocation info stripped from file.
EXECUTABLE_IMAGE 0x0002 File is executable (i.e. no unresolved externel references)
LINE_NUMS_STRIPPED 0x0004 Line nunbers stripped from file
LOCAL_SYMS_STRIPPED 0x0008 Local symbols stripped from file
AGGRESIVE_WS_TRIM 0x0010 Agressively trim working set
LARGE_ADDRESS_AWARE 0x0020 App can handle >2gb addresses
BYTES_REVERSED_LO 0x0080 Bytes of machine word are reversed.
32BIT_MACHINE 0x0100 32 bit word machine.
DEBUG_STRIPPED 0x0200 Debugging info stripped from file in .DBG file
REMOfBLE_RUN_FROM_SWAP 0x0400 If Image is on removable media, copy and run from the swap file.
NET_RUN_FROM_SWAP 0x0800 If Image is on Net, copy and run from the swap file.
SYSTEM 0x1000 System File.
DLL 0x2000 File is a DLL.
UP_SYSTEM_ONLY 0x4000 File should only be run on a UP machine
BYTES_REVERSED_HI 0x8000 Bytes of machine word are reversed.

 

3-3. OptionalHeader: 구조체 (주로 주소 관련 내용, 31개의 필드, 가변적)

   - 32/64구분자, EntryPoint주소, PE파일이 매핑되는 시작주소, 메모리의 섹션최소단위, 파일의 섹션최소단위, ...

typedef struct _IMAGE_DATA_DIRECTORY {
 
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
 
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES  
 
typedef struct _IMAGE_OPTIONAL_HEADER {
    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;
    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

3-3-1. Magic : 구조체의 비트에 따라... IMAGE_OPTIONAL_HEADER32 - 0x010B / 64 - 0x020B (2byte, little endian)

3-3-2. SizeOfCode: 코드 영역 전체의 크기 (=.text 섹션의 크기) 4byte

3-3-3. ImageBase : PE파일이 메모리에 로드될 때의 시작주소, RVA의 기준이 됨 4byte

            EXE파일인 경우 0x400000번지 / DLL파일인 경우 0x10000000번지 //고정아님. 링커 옵션을 통해 지정 가능 + 이미 있는 경우 재배치 이루어짐)

             (RVA: Relative Virtual Address, 상대 가상주소 ImageBase를 기준으로 어느만큼 떨어져있는지 나타냄_메모리주소

              ImageBase가 0x400000 번지일 경우 .text섹션 RVA값이 0x3000이라면 실제로 .text 섹션이 메모리에 로드되는 위치는 0x403000)

3-3-4. AddressOfEntryPoint : EP; Entry Point (프로그램의 시작점) 주소를 가짐, RVA주소이므로 ImageBase(3-3-3)에 더해야 VA주소 4byte

3-3-5. BaseOfCode: 코드 영역이 시장되는 RVA주소

3-3-5. SectionAlignment : 메모리에서의 섹션의 최소단위 (즉, 메모리에서 섹션의 크기는 반드시 SectionAlignment의 배수 = 시작주소도 이 값 배수)

3-3-6. FileAlignment : 파일에서 섹션의 최소단위 (즉, 파일=저장공간에서 섹션의 크기는 반드시 FileAlignment의 배수 = 시작주소도 이 값 배수)

3-3-7. SizeOfimage : 파일이 메모리에 로딩되었을때 PE파일이 차지하는 크기

3-3-8. SizeOfHeader : PE 모든 헤더의 전체크기(DOS Header + DOS Stub + PE Header + Section Header)

                                            즉, 파일의 시작점에서 SizeOfHeader만큼 떨어진 Offset에 첫번째 섹션이 존재하는 것

3-3-9. SubSystem : 파일을 실행하기위한 기본 환경

                                      #define IMAGE_SUBSYSTEM_(명칭)   (값)

명칭 설명
UNKNOWN 0 Unknown subsystem.
NATIVE   1 Image doesn't require a subsystem.
WINDOWS_GUI 2 Image runs in the Windows GUI subsystem.
WINDOWS_CUI 3 Image runs in the Windows character subsystem
OS2_CUI    5 image runs in the OS/2 character subsystem.
POSIX_CUI 7 image runs in the Posix character subsystem.
NATIVE_WINDOWS 8 image is a native Win9x driver.
WINDOWS_CE_GUI  9 Image runs in the Windows CE subsystem.
EFI_APPLICATION 10  
EFI_BOOT_SERVICE_DRIVER 11  
EFI_RUNTIME_DRIVER 12  
EFI_ROM 13  
XBOX 14  
WINDOWS_BOOT_APPLICATION 16  

3-3-9. NumberOfRvaAndSizes : DataDirectory(3-3-10)구조체의 멤버변수로, 배열 크기를 정함

3-3-10. DataDirectory: PE파일에서 중요한 역할을 하는 개체들의 위치 및 크기

                                              파일이 어떤 라이브러리를 제공하고, 필요한지를 정의한 테이블의 위치와 크기

typedef struct _IMAGE_DATA_DIRECTORY {
	DWORD VirtualAddress;
	DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_DIRECTORY_ENTRY_(명칭)  (값) 

0 Export                8 GLOBALPTR

1 Import                9 TLS

2 RESOURCE     10 LOAD_CONFIG 

3 EXCEPTION     11 BOUND_IMPORT

4 SECURITY        12 IAT

5 BASERELOC    13 DELAY_IMPORT

6 DEBUG               14 COM_DESCRIPTOR

7 COPYRIGHT      15 Reserved

더보기

IMAGE_OPTIONAL_HEADER의 DataDirectory 필드는 익스포트 디렉터리, 임포트 디렉터리, 리소스 디렉터리, 예외 디렉터리, 보안 디렉터리 영역 등에 접근할 수 있는 주소와 크기를 지니고 있는 배열로, IMAGE_DATA_DIRECTORY 구조체의 VirtualAddress를 통해 가상 주소를 알 수 있으며, Size를 통해 크기를 알 수 있습니다. 여기서 중요한 값은 EXPORT, IMPORT, RESOURCE, TLS, IAT인데 우선은 이것들을 잘 기억해두시기 바랍니다. 이부분에 대해서는 추후에 다시 설명하도록 하겠습니다.

IMAGE_OPTIONAL_HEADER의 DataDirectory 필드는 익스포트 디렉터리, 임포트 디렉터리, 리소스 디렉터리, 예외 디렉터리, 보안 디렉터리 영역 등에 접근할 수 있는 주소와 크기를 지니고 있는 배열로, IMAGE_DATA_DIRECTORY 구조체의 VirtualAddress를 통해 가상 주소를 알 수 있으며, Size를 통해 크기를 알 수 있습니다. 여기서 중요한 값은 EXPORT, IMPORT, RESOURCE, TLS, IAT인데 우선은 이것들을 잘 기억해두시기 바랍니다. 이부분에 대해서는 추후에 다시 설명하도록 하겠습니다.

4) Section Header (=Section Table)

Section에 대한 정보를 관리하는 구조체, Section의 속성을 정의

Section을 나누고, 각 Section들의 시작위치, 크기, 속성값 등 정함

.text .data. rdata Section 등에 대한 정보를 알 수 있음

 

Section마다 액세스 권한이 달라야 함 (프로그램의 안정성을 위하여)

ㄴCode: 실행, 읽기 권한

   Data: 비실행, 읽기, 쓰기 권한

   Resource: 비실행, 읽기 권한

#define IMAGE_SIZEOF_SHORT_NAME     8         
 
typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

4-0. Name 8byte

4-1. VirtualSize : 메모리에서의 Section의 크기 4byte

4-2. VirtualAddress : 메모리에서 Section이 시작되는 RVA 주소 4byte

4-3. SizeOfRawData : 파일에서 Section이 차지하는 크기 4byte

4-4. PointerToRawData : 파일에서 Section이 시작하는 위치 4byte → 검색 후 SizeOf(4-3) 값 단위로 Section임

4-5. Characteristics : 섹션의 속성. NT헤더의 Characteristics랑 같은 역할 및 형식. 조합하여 사용 4byte

#define IMAGE_SCN_(명칭)  (값)

명칭 설명
CNT_CODE 0x00000020 Section contains code.
CNT_INITIALIZED_DATA 0x00000040 Section contains initialized data.
CNT_UNINITIALIZED_DATA 0x00000080 Section contains uninitialized data.
MEM_EXECUTE 0x20000000 Section is executable.
MEM_READ   0x40000000 Section is readable.
MEM_WRITE 0x80000000 Section is writeable.

 

blog.hexabrain.net/270 그 이후..IAT 부가 설명..

zesrever.tistory.com/56


섹션

실제 프로그램을 구성하는 어셈블리 코드

소스코드 내에서 선언한 전역변수나 static변수 등

 


 

Comments