ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [리버싱 핵심원리 study] 16장 Base Relocation Table
    Reverse Engineering 2020. 12. 29. 23:29

    1. PE 재배치

    PE 파일이 메모리에 로딩될 때 ImageBase 주소에 로딩이 된다. DLL의 경우 이미 다른 DLL이 로딩되어 있다면 다른 비어 있는 주소 공간에 로딩된다. 이와 같은 것을 PE 재배치라고 한다. DLL과 달리 EXE 파일은 가장 먼저 메모리에 로딩되기 때문에 재배치를 고려할 수가 없었으나, Windows Vista 이후부터는 보안 강화를 위해 ASLR(Address Space Layout Randomization) 기능이 추가되어 실행될 때마다 랜덤 한 주소에 로딩이 된다.

     

    => 이 글을 작성하는 시점에 Windows 10 환경에서 OllyDbg로 notepad.exe를 여러번 재실행해보았지만, 로딩되는 주소에는 변화가 없었다. 해당 부분에 대한 궁금증을 해소하기 위해서 구글링을 해보았고 다음 링크의 글들이 궁금증을 해결하는데 도움을 주었다.

     

     

     

    Six Facts about Address Space Layout Randomization on Windows

    Learn some basic facts about address space layout randomization (ASLR), focusing on the Windows implementation.

    www.fireeye.com

     

     

    Microsoft says ASLR behavior in Windows 10 is a feature, not a bug | ZDNet

    After a prominent security analyst criticized the implementation of a Windows 10 security feature, Microsoft fired back. That behavior is "by design," says Redmond. Here's the full story.

    www.zdnet.com

    프로그램을 단시간내에 실행했을 때에 ASLR이 작동하기보다는 재부팅 등을 수행한 후에 ASLR이 작동한다는 등의 내용을 포함하고 있는 글이다. 참고해보면 좋을 것 같다.

     

    2. PE 재배치 발생시 수행되는 작업

    PEView를 통해 Windows7의 notepad.exe의 ImageBase를 확인해보면 다음과 같다.

    notepad.exe의 ImageBase

    OllyDbg로 notepad.exe를 실행하면 다음과 같다.

    notepad.exe의 EP

    PEView에 나타난 ImageBase와는 다른 001D0000에 프로그램이 로딩된 것을 확인할 수 있으며, 위 첨부 사진에서 빨간색 동그라미는 각 프로세스 메모리 주소가 하드 코딩되어 있다. notepad.exe 프로그램이 재 실행되었을 때, 메모리의 다른 위치에 로딩된다면 위의 빨간 영역들은 로딩된 주소에 맞게 relocation을 해주어야 한다.

     

    3. PE 재배치 동작 원리

    Windows의 PE 로더가 수행하는 PE 재배치 작업의 동작 원리는 다음과 같다.

     

    1) 프로그램에서 하드코딩된 주소 위치를 찾는다.

    2) 값을 읽은 후 ImageBase를 뺀다. (VA -> RVA)

    3) 실제로 로딩된 주소를 더한다. (RVA -> VA)

     

    여기서 핵심은 하드코딩된 주소의 위치를 찾는 것으로, PE 파일 내부에 Relocation Table이라고 하는 하드코딩 주소들의 offset을 모아놓은 목록이 존재한다. Relocation Table을 찾아가기 위해서는 PE 헤더의 Base Relocation Table을 따라가면 된다.

     

    (1) Base Relocation Table

    PE 헤더의 DataDirectory의 5번 Index (6번째)에 존재한다. PEView를 통해 확인하면 다음과 같다.

    Base Relocation Table 주소

    RVA는 0002F000이다. PEView에서 해당 위치를 찾아보자.

    Base Relocation Table

     

    (2) IMAGE_BASE_RELOCATION 구조체

    위 그림에는 하드코딩 주소들의 offset이 나열되어 있다. 이 테이블을 이용하여 하드코딩 주소의 offset을 정확히 알아낼 수 있다. Base Relocation Table은 IMAGE_BASE_RELOCATION 구조체 배열인데, 그 정의는 다음과 같다.

     

    typedef struct _IMAGE_BASE_RELOCATION {
    	DWORD VirtualAddress;
        DWORD SizeOfBlock;
    //  WORD TypeOffset[1];
    } IMAGE_BASE_RELOCATION;
    typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
    
    #define IMAGE_REL_BASED_ABSOLUTE		0
    #define IMAGE_REL_BASED_HIGH			1
    #define IMAGE_REL_BASED_LOW			2
    #define IMAGE_REL_BASED_HIGHLOW			3
    #define IMAGE_REL_BASED_HIGHADJ			4
    #define IMAGE_REL_BASED_MIPS_JMPADDR		5
    #define IMAGE_REL_BASED_MIPS_JMPADDR16		9
    #define IMAGE_REL_BASED_IA64_IMM64		9
    #define IMAGE_REL_BASED_DIR64			10

    첫 번째 멤버 Virtual Address는 기준 주소를 나타내며(RVA), 두 번째 멤버 SizeOfBlock은 각 단위 블록의 크기를 가리킨다. 마지막으로 주석 처리된 TypeOffset[1]의 의미는 구조체 밑으로 WORD 타입의 배열이 따라온다는 의미를 나타낸다. 

     

    위의 구조체 정의를 기반으로 Base Relocation Table을 분석해보자. VirtualAddress 멤버의 값은 1000이고, 블록 전체 크기는 150(hex)이다. 이후로는 2byte짜리 TypeOffset이 나오는데 앞의 4비트는 매크로로 정의된 TYPE, 뒤의 12비트는 offset이 된다. TypeOffset의 개수는 블록 사이즈가 150이므로 (150-8)/2 = A4(hex) 이다. 이제 실제로 1420 RVA에 PE 재배치가 필요한지 OllyDbg에서 확인해보자.

     

    하드코딩된 주소 예제

    (3) 실습

    간단한 실습을 통해 PE 재배치 작업의 동작 원리를 이해해보자. 앞에서 설명한 3.PE 동작 원리를 바탕으로 진행한다.

     

    #1 프로그램에서 하드코딩된 주소 위치를 찾기

    RVA 1420 주소의 내용

    RVA 1420 주소에는 010010C4가 들어있다.

     

    #2 ImageBase 만큼 빼기

    010010C4 - 01000000 = 000010C4

     

    #3 실제 로딩 주소 더하기

    000010C4 + 001D0000 = 001D10C4

    반응형

    댓글

Designed by Tistory.