RVA TO RAW, IAT

2025. 2. 12. 23:14·reversing

RVA TO RAW

PE 파일이 메모리에 로딩되었을 때 각 섹션에서 메모리의 주소(RVA)와 오프셋을 잘 매핑해야 한다. 이러한 매핑을 RVA TO RAW라고 부른다

RAW(File Offset)

  • 매핑 방식
    • RVA가 속해있는 섹션 찾기
    • 공식을 이용하여 파일 오프셋을 계산
  • 공식
    • RAW - PointerToRawData(파일에서의 섹션 시작 위치) = RVA - VA(메모리에서 섹션 시작 위치)
    • RAW = RVA - VA + PointerToRawData

 

예제 #1 RVA = 3000일 때, RAW는 얼마인가?

RVA는 400보다 크고 53200보다 작으므로 Section(text)에 있다

PointerToRawData: 00000400

VA: 01001000

RAW = RVA - VA + PointerToRawData

→ 3000 - 01001000 + 00000400 = FFFF FFFF FF00 2040

⇒ 오류!!! : imagebase를 고려하지 않음

imagebase: 01000000

VA - imagebase(주소를 조정하기 위해) = 1000

다시 ⇒ 3000-1000+400 = 2400(RAW)

 

#2 RVA = BC123일 때, RAW는?

RVA는 section(.reloc)에 위치

PointerToRawData: B9C00

VA: BC000

RAW = BC123 - BC000 + B9C00

 


IAT(1)

IAT: 윈도우 운영체제의 핵심 개념인 process와 memory 구조 등의 근간을 이해한다고 할 수 있음. 프로그램에서 어떤 라이브러리에서 어떤 함수를 사용하고 있는지 기술한 테이블(배열)

DLL: 동적 링크 라이브러리.

  • dll의 초기 구상
    • 프로그램에 라이브러리를 포함시키지 말고 별도의 파일 dll로 구성하여 필요할 때마다 호출하자
    • 일단 한 번 로딩된 dll의 코드 리소스를 메모리 매핑 기술로 다같이 나누어 쓰자
    • 라이브러리가 업데이트 됐을 때 해당 dll 파일만 교체하면 되니까 간편하다
  • dll이 로딩되는 방식
    1. 프로그램에서 사용되는 순간 딱 로딩하고 사용 끝나면 메모리에서 해제되는 방법 → explicit linking
    2. 프로그램이 실행될 때 같이 연결되어 프로그램 종료 시 메모리에서 해제된다 → implicit linking
  • dll 재배치
    • 어떤 파일의 imagebaserk 10000인데 로딩을 하려고 하니 다른 파일이 이미 그 자리를 차지하고 있다면, 다른 빈 공간을 찾아서 로딩

IAT(2)

PE파일은 자신이 어떤 라이브러리를 import 하고 있는지 IAT 구조체를 통해서 명시하고 있다

아래의 모든 주소는 RVA

  • OriginalFirstThunk: INT(Import name table) 주소(RVA)
  • Characteristics:
  • Name: library 이름 문자열 주소
  • FirstThunk: IAT 주소를 가리킨다

참고로 INT와 IAT는 Long type 배열이고 null로 끝나고 INT와 IAT 값이 서로 같아야 한다

PE로더가 임포트 함수를 IAT에 입력하는 기본적인 순서가 있음!

  • IAT 입력 순서
    1. IMAGE_IMPORT_DESCRIPTOR의 name 멤버를 읽고 나서 library 이름 문자열(kernel32.dll)을 읽기
    2. 해당 라이브러리를 로딩한다 → LoadLibrary(kernel32.dll)
    3. IMAGE_IMPORT_DESCRIPTOR의 OriginalFirstThunk 멤버를 읽어서 INT 주소를 얻는다
    4. 그 주소로 INT에서 배열의 값을 하나씩 읽어서 IMAGE_IMPORT_BY_NAME 주소(RVA)를 얻음
    5. IMAGE_IMPORT_BY_NAME에서 Hint(고유번호) 또는 Name 항목 > 함수 시작주소 얻음 (GetProcAddress() 함수로)
    6. IAT 배열 값에 위에서 구한(4번) 함수 주소를 입력
    7. INT null일 때까지 4~6 반복

IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress → IMAGE_IMPORT_DESCRIPTOR

  1. 라이브러리 이름(Name)→ IMAGE_IMPORT_DESCRIPTOR의 name 멤버를 읽고 나서 library 이름 문자열(kernel32.dll)을 읽기
  2. Name 항목은 임포트 함수가 라이브러리에 파일의 이름 문자열 포인터이다
  3. OriginalFirstThunk - INT(import name table)→ IMAGE_IMPORT_BY_NAME
  4. INT: 임포트하는 함수의 정보가 담긴 구조체 포인터 배열. 이 정보는 필요로 하는 프로세스의 메모리에 로딩된 라이브러리에서 해당 함수의 시작주소를 정확히 구할 수 있다
  5. Ordinal은 고유번호인데 함수들이 변수들을 구별하기 위한 번호
  6. 정리하자면 IMAGE_IMPORT_BY_NAME은 DLL에서 함수를 호출할 때 필요한 정보(이름, 고유번호)을 담고있다 (그 정보를 토대로 주소를 서치)

<정리>

OriginalFirstThunk는 INT를 가리킨다. 그리고 INT와 IMAGE_IMPORT_BY_NAME의 차이점으느 INT는 함수 이름과 고유번호를 담고 있고, IMAGE_IMPORT_BY_NAME는 해당 함수에 대한 자세한 정보를 담고 있다.

그리고 NAME과 IMAGE_IMPORT_BY_NAME의 차이점은 가져와야 하는 DLL 파일의 이름을 가리키고 IMAGE_IMPORT_BY_NAME DLL에서 내보내야 하는 함수의 이름과 고유번호 값을 가지고 있는 구조체이다

저작자표시 비영리 변경금지 (새창열림)

'reversing' 카테고리의 다른 글

[dreamhack] rev-basic-0  (0) 2025.03.23
NT header, Section header  (0) 2025.02.12
함수 호출 규약, PE file  (0) 2025.02.12
레지스터, 프로세스 메모리 구조, 섹션, 스택, 힙  (0) 2024.10.27
악성코드 종류와 분석  (1) 2024.10.19
'reversing' 카테고리의 다른 글
  • [dreamhack] rev-basic-0
  • NT header, Section header
  • 함수 호출 규약, PE file
  • 레지스터, 프로세스 메모리 구조, 섹션, 스택, 힙
hauni
hauni
  • hauni
    200 OK
    hauni
  • 전체
    오늘
    어제
    • 분류 전체보기 (54)
      • W3B H4CK1NG (15)
      • reversing (10)
      • python (19)
      • project (1)
        • WHS (0)
        • network (1)
      • 동아리_I.Sly() (9)
      • something... (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    록키리눅스
    리눅스
    방화벽
    VMware
    보안
    방화벽 구현
    이것이리눅스다
    네트워크
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hauni
RVA TO RAW, IAT
상단으로

티스토리툴바