아마 올리디버거나 IDA.. 등등 디버거들을 사용하면서 실행 중인 프로세스를 디버거에서 Attach를 시켜본 경험이 있을 것입니다.
보통 올디를 보면 File에서 Attach를 클릭하면 나오는 화면입니다. 실행 중인 프로세스들이 쭉 나오는데 디버깅을 원하는 프로세스를 선택해서 Attach를 시켜주면 해당 프로그램이 디버거에 붙게 될 것입니다.
그러면 여기서 생각해 볼것이 있습니다.
여기서 제가 해볼 목표는 디버거가 제 프로세스를 Attach못하도록 막아내는 것입니다.
이것도 일종의 안티디버깅 기술이 될 수 있겠네요. 여러 안티디버깅 기법이 존재하지만 그 중에서 전 API후킹을 이용해 Attach를 막는 안티디버깅 기법에 대해서 설명해 보려고 합니다.
이번에 해보려는 기법에 대해서는 예전부터 그냥 추상적으로만 생각하고 지내왔는데 DLL 인젝션, API후킹에 대해서 공부를 해보니 머리 속에서 하나씩 정리가 되면서 " 아~! 이건 쉽게 해볼 수 있겠구나!! " 라는 자신감이 생겨서 직접 해보게 됬습니다.
비록 제가 한 방법보다 더욱 쉬운 방법이 존재하며, 제가 짠 소스코드 보다 더욱 깔끔한 소스코드 또한 있을 것입니다.
고수분들은 엉망인 저의 방법에 태클, 조언 해주시면 감사하겠습니다. 이제 시작하겠습니다.
( 공부는 reversecore님 블로그에 있는 내용을 보면서 공부 했습니다. 제대로 공부하고 싶다면 reversecore님 블로그에 가셔서 차근차근 공부하시면 됩니다. 아주 자세히 설명이 되어있습니다. )
( 어떻게 동작하는지 먼저 보시고 싶은 분들은 아래 동작 영상이 있으니 먼저 보고 오셔도 됩니다. )
설명을 하기전에 제가 어떠한 방법으로 구현을 했는지 전체적인 그림을 먼저 보도록 하겠습니다.
DLL 인젝션을 사용했기 때문에 DLL파일과 EXE파일이 있습니다.
먼저 EXE파일의 동작 방법을 보도록 하겠습니다.
실행 중인 저의 프로세스가 하는 일입니다.
위 설명대로 단순히 올디가 프로세스 목록에 발견되면 제가 만든 DLL을 올디에 인젝션 시키는 파일입니다.
바로 저 파일이 제가 보호하려는 파일입니다.
이번에는 DLL입니다.
이 DLL에서 API후킹을 하는 과정이 들어있습니다.
그러면 어떠한 함수를 후킹하느냐?? 바로 kernel32.dll_DebugActiveProcess함수 입니다. 올디에서 프로세스를 Attach를 하게되면 호출되는 함수입니다. 올디에서 notepad.exe를 Attach시켰을 때 호출되는 함수와 인자를 봐보겠습니다.
위 그림은 DebugActiveProcess가 호출 됬을 때 그림입니다. 인자는 0x18A4가 들어오고 있습니다.
아래는 작업관리자에서 봤을 때 notepad의 PID값입니다. 10진수로 나와있지만 16진수로는 0x18A4로 같습니다.
이제 우리가 어떠한 함수를 후킹을 해야 되는지에 대한 정보는 얻었으니 DLL이 어떠한 동작을 하는지 보겠습니다.
그림에선 설명이 크게 없으니 글로 설명을 하도록 하겠습니다.
OllyDbg에서는 특정 프로세스를 Attach를 시키려고 하면 DebugActiveProcess함수를 호출할 것입니다.
DebugActiveProcess함수가 호출되면 후킹이 되어있기 때문에 제가 만든 함수로 점프를 하게될 것입니다.
제가 만든 함수 내부에서는 이러한 일을 하게 됩니다.
1. 보호하려는 프로세스 PID를 구한다.
2. Attach되는 PID를 구한다.
3. 다르면 그냥 DebugActiveProcess를 호출시키고
같으면 인자를 이상한 것으로 바꿔서 다시 호출을 시킨다.
위 과정이 전부 입니다. 이제 소스코드를 봐보겠습니다.
exe파일부터 보겠습니다. ( 잘 안보이시면 클릭하시면 됩니다. )
위 설명대로 올디를 찾아서 PID값 반환하고 DLL 인젝션 시키는 과정은 스레드로 구현해 놨습니다.
GET_PID함수를 봐보겠습니다.
크게 볼건 없습니다.
계속적으로 전체 프로세스 목록을 검사하면서 목록 중에 OLLYDBG가 발견되면 해당 프로세스 PID값을 반환하는 함수입니다.
DLL을 Injection시키는 소스코드를 보시겠습니다.
주석을 보시면 대충 이해가 될 것입니다.
전체적인 내용은 DLL절대경로는 해당 프로세스에 넣어주고
해당 프로세스에서 LoadLibrary함수를 사용해 인젝션 된 DLL을 호출하는 과정입니다.
아래 CreateRemoteThread 함수에 대해서 약간 궁금하신 분이 계실 것입니다. 해당 함수는 첫번째 인자인 핸들 값이 가리키는 프로세스에서 스레드를 생성시키는 함수입니다.
그러면 스레드가 만들어지는 형태와 LoadLibrary함수의 형태를 비교해보겠습니다.
함수 인자도 하나에 4Byte이구, 리턴 크기도 똑같은 4Byte입니다. 그렇기 때문에 ThreadProc대신 LoadLibrary를 사용한 것입니다. 인자로는 DLL경로가 들어있는 주소를 전달해주면 스레드가 생성이 되는게 아니라 LoadLibrary함수를 호출하는 것과 같게 됩니다. 너무 주저리 주저리 써서 이해가 될련지는 모르겠습니다.
위 과정을 수행하면 DLL 인젝션 과정은 끝나게 됩니다.
이제 DLL 소스를 보도록 하겠습니다.
위 DLL Injection과정도 전 문서에서 설명한거 같지만 다시 해봤습니다.
이 부분도 설명을 했던 부분입니다. 프로세스에 DLL이 맵핑이 되면 DllMain이 호출되고 fdwReason변수에 DLL_PROCESS_ATTACH가 셋팅이 됩니다. 내부에 있는 Hook_Code함수를 보시겠습니다.
( 소스코드는 reversecore님이 짜신 것을 완벽히 이해하고 몇 번씩 쳐보면서 느낀건데
제가 보기엔 너무 잘 짜신거 같아서 그 스타일 그대로 짰습니다. )
주석만 보신다면 전부 이해 될것입니다.
이제 훅이 설치 됬으니 우리는 DebugActiveProcess함수가 호출 될때까지 기다리면 되는 것입니다.
해당 함수가 호출하면 제가 만든 MyDebugActiveProcess함수로 갈 것입니다. 해당 함수를 보겠습니다.
이것 또한 주석을 보시면 쉽게 이해되실 것입니다.
위에서 설명했던 대로 제가 보호하려는 프로세스의 PID를 구해옵니다.
그리고 현재 Attach되려는 프로세스의 PID값과 비교를 해서 같다면 PID값을 1로 바꿔버리고 DebugActiveProcess함수를 호출하는 것입니다. 그렇게되면 올디는 어테치 할 수 없는 PID를 어테치 하려고 해서 멈춰버리고 말 것입니다.
이제 모든 과정이 끝났습니다. 어떻게 동작하는지는 영상으로 보여드리겠습니다.
영상 다운로드 ( 잘 안보이시면 .. Ctrl누르고 마우스 휠로 웹크기 조정하면 영상을 크게 볼수 있습니다. )
'My Study > Reversing' 카테고리의 다른 글
ZwContinue 함수 정체 (0) | 2010.04.29 |
---|---|
가상 머신 탐지 기법 (2) | 2010.04.26 |
프로그램 시작 시 디버거 자동으로 붙게하기 (6) | 2010.04.20 |
WinDbg 어플리케이션 크래쉬 발생 시 자동으로 붙게하기 (0) | 2010.04.20 |
피카츄배구 스피드업 ( Vista, Win 7 호환 ) (0) | 2010.04.19 |