MyDrv.sys 라는 커널모드 드라이버를 디버깅해보는 것을 생각해보자.
이런 커널모드 라이브 디버깅을 하면 MyDrv.sys 뿐만 아니라 운영체제 커널까지 디버깅할 수 있다.
이를 통해 윈도우 커널이 어떻게 생겼는지 구경할 수 있는 기회가 제공된다.
커널모드 디버깅은 이름에서 알 수 있듯이 윈도우 커널 자체를 디버깅하는 것이다.
디버거로 운영체제 커널을 디버깅하려고 멈춘다면 시스템 전체가 멈춰버린다.
따라서 디버기 시스템을 멈추면 시스템 전체가 멈춰 버리므로 디버거를 같은 시스템에서 동작시킬 수는 없다.
WinDbg는 호스트(디버거 시스템)와 타겟(디버기 시스템)을 연결하는 방법으로 네트워크, 시리얼, IEEE 1394, USB 네 가지를 지원한다.
요즘은 개발 환경에서 VMWare나 VirtualBox 같은 가상 머신이 널리 사용 되고 있기 때문에 PC 1대에서도 가상 머신을 이용해 커널 디버깅을 할 수 있다.
가상 머신을 통한 커널모드 라이브 디버깅시 pipe를 통해 연결하는 방식보다는 VirtualKD 라는 툴을 사용하면 훨씬 빠른 속도로 커널 디버깅을 할 수 있다.
※ 아래 링크에서 다운받을 수 있다.
VirtualKD - Windows Kernel Debugger Booster for Virtual Machines
Overview VirtualKD is a tool that improves your kernel debugging performance with VMWare and VirtualBox. It seamlessly integrates with WinDbg and dramatically reduces debugging latency. Just run the Virtual Machine Monitor, select a VM and press "Run debug
sysprogs.com
자세한 방법은 책 141p 참조
64비트 윈도우에서 드라이버를 로드하려면 드라이버 파일에 디지털 서명을 해줘야 한다.
디지털 서명이 없는 드라이버는 운영체제에서 금지시켜 로드되지 않는다.
비주얼 스튜디오는 드라이버를 개발하는 동안 사용할 수 있도록 테스트 인증서를 제공해 드라이버 빌드시 드라이버 파일에 디지털 서명을 할 수 있게 해준다.
정상적인 64비트 윈도우에서는 테스트 사이닝이 된 드라이버 역시 로드되지 않는다.
로드를 위해서는 운영체제의 부팅 설정에서 '테스트 사이닝 모드'를 켜줘야한다.
cmd> bcdedit /set testsigning on
또 다른 방법은 VirtualKD 설치 후 부팅 시 F8 키를 눌러 부팅 메뉴에서 '드라이버 서명 적용 안 함'을 선택해 부팅하는 것이다.
콜 스택 창에서 Arrds와 Heading 버튼을 클릭하면 Child-SP 주소와, 리턴 주소를 볼 수 있다.
Child-SP 주소를 보면 유저모드인지 커널모드인지 구분할 수 있다.
윈도우는 유저모드 스택과 커널모드 스택을 별도로 사용하므로 유저모드에서 커널모드로 진입하면 커널 주소 영역에 할당된 스택을 사용한다.
32비트 윈도우 시스템 | 64비트 윈도우 시스템 | |
유저모드 영역 | 0 ~ 0x7fffffff | 0 ~ 0x0000xxxx`ffffffff |
커널모드 영역 | 0x80000000 ~ 0xffffffff | 0xffffxxxx`00000000 ~ 0xffffffff`ffffffff |
보통의 경우 위와 같이 영역이 분리되므로, 주소의 최상위 비트로 유저모드와 커널모드를 수분할 수 있다.
예를들어 64비트 윈도우 시스템에서 00000056`3619xxxeb78 은 유저모드에서 실행 중인 함수이고,
ffffd58f`9f3f77cb는 커널모드에서 실행 중인 함수이다.
커널모드에서 kb 명령어를 통해 파라미터를 조회하는 경우에도, 64비트 윈도우에서는 파라미터 값이 대부분 쓰레기인 경우가 많다.
하지만 32비트 윈도우에서는 파라미터가 정확히 나타나기 때문에 유용하게 사용할 수 있다.
'64비트 프로그램'이나 '최적화 옵션이 적용된 경우'는 지역변수 조회시 일부 변수가 나오지 않을 수도 있다.
64비트 컴파일러는 변수를 모두 스택에 저장하지 않기 때문에 디버거도 변수를 정확히 보여주지 못하는 경우가 종종 발생한다.
이런 경우 디스어셈블리 코드를 분석해 지역변수를 찾아내거나, 최적화 옵션을 조정하는 방법을 사용해야한다.
커널모드 라이브 디버깅 내용을 보다보면 유저모드에서와 커널모드에서의 사용법은 디버거 연결만 다를 뿐 나머지는 거의 동일하다는 것을 알 수 있다.
'Windows Debugging' 카테고리의 다른 글
Bugcheck 0xD6 (0) | 2022.02.20 |
---|---|
어셈블리와 스택의 이해 (0) | 2020.04.21 |
유저모드 라이브 디버깅 (0) | 2020.04.06 |