소마형님의 결정적인 단서로 왜 Bugcheck 0x50 "PAGE_FAULT_IN_NONPAGED_AREA"이 뜨는지 알았다.
win32k.sys는 DriverEntry에서 필요한 초기화 과정을 마친후 드라이버 전체가 PagedPool 메모리로 변경된다.
드라이버 초기과정에 KeAddSystemServiceTable을 통해서 KeServiceDescriptorTableShadow의 1번째 배열
에 등록이 되는데 이를 코드로 도식화 하면 다음과 같다
KeAddSystemServiceTable(W32pServiceTable, CounterTable, Limit, ArgumentTable, 1);
첫번째 인자인 Win32pServiceTable가 바로 KeServiceDescriptorTableShadow[1].ServiceTable 에 할당되어지는 win32k의 서비스함수테이블이다. 그러나 이 영역은 이미 PagedPool 메모리로 변경된 상태이다.
그러므로 이 메모리에 접근할때는 주의깊게 접근해야 한다. 별 생각없이 DriverEntry에서 SDT훅을 하게 되면
Bugcheck 0x50이 뜨면서 BSoD가 뜰것이다. 왜냐하면 DriverEntry가 호출될때 System프로세스문맥으로
실행되기 때문이다.
손쉬운 방법으로 Driver를 제어하는 유저스레드가 GDI/User32 서비스를 호출했던 GuiThread이고,
이 스레드에서 드라이버로 'SDT훅' 이라는 제어코드를 드라이버로 전달한다.
드라이버에서는 IoDeviceControl 디스패치루틴에서 SDT훅을 하면 된다는 것이다.
KThread.Win32Thread가 0인지 아닌지로 판단할 수 있을것이다.
Kd> !process notepad.exe
해당 프로세스이미지명으로 프로세스 정보를 보면 소유한 스레드정보가 나오고, GUI인지 아닌지도 확인이 가능함
만약 GUI스레드를 가질 수 없다면, 시스템에서 GUI 스레드를 검색하고 GUI스레드를 소유하고 있는 프로세스로
KeStackAttachProcess()를 통해서 Win32k.sys에 접근할 수 있을 것이다.
참고:
[1] https://www.blackhat.com/presentations/bh-usa-07/Eriksson_Oberg_Nyberg_and_Jammar/Presentation/bh-usa-07-eriksson_oberg_nyberg_and_jammar.pdf
[2] http://www.awarenetwork.org/etc/beta/?x=1
[3] http://forum.eviloctal.com/thread-17447-1-4.html
[4] http://bbs.pediy.com/showthread.php?t=65325
[5] Adding New System Services to the Windows NT Kernal
|
Tracked from 我好电脑,我是一名的程序设计员. 我们走何处吗? - vbdream's 프로그래밍 연구소 | 2008/08/23 14:35 | DEL
[Kernel] KeServiceDescriptorTableShadow 후킹시 주의점 GuiThread에서 접근하지 않으면 BSOD가 뜨면서 후킹이 안될수도 있다고 합니다. 0range.net님 블로그에서 보았어요~~ 바로가기 |

