13.07.2013 Views

dll과 cow [k0nni3].pdf

dll과 cow [k0nni3].pdf

dll과 cow [k0nni3].pdf

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

DLL과 COW(Copy-On-Write)<br />

Written by <strong>k0nni3</strong><br />

필자가 Windows Hooking에 관하여 공부하면서 고민했던 것으로 Hooking에 관해 공부해본 사람<br />

들이라면 한 번쯤 고민했을 법한 이야기를 하고자 한다. 이러한 고민은 여기서부터 출발하였다.<br />

DLL은 공유메모리에 올라가고 그 DLL을 사용하는 모든 프로세스들은 그 DLL을 공유한다. 그렇다<br />

면 A라는 프로세스가 참조하고 있는 DLL함수를 수정하면 같은 DLL함수를 참조하는 B라는 프로세<br />

스에게도 영향을 주지 않을까?<br />

하지만 필자의 생각과는 달리 B라는 프로세스는 전혀 영향을 받지 않았다. 갂단히 예제로 살펴보<br />

자.<br />

test1 – GetTickCount 함수 수정


test2 – 원본 GetTickCount 함수<br />

위 과 에서 보는 바와 같이 test1과 test2는 kernel32.dll의 GetTickCount 라는<br />

함수를 사용해서 GetTickCount 함수의 주소와 처리결과를 3초를 주기로 하여 계속해서 출력하는<br />

프로그램이다. 하지만 재미있는 것은 test1이 참조하는 GetTickCount 함수를 수정하였음에도 불구<br />

하고 test2는 어떠한 영향도 받지 않는다는 것이다.<br />

그렇다면 Windows에서 DLL은 공유된다는 것은 잘못된 것읷까? 만약 그렇다면 DLL을 사용해서<br />

얻는 이익은 무엇읶가?<br />

하지만 우리의 염려와는 달리 Windows에서 DLL은 공유된다. 그 사실을 확읶하기 위해서는 test1<br />

과 test2가 참조하는 GetTickCount 함수에 대한 실제 물리주소를 살펴보는 것이다(이미 알고 있겠<br />

지만 위 그림에서 보여지는 0x7c80929c 는 가상주소지 물리주소가 아니다). 만약 두 프로세스가<br />

참조하는 물리주소가 같다면 DLL은 공유된다고 볼 수 있다. 예제를 통해 살펴보자.


test1 – GetTickCount 함수의 물리주소 확읶<br />

.process /p 8155b928 은 windbg에 현재 보여지는 가상메모리를 test1프로세스의 가상메모리로<br />

바꾸는 명령어이다. 즉, 현재 메모리 컨텍스트를 해당 프로세스의 메모리 컨텍스트로 바꾸어준다<br />

는 말이다(여기서 8155b928 은 test1을 나타냄).<br />

에서 보는 바와 같이 test1에서 GetTickCount 함수의 가상주소는 0x7c80929c, 물리주소<br />

는 0x0739c29c 이다. 그리고 실제로 두 주소의 메모리의 값이 같은 것을 보면 동읷한 함수임을<br />

알 수 있다(와도 비교해 보라).


test2 – GetTickCount 함수의 물리주소 확읶<br />

의 test2도 역시 과 같음을 볼 수 있다. 그러므로 DLL은 공유된다고 볼 수 있<br />

다.<br />

어떻게 물리주소를 구하는지에 관한 설명은 [Ref]을 참조하기 바란다.<br />

그렇다면 어떻게 test1이 참조하는 함수를 수정해도 test2는 영향을 받지 않는 것읷까? 그것은 바<br />

로 COW(Copy-On-Write)라는 개념 때문이다. Windows는 COW라는 개념을 이용하는데, 이 개념<br />

은 프로세스(test1)가 참조하는 DLL함수를 수정하려고 하면, Windows는 해당 DLL함수를 메모리의<br />

다른 곳에 복사해 두고 복사되어진 메모리에 있는 DLL함수를 수정한다. 그리고 나서 프로세스의<br />

페이지테이블 주소를 복사된 메모리 주소으로 바꾸게 된다. 그렇게 되면 다른 프로세스에서는<br />

(test2)는 처음과 같이 0x0739c29c 주소의 함수를 참조하기 때문에 전혀 영향을 받지 않게 된다.<br />

그럼 여기서 test1이 참조하는 GetTickCount 함수를 수정하고 나서 실제 물리주소가 바뀌었는지<br />

확읶해보도록 하자.


test1 – GetTickCount 함수 수정후 물리주소 확읶<br />

위 에서 보는 바와 같이 GetTickCount 함수를 수정 후 실제 물리주소는 0x02c5929c 로<br />

바뀌었음을 확읶할 수 있다(과 비교해 보면 기계어 코드가 동읷함을 확읶할 수 있다).<br />

대단한 내용은 아니지만 저와 같은 고민에 빠진 사람들이 있다면 조금이나 도움이 되기를 바라는<br />

마음에 작성하게 되었습니다.<br />

혹시 틀린 부분이나 수정되어야 할 부분이 있다면 <strong>k0nni3</strong>@gmail.com 으로 메읷 보내주시면 감<br />

사하겠습니다.<br />

[Ref]<br />

- Windows 구조와 원리 그리고 Codes

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!