티스토리 뷰
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
목적:
자 이번글에서는 프로그램에서 Import Table에 대하여
알아볼것이다. Import Table이란 프로그램이
Dll에서?Export 해주는 함수들을 동적 Import 해주는
집합?구조체이다. 이번 글을 알기위해서는
10번 RVA에 관한 강좌를 꼭 알아야만 한다.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
타켓 파일: 다운받기
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
타켓 파일의 구조:
우선?PE 시그니처로 부터 0x80 의 위치에는??
Import Directory?의?RVA 값이 들어있다. 우리의
타겟 프로그램의?PE 시그니처는 0xB9 임으로
0xB9+0x80=0x139 부터 Import Directory?의 RVA
값이 있다는 것을 알수 있다.
위의 그림을 보면 0x139 의 위치에 있는 값이
50 20 00 00 인것을 알수 있다. 이는 RVA 값
0x2050을 뜻한다. RVA 0x2050은 FileOffset
0x850 이다. 0x850으로 가보자.
FileOffset 0x850즉 Import Directory에는 다음과 같은
값들이 들어있다. 이 값들은 0x14개씩이 한개의
Image_Import_Descriptor?이다.?우리의 타겟?프로그램
에는?0x850 부터?0x863 까지?첫번쨰 Ima_Imp_Des
이고 0x864 부터 0x877 까지 두번쨰 Ima_Imp_Des
0x878 부터 0x88B 까지가 세번쨰 Ima_Imp_Des 이며
마지막 0x88C 부터 0x89F 까지의 0x14만큼의?00은
Import Directory의 끝을 알리는 것이다.따라서 우리의
타겟 프로그램은 3개의 DLL에서 함수를 Import 하여
쓰고 있다는 말이 되는것이다.
Image_Import_Descriptor?의 구조는 밑과 같다.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
0x0~0x3????:? Dword?? OriginalFirstThunk
0x4~0x7????:??Dword?? TimeDateStamp
0x8~0xB??? : ?Dword?? ForwarderChain
0xC~0xF??? :??Dword?? Name
0x10~0x13 :? Dword?? FirstThunk
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
여기서 TimeDateStamp 와 ForwarderChain은 00으로
셋팅하여 주며 Name은 DLL의 이름이 있는 주소의
RVA값이 들어있다.OriginalFirstThunk?나 FirstThunk는
Image_Thunk_Data의 시작지점의 RVA값이 들어있다.
우선 첫번쨰Ima_Imp_Des의 Name은 무언지 알아보자
0x850+0xC=0x85C~0x85F 이 Name 값인데
CA 21 00 00 이란 값이 들어 있음을 볼수 있다.
이는 RVA 0x21CA 를 뜻한다. RVA 0x21CA를
FileOffset으로 나타내기 위해 다음과 같은 식을 사용?
RVA(0x21CA)-VirtualOffset(0x2000)+RawOffset(0x800)
즉 FileOffset은 0x9CA 임을 알수있다.
위의 그림과 같이 0x9CA의 위치에는 user32.dll 이라는
것을 확인할수 있으며 이와 같은 방법으로 두번째
Ima_Imp_Des의 Name은 0xA0A 즉 kernel32.dll 이고
세번쨰 Ima_Imp_Des은 0xA26 즉 gdi32.dll 이라는
사실을 알수있다.
이제 두번쨰 OriginalFirstThunk 또는 FirstThunk가
포인트 하는 Image_Thunk_Data에 대하여 알아보자.
우선 위에서 왜또는이라는 말을 썻는가 하면 가끔 보면
OriginalFirstThunk의 값이 00 으로 셋팅된것을 볼수있다
그럴떄는 FirstThunk에 Image_Thunk_Data의 RVA값이
들어 있다는 것을 알아두자.
위의 그림은 첫번쨰 Ima_Imp_Des의 OriginalFirstThunk
값이 B8 20 00 00 임을 보여준다. 이는 RVA 0x20B8
로서 FileOffset으로 바꾸어 주기 위해 밑에 식을 사용
RVA(0x20B8)-VirtualOffset(0x2000)+RawOffset(0x800)
위 식을 사용하여 RVA 0x20B8의 FileOffset값 0x8B8
즉 Image_Thunk_Data의 시작지점을 알수 있다.
위의 그림에서 보듯이 0x8B8 부터 13개의 RVA값들이
들어 있고?이 RVA들은 각각?Image_Import_By_Name
의?위치를 가르키는?RVA값들이다. 맨끝 부분에는
Image_Thunk_Data의 끝을 알리는 1Word의 00으로
Image_Thunk_Data는 이루어져 있다.첫번쨰 RVA가
가르키는Image_Import_By_Name가 무언지 알아보자.
36 21 00 00 은 RVA 0x2136을 의미한다. 이를
FileOffset으로 바꾸어주면 0x2136-0x2000+0x800
=0x936이 된다.
위의 그림에서 보듯이 FileOffset 0x936 에는 Word 값의
Hint 값, Import 할?함수 이름 그리고 끝을알리는 00 으로
이루어져있음을 볼수있다.
Image_Import_By_Name 의 구조는 밑과 같다.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
0x0~0x2????:? Word???? ?Hint
0x3~0x???? :? String???? Name
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
어떤떄는 Name이 00으로 셋팅되어 있을떄가 있다.
이럴떄는 Hint 값을 통하여?함수 가 Import 되는것이다.
자 지금까지 우리는 Import Table의 구조에 대하여
알아보았다. 저는 이제 위에의 내용을 응용하여
프로그램에 새로운 함수를 Import 시키는 방법에
대해서 적을것이다.이미 이 기능을 하는 툴은?있으며
한번 알아보는 것이 좋음으로 한번 읽어 보자.
보다 시피 우리의 타겟 프로그램 의 IAT에는 새로운
Image_Import_Descriptor를 추가 시킬 공간이 없다.
이럴떄는 IAT의 위치를 옮기어 주면 된다.
우리의 IAT는 0x850 ~ 0x88B 까지이다.
이를 밑의 그림처럼 복사하여 준다.
그런 다음 Stud_PE 같은 PE파일에 섹션을 추가시킬수 있
는툴을 사용하여 해더를 추가하여 준다.
저는 위와 같이 0x300 크기의 섹션을 추가하였습니다.
우리가 새로 추가 시킨 섹션의 처음 시작지점(RawOffset)
이 0x1400이고 0x1400 부터 0x300 까지인 16FF 까지가
우리가 새로 추가시킨 색션의 크기 입니다. 이제?새로
추가 시킨 섹션에?0x3C 만큼의?IAT를 복사하여 넣을
것이기 떄문에?여기서 0x3C만큼을 밑처럼 삭제해 줍니다
그런 다음 0x1400 부터 밑처럼 IAT를 복사하여 넣습니다.
이제 PE해더에 기록되있는 ?IAT의 위치 RVA를 변경해
주어야 합니다. 우리의 타겟에 PE시그니처는 0xB9
인데 이 RVA는 PE시그니처로부터 0x80뒤에 있음으로
0xB9+0x80=File Offset 0x139에 IAT 위치에 대한 RVA
가 기록되어 있다. 0x139에는 다음과 같이 되어 있다.
50 20 00 00 은 RVA 0x2050 임으로 이것을 FileOffset
으로 변경시키면 0x2050-0x2000+0x800=0x850 이
기록되 있음을 알수있다. 이것을 우리가 IAT를 옮긴
위치인 FileOffset 0x1400으로 옮겨 주어야 한다.
0x1400-0x1400+0x5000=0x5000 이 우리가 IAT를
옮긴 FileOffset 0x1400의 RVA 값인것이다. 이제
50 20 00 00 을 00 50 00 00 으로 바꾸어 준다.
자 위의 내용을 저장하고 파일을 실행해 봅시다.
정상적으로 실행되는걸 보실수 있을겁니다.
(실수만 하지 않았다면 말이죠) 이제 새로운 함수
를 추가시켜 보죠. 어떤 함수를 추가할까 생각해
보았지만 마땅히 떠오르는게 없어서 그냥
MessageBoxA를 추가시켜 보도록 하겠습니다.
MessageBoxA는 User32.dll 에 속하는 Dll 임으로
User32.dll 을 Name으로 하는 하나의 새로운
Image_Import_Descriptor을 추가시키어 보자.
(Image_Import_Descriptor?의 구조는 강좌의 상단부 참조)
위에처럼 Image_Import_Descriptor?를 추가시키어
주었습니다. 이대로 저장하고 프로그램을 실행하면
에러가 납니다.IAT의 사이즈가 틀려졌기 떄문이죠.
PE해더에 있는 IAT사이즈 값을 수정하여 주어야 합니다.
IAT사이즈는 PE시그니처로부터 0x84위치에 존재한다.
0xB9+0x84=FileOffset 0x13D에?IAT의 사이즈가 들어있다.
위 처럼?0x13D에는 50 00 00 00 이란 값이 들어 있었다.
한개의 Image_Import_Descriptor는 0x14의 크기를 가짐
으로 3개의 DLL의 Image_Import_Descriptor 과 끝을 알리는
빈 0x14 Image_Import_Descriptor 를 합치어서 0x50이란
값이 되는것인데 우리는 하나의 Image_Import_Descriptor를
더 추가 시키어 주었음으로 이값을 0x64로 수정시키어 준
다.이로써 실수한바만 없다면 성공적으로 MessageBoxA를
프로그램에 Import 시킨것이다. 이제 Import 시켰으니 이를
쓰기 위해선 어떻게 해야할까? 밑은 MessageBoxA의 원형이다.
int MessageBoxA(핸들,문자열,제목,타입);
이는 밑과 같다.?
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Push 타입????????????? ;스택에 타입집어넣음
Push 제목????????????? ;스택에 제목집어넣음
Push 문자열?????????? ;스택에 문자열 집어넣음
Push 핸들????????????? ;스택에 핸들 집어넣음
Call?MessageBoxA의 Import_By_Name?의 주소
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
이에 대한것은 나중에 쓰도록 하죠. 지금은 시간이
없어서.:p 그럼 다음에 다시...Bye?
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'Application > Debug' 카테고리의 다른 글
[해킹] IceExt 를 이용한 화면 캡쳐하기 (0) | 2006.06.30 |
---|---|
[해킹] RAW 와 RVA 간의 계산 (0) | 2006.06.30 |
[해킹] PE 형태의 파일에 섹션 추가하기 (0) | 2006.06.30 |
[해킹] 올리 디버거에서 API에 브포 걸기 (0) | 2006.06.30 |
[해킹] What a W.P.E? (0) | 2006.06.30 |
- Total
- Today
- Yesterday
- 나비효과
- 짤방 및 아이콘
- 막장로그
- diary
- win32
- wallpaper
- Battle
- Embedded System
- Network Inspector
- Mabinogi
- Assembly
- Linux
- console
- 3D Engine
- Life News
- Tech News
- medical
- Information Processor
- 야마꼬툰
- humor
- BadCode
- cartoon
- USB Lecture
- 프리랜서로 살아남는 법
- Reverse Engineering
- network
- Web Programming
- C#
- Military
- WDB
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |