windows pe 중 실행파일인 exe 에서 reloc섹션은 필요 없는 섹션중 하나 입니다.


reloc은 dll이나 sys 파일에서는 필수지만 exe에서는 필요가 없습니다.


실제로 제거를 해도 정상적으로 실행이 됨니다.


그럼 이제 이 섹션을 제거 해봅시다.


섹션을 제거 할려면 일단 섹션을 물리적으로 제거를 하고 섹션의 해더에서 섹션의 주소를 null로 수정하고 섹션의 수가 변경 되었으니 number of section 값을 줄여 줘야합니다.


그리고 메모리에서 크기가 줄어들었으니 줄여 주면 좋겠져 


reloc 섹션을 제거하기위해서는 총 4가지의 작업이 필요합니다.


reloc섹션 제거를 하신후 reloc 섹션의 해더를 정리 하고 IMAGE_FILE_HEADER의 number of section 값을 변경한후에 IMAGE_OPTIONAL_HEADER의 size of image 값을 수정하시면 됨니다.


첫번쨰로 reloc섹션을 물리적으로 제거를 해봅시다.



reloc 섹션의 raw 는 7400입니다. 헥스 에디터로 7400부터 끝까지 null로 하시면 됨니다.


하지만  null로 수정하기에는 힘이듬니다. 따라서 선택 채우기를 사용하여 제거 합니다.


선택채우기는 선택된 (드래그된) 값들을 특정 값으로 변경하는것 입니다.



7400부터 끝까지 드래그 하신뒤에 오른쪽클릭으로 선택 채우기를 클릭합니다.



00가 null이나 00으로 선택후에 수락을 누루시면 됨니다.


reloc 섹션이 00로 바뀌었습니다.


이제 reloc 섹션 해더를 수정해야합니다.




pointer to raw data는 reloc섹션의 주소입니다.


이주소값을 null로 하시면 됨니다.




자 이제 섹션이 제거 되었으니 섹션의 수가 줄어 들었다고 알려줘야져 


IMAGE_FILE_HEADER의 number of section을 1 감소 하시면 됨니다.



number of section의 주소는 f6 입니다.


헥스 에디터로 07 이므로 06으로 변경 하시면 됨니다.




자 이제 마지맏 메모리 공간을 줄이는 일만 남았습니다.


전체 메모리 공간은 reloc 섹션이 제거되면서 줄어들었습니다. 


그런데 남은 메모리 공간을 다른곳에 쓰면 좋을거같아서 안줄이시면 안됨니다.


메모리공간을 줄여 주지 않으면 reloc 섹션을 제거하면서 줄어든 크기가 변경되어 pe파일에 명시된 크기와 실제 파일의 크기가 맞지않아 에러가 뜸니다.


자 이제 메모리공간을 줄여 봅시다.


메모리 크기는 IMAGE_OPTIONAL_HEADER의 size of image에 명시되어 있습니다.




중요한것은 얼마큼 줄여야 정상적으로 실행이 될지 인데요


섹션의 크기는 section alignment에 정의 되어 있습니다.



1000이 네요 1000을 size of image에서 빼시면 됨니다.


헥스 에디터에서 raw가 140이므로 


140에가서 0001c000을 0001b000으로 변경하시면 됨니다.




변경이 완료 되었으면 실행해 보시면 정상적으로 실행이 됨니다.




reloc 섹션이 제거가 된것을 보실수 있습니다.



'Reversing > Windows PE' 카테고리의 다른 글

windows pe) EAT  (0) 2014.08.06
windows pe) IAT  (0) 2014.07.25
windows pe) null패딩이 진짜 null패딩인지 확인하기  (0) 2014.07.23
windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
Posted by 준P

windows 운영체제에서는 프로그램에서 함수를 호출할때 라이브러리를 사용함니다.


dll이나 sys파일이 대표적입니다.


EAT는 Export Adress Table의 약자이고 라이브러리에서 함수를 가져다주는 메커니즘입니다.


IMAGE_EXPORT_DIRECTORY에서 익스포트 정보를 저장하고있습니다.


IMAGE_EXPORT_DIRECTORY 은 pe 파일 안에 하나만 존제합니다.


EAT는 IMAGE_OPTIONAL_HEADER의 DATA DIRECTORY의 첫번쨰 배열에 속합니다.


EAT의 첫번쨰 4바이트는 Vitual Address를 나타내고 두번쨰 4바이트가 size 맴버입니다.


EAT의 Vitual Address의 주소는 IMAGE_EXPORT_DIRECTORY의 시작 주소를 가르킴니다.



peview 에서 아무dll파일을 열어서 EXPORT TABLE을 본것입니다.


data값을 따라가보면 export address table 을 찾으 실수 있습니다.


IMAGE_EXPORT_DIRECTORY의 DATA DIRECTORY배열의 첫번쨰를 보여주고 있습니다.


typedef struct _IMAGE_EXPORT_DIRECTORY {

    DWORD   Characteristics;

    DWORD   TimeDateStamp;

    WORD    MajorVersion;

    WORD    MinorVersion;

    DWORD   Name;

    DWORD   Base;

    DWORD   NumberOfFunctions;

    DWORD   NumberOfNames;

    DWORD   AddressOfFunctions;     // RVA from base of image

    DWORD   AddressOfNames;         // RVA from base of image

    DWORD   AddressOfNameOrdinals;  // RVA from base of image

} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;


위 구조체는 IMAGE_EXPORT_DIRECTORY의 구조체입니다.


여기에 정의되는 값은 모두 RVA입니다.


 NumberOfFunctions  실제 export하는 함수의 개수


NumberOfNames   실제 export하는 함수중 이름을 가지는 함수의 개수


AddressOfFunctions   export하는 함수의 주소 배열


AddressOfNames  함수이름의 주소배열


AddressOfNameOrdinals   ordinal 주소 배열


ordinal 이란 도데쳐 무엇일까여 바로 export function의 고유 번호 입니다.


GetProcAddress로 dll에서 함수를 가져올때 


dll제공자 에게서 함수의 고유번호를 받을떄가있는데 이떄 이번호로 가져옴니다.


예로 함수를 번호로 얻을떄와 함수 이름으로 얻을떄 입니다.


pfunc=GetProcAddress("TEST");             //함수명으로 가져올떄

pfunc=GetProcAddress(2);                       //함수 고유 번호로 얻을떄


dll 에서 함수명을 가져올려면 함수 이름 배열을 알아야하는데


address of names (name pointer table rva) 맴버의 위치로가면 4바이트씩 rva로 되어있는 값들이 있는데 그주소로 가면 함수이름이 나옴니다.


address of names 의 data 값인 000c0f64 을 raw로 변경하면 000b1364 값이나오는데 이걸 헥스 에디터로 보면


000c2f4b라는 값을 찾으실수 있습니다.


이값을 raw로 바꾸어주면 000b334b란 값이나오는데 이걸 또 헥스에디터로 가면



요렇게 이름 배열을 찾으실수 있습니다.


그러면 함수 고유 번호를 찾을수 도 알아야하느데


함수고유번호를 찾기위해서는 addressofnamesordinals(ordinals table rva) 값의 data값인 000c24a0를 raw로 바꾸면 000b28a0을 헥스에디터로 보면


2바이트씩 구성되어있는 배열을 보실수 있습니다.




이값들이 함수 고유 번호 입니다.


그런데 이값이 어떤 함수의 ordinal인지 알 수없습니다.


함수 이름배열의 원소 에서 1을 뺀 값이 ordinal값입니다.


함수의 실제 주소를 찾아갈려면 addressoffunctions의 배열에서 4바이트로되어잇는 값을 따라가시면 됨니다.


이값은rva값임니다.


그리고 디버거에서 볼수있는 주소 값들은 이값에서 imagebase값을 더하면 됨니다.

'Reversing > Windows PE' 카테고리의 다른 글

pe) reloc 섹션 제거  (0) 2014.09.17
windows pe) IAT  (0) 2014.07.25
windows pe) null패딩이 진짜 null패딩인지 확인하기  (0) 2014.07.23
windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
Posted by 준P

IAT는 Import Adress Table의 약자 이고 process, memory, DLL의 구조등에 대한내용이 있습니다.


DLL은 Dinamic Linked Libary의 약어로 프로그램에서 함수를 사용할떄 이 라이브러리에서 함수를 가져와서 사용합니다.


프로그램 안에 함수가 있으면 똑같은 함수를 여러프로그램에서 사용하는데 각 프로그램마다 가지고 있으면 자원낭비 입니다.


참고로 DOS시절에는 각프로그램이 함수를 내장하고 있었습니다.


windows nt버전이나오면서 멀티테스킹을 지우너하면서 DLL파일이 나온것입니다.


DLL이 로딩될떄 프로그램에서는 함수를 호출하고 사용이끝나면 바로 헤제하는 방법과 프로그램이 끝날때 같이 헤제하는 방법이있습니다.




ollydbg에서 오은쪽클릭후 long -adress 로 변경하시면 위와 같이 보실수 있습니다.


만약 call 75258A29를 한다면 이것은 DOS시절방식입니다.


IMAGE_IMPORT_DESCRIPTOR


이구조체는 어떤라이브러리를 포함하고있는지 나타내는 구조체입니다.


이구조체는 라이브러리를 포함하는 많큼 배열로 나타내짐니다.(여러개라는 뜻)



typedef struct _IMAGE_IMPORT_BY_NAME {

    WORD    Hint;

    CHAR   Name[1];

} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;


typedef struct _IMAGE_IMPORT_DESCRIPTOR {

    union {

        DWORD   Characteristics;            // 0 for terminating null import descriptor

        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)

    } DUMMYUNIONNAME;

    DWORD   TimeDateStamp;                  // 0 if not bound,

                                            // -1 if bound, and real date\time stamp

                                            //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)

                                            // O.W. date/time stamp of DLL bound to (Old BIND)


    DWORD   ForwarderChain;                 // -1 if no forwarders

    DWORD   Name;

    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)

} IMAGE_IMPORT_DESCRIPTOR;

typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;


프로그램에서는 라이브러리를 여러개 import 시키기떄문에 라이브러리개수많큼 위구조체를 갯수만큼 가짐니다.


그리고 구조체의 마지막은 null 구조체로 끝남니다.



 함목

 의미

 OriginalFirstThunk

 INT(Import Adress Table)의 주소(RVA)

 Name

 Library 이름 문자열의 주소 (RVA)

 FirstThunk

 IAT(Import Address Table)의 주소 (RVA)



참조

*pe해더에서 table은 배열을 뜻합니다.

*IAT와INT는 long type 배열이고 null로 끝남니다.(크기가 명시되어있지않음)

*INT에서 각 원소의 값은 IMAGE_IMPORT_BY_NAME 구조체배열 입니다.(IAT도 같은 값을 가지는 경우도 있습니다,)

*INT와IAT의 크기는 같아야합니다.



출처 리버스코어 http://reversecore.tistory.com


간단하게 정리한 그림입니다.

pe view 에서도 IAT와 INT는 같은 값을 가지고 있습니다.





주소만 다를 뿐 DESCRIPTION과 VALUE의 값은 같습니다.



'Reversing > Windows PE' 카테고리의 다른 글

pe) reloc 섹션 제거  (0) 2014.09.17
windows pe) EAT  (0) 2014.08.06
windows pe) null패딩이 진짜 null패딩인지 확인하기  (0) 2014.07.23
windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
Posted by 준P

파일이 메모리에 올라가면 null공간이 생기는데 이공간에 dll injection이나 악성파일등을 넣을수있습니다,


허나 이null공간이 나중에 메모리에서 사용하는공간이면 에러가 나옴니다.


이null공간이 진짜null공간인지 알아보겟습니다.





명칭

값 

기능 

virtual size 

00002c56 

메모리섹션의  크기

RVA

00006000 

메모리섹션의 시작 

size of raw data

00002e00 

파일 섹션의 크기 

 pointer to raw data

00005200 

파일 섹션의 시작 


파일이 메모리에 로딩되면 크기는 달라짐니다.


rdata의 파일의 크기는 2e00이지만 메모리에서 사용하는 크기는 2c56입니다.


파일 섹션에서 메모리에서 사용하는 크기를 뺸 공간이 실제로 사용하지 않는 공간 입니다.



2e00에서 2c56을 뺸 나머지 공간이 null패딩입니다.


간단히 계산기를 만들어서 계산을 해보앗습니다.


1aa만큼의 공간이 null공간입니다.


그렇다면 파일섹션의 시작값과 파일섹션의 크기를 더하면값에서 1aa값을 뺴면 그값에서 1aa크기만큼은 null공간 입니다.


파일 섹션의 시작값은 5200이고 파일섹션의 크기는 2e00입니다.


이값을 더하면 8000입니다. 


8000에서 1aa값을 빼면 7e56입니다.


7e56부터 8000까지는 null공간입니다.




실제로도 null로 구성되어 있습니다.

'Reversing > Windows PE' 카테고리의 다른 글

windows pe) EAT  (0) 2014.08.06
windows pe) IAT  (0) 2014.07.25
windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
windows pe) NT_HEADER 상  (0) 2014.07.10
Posted by 준P

windows pe에서 RVA(file offset) to RAW는 매우 중요합니다.


RVA에서 RAW로 변환하기위해서는 간단한 식이 있는데요


RAW(file offset)=RVA-VA+PointerToRawData)


입니다.


간단하게 textview에서 찾아보겟습니다.


일단 IMPORT_TABLE구조체가 중요하기 이 구조체의 RAW(file offset)을 알아보도록하겟습니다.




IMPORT_TABLE의 RVA의 값은 84cc입니다.


84CC는 .rdata의 섹션해더에 있습니다.


섹션 뒤지면서 위치를 대략 적으로 찾으시면 됨니다.


이섹션해더에가서 VA랑 PointerToRawData의 값을 가져오시면됨니다.




어 근데 VA는 없고 RVA만 있는데요?


pe view는 메모리 로딩했을때를 나타내므로 RVA가 나오기때문 입니다.


실제 VA값이 여기선 RVA값이라고 생각해주세요



Pointer To RawData의 값이 5200입니다.


84CC-6000+5200은 76CC이므로 


IMPORT_TABLE의 RAW(file offset)의 값은 76CC입니다.


그렇다면 이제 확인해봐야겟져?


hexedit로 76cc의 데이터와 pe view로본 86cc의 값을 비고하시면 됨니다.




이 둘을 비교하시면 서로 같습니다.


오른쪽 value로 비교하시지 마시고 hex코드를 비교해보시기 바람니다.


예외로 RAW(file offset)의 값이 안나오는경우가있는데


이경우는 virtual size의 값이 Size Of RAW Data보다 크기때문 입니다.


'Reversing > Windows PE' 카테고리의 다른 글

windows pe) IAT  (0) 2014.07.25
windows pe) null패딩이 진짜 null패딩인지 확인하기  (0) 2014.07.23
windows pe)NT_HEADER 하  (0) 2014.07.11
windows pe) NT_HEADER 상  (0) 2014.07.10
windows pe)DOS_STUB  (0) 2014.07.10
Posted by 준P

IMAGE_FILE_HEADER 의 구조체중 마지막인 Optional Header입니다.


Optional Header는 NT_HEADER중 가장크기가크며 이값이 잘못 설정되면 실행이되지 않습니다.


typedef struct _IMAGE_DATA_DIRECTORY {

    DWORD   VirtualAddress;

    DWORD   Size;

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

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;


주석은 제거하엿습니다.


magic은 32비트이면 010B값을 가지고 64비트이면 020B값을 가짐니다.


IMAGE_OPTIONAL_HEADER32인경우 010B값을  IMAGE_OPTIONAL_HEADER64 구조체인경우 020B값을 가짐니다.


AdressOfEntryPoint


AdressOfEntryPoint는 EP(Entry Point)의 RVA값을 가짐니다.


EP는 프로그램에서 최초로 시작되는 코드의 시작주소입니다.


ImageBase


프로세스의 가상메모리는 0~FFFFFFFF까지 같습니다. (64비트에서는 0~FFFFFFFFFFFFFFFF까지 같습니다)


ImageBase는 이 엄청난 범위에서 pe파일의 시작 주소를 나타냄니다.


EXE,DLL파일은 유져 메모리영역(user memory)인 0~7FFFFFFF 범위에 로딩되고 


SYS파일은 커널메모리 영역인 80000000~FFFFFFFF범위에 로딩됨니다,


일방적으로 개발도구에서는EXE파일의ImageBase의 값은 00400000입니다,(다른 값도 가능합니다,)


DLL파일의 경우 10000000입니다 이 또한 다른 값이 가능합니다.


pe로더는 pe파일을 실행시키기위해 프로세스를 생성합니다.


그리고 파일을 메모리에 로딩한후 EIP 레지스터값을 ImageBase + AddressOfEntryPoint 값으로 세팅합니다.



SectionAlignment, FileAlignment


pe파일의 body부분은 많은 section으로 나누어져있습니다.


메모리에서 섹션의 최소단위는 SectionAlignment입니다.


파일에서 섹션의 최소단위를 나타내는것이 FileAlignment 입니다.


하나의 파일안에서 SectionAlignment와 FileAlignment값은 서로 같을수도 있고 다를수도 있습니다.


파일 메모리의 섹션의 크기는 각각SectionAlignment와 FileAlibgnment의 베수가 할당됨니다.


SizeOfImage


SizeofImage는 pe파일이 메모리에 로딩되었을떄 가상메모리에서 PE Image가 차지하는 크기를 나타냄니다.


SizeOfHeader


SizeofHeader는 pe전체의 크기를 나타냄니다. 이값은 Alibgnment값의 배수여야합니다.


파일시작에서 SizeOfHeader옵셋만큼 떨어진위치에서 첫번쨰 섹션이 위치합니다.


sub system


이값을 보고 시스템 드라이버파일인지 일반실행파일인지 콘솔실행파일인지 알수있습니다.


값 

의미 

비교 

 Driver fIle

시스템 드러이버(ex: ntfs sys)

 2

GUI File 

창기반 어플리케이션 

 3

 CUI File

콘솔기반어플리케이션 


NumberOfRvaAndSizes


NumberOfRvaAndSizes는 IMAGR_OPTIONAL_HEADER32구조체의 마지막 맴버인 data Directory 배열의 개수를 나타냄니다.


IMAGE_NUMBEROF_DIRECTORY_ENTRORY는 16이라 정이되어잇지만


pe로더는 numberofrvaandsizes의 값을보고 배열을 크기를 인식합니다 16이 아닐수도 있습니다.


Data Directory


Data Directory는 IMAGE_FATA_DIRECTORY 구조체 의 배열로 


각항목마다 정의된값을 가짐니다.


배열의개수는 16개이며 define으로 갯수가 정해저있습니다.


typedef struct _IMAGE_DATA_DIRECTORY {

    DWORD   VirtualAddress;

    DWORD   Size;

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;


#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16


DataDirectory

DataDirectory[0] = Export Directory

DataDirectory[1] = Import Directory

DataDirectory[2] = Resource Directory

DataDirectory[3] = Exception Directory

DataDirectory[4] = Security Directory

DataDirectory[5] = Basereloc Directory

DataDirectory[6] = debug Directory

DataDirectory[7] = COPYRIGHT Directory

DataDirectory[8] = Global Directory

DataDirectory[9] = TLS Directory

DataDirectory[A] = LOAD_CONFIG Directory

DataDirectory[B] = BOUND_IMPORT Directory

DataDirectory[C] = IAT Directory

DataDirectory[D] = DELAY_IMPORT Directory

DataDirectory[E] = COM_DESCRIPTOR Directory

DataDirectory[F] = Reserved Directory


여기서 Directory는 구조체의 배열입니다.


여기서 


DataDirectory[1] = Export Directory

DataDirectory[2] = Import Directory

DataDirectory[3] = Resource Directory

DataDirectory[9] = TLS Directory


가 중요함니다.


이것들은 나중에 같이 설명할것으므로 눈으로만 보시길 바람니다.

'Reversing > Windows PE' 카테고리의 다른 글

windows pe) null패딩이 진짜 null패딩인지 확인하기  (0) 2014.07.23
windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe) NT_HEADER 상  (0) 2014.07.10
windows pe)DOS_STUB  (0) 2014.07.10
windows pe) pe 해더 DOS_HEADER  (0) 2014.07.09
Posted by 준P

IMAGE_NT_HEADERS 구조체는 총 3가지로 구성되어있으며 크기는 F8입니다.


Signature,  FileHeader, OptionalHeader 구조체 맴버로 구성되어있습니다.


FileHeader, OptionalHeader는 또 다른 구조체로구성되어있습니다.


signature는 ("PE"0000)로 구성되어 있습니다.


만약 64비트라면  _IMAGE_NT_HEADER64를 사용합니다.


참고로 _IMAGE_NT_HEADERS 구조체입니다.


typedef struct _IMAGE_NT_HEADERS {

    DWORD Signature;

    IMAGE_FILE_HEADER FileHeader;

    IMAGE_OPTIONAL_HEADER32 OptionalHeader;

} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;


typedef struct _IMAGE_NT_HEADERS64 {

    DWORD Signature;

    IMAGE_FILE_HEADER FileHeader;

    IMAGE_OPTIONAL_HEADER64 OptionalHeader;

} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;


두번쨰로 FILE_HEADER 구조체는 파일의 개략적인 속성을 나타냄니다.


일단 구조체를 살펴보시면 


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;


Machine,  NumberOfSections, TimeDateStamp,   PointerToSymbolTable,  NumberOfSymbols, SizeOfOptionalHeader,  Characteristics


총7가지로 이루어져있습니다.


machine은 cpu의 고유한 값입니다.


windows 에서는 이렇게 정의되어있습니다.


#define IMAGE_FILE_MACHINE_UNKNOWN           0

#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.

#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian

#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian

#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian

#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2

#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP

#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian

#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3

#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian

#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian

#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5

#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian

#define IMAGE_FILE_MACHINE_THUMB             0x01c2  // ARM Thumb/Thumb-2 Little-Endian

#define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian

#define IMAGE_FILE_MACHINE_AM33              0x01d3

#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian

#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1

#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64

#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS

#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64

#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS

#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS

#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64

#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon

#define IMAGE_FILE_MACHINE_CEF               0x0CEF

#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code

#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)

#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian

#define IMAGE_FILE_MACHINE_CEE               0xC0EE


제 컴퓨터는 0x8664 라고 써져잇으니 AMD64 이군요 (intel 에서는 리틀에디안 사용!!!)


number of section 말그대로 섹션의 수 입니다.


0006 이라고 써져 잇으니 6개인가봄니다.


실제로 peview 로 보시면 6개나옴니다.




IMAGE_SECTION_HEADER ~라고 보이시져 이게 섹션 입니다.


이렇게 생긴게 6개 보이네요 peview 사용방법을 익히시는것도 좋습니다.


TimeDateStamp는 수정한 날자인데 오류가 있는지 2009년이네여




참고로 속성에서 보이는 날자는 한국시간입니다. UTC는 표준시이므로 9시간을 더해주셔야합니다.



PointerToSymbolTable은 symboltable로가는 포인터 주소 입니다.


coff는 많은 프로그램을 하나로 모아 메모리에 옮기는 과정이 매우 복잡하고 많은시간이 필요해서 미국 AT&T에서 고안해낸 방법이다.


같은 성질을 가지는것은 하나로 합친것을 섹션이라하고 언어에 따라 섹션이 달라진다. 그리고 프로그램의 개수와 상관없이 프로그램을 몇개의 색션으로 구분하기 떄문에 간단해진다.


numberofsymbols 


말그대로 심볼의 개수 입니다. PointerToSymbolTable 이 정의 되었다면 symbol의 갯수를 같는다.


헌데 요즘은 symbol의 크기가 커져서 사용하지 않는다고 한다,,,,


characteristics는 파일 속성을 나타내는값으로  실행가능한 형태인지 혹은 dll파일인지 정보들이 bit or 형식으로 조합됨니다.


#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.

#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved external references).

#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.

#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.

#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Aggressively trim working set

#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses

#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.

#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.

#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file

#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.

#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.

#define IMAGE_FILE_SYSTEM                    0x1000  // System File.

#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.

#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine

#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.


참고로 characteristics 값애 0002 값이 없는경우 (#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002)가 있는데요

obj나 resoure dll 파일같은경우 입니다.



'Reversing > Windows PE' 카테고리의 다른 글

windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
windows pe)DOS_STUB  (0) 2014.07.10
windows pe) pe 해더 DOS_HEADER  (0) 2014.07.09
windows pe) pe 구조  (0) 2014.07.05
Posted by 준P

DOS_HEADER 밑에는 dos환경에서 돌아갈 코드가 있습니다.


dos stub는 있어도 되고 없어도 되는 옵션 입니다.


싹다그리 지워도 별상관없는 구조체란것이조 



이렇게 싹지워도 상관없습니다.


dos stub에는 코드와 데이터의 혼합으로 이루어져있으며 


windows OS 에서 실행하면 이코드는 무시됨니다.


pe파일로 인식하기 떄문에 이코드는 아예무시가됨니다. dos 환경에서 실행하거나 debug 툴로 열지않으면 실행되지않습니다.



'Reversing > Windows PE' 카테고리의 다른 글

windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
windows pe) NT_HEADER 상  (0) 2014.07.10
windows pe) pe 해더 DOS_HEADER  (0) 2014.07.09
windows pe) pe 구조  (0) 2014.07.05
Posted by 준P
windows pe 해더는 많은 구조체로 이루어져있습니다.

DOS header

microsoft는 dos파일에 대한 하위 호환성을 고려해서 pe를 만들었기때문에 pe해더 앞에는 dos exeheader를 확장시킨 IMAGE_DOS_HEADER구조체가 있습니다.

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header

    WORD   e_magic;                     // Magic number

    WORD   e_cblp;                      // Bytes on last page of file

    WORD   e_cp;                        // Pages in file

    WORD   e_crlc;                      // Relocations

    WORD   e_cparhdr;                   // Size of header in paragraphs

    WORD   e_minalloc;                  // Minimum extra paragraphs needed

    WORD   e_maxalloc;                  // Maximum extra paragraphs needed

    WORD   e_ss;                        // Initial (relative) SS value

    WORD   e_sp;                        // Initial SP value

    WORD   e_csum;                      // Checksum

    WORD   e_ip;                        // Initial IP value

    WORD   e_cs;                        // Initial (relative) CS value

    WORD   e_lfarlc;                    // File address of relocation table

    WORD   e_ovno;                      // Overlay number

    WORD   e_res[4];                    // Reserved words

    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)

    WORD   e_oeminfo;                   // OEM information; e_oemid specific

    WORD   e_res2[10];                  // Reserved words

    LONG   e_lfanew;                    // File address of new exe header

  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;


IMAGE_DOS_HEADER의 크기는 40입니다.


이구조체에서 알아야하것은 


e_magic : DOS signature (4D5A "MZ")

e_ifanew: NT header의 옵셋을 표시 (파일에따라 가변의 값을가짐)



모든 pe파일은 e_magic("MZ")가 존제하며 Eifanew가 가르키는위치에 NT_header가 존체 합니다.


NT_HEADER==IMAGE_NT_HEADER 입니다,



아무 파일을 hexedit로 열면 MZ와 300c부터 300f까지 e_ifanew 를 찾으실수있습니다.


intel에서는 리틀에디안 기법을 사용하므로 거꾸로 표기를 합니다.




'Reversing > Windows PE' 카테고리의 다른 글

windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
windows pe) NT_HEADER 상  (0) 2014.07.10
windows pe)DOS_STUB  (0) 2014.07.10
windows pe) pe 구조  (0) 2014.07.05
Posted by 준P

pe는 실행 파일의 실행 형식 입니다.


pe는 32비트의 실행파일의 형태를 말하고 pe32는 64비트의 실행 파일의 형태를 말합니다.


pe 파일의 종류



 종류

주요확장자 

종류

주요확장자 

실행계열 

exe,scr 

드라이버 계열 

sys,vxd 

라이브러리 계열 

 dll,ocx,cpl,drv

오브젝트 파일 계열 

obj *pe공식에서는 obj도 pe파일로 간주 합니다


참고로 오브젝트 파일을 제외하고 다실행가능합니다.dll 이나 sys는 쉘에서 바로 실행할순 없지만 디버거 또는 서비스 등으로 실행가능합니다.


pe 파일의 기본 구조 


dos 해더부터 section header 까지 pe해더라고 하며 이 밑섹션을 바디라고 합니다.


파일에서는 offset 이라하고 메모리에서는 va (절대주소)라고 합니다.


파일이 매모리에 로딩되면 모양이 달라집니다.섹션의 크기 또는 위치등 


파일은 .text .data .rsrc로 나누어 집니다.




pe 해더의 끝부분에는 null로 이루어진 곳이있는데 null padding 이라고 하며 dll인젝션등또는 문자열 수정등 여러가자로 사용됨니다.


이 nullpadding은 컴퓨터에서 파일 메모리 네트워크 페팃등을 처리할떄 효율을 높이기위해 최소 기본단위개념을 쓰기때문에 pe파일에도 똑같이 적용된것입니다.


파일 메모리에서 섹션이 시작되는 위치는 각파일 메모리의 최소기본단위의 배수에 해당하는 위치이고 빈공간을 null로 채워버림니다,


va와 rva


va(절대주소)는 프로세스 가상 메모리의 절대주소를 말하며 rva는 어느 기분(imagebase)에서부터의 상대주소를 말합니다.


rva+imagebase=va


pe해더내에서는 rva(상대주소)형태로된것이 많습니다. 이유는 pe파일이 프로세스 가상메모리의 특정위치에 로딩되는 순간 이미 그위치에 다른pe파일(dll) 로딩되어있을수도 있습니다.


이떄재배치(relocation)를 통해서 다른위치에 로딩되야하는데 만약 pe해더정보가 va(절대주소)로 되어있다면 정상적인 엑셋스가 되지 않기 떄문에 rva(상대주소)로 해주면 재배치가 이일어나도 기준위치에 대한 상대주소가 변하지 않기떄문에 문제없이 원하는 정보에 엑세스할수있습니다.



'Reversing > Windows PE' 카테고리의 다른 글

windows pe) RVA to RAW(file offset)  (0) 2014.07.15
windows pe)NT_HEADER 하  (0) 2014.07.11
windows pe) NT_HEADER 상  (0) 2014.07.10
windows pe)DOS_STUB  (0) 2014.07.10
windows pe) pe 해더 DOS_HEADER  (0) 2014.07.09
Posted by 준P