뭉근 : 느긋하게 타는 불

1. vmware를 이용한 드라이버 디버깅 방법

데브구루의 기술 칼럼을 따라했는데 잘 되지 않았다.

프로젝트 생성한 후, 호스트가 윈도우 7 x64이고 타겟이 가상머신 윈도우 7 x86인 환경에서

디버깅 환경 설정을 진행하였는데 드라이버 컴파일 후 가상 머신으로 전송하고 Driver Install 하는 부분에서 막혔다.

이후 타겟을 윈도우 8.1 x64로 변경하였는데 잘되었다.

컴파일 설정은 당연히 바꾸고 했는데 이상했다... 

아무튼 디버깅을 해보니 타겟으로 Driver Install 하는데 시간도 오래 걸리고 디버깅하는데도 버벅 거렸다.

간단한 제작에는 DbgPrint 등으로 디버깅하는게 더 빠르겠다.


참고
http://devguru.co.kr/blog/6619/

https://msdn.microsoft.com/en-us/library/windows/hardware/hh439654(v=vs.85).aspx



2. WinDbg에 DbgPrint 출력하기

DbgPrint 출력 전에 WinDbg 커맨드 라인에 아래와 같이 해주면 된다.

kd> ed Kd_DEFAULT_MASK 8


3. 커널 페이지 메모리 보호 해제

MDL을 사용하여 페이지 메모리 보호 해제를 하려다 

예전에 공부한 CR0 레지스터 변경을 찾아서 적용했더니 바로 되었다.

짬내어 MDL 공부도 해놓아야겠다.


참고 

http://resources.infosecinstitute.com/hooking-system-service-dispatch-table-ssdt/


4. 드라이버 로드 & 언로드 1

윈도우 서비스 메니저(SCM)을 이용하여 로드까진 진행이 잘 되었는데

드라이버를 언로드하려 할 때 아래 코드에서 자꾸 에러가 났다.

ControlService(service, SERVICE_CONTROL_STOP, &ss)

알고보니 드라이버 언로드 루틴이 없어서 그런거였다.

또는 MJ_IRP_CLOSE 루틴인가? .. 사실 언로드 루틴과 클로즈 루틴을 다 넣어놨다.

뭐 때문인지는 테스트해봐야겠지만 일단 그냥 둔다.


참고

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682571(v=vs.85).aspx


5. 드라이버 로드 & 언로드 2

이번엔 드라이버가 처음에는 잘 로드되는데

처음 로드한 드라이버를 언로드 후 다시 로드하면 시스템 에러 0x02가 났다.

확인해보니 디바이스 생성 후 삭제를 안해서 

커널에 똑같은 이름의 디바이스가 남아있었다.

드라이버 언로드 루틴에 디바이스 오브젝트 삭제 코드를 추가하였다.


실행 상태(SERVICE_RUNNING)인 드라이버를 언로드하기 위해서는 반드시

QueryServiceStatusEx를 호출하여 서비스 실행 상태를 얻고

실행 중이면 ControlService를 이용해 중지 명령을 내려야 한다.

(일부 드라이버는 delete pending에 들어가 재부팅 후에만 제대로 언로드가 될 수 있다.)


참고

IOCTL 예제 코드(https://code.msdn.microsoft.com/IOCTL-a583bbeb?SRC=VSIDE)

* VS2013에서는 New Project 다이얼로그의 Online - Samples에서 바로 컴파일 가능한 형태로 다운받을 수 있다.


6. 디바이스 핸들 얻기

CreateFile을 이용하여 디바이스 핸들을 얻기 위해서 드라이버에 반드시 추가해야할 코드가 있다.

첫번째는 IoCreateDevice, IoCreateSymbolicLink, IoDeleteSymbolicLink, IoDeleteDevice 함수 셋이다.

이 함수들이 뭐냐하면 디바이스를 생성하고 생성한 디바이스에 대해 유저 영역(Win32)에서 디바이스로 접근할 수 있는 이름을 생성하는 것이다.

IoCreateDevice에서 인자로 넣어주는 이름은 디바이스 이름이고, IoCreateSymbolicLink에서 넣어주는 이름은 유저 핸들 이름(?)이라 할 수 있겠다.

꼭 이렇게 해주고 드라이버 언로드 루틴에서 디바이스와 심볼릭 링크를 삭제해야 다음 로드시 드라이버 로드가 된다.

두번째는 IPR_MJ_CREATE와 IRP_MJ_CLOSE이다. 이 함수가 드라이버에 등록되지 않으면 CreateFile로 핸들 생성 자체가 안된다.

예전에 디폴트 커널 코드가 있다고 알고 있었는데 없어졌나 싶다.

(IRP_MJ_CLOSE는 아닐 수도 있다... 테스트할 시간이 없다.)


0. 드라이버 개발에 좋은 도구들

devicetree : 디바이스가 제대로 등록되어 있는지 확인할 수 있다.

osrloader : 등록한 드라이버가 서비스에 등록되어 있는지 확인할 수 있다.

winobj : 디바이스와 디바이스의 심볼릭 링크가 있는 전역이름공간(\\??\, 즉 \\.\)을 확인할 수 있다.


계속 추가 예정이다.

'프로그래밍' 카테고리의 다른 글

PsSetCreateProcessNotifyRoutineEx 접근 권한 문제  (1) 2016.05.10
Rstudio 3.3.0 스케일링 문제  (0) 2016.05.06
ofstream 한글 출력 문제  (0) 2014.10.22
ifstream 64  (0) 2014.09.25
CPP 벡터 반복문 중 원소 지우기  (0) 2014.09.22