04 dll 분석

19
04 DLL 분분 01 분 분분분 분분분분분 분분 분분분 E-mail : [email protected] Writing by Ilsun Choi 1

Upload: ilsun-choi

Post on 17-Aug-2015

13 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: 04 dll 분석

Writing by Ilsun Choi 1

04 DLL 분석01 부 리버스 엔지니어링 기본

최일선

E-mail : [email protected]

Page 2: 04 dll 분석

Writing by Ilsun Choi 2

Index1. EXE 와 DLL

1) 공통점2) 차이점

2. DLL 의 번지 계산법3. 재배치를 고려한 방법4. 번지 고정5. 익스포트 함수6. DllAttach/DllDetach 찾기7. 패킹된 DLL 의 DllMain() 찾기8. DisableThreadLibraryCalls 로 찾기

E-mail : [email protected]

Page 3: 04 dll 분석

Writing by Ilsun Choi 3

1. EXE 와 DLL > 1) 공통점 DLL 에도 같은 PE Header 가 존재

DLL 역시 C/C++ 로 프로그래밍 구조가 비슷하다 .

E-mail : [email protected]

Page 4: 04 dll 분석

Writing by Ilsun Choi 4

1. EXE 와 DLL > 2) 차이점 WinMain() 대신 DllMain() 이 존재

DLL 은 주로 Export 함수 /EXE 는 주로 Import 함수를 가짐

DLL 파일은 하나의 EXE 에서 여러 개를 로딩할 수 있음

DLL 파일끼리 주소가 겹칠 경우 재배치를 함

E-mail : [email protected]

Page 5: 04 dll 분석

Writing by Ilsun Choi 5

2. DLL 의 번지 계산법 [1/3] IDA 로 디스어셈했을 때와 DLL 이 실제 메모리에 올라갔을 때 주소가 다르기에 초보들이 주로 혼동

단지 Image Base 가 달라졌기 때문 !

PE View 로 본 kernel32.dll(0x7C800000) 와 TestDLL2.dll( 기본 설정 : 0x10000000) 의 Im-age Base

E-mail : [email protected]

Page 6: 04 dll 분석

Writing by Ilsun Choi 6

2. DLL 의 번지 계산법 [2/3] 직접 제작한 DLL 은 0x10000000 으로 기본 고정되어 있기 때문에 겹칠 수 있음

##TIP2 를 참고하여 TestDLL3 를 제작하여 테스트함 ( 소스는 TestDLL2 와 같다 )

TestDLL3 역시 0x10000000 Image Base 를 가지고 있으나 로딩 시에는 다른 주소로 로딩됨

E-mail : [email protected]

Page 7: 04 dll 분석

Writing by Ilsun Choi 7

다음과 같은 방법으로 번지 계산이 가능하다 .( 저자의 글로는 너무 간단하여 계산이라고 하기에 부끄럽다 함 )

앞서 실습한 TestDLL3.dll 의 경우

E-mail : [email protected]

2. DLL 의 번지 계산법 [3/3]

Base Address + Base of Code0x10000000 + 0x1000( 파일 )0x003B000 + 0x1000

ex) 0x10001000 에 로딩되는 코드는 0x003B1000 으로 가면 찾을 수 있다 !

Page 8: 04 dll 분석

Writing by Ilsun Choi 8

3. 재배치를 고려한 방법 재배치된 DLL 파일에서 어떤 변화가 일어났는지 살펴보자 .

1. push 문

2. CALL 문

E-mail : [email protected]

Page 9: 04 dll 분석

Writing by Ilsun Choi 9

4. 번지 고정 DLL 파일에 다음 코드를 추가하면 DLL Base Address 를 고정시킬 수 있다 .

pragma comment(linker, “/base:0x23400000 /fixed”)

로딩 주소에 다른 DLL 이 있다면 제대로 로딩되지 않을 수 있기 때문에 추천하지 않음

E-mail : [email protected]

Page 10: 04 dll 분석

Writing by Ilsun Choi 10

5. 익스포트 함수 EXE 파일은 Entry Point(EP) 가 하나뿐이지만 DLL 의 경우는 익스포트 함수의 수만큼 존재

Dependency Walker 로 분석한 TESTDLL2.DLL 함수의 수 : 2 개

IDA 를 통해 확인한 EP : Export 함수 (2) + DLLMain(1) = 3

E-mail : [email protected]

Page 11: 04 dll 분석

Writing by Ilsun Choi 11

6. DllAttach/DllDetach 찾기 [1/5] DLL 이 로딩되자마자 해야 할 작업이 있다면 DllMain() 에 코드를 삽입한다 .

DLLMain() 의 원형

fdwReason 의 값에 따라 분기

E-mail : [email protected]

BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpRes);

Page 12: 04 dll 분석

Writing by Ilsun Choi 12

다음과 같이 DllMain 을 작성하여 컴파일

E-mail : [email protected]

6. DllAttach/DllDetach 찾기 [2/5]

Page 13: 04 dll 분석

Writing by Ilsun Choi 13

DllMain() : Switch 분기 ( 책과 많이 다름 )

E-mail : [email protected]

6. DllAttach/DllDetach 찾기 [3/5][EBP+C] 로부터 EAX 에 fdwReason 값을

받음EAX 값을 [EBP-8] 로 옮긴 후

0 이나 1 과 같은지 비교하여 분기한다 .

Page 14: 04 dll 분석

Writing by Ilsun Choi 14

DllMain() : Switch 분기 ( 책과 많이 다름 )

E-mail : [email protected]

6. DllAttach/DllDetach 찾기 [4/5]

0 과 같으면 PROCESS_ATTACH 를 출력

1 과 같으면 PROCESS_DETACH 를 출력

어떤 값과도 같지 않으면 무조건 분기문 (JMP)에 의해서 함수 에필로그를 진행

Page 15: 04 dll 분석

Writing by Ilsun Choi 15

IDA 를 통해 DllMain() Text 를 검색하면 바로 찾을 수 있다 .

E-mail : [email protected]

6. DllAttach/DllDetach 찾기 [5/5]

Page 16: 04 dll 분석

Writing by Ilsun Choi 16

7. 패킹된 DLL 의 DllMain() 찾기 패킹된 바이너리인 경우에는 DllMain() 을 수동으로 찾아야 한다 .

OllyDbg 를 실행하여 CPU 창 – [ 마우스 오른쪽 ] – [Search for] – [Binary String]

“8B 44 24 08 83 E8 00 74( 책에서 나온 패턴 )” 을 입력( 실습 결과는 “ 8B 45 0C 89 45 F8 83 7D”)

E-mail : [email protected]

Page 17: 04 dll 분석

Writing by Ilsun Choi 17

확인을 누르면 패턴이 일치하는 지점을 찾아줌

분석이 어렵다는 데미다 (Themida) 로 패킹해도 결과는 같음 이 패턴을 피해가기 쉽지 않음

특정 기능을 위해서 어떤 코드를 사용할 수 밖에 없는 패턴을 이용함( 휴리스틱 패턴 , heuristic pattern)

E-mail : [email protected]

7. 패킹된 DLL 의 DllMain() 찾기

Page 18: 04 dll 분석

Writing by Ilsun Choi 18

8. DisableThreadLibraryCalls 로 찾기 DisableThreadLibraryCalls()?

DLL_THREAD_ATTACH/DLL_THREAD_DETACH 와 연관( 스레드가 생성 / 종료될 때 마다 호출 )

스레드가 생성 / 소멸을 반복한다면 DllMain() 이 반복 호출되어 , 프로세스에 부하

의도적으로 DllMain() 호출을 막는 함수가 바로 DisableThreadLibraryCalls() 이다 !

많은 개발자들이 습관처럼 이 함수를 Dll_THREAD_ATTACH 에 넣는 편이므로이 IAT 를 역추적하면 DllMain() 을 찾을 수 있음

E-mail : [email protected]

Page 19: 04 dll 분석

Writing by Ilsun Choi 19

참고문헌 리버싱 엔지니어링 바이블 , 강병탁 지음

E-mail : [email protected]