프로세스가 실행된 처음부터 디버깅해보고 싶을 땐 디버거에서 실행하면 되죠. 이미 실행중인 프로세스를 디버깅해보고 싶을 땐 Attach해서 디버깅하면 되구요... 서비스를 디버깅하는 경우에도 보통 디버거를 서비스 프로세스에 Attach 해서 디버깅하면 됩니다. 이건 너무 쉽죠. ^^;;;


그런데 서비스 프로세스를 처음 실행될 때(Entry Point)부터 디버깅하고 싶을 때는 어떻게 해야 할까요?? 서비스 프로세스는 Services.exe에 의해 실행됩니다... 내가 실행하는게 아니니 디버거에서 실행하여 디버깅할 수가 없죠... 서비스를 먼저 실행한 다음에 디버거를 Attach하려고 하면 벌써 디버깅하려고 하는  부분은 지나가버릴 것입니다. 이럴 때 사용할 수 있는 Tip을 알려드리고자 합니다.


Step 1. "Image File Execution Options" 레지스트리를 사용하여 디버깅하는 방법 (XP이전)

"Image File Execution"이란 레지스트리를 이용하면 특정 프로세스가 실행될 때 자동으로 디버거를 Attach시킬 수 있습니다. 보통 제 3의 프로세스에 의해 실행되는 자식 프로세스를 디버깅할 때 사용하죠. 여기서 얘기하는 윈도우 서비스도 그렇고... 별도의 Launcher에 의해 실행되는 프로세스를 디버깅할 때도 해당됩니다. (악성코드들도 많이 사용하는 레지스트리입니다.)


먼저, 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

키 밑에 서비스 실행파일 이름으로 된 서브키를 만듭니다. 그러고 나서 생성한 키 밑에 "Debugger"라는 이름의 문자열 값을 만들고, 실행할 디버거 실행파일 경로를 적어줍니다. 

서비스 실행파일의 이름이 "LeoBrokerSvc.exe"라고 가정하면 다음과 같이 되겠죠?

위와 같이 등록해준 다음에 서비스를 실행해주면 자동으로 디버거(WinDbg)가 실행되고, 서비스 프로세스가 시작 단계에서 Attach되어 Break걸린 상태가 됩니다. 자 이제 원하는대로 디버깅을 진행하시면 되겠습니다~ ^^

이때, Process Explorer로 확인해보면 다음과 같이 Service 프로세스가 Services.exe가 아닌 WinDbg에 의해 실행된 것을 알 수 있습니다.


Step 2. "Image File Execution Options" + WinDbg Network Debugging (Vista 이후)

위와 같은 방법으로 서비스 프로세스를 디버깅할 수 있습니다만... Vista 이후에서 이런 방법을 사용하려고 하면 좀 문제가 생깁니다... 그것은 디버거가 실행은 되는데....  디버거가 Session 0 (서비스 세션)에서 실행되기 때문에 디버거의 UI가 보이지 않는다는 것이죠... ㅋㅋㅋ

이럴 때는 "Image File Executione Options" 레지스트리 외에도 두가지 팁이 더 필요한데요....

1. "Image File Execution Options"에 의해 실행된 디버거를 별도의 PC에서 원격 조종 (일명 "Remote Debugging" 혹은 "Network Debugging"이라고 하죠.)

2. "서비스 세션이므로... GUI가 제공되는 WinDbg 대신 WinDbg의 콘솔 버젼인 "cdb.exe"를 사용.


리모트 디버깅의 개념이 생소하신 분은 다음 포스트를 먼저 살펴보시기 바랍니다.

http://kuaaan.tistory.com/219


일단 리모트 디버깅을 하려면 다음과 같이 2대의 PC가 필요합니다. (VM도 상관없습니다.)

그림과 같이 디버거를 실행할 원격PC를 "Debugger PC", 디버깅을 당할 프로세스가 실행되는 PC를 "Debuggee PC"라고 부르도록 하겠습니다.

1) 먼저 Debuggee PC의 "Image File Execution Options" 탭에 다음과 같이 디버거를 등록합니다. (아래의 예는 네트워킹에 10000/TCP 포트를 사용하는 경우의 예입니다.)

"C:\Program Files\Debugging Tools for Windows (x86)\cdb.exe" -server tcp:port=10000


2) 그러고 나서 서비스를 시작시킵니다. 그러면 서비스가 "Running" 상태로 바뀌지 않고 "Start Pending"(시작하는 중)으로 남아있게 됩니다. 

3) 이때 재빨리 Debugger PC에서 아래와 같이 원격 디버깅 모드로 WinDbg를 실행시킵니다. 

- 192.168.100.63은 Debuggee PC의 IP주소입니다.

C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x86>windbg.exe -remote tcp:server=192.168.100.63,port=10000



그러면 아래와 같이 디버거가 실행되면서 원격 Debuggee PC 의 "LeoBrokerSvc.exe"  프로세스에 Attach된 상태가 됩니다.

이 상태에서 WinDbg 명령을 실행하면 원격 Debuggee PC에 있는 "LeoBrokerSvc.exe" 프로세스를 대상으로 명령이 실행됩니다.


이제 원하시는 대로 디버깅을 진행하시면 되겠습니다~~~ ^^;;;



Tip 1. 서비스 시작 Timeout 값 수정하기

위와 같은 방법으로 서비스 프로세스를 디버깅할 수 있습니다만, 실제로 서비스 상태가 "Running"으로 변경되기 전 부분을 디버깅을 진행하다보면 "30초" 가 지나면 서비스 프로세스가 Terminate되는 문제 때문에 디버깅이 곤란해집니다. 따라서 이 Timeout 값을 길게 늘려줄 필요가 있습니다. 다음과 같이 레지스트리를 수정하시면 됩니다.

1. HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control 키에 ServicesPpeTimeout이라는 DWORD값 생성 (디폴트로 해당 값 없음.)

2. Timeout으로 사용될 충분히 긴 값(밀리세컨)을 설정 (예 : 86400000) 

3. 리부팅


Tip 2. "Image File Execution Options" 수정 후 리부팅 중 PC가 멈출 때

위와 같은 방법으로 Image File Execution에 등록된 서비스 프로세스가 "부팅시 자동시작" 되는 서비스인 경우에는 Debuggee PC 를 리부팅하게 되면 부팅이 늦어지거나 멈추게 됩니다. (조금만 생각해보시면 이유를 금방 알 수 있지만... 모르는 상태에서 처음 이런 일을 겪으면 당황스럽죠. ^^)

이럴 때는 Debugger PC에 Windbg를 원격으로 접속시켜서 멈춰있는 서비스에 Attach 한 다음 "F5" (go)를 눌러주시면 됩니다. ^^


Tip 3. 원격 디버깅 완료 후 Debuggee 프로세스를 Terminate시키는 방법

원격으로 디버깅을 마치고 Debugger PC 에서 WinDbg를 종료시키거나 "q" 명령으로 디버깅을 마치게 되면... 좀 당황스러운 일이 생깁니다. Debuggee PC에서 Debuggee Process가 종료되지 않아요... 심지어 작업관리자에세 직접 Terminate 시켜도 안죽습니다... 당황스럽죠.. ㅋㅋ

이것은 Debuggee PC가 디버거(cdb.exe)에 의해 Attach된 상태이기 때문입니다. 이럴 땐 다음의 둘 중 한가지 방법으로 종료시켜주시면 됩니다.

1. Debugger PC의 WinDbg에서 "q" 명령 대신 "qq" 명령으로 디버깅을 종료

2. Debuggee PC에서 작업관리자를 실행시켜 디버거 프로세스 (cdb.exe 혹은 windbg.exe 등)을 Terminate




Posted by kuaaan
,


사랑합니다. 편안히 잠드소서