programming/windows

까먹까먹하는 PE rewrite

clarus 2011. 9. 16. 11:07
트리
- 이미지_엔티_헤더
-- 이미지_파일_헤더

-- 이미지_옵셔널_헤더32
--- 이미지_데이터_디렉토리
---- 2번째 데이터디렉토리 버츄얼어드레스 (임포트 테이블 주소)
---- 임포트 테이블은 이미지_임포트_디스크립터
---- 이미지_임포트_디스크립터 {오리지날퍼스트텅크 - 이미지_텅크_데이터 구조체 배열}
---- 이미지_텅크_데이터 (이미지_임포트_바이_네임 구조체 포인터로 해석)
----- 이미지_임포트_바이_네임 

- 이미지_섹션_헤더


이미지_엔티_헤더
{
시그너쳐 4D 5A
파일헤더 이미지_파일_헤더
옵셔널헤더 이미지_옵셔널_헤더32
}


파일헤더 이미지_파일_헤더
{
머신 : i386
넘버오브섹션 : 섹션수
타임스템프 : 생성시간
캐릭터리스틱 : exe이냐, dll이냐
}


옵셔널헤더 이미지_옵셔널_헤더32
{
어드레스오브엔트리포인트 : PE파일 실행 시 실행될 첫 번째 명령의 RVA 주소
이미지베이스 : PE 파일을 위한 로드 주소, 로드 시작 주소
사이즈오브이미지 : 메모리에 풀린 PE이미지 전체크기
사이즈오브헤더스 : 헤더와 섹션 테이블을 합친 크기
이미지_데이타_디렉토리 (구조체의 배열) : 임포트 어드레스 테이블과 같은 중요한 데이터 구조체의 RVA 값을 갖고있음
}


이미지_섹션_헤더 - 이미지_파일_헤더 구조체 멤버의 넘버오브섹션 영역에 의해 결정
{
네임 : 섹션의 이름을 가지고 있음, 최대 길이가 8바이트
버츄얼어드레스 : 섹션RVA, 메모리 로딩시 RVA 1000h를 갖고있다면 이미지베이스+1000h에 위치하게 됨
사이즈오브로우데이타 : 한 섹션 데이터의 크기
포인터투로우데이타 : 섹션의 시작을 담고 있는 파일 오프셋
캐릭터리스틱 : 섹션의 실행코드, 초기/비초기화된 데이터와 플래그를 갖고 있음
}


이미지_데이터_디렉토리 - 이미지_옵셔널_헤더32의 멤버중 하나임, 임포트 테이블 설명
{
버추얼어드레스 : 데이터 구조체의 RVA
isize : 버추얼어드레스에서 참조된 데이터 구조체의 크기
}

데이터디렉토리에는 16개의 인덱스가 있음
데이터디렉토리는 PE파일의 중요한 데이터구조체의 위치와 크기를 가지고 있음

임포트 테이블에는 각 인덱스(멤버)와 정보(인포 인사이드)가 있음
ex)
0 Exprot symbols
1 Import symbols
2 Resources
5 Base relocation
11 Bound Import
12 Import Address Table


임포트 테이블의 주소
- 2번째 데이터 디렉토리의 버츄얼어드레스


임포트 테이블은 이미지_임포트_디스크립터 구조체의 배열임


각 구조체는 PE 파일이 심볼로 import해오는 DLL에 대한 정보가 있음
(dll 5 import - 5개의 요소가 있음)


이미지_임포트_디스크립터
{
union
캐릭터리스틱
오리지널퍼스트텅크
오리지널퍼스트텅크 - 이미지_텅크_데이터 구조체 배열의 RVA
(이미지_텅크_데이터는 이미지_임포트_바이_네임 구조체 포인터로 해석)
ends
타이스탬프
포워더체인
네임
퍼스트청크
}

이미지_임포트_바이_네임
{
힌트 : Import 한 함수가 추가될때마다 1씩 증가 (베이스는 0)
네임 : 실제 임포트 함수 이름
}


PE로더가 프로그램을 실행 시킬 때 관련 DLL을 해당 프로세스 주소공간에 로드
그 후 메인 프로그램의 임포트 함수에 대한 정보를 추출
이를 이용해 메인 프로그램 함수 주소를 구하기 위해 DLL을 찾음
PE로더가 그런 함수를 구하기 위해 DLL에서 찾는 부분이 바로 익스포트 테이블