<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="http://rss.egloos.com/style/blog.xsl" type="text/xsl" media="screen"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
	<title>lain32 - Delphi 2010 And Reverse Engineering</title>
	<link>http://lain32.egloos.com</link>
	<description>...</description>
	<language>ko</language>
	<pubDate>Tue, 20 Oct 2009 09:36:02 GMT</pubDate>
	<generator>Egloos</generator>
	<image>
		<title>lain32 - Delphi 2010 And Reverse Engineering</title>
		<url>http://pds16.egloos.com/logo/200909/26/82/b0072382.png</url>
		<link>http://lain32.egloos.com</link>
		<width>80</width>
		<height>78</height>
		<description>...</description>
	</image>
  	<item>
		<title><![CDATA[ VirtualBox 3.0.6 r52128 네트워크 공유 폴더 접근 시 BSDO ]]> </title>
		<link>http://lain32.egloos.com/4539472</link>
		<guid>http://lain32.egloos.com/4539472</guid>
		<description>
			<![CDATA[ 
  <img border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds15.egloos.com/pds/200909/30/82/b0072382_4ac343ded6fa9.png" width="500" height="428.240740741" onclick="Control.Modal.openDialog(this, event, 'http://pds15.egloos.com/pds/200909/30/82/b0072382_4ac343ded6fa9.png');" /><br />
<br />
<br />
네트워크 공유 폴더에 접근 시 랜덤하게 위와 같은 블루 스크린을 볼 수가 있습니다.<br />
저같은 경우에는 네트워크 공유 폴더에 접근 후에 파일의 속성을 볼려고 시도를 하면 파일 속성창이<br />
바로 뜨지 않고 딜레이가 생기다가 간혹 블루 스크린이 뜨는 것 같습니다.<br />
<br />
밑에 링크를 따라가면 해결책이 나오긴 했는데 워낙에 랜덤하게 발생하는 문제라서 테스트는 해보지는 못 하였네요.<br />
<a target="_blank" href="http://justcheckingonall.wordpress.com/2009/01/08/windows-xp-under-virtualbox/">http://justcheckingonall.wordpress.com/2009/01/08/windows-xp-under-virtualbox/</a><br />
<br />
이것말고도 VirtualBox에 경우 블루 스크린이 뜰 때 간혹 화면이 깨진 상태로 GuestOS가 멈춰버리는 문제점도 있는데<br />
아직까지 안정성에는 좀 문제가 있는 것 같습니다. 하지만 속도는 매우 빠르네요..<br />
<br/><br/>tag : <a href="/tag/VirtualBox" rel="tag">VirtualBox</a>,&nbsp;<a href="/tag/버츄얼박스" rel="tag">버츄얼박스</a>,&nbsp;<a href="/tag/VMWare" rel="tag">VMWare</a>			 ]]> 
		</description>
		<category>VirtualBox</category>
		<category>버츄얼박스</category>
		<category>VMWare</category>

		<comments>http://lain32.egloos.com/4539472#comments</comments>
		<pubDate>Wed, 30 Sep 2009 11:44:12 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Delphi 2010에 Format Source 기능 ]]> </title>
		<link>http://lain32.egloos.com/4537666</link>
		<guid>http://lain32.egloos.com/4537666</guid>
		<description>
			<![CDATA[ 
  Delphi 2010에는 다음과 같은 메뉴가 새로 생겼습니다.<br />
<br />
<img border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds16.egloos.com/pds/200909/28/82/b0072382_4ac0c44bf1f97.png" width="500" height="388.513513514" onclick="Control.Modal.openDialog(this, event, 'http://pds16.egloos.com/pds/200909/28/82/b0072382_4ac0c44bf1f97.png');" /><br />
<br />
<br />
Format Source라는 메뉴인데 이 기능은 코드를 정렬해주는 기능입니다.<br />
아주 깔끔하게 코드를 정렬해줍니다.<br />
<br />
예를 들어 다음과 같은 개념없는 코드가..<br />
<br />
<img border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds17.egloos.com/pds/200909/28/82/b0072382_4ac0c48b9e62f.png" width="500" height="105.263157895" onclick="Control.Modal.openDialog(this, event, 'http://pds17.egloos.com/pds/200909/28/82/b0072382_4ac0c48b9e62f.png');" /><br />
<br />
<br />
그냥 아무 생각없이 Ctrl + D 를 누르면.....<br />
다음과 같이 바뀌는 것입니다.<br />
<br />
<img border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds16.egloos.com/pds/200909/28/82/b0072382_4ac0c49fb6b3c.png" width="471" height="184" onclick="Control.Modal.openDialog(this, event, 'http://pds16.egloos.com/pds/200909/28/82/b0072382_4ac0c49fb6b3c.png');" /><br />
<br />
<br />
<br/><br/>tag : <a href="/tag/Delphi2010" rel="tag">Delphi2010</a>,&nbsp;<a href="/tag/Delphi" rel="tag">Delphi</a>,&nbsp;<a href="/tag/SourceFormat" rel="tag">SourceFormat</a>			 ]]> 
		</description>
		<category>델파이</category>
		<category>Delphi2010</category>
		<category>Delphi</category>
		<category>SourceFormat</category>

		<comments>http://lain32.egloos.com/4537666#comments</comments>
		<pubDate>Mon, 28 Sep 2009 14:14:20 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 커널 디버거 탐지 기법 우회 ]]> </title>
		<link>http://lain32.egloos.com/4537616</link>
		<guid>http://lain32.egloos.com/4537616</guid>
		<description>
			<![CDATA[ 
  다음 코드 2줄로 우회가 가능합니다.<br />
<br />
extern PBOOLEAN KdDebuggerEnabled; // 선언..<br />
*KdDebuggerEnabled = FALSE; // 우회 코드<br />
<br />
KdDebuggerEnabled 변수를 직접적으로 접근하지 않는 방식을 사용하여도 이 방법은 통합니다.<br />
왜냐하면 결국엔 그 함수들은 저 전역변수를 참조하게 됩니다.<br />
심지어 WinDbg 조차도 저렇게 값을 임의로 바꾸면 Attach가 안됩니다.<br />
<br />
따라서 이러한 경우 커널 디버거는 우회가 되는데 WinDbg로 Attach 하여서 디버깅하는데 조금 문제가 생길것입니다.<br />
따라서 디버거를 탐지하는 코드가 실행되는 경우에는 우선 저렇게 전역변수를 FALSE로 바꾸고<br />
디버거 탐지코드가 실행되었다면 다시 KdDebuggerEnabled 커널 전역변수를 TRUE로 바꿔주면<br />
WinDbg로 Attach 도 되고 디버깅이 가능해집니다.<br />
<br />
커널 디버거를 탐지하는 대상 코드는 아래와 같고 이러한 코드는 이전에 말했듯이 내부적으로<br />
위에 커널 전역변수를 사용하므로 우회가 됩니다.<br />
<br />
bool __stdcall IsDebugPort(PVOID Object)<br />
{<br />
&nbsp; void *pZwQueryInformationProcess; // eax@2<br />
&nbsp; bool result; // eax@4<br />
&nbsp; signed int bDebug; // [sp+10h] [bp-4h]@1<br />
&nbsp; int v4; // [sp+Ch] [bp-8h]@2<br />
&nbsp; UNICODE_STRING DestinationString; // [sp+4h] [bp-10h]@3<br />
<br />
&nbsp; bDebug = 0;<br />
&nbsp; if ( PsLookupProcessByProcessId(Object, &amp;Object) &gt;= 0<br />
&nbsp;&nbsp;&nbsp; &amp;&amp; ((ObOpenObjectByPointer(Object, 0, 0, 0, 0, 0, &amp;v4), ObfDereferenceObject(Object), pZwQueryInformationProcess = (void *)g_ZwQueryInformationProcess, g_ZwQueryInformationProcess)<br />
&nbsp;&nbsp;&nbsp;&nbsp; || (RtlInitUnicodeString(&amp;DestinationString, L"ZwQueryInformationProcess"), pZwQueryInformationProcess = MmGetSystemRoutineAddress(&amp;DestinationString), g_ZwQueryInformationProcess = (int)pZwQueryInformationProcess, pZwQueryInformationProcess)) )<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; ((int (__stdcall *)(int, signed int, signed int *, signed int, _DWORD))pZwQueryInformationProcess)(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; v4,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;bDebug,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 이 함수에 두 번째 인자 ProcessDebugPort를 넘기고 있다.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 즉, 이것은 디버그중인지 체크한다고 보면 될것이다.<br />
&nbsp;&nbsp;&nbsp; result = bDebug == -1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // -1(0xFFFFFFFF) 일 경우 디버깅중인 상태입니다.<br />
&nbsp; }<br />
&nbsp; else<br />
&nbsp; {<br />
&nbsp;&nbsp;&nbsp; result = 0;<br />
&nbsp; }<br />
&nbsp; return result;<br />
}<br />
<br />
일부 보안 드라이버에서는 실시간으로 KdDebuggerEnabled 에 직접 접근하여 디버깅중인지 체크하는데<br />
이러한 경우 해당 드라이버에 한해서 IAT만 변조하는 방식으로 우회하여도 됩니다.<br />
그러나 일반적인 경우 드라이버 초기화 작업에서만 디버깅중인지 체크하므로 위에 방법으로 왠만하면 우회가 가능합니다.<br />
<br/><br/>tag : <a href="/tag/키보드보안" rel="tag">키보드보안</a>,&nbsp;<a href="/tag/커널디버거" rel="tag">커널디버거</a>,&nbsp;<a href="/tag/디버거" rel="tag">디버거</a>,&nbsp;<a href="/tag/디버거우회" rel="tag">디버거우회</a>,&nbsp;<a href="/tag/커널디버거탐지우회" rel="tag">커널디버거탐지우회</a>,&nbsp;<a href="/tag/커널디버거탐지기법우회" rel="tag">커널디버거탐지기법우회</a>			 ]]> 
		</description>
		<category>리버스 엔지니어링</category>
		<category>키보드보안</category>
		<category>커널디버거</category>
		<category>디버거</category>
		<category>디버거우회</category>
		<category>커널디버거탐지우회</category>
		<category>커널디버거탐지기법우회</category>

		<comments>http://lain32.egloos.com/4537616#comments</comments>
		<pubDate>Mon, 28 Sep 2009 13:40:25 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 오픈캡쳐 버전관리 사이트를 soureforege로 옮겼습니다. ]]> </title>
		<link>http://lain32.egloos.com/4536449</link>
		<guid>http://lain32.egloos.com/4536449</guid>
		<description>
			<![CDATA[ 
  변경 된 가장 핵심적인 부분은 다음과 같습니다.<br />
<br />
sourceforge 주소가 다음과 같이 변경되었습니다.<br />
<a href="http://sourceforge.net/projects/opencapture" target="_blank">http://sourceforge.net/projects/opencapture</a><br />
<br />
svn 주소가 다음과 같이 변경되었습니다.<br />
<code><a href="https://opencapture.svn.sourceforge.net/svnroot/opencapture" target="_blank">https://opencapture.svn.sourceforge.net/svnroot/opencapture</a> </code><br />
<br />
소스 브라우저는 기존 trac를 사용하지 않고 SCM Repositories 를 사용합니다.<br />
주소는 다음과 같습니다.<br />
<a href="http://opencapture.svn.sourceforge.net/viewvc/opencapture/" target="_blank">http://opencapture.svn.sourceforge.net/viewvc/opencapture/</a><br />
<br />
현재 개발진행 중인 최신 소스코드는 다음 주소에서 받을 수 있습니다.<br />
<a href="http://opencapture.svn.sourceforge.net/viewvc/opencapture.tar.gz?view=tar" target="_blank">http://opencapture.svn.sourceforge.net/viewvc/opencapture.tar.gz?view=tar</a><br />
<br/><br/>tag : <a href="/tag/오픈캡쳐" rel="tag">오픈캡쳐</a>,&nbsp;<a href="/tag/버전관리" rel="tag">버전관리</a>,&nbsp;<a href="/tag/sourceforge" rel="tag">sourceforge</a>,&nbsp;<a href="/tag/opencapture" rel="tag">opencapture</a>			 ]]> 
		</description>
		<category>오픈캡쳐</category>
		<category>오픈캡쳐</category>
		<category>버전관리</category>
		<category>sourceforge</category>
		<category>opencapture</category>

		<comments>http://lain32.egloos.com/4536449#comments</comments>
		<pubDate>Sun, 27 Sep 2009 12:38:33 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 오픈캡쳐가 Delphi 2010으로 개발됩니다. ]]> </title>
		<link>http://lain32.egloos.com/4536446</link>
		<guid>http://lain32.egloos.com/4536446</guid>
		<description>
			<![CDATA[ 
  <img border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds17.egloos.com/pds/200909/27/82/b0072382_4abf5b8a0b171.png" width="500" height="172.865013774" onclick="Control.Modal.openDialog(this, event, 'http://pds17.egloos.com/pds/200909/27/82/b0072382_4abf5b8a0b171.png');" /><br />
<br />
원래 Turbo Delphi 2006으로 개발을 진행하였는데 해당 버전이 엠바카데로에서 더 이상 지원을<br />
하지 않는 것 같네요. 거기다가 문제가 너무 많구요..<br />
<br />
그래서 그냥 정품을 샀습니다.<br />
아무튼 업그레이드 하면서 자동적으로 유니코드가 지원이 되었네요.<br />
<br />
한동안 오픈캡쳐 개발을 거의 안 하다시피 했는데 ( 몇 달 동안 안 한듯 .. -_- ) 이제부터라도 조금씩<br />
기능추가들을 해놓겠습니다.<br />
<br />
<br/><br/>tag : <a href="/tag/Delphi2010" rel="tag">Delphi2010</a>,&nbsp;<a href="/tag/오픈캡쳐" rel="tag">오픈캡쳐</a>			 ]]> 
		</description>
		<category>오픈캡쳐</category>
		<category>Delphi2010</category>
		<category>오픈캡쳐</category>

		<comments>http://lain32.egloos.com/4536446#comments</comments>
		<pubDate>Sun, 27 Sep 2009 12:36:07 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ VMWare 탐지 기법 우회 ]]> </title>
		<link>http://lain32.egloos.com/4536437</link>
		<guid>http://lain32.egloos.com/4536437</guid>
		<description>
			<![CDATA[ 
  <pre><a target="_blank" href="http://www.trapkit.de/">http://www.trapkit.de/</a><br />
<br />
위에 사이트에 가시면 여러가지 VMWare 탐지 기법들에 대해서 소개하고 있고 맨 마지막으로 그 모든 탐지기법들을<br />
우회하는 방법에 대해서 설명하는데 우회하는 방법은 VMWare에 vmx 파일에 다음 설정을 추가하는 것입니다.<br />
<br />
<span style="font-weight: bold;">isolation.tools.getPtrLocation.disable = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">isolation.tools.setPtrLocation.disable = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">isolation.tools.setVersion.disable = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">isolation.tools.getVersion.disable = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_directexec = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_chksimd = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_ntreloc = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_selfmod = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_reloc = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_btinout = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_btmemspace = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_btpriv = "TRUE"</span><br style="font-weight: bold;"><span style="font-weight: bold;">monitor_control.disable_btseg = "TRUE"<br />
<br />
</span>테스트 해본결과 일부 상용 DRM 솔루션이 VMWare 탐지인지 체크하는데 유명한 DRM 솔루션도 이 방법은<br />
우회를 하지 못 하였네요.<br />
</pre><br/><br/>tag : <a href="/tag/VMWare" rel="tag">VMWare</a>,&nbsp;<a href="/tag/VMWareDection" rel="tag">VMWareDection</a>,&nbsp;<a href="/tag/리버스엔지니어링" rel="tag">리버스엔지니어링</a>,&nbsp;<a href="/tag/VMWareDetoure" rel="tag">VMWareDetoure</a>,&nbsp;<a href="/tag/Detoure" rel="tag">Detoure</a>			 ]]> 
		</description>
		<category>리버스 엔지니어링</category>
		<category>VMWare</category>
		<category>VMWareDection</category>
		<category>리버스엔지니어링</category>
		<category>VMWareDetoure</category>
		<category>Detoure</category>

		<comments>http://lain32.egloos.com/4536437#comments</comments>
		<pubDate>Sun, 27 Sep 2009 12:29:29 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Sysinternals - Filemon source code ]]> </title>
		<link>http://lain32.egloos.com/4459635</link>
		<guid>http://lain32.egloos.com/4459635</guid>
		<description>
			<![CDATA[ 
  Filemon 소스코드입니다.<br />
요것도 꽤 오래된 소스코드이지만 하드에서 증발할 가능성이 있어서 이곳에 올립니다.<br />
<br />
참고로 WDK Samples에 보면 Minispy라고 Filemon가 같은 역할을 하는 MiniFilter 드라이버 예제코드가 있습니다.<br />
<br />
<a href="http://pds13.egloos.com/pds/200907/25/82/filemon434.7z">filemon434.7z</a><br />
<br/><br/>tag : <a href="/tag/Filemon" rel="tag">Filemon</a>,&nbsp;<a href="/tag/DeviceDriver" rel="tag">DeviceDriver</a>			 ]]> 
		</description>
		<category>디바이스 드라이버</category>
		<category>Filemon</category>
		<category>DeviceDriver</category>

		<comments>http://lain32.egloos.com/4459635#comments</comments>
		<pubDate>Sat, 25 Jul 2009 12:32:32 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Sysinternals - Regmon source code ]]> </title>
		<link>http://lain32.egloos.com/4459630</link>
		<guid>http://lain32.egloos.com/4459630</guid>
		<description>
			<![CDATA[ 
  Sysinternals 에서 만든 Regmon 소스코드입니다.<br />
좀 오래된 소스이긴한데 나중에 제 하드에서 증발할 가능성이 있어서 이곳에 올립니다.<br />
<br />
<a href="http://pds13.egloos.com/pds/200907/25/82/regmon435.7z">regmon435.7z</a><br />
<br/><br/>tag : <a href="/tag/Regmon" rel="tag">Regmon</a>,&nbsp;<a href="/tag/DeviceDriver" rel="tag">DeviceDriver</a>			 ]]> 
		</description>
		<category>디바이스 드라이버</category>
		<category>Regmon</category>
		<category>DeviceDriver</category>

		<comments>http://lain32.egloos.com/4459630#comments</comments>
		<pubDate>Sat, 25 Jul 2009 12:28:43 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 기본적인 커널 후킹 탬플릿 코드 2 - IRP Completion Hook ]]> </title>
		<link>http://lain32.egloos.com/4459453</link>
		<guid>http://lain32.egloos.com/4459453</guid>
		<description>
			<![CDATA[ 
  이전에 설명한 IRP Hook 코드와는 크게 다른 부분은 없고 추가적으로<br />
완료 루틴을 훅킹하는 예제를 보여줍니다.<br />
완료 루틴을 훅킹함으로써 하드 디스크에서 어떠한 데이터를 읽었는지 알아내는 예제입니다.<br />
<br />
완료루틴에서 데이터를 가져올 때 지금과 같이 ATAPI.sys에 경우<br />
Irp-&gt;MdlAddress 로부터 읽은 섹터를 가져오는데 이 때 MmGetSystemAddressForMdlSafe 함수를<br />
사용하면 안되고 자체적으로 해당 매크로를 구현해주었습니다.<br />
주석에도 나왓듯이 간혹 MDL_MAPPED_TO_SYSTEM_VA 플래그가 MDL에 포함 된 상태로<br />
오는 경우가 있기 때문입니다.<br />
만약 그런 경우가 발생하게 되면 다음과 같이 블루 스크린이 뜰 수 있습니다.<br />
<br />
<img border="0" onmouseover="this.style.cursor='pointer'" alt="" src="http://pds15.egloos.com/pds/200907/25/82/b0072382_4a6ad2e2e6dc6.png" width="500" height="375" onclick="Control.Modal.openDialog(this, event, 'http://pds15.egloos.com/pds/200907/25/82/b0072382_4a6ad2e2e6dc6.png');" /><br />
<br />
<br />
그리고 현재 ATAPI.sys를 훅킹하기 위해 \\Device\\Ide\\IdeDeviceP1T0L0-17 요런식으로<br />
디바이스 이름을 가져오는데 이렇게 가져오지 않고 다음과 같이 드라이버 오브젝트를 가져오는<br />
방식으로 해도 상관이 없습니다.<br />
<br />
UNICODE_STRING uniname;<br />
PDRIVER_OBJECT atapi_dev;<br />
<br />
NTSTATUS ntStatus;<br />
<br />
RtlInitUnicodeString(&amp;uniname , L"\\Driver\\Atapi");<br />
<font face="GulimChe">ntStatus = ObReferenceObjectByName</font>( &amp;uniname , <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OBJ_CASE_INSENSITIVE , <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL , <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *IoDriverObjectType , <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KernelMode ,<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL , <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PVOID*)&amp;atapi_dev);<br />
<br />
참고로 특정 PC에 경우에는 ATAPI.sys를 안 쓰고 자체 드라이버를 쓰는 경우도 있으니 참고바랍니다.<br />
<br />
IRP Completion Hook에 대해 어려운 부분이 없으므로 잡담은 그만하고 소스코드올립니다.<br />
<br />
<a href="http://pds15.egloos.com/pds/200907/25/82/IRPCompletionHookTemplate.7z">IRPCompletionHookTemplate.7z</a><br />
<br />
<br />
#include &lt;Wdm.h&gt;<br />
#include &lt;Scsi.h&gt;<br />
<br />
//<br />
// 이 구조체에 필요한 데이터 변수들을 추가합니다.<br />
//<br />
typedef struct _MY_CONTEXT_DATA<br />
{<br />
&nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; // 이곳에 추가..<br />
&nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; PVOID pNotUsedData;<br />
} MY_CONTEXT_DATA, *PMY_CONTEXT_DATA;<br />
<br />
typedef struct _HOOK_CONTEXT_DATA<br />
{<br />
&nbsp;&nbsp;&nbsp; PIO_COMPLETION_ROUTINE pOrgCompletionRoutine;<br />
&nbsp;&nbsp;&nbsp; PVOID pOrgContext;<br />
<br />
&nbsp;&nbsp;&nbsp; MY_CONTEXT_DATA MyContextData;<br />
} HOOK_CONTEXT_DATA, *PHOOK_CONTEXT_DATA;<br />
<br />
PDEVICE_OBJECT g_HookDeviceObject = NULL;<br />
PDRIVER_DISPATCH g_OrgHandler = NULL;<br />
UCHAR g_HookMajorFunctionIndex = 0xFF;<br />
<br />
LONG g_IRPEnterCount = 0;<br />
<br />
PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated);<br />
<br />
BOOLEAN IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler);<br />
BOOLEAN IrpHookFormName(__in WCHAR *DeviceObjectName, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler);<br />
<br />
VOID IrpUnhook();<br />
<br />
NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp);<br />
<br />
PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated)<br />
{<br />
&nbsp;&nbsp;&nbsp; NTSTATUS ntStatus;<br />
&nbsp;&nbsp;&nbsp; PFILE_OBJECT FileObject;<br />
&nbsp;&nbsp;&nbsp; PDEVICE_OBJECT DeviceObject;<br />
&nbsp;&nbsp;&nbsp; UNICODE_STRING Name;<br />
<br />
&nbsp;&nbsp;&nbsp; OBJECT_ATTRIBUTES ObjectAttributes;<br />
&nbsp;&nbsp;&nbsp; HANDLE FileHandle;<br />
&nbsp;&nbsp;&nbsp; IO_STATUS_BLOCK IoStatus;<br />
<br />
&nbsp;&nbsp;&nbsp; DeviceObject = NULL;<br />
<br />
&nbsp;&nbsp;&nbsp; RtlInitUnicodeString(&amp;Name, DeviceObjectName);<br />
&nbsp;&nbsp;&nbsp; if (bRelated == TRUE)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // IoGetDeviceObjectPointer는 내부적으로 IoGetRelatedDeviceObject 함수를 호출합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 따라서 DeviceObjectName 에 해당하는 디바이스 오브젝트 포인터를 얻어오는게 아니라 <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 해당 디바이스 오브젝트에 대한 최상위 디바이스 오브젝트를 얻어옵니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntStatus = IoGetDeviceObjectPointer(&amp;Name, FILE_READ_ATTRIBUTES, &amp;FileObject, &amp;DeviceObject);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (NT_SUCCESS(ntStatus) == TRUE)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return DeviceObject;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 실제 해당 이름을 가진 디바이스 오브젝트를 얻옵니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InitializeObjectAttributes(&amp;ObjectAttributes,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;Name,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (HANDLE) NULL,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (PSECURITY_DESCRIPTOR)NULL);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntStatus = ZwOpenFile(&amp;FileHandle,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;FILE_READ_ATTRIBUTES,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&amp;ObjectAttributes,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&amp;IoStatus,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;0,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;FILE_NON_DIRECTORY_FILE);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (NT_SUCCESS(ntStatus) == FALSE)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 해당 디바이스 오브젝트를 열 수 없습니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ntStatus = ObReferenceObjectByHandle(FileHandle,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 0,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *IoFileObjectType,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KernelMode,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (PVOID *)&amp;FileObject,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (NT_SUCCESS(ntStatus) == TRUE)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Windows 2000 소스코드 참고<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 실제 내부 구현도 이와 비슷하게 되어 있습니다.<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // If the file object was taken out against the mounted file system, it<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // will have a Vpb. Traverse it to get to the DeviceObject. Note that in<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // this case we should never follow FileObject-&gt;DeviceObject, as that<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // mapping may be invalid after a forced dismount.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (FileObject-&gt;Vpb != NULL &amp;&amp; FileObject-&gt;Vpb-&gt;DeviceObject != NULL) <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DeviceObject = FileObject-&gt;Vpb-&gt;DeviceObject;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // If a driver opened a disk device using direct device open and <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // later on it uses IoGetRelatedTargetDeviceObject to find the<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // device object it wants to send an IRP then it should not get the<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // filesystem device object. This is so that if the device object is in the<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // process of being mounted then vpb is not stable.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else if (!(FileObject-&gt;Flags &amp; FO_DIRECT_DEVICE_OPEN) &amp;&amp;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; FileObject-&gt;DeviceObject-&gt;Vpb != NULL &amp;&amp;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; FileObject-&gt;DeviceObject-&gt;Vpb-&gt;DeviceObject != NULL) <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DeviceObject = FileObject-&gt;DeviceObject-&gt;Vpb-&gt;DeviceObject;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // This is a direct open against the device stack (and there is no mounted<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // file system to strain the IRPs through).<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DeviceObject = FileObject-&gt;DeviceObject;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ZwClose(FileHandle);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return DeviceObject;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ZwClose(FileHandle);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)<br />
{<br />
&nbsp;&nbsp;&nbsp; KdPrint(("Driver unload.\n"));<br />
<br />
&nbsp;&nbsp;&nbsp; // 드라이버 언로드 루틴에서 호출됩니다.<br />
&nbsp;&nbsp;&nbsp; IrpUnhook(TRUE);<br />
}<br />
<br />
BOOLEAN IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler)<br />
{<br />
&nbsp;&nbsp;&nbsp; g_IRPEnterCount = 0;<br />
<br />
&nbsp;&nbsp;&nbsp; *pOrgHandler = DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex];<br />
&nbsp;&nbsp;&nbsp; if (*pOrgHandler == NULL)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return FALSE;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; g_HookDeviceObject = DeviceObject;<br />
&nbsp;&nbsp;&nbsp; g_HookMajorFunctionIndex = MajorFunctionIndex;<br />
<br />
&nbsp;&nbsp;&nbsp; InterlockedExchangePointer(&amp;(DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex]), pNewHandler);<br />
<br />
&nbsp;&nbsp;&nbsp; return TRUE;<br />
}<br />
<br />
BOOLEAN IrpHookFormName(__in WCHAR *DeviceObjectName, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler)<br />
{<br />
&nbsp;&nbsp;&nbsp; PDEVICE_OBJECT DeviceObject;<br />
<br />
&nbsp;&nbsp;&nbsp; DeviceObject = MyIoGetDeviceObjectPointer(DeviceObjectName, FALSE);<br />
&nbsp;&nbsp;&nbsp; if (DeviceObject != NULL)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return (IrpHook(DeviceObject, MajorFunctionIndex, pOrgHandler, pNewHandler));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return FALSE;<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
VOID IrpUnhook(BOOLEAN DriverUnloadRoutine)<br />
{<br />
&nbsp;&nbsp;&nbsp; if ((g_HookDeviceObject == NULL)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; || (g_OrgHandler == NULL))<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("Not hooked.\n"));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // IRP 핸들러를 원래의 핸들러로 되돌려줍니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InterlockedExchangePointer(&amp;(g_HookDeviceObject-&gt;DriverObject-&gt;MajorFunction[g_HookMajorFunctionIndex]), g_OrgHandler);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (DriverUnloadRoutine == TRUE)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LARGE_INTEGER WaitTime;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WaitTime.QuadPart = -1 * 10 * 1000 * 1000;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 드라이버 언로드 루틴에서 이 함수가 호출되었다면<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // InterlockedExchangePointer 후에 바로 드라이버가 언로드 되므로<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 이 때 InterlockedExchangePointer를 하기전에 훅킹 핸들러가 실행되었고<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 그 후에 InterlockedExchangePointer함수가 리턴하게 되면<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 훅킹 핸들러를 원래대로 되돌려주었지만 현재 루틴이 실행중일 수 있으므로 이에 대한 동기화 처리를<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 진행합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // <br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (g_IRPEnterCount &gt; 0)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 현재 훅킹루틴이 실행중에 있으므로 잠시 대기합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KeDelayExecutionThread(KernelMode ,FALSE, &amp;WaitTime);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 마지막으로 한 번 더 대기합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KeDelayExecutionThread(KernelMode ,FALSE, &amp;WaitTime);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
NTSTATUS NewIoCompletionRoutine(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in_opt PVOID Context)<br />
{<br />
&nbsp;&nbsp;&nbsp; PHOOK_CONTEXT_DATA pHookContextData;<br />
<br />
&nbsp;&nbsp;&nbsp; PIO_COMPLETION_ROUTINE pOrgCompletionRoutine;<br />
&nbsp;&nbsp;&nbsp; PVOID pOrgContext;<br />
<br />
&nbsp;&nbsp;&nbsp; PIO_STACK_LOCATION pIoStackLocation;<br />
<br />
&nbsp;&nbsp;&nbsp; UCHAR *pBuffer;<br />
&nbsp;&nbsp;&nbsp; ULONG i, DataLength;<br />
<br />
&nbsp;&nbsp;&nbsp; BOOLEAN bUnlock;<br />
<br />
&nbsp;&nbsp;&nbsp; pHookContextData = (PHOOK_CONTEXT_DATA)Context;<br />
<br />
&nbsp;&nbsp;&nbsp; pOrgCompletionRoutine = pHookContextData-&gt;pOrgCompletionRoutine;<br />
&nbsp;&nbsp;&nbsp; pOrgContext = pHookContextData-&gt;pOrgContext;<br />
<br />
&nbsp;&nbsp;&nbsp; pIoStackLocation = IoGetNextIrpStackLocation(Irp);<br />
&nbsp;&nbsp;&nbsp; if (pIoStackLocation-&gt;MajorFunction == g_HookMajorFunctionIndex)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (Irp-&gt;MdlAddress != NULL)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("Irp-&gt;MdlAddress-&gt;MdlFlags : %u\n", Irp-&gt;MdlAddress-&gt;MdlFlags));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 이 접근 방식을 사용하지 않습니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 특정 상황에 경우 블루 스크린이 뜰 수 있습니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 왜냐하면 간혹 MDL이 이미 맵핑되어 있는 상태로 올 수가 있는데 이 때<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // MmUnmapLockedPages 함수를 호출해버리면 훅킹루틴에서 맵핑을 해제해 버리기 때문에<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 블루 스크린이 발생합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // ( 정확하게 말해서 Irp-&gt;MdlAddress-&gt;MdlFlags에 MDL_MAPPED_TO_SYSTEM_VA 플래그가<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; 포함 된 상태인 경우가 어쩌다가 한 번씩 존재합니다. )<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //pBuffer = MmGetSystemAddressForMdlSafe(Irp-&gt;MdlAddress, NormalPagePriority);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (Irp-&gt;MdlAddress-&gt;MdlFlags &amp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (MDL_MAPPED_TO_SYSTEM_VA |<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MDL_SOURCE_IS_NONPAGED_POOL))<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pBuffer = Irp-&gt;MdlAddress-&gt;MappedSystemVa;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bUnlock = FALSE;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pBuffer = MmMapLockedPagesSpecifyCache(Irp-&gt;MdlAddress,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KernelMode,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MmCached,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FALSE,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NormalPagePriority);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bUnlock = TRUE;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pBuffer != NULL)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DataLength = Irp-&gt;IoStatus.Information;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("ATAPI read databuffer. read length : %u\n", DataLength));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (DataLength &gt; 5)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 읽은 데이터의 일부분만 출력합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DataLength = 5;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (i = 0; i &lt; DataLength; i++)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("%#x\n", pBuffer[i]));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (bUnlock == TRUE)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MmUnmapLockedPages(pBuffer, Irp-&gt;MdlAddress);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; KdPrint(("NewIoCompletionRoutine\n"));<br />
<br />
&nbsp;&nbsp;&nbsp; return (pOrgCompletionRoutine(DeviceObject, Irp, pOrgContext));<br />
}<br />
<br />
NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)<br />
{<br />
&nbsp;&nbsp;&nbsp; NTSTATUS ntStatus;<br />
<br />
&nbsp;&nbsp;&nbsp; // 동기화를 위한 전역 카운트를 증가시킵니다.<br />
&nbsp;&nbsp;&nbsp; InterlockedIncrement(&amp;g_IRPEnterCount);<br />
<br />
&nbsp;&nbsp;&nbsp; // 디바이스 오브젝트에 대한 필터링을 하였지만 상황에 따라 하지 않아야 할 수도 있습니다.<br />
&nbsp;&nbsp;&nbsp; //if (DeviceObject == g_HookDeviceObject)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 우리가 원하는 DeviceObject에서 발생한 Irp입니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIO_STACK_LOCATION pIoStackLocation;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pIoStackLocation = IoGetCurrentIrpStackLocation(Irp);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pIoStackLocation-&gt;MajorFunction == g_HookMajorFunctionIndex)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 이곳에 원하는 코드를 작성합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 예제코드에서는 간단히 CDB에 대해서 출력하겠습니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; switch (pIoStackLocation-&gt;Parameters.Scsi.Srb-&gt;Cdb[0])<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case SCSIOP_READ:<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // ATAPI.sys에 기본적인 읽기명령이 발생하였습니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pIoStackLocation-&gt;CompletionRoutine != NULL)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 예제에서는 완료루틴이 등록되어 있을 경우에만 완료 루틴을 훅킹합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PHOOK_CONTEXT_DATA pHookContextData;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pHookContextData = ExAllocatePoolWithTag(NonPagedPool, sizeof(HOOK_CONTEXT_DATA), 'tseT');<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pHookContextData != NULL)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pHookContextData-&gt;pOrgCompletionRoutine = pIoStackLocation-&gt;CompletionRoutine;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pHookContextData-&gt;pOrgContext = pIoStackLocation-&gt;Context;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pIoStackLocation-&gt;CompletionRoutine = NewIoCompletionRoutine;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pIoStackLocation-&gt;Context = pHookContextData;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // pIoStackLocation-&gt;Control = SL_INVOKE_ON_SUCCESS;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; ntStatus = g_OrgHandler(DeviceObject, Irp);<br />
<br />
&nbsp;&nbsp;&nbsp; // 동기화를 위한 전역 카운트를 감소합니다.<br />
&nbsp;&nbsp;&nbsp; InterlockedDecrement(&amp;g_IRPEnterCount);<br />
<br />
&nbsp;&nbsp;&nbsp; return (ntStatus);<br />
}<br />
<br />
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)<br />
{<br />
&nbsp;&nbsp;&nbsp; NTSTATUS ntStatus;<br />
&nbsp;&nbsp;&nbsp; PDEVICE_OBJECT DeviceObject;<br />
<br />
&nbsp;&nbsp;&nbsp; // 드라이버가 언로드 될 수 있도록 합니다.<br />
&nbsp;&nbsp;&nbsp; DriverObject-&gt;DriverUnload = DriverUnload;<br />
<br />
&nbsp;&nbsp;&nbsp; // 예제로 훅킹하는 디바이스는 하드 디스크입니다. <br />
&nbsp;&nbsp;&nbsp; // ( 실제 하드 디스크에 섹터를 읽어주는 디바이스입니다. )<br />
&nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; // 해당 디바이스 이름은 시스템에 따라서 다릅니다.<br />
&nbsp;&nbsp;&nbsp; // IRP_MJ_SCSI 를 훅킹합니다.<br />
&nbsp;&nbsp;&nbsp; if (IrpHookFormName(L"\\Device\\Ide\\IdeDeviceP1T0L0-17", IRP_MJ_SCSI, &amp;g_OrgHandler, NewIrpHandler) == TRUE)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("IrpHookFormName successed.\n"));<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("IrpHookFormName failed.\n"));<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; return STATUS_SUCCESS;<br />
}<br />
<br/><br/>tag : <a href="/tag/IRPHook" rel="tag">IRPHook</a>,&nbsp;<a href="/tag/IRPCompletion" rel="tag">IRPCompletion</a>,&nbsp;<a href="/tag/ATAPI" rel="tag">ATAPI</a>,&nbsp;<a href="/tag/ATAPI.sys" rel="tag">ATAPI.sys</a>,&nbsp;<a href="/tag/DeviceDriver" rel="tag">DeviceDriver</a>			 ]]> 
		</description>
		<category>디바이스 드라이버</category>
		<category>IRPHook</category>
		<category>IRPCompletion</category>
		<category>ATAPI</category>
		<category>ATAPI.sys</category>
		<category>DeviceDriver</category>

		<comments>http://lain32.egloos.com/4459453#comments</comments>
		<pubDate>Sat, 25 Jul 2009 09:46:05 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
	<item>
		<title><![CDATA[ 기본적인 커널 후킹 탬플릿 코드 1 - IRP Hook ]]> </title>
		<link>http://lain32.egloos.com/4451358</link>
		<guid>http://lain32.egloos.com/4451358</guid>
		<description>
			<![CDATA[ 
  간단한 IRP Hook 코드입니다.<br />
해당 코드에 일부를 수정하여 다른 IRP를 손쉽게 훅킹할 수 있습니다.<br />
보통 저에 경우에는 다른 드라이버에 대한 값을 모니터링 할 때 많이 사용합니다.<br />
<br />
예제코드는 ATAPI.sys에 IRP_MJ_SCSI를 훅킹하고 있고 Cdb를 출력합니다.<br />
Cdb와 SCSI에 대한 설명은 IRP Hook 범위를 넘어가므로 이에 대한 설명을 하지 않겠습니다.<br />
<br />
개인적으로 만든 코드라서 개인적인 루틴도 추가되었습니다.<br />
예를 들어 IRP 핸들러 시작부분과 끝부분에 g_IRPEnterCount변수 사용 및<br />
IRPUnhook 시 이 변수를 체크합니다. <br />
이는 드라이버 동적 언로드 시 극악의 확률로 발생가능한 동기화문제를 막기 위해서입니다.<br />
<br />
또 IRP Hook시 주의해야 할 점은 이러한 방식에 훅킹은 접근이 허용되지만 <br />
*pOrgHandler = DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex];<br />
 InterlockedExchangePointer(&amp;(DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex]), pNewHandler);<br />
<br />
이러한 방식에 접근은 허용되지 않습니다.<br />
 *pOrgHandler&nbsp; = InterlockedExchangePointer(&amp;(DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex]), pNewHandler);<br />
<br />
물론 위에 코드나 밑에 코드나 별차이가 없어보이고 실제로 동작시켜보면 둘 다 아무런 문제가 없어보이지만<br />
밑에 코드에 경우에는 새로운 IRP 핸들러루틴에서 pOrgHandler를 참조하게 되는데 이 때 InterlockedExchangePointer<br />
함수가 리턴하기전에 이미 함수 포인터는 바꼈고 이 상태에서 새로운 IRP 핸들러 루틴이 실행될 수 있기 때문에<br />
정말 극악의 확률로 블루 스크린이 뜰 수 있기 때문입니다.<br />
( 또한 InterlockedExchangePointer 는 함수가 아니라 컴파일 시 어셈블리 코드로 변환됩니다. )<br />
<br />
<a href="http://pds15.egloos.com/pds/200907/19/82/IRPHookTemplate.7z" player="0" style="padding: 0pt 0pt 0pt 15px; background: transparent url(http://md.egloos.com/img/eg/icon_file.gif) no-repeat scroll left center; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; list-style-type: none; list-style-image: none; list-style-position: outside;">예제 코드 다운로드 ( IRPHookTemplate.7z )</a> <br />
<br />
<br />
#include &lt;Wdm.h&gt;<br />
#include &lt;Scsi.h&gt;<br />
<br />
PDEVICE_OBJECT g_HookDeviceObject = NULL;<br />
PDRIVER_DISPATCH g_OrgHandler = NULL;<br />
UCHAR g_HookMajorFunctionIndex = 0xFF;<br />
<br />
LONG g_IRPEnterCount = 0;<br />
<br />
PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated);<br />
<br />
BOOLEAN IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler);<br />
BOOLEAN IrpHookFormName(__in WCHAR *DeviceObjectName, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler);<br />
<br />
VOID IrpUnhook();<br />
<br />
NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp);<br />
<br />
PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated)<br />
{<br />
&nbsp;&nbsp; &nbsp;NTSTATUS ntStatus;<br />
&nbsp;&nbsp; &nbsp;PFILE_OBJECT FileObject;<br />
&nbsp;&nbsp; &nbsp;PDEVICE_OBJECT DeviceObject;<br />
&nbsp;&nbsp; &nbsp;UNICODE_STRING Name;<br />
<br />
&nbsp;&nbsp;&nbsp; OBJECT_ATTRIBUTES ObjectAttributes;<br />
&nbsp;&nbsp;&nbsp; HANDLE FileHandle;<br />
&nbsp;&nbsp;&nbsp; IO_STATUS_BLOCK IoStatus;<br />
<br />
&nbsp;&nbsp; &nbsp;DeviceObject = NULL;<br />
<br />
&nbsp;&nbsp; &nbsp;RtlInitUnicodeString(&amp;Name, DeviceObjectName);<br />
&nbsp;&nbsp; &nbsp;if (bRelated == TRUE)<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// IoGetDeviceObjectPointer는 내부적으로 IoGetRelatedDeviceObject 함수를 호출합니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 따라서 DeviceObjectName 에 해당하는 디바이스 오브젝트 포인터를 얻어오는게 아니라 <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 해당 디바이스 오브젝트에 대한 최상위 디바이스 오브젝트를 얻어옵니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ntStatus = IoGetDeviceObjectPointer(&amp;Name, FILE_READ_ATTRIBUTES, &amp;FileObject, &amp;DeviceObject);<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (NT_SUCCESS(ntStatus) == TRUE)<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return DeviceObject;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return NULL;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 실제 해당 이름을 가진 디바이스 오브젝트를 얻옵니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;InitializeObjectAttributes(&amp;ObjectAttributes,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&amp;Name,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;0,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;(HANDLE) NULL,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;(PSECURITY_DESCRIPTOR)NULL);<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ntStatus = ZwOpenFile(&amp;FileHandle,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; FILE_READ_ATTRIBUTES,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &amp;ObjectAttributes,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &amp;IoStatus,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 0,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; FILE_NON_DIRECTORY_FILE);<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (NT_SUCCESS(ntStatus) == FALSE)<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 해당 디바이스 오브젝트를 열 수 없습니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return NULL;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ntStatus = ObReferenceObjectByHandle(FileHandle,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;0,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;*IoFileObjectType,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;KernelMode,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;(PVOID *)&amp;FileObject,<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;NULL);<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (NT_SUCCESS(ntStatus) == TRUE)<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// Windows 2000 소스코드 참고<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 실제 내부 구현도 이와 비슷하게 되어 있습니다.<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// If the file object was taken out against the mounted file system, it<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// will have a Vpb. Traverse it to get to the DeviceObject. Note that in<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// this case we should never follow FileObject-&gt;DeviceObject, as that<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// mapping may be invalid after a forced dismount.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (FileObject-&gt;Vpb != NULL &amp;&amp; FileObject-&gt;Vpb-&gt;DeviceObject != NULL) <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DeviceObject = FileObject-&gt;Vpb-&gt;DeviceObject;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// If a driver opened a disk device using direct device open and <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// later on it uses IoGetRelatedTargetDeviceObject to find the<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// device object it wants to send an IRP then it should not get the<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// filesystem device object. This is so that if the device object is in the<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// process of being mounted then vpb is not stable.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else if (!(FileObject-&gt;Flags &amp; FO_DIRECT_DEVICE_OPEN) &amp;&amp;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileObject-&gt;DeviceObject-&gt;Vpb != NULL &amp;&amp;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FileObject-&gt;DeviceObject-&gt;Vpb-&gt;DeviceObject != NULL) <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DeviceObject = FileObject-&gt;DeviceObject-&gt;Vpb-&gt;DeviceObject;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// This is a direct open against the device stack (and there is no mounted<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// file system to strain the IRPs through).<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DeviceObject = FileObject-&gt;DeviceObject;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ZwClose(FileHandle);<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return DeviceObject;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ZwClose(FileHandle);<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return NULL;<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;}<br />
}<br />
<br />
VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)<br />
{<br />
&nbsp;&nbsp; &nbsp;KdPrint(("Driver unload.\n"));<br />
<br />
&nbsp;&nbsp; &nbsp;// 드라이버 언로드 루틴에서 호출됩니다.<br />
&nbsp;&nbsp; &nbsp;IrpUnhook(TRUE);<br />
}<br />
<br />
BOOLEAN IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler)<br />
{<br />
&nbsp;&nbsp; &nbsp;g_IRPEnterCount = 0;<br />
<br />
&nbsp;&nbsp; &nbsp;*pOrgHandler = DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex];<br />
&nbsp;&nbsp; &nbsp;if (*pOrgHandler == NULL)<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return FALSE;<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;g_HookDeviceObject = DeviceObject;<br />
&nbsp;&nbsp; &nbsp;g_HookMajorFunctionIndex = MajorFunctionIndex;<br />
<br />
&nbsp;&nbsp; &nbsp;InterlockedExchangePointer(&amp;(DeviceObject-&gt;DriverObject-&gt;MajorFunction[MajorFunctionIndex]), pNewHandler);<br />
<br />
&nbsp;&nbsp; &nbsp;return TRUE;<br />
}<br />
<br />
BOOLEAN IrpHookFormName(__in WCHAR *DeviceObjectName, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, PDRIVER_DISPATCH pNewHandler)<br />
{<br />
&nbsp;&nbsp; &nbsp;PDEVICE_OBJECT DeviceObject;<br />
<br />
&nbsp;&nbsp; &nbsp;DeviceObject = MyIoGetDeviceObjectPointer(DeviceObjectName, FALSE);<br />
&nbsp;&nbsp; &nbsp;if (DeviceObject != NULL)<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return (IrpHook(DeviceObject, MajorFunctionIndex, pOrgHandler, pNewHandler));<br />
&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return FALSE;<br />
&nbsp;&nbsp; &nbsp;}<br />
}<br />
<br />
VOID IrpUnhook(BOOLEAN DriverUnloadRoutine)<br />
{<br />
&nbsp;&nbsp; &nbsp;if ((g_HookDeviceObject == NULL)<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;|| (g_OrgHandler == NULL))<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;KdPrint(("Not hooked.\n"));<br />
&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// IRP 핸들러를 원래의 핸들러로 되돌려줍니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;InterlockedExchangePointer(&amp;(g_HookDeviceObject-&gt;DriverObject-&gt;MajorFunction[g_HookMajorFunctionIndex]), g_OrgHandler);<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (DriverUnloadRoutine == TRUE)<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;LARGE_INTEGER WaitTime;<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;WaitTime.QuadPart = -1 * 10 * 1000 * 1000;<br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// <br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 드라이버 언로드 루틴에서 이 함수가 호출되었다면<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// InterlockedExchangePointer 후에 바로 드라이버가 언로드 되므로<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 이 때 InterlockedExchangePointer를 하기전에 훅킹 핸들러가 실행되었고<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 그 후에 InterlockedExchangePointer함수가 리턴하게 되면<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 훅킹 핸들러를 원래대로 되돌려주었지만 현재 루틴이 실행중일 수 있으므로 이에 대한 동기화 처리를<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 진행합니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// <br />
<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;while (g_IRPEnterCount &gt; 0)<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 현재 훅킹루틴이 실행중에 있으므로 잠시 대기합니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;KeDelayExecutionThread(KernelMode ,FALSE, &amp;WaitTime);<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// 마지막으로 한 번 더 대기합니다.<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;KeDelayExecutionThread(KernelMode ,FALSE, &amp;WaitTime);<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;}<br />
}<br />
<br />
NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)<br />
{<br />
&nbsp;&nbsp;&nbsp; NTSTATUS ntStatus;<br />
<br />
&nbsp;&nbsp;&nbsp; // 동기화를 위한 전역 카운트를 증가시킵니다.<br />
&nbsp;&nbsp;&nbsp; InterlockedIncrement(&amp;g_IRPEnterCount);<br />
<br />
&nbsp;&nbsp;&nbsp; // 디바이스 오브젝트에 대한 필터링을 하였지만 상황에 따라 하지 않아야 할 수도 있습니다.<br />
&nbsp;&nbsp;&nbsp; if (DeviceObject == g_HookDeviceObject)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 우리가 원하는 DeviceObject에서 발생한 Irp입니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PIO_STACK_LOCATION pIoStackLocation;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pIoStackLocation = IoGetCurrentIrpStackLocation(Irp);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (pIoStackLocation-&gt;MajorFunction == g_HookMajorFunctionIndex)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 이곳에 원하는 코드를 작성합니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // 예제코드에서는 간단히 CDB에 대해서 출력하겠습니다.<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; KdPrint(("DeviceObject : %p, Cdb : %#x\n", DeviceObject, pIoStackLocation-&gt;Parameters.Scsi.Srb-&gt;Cdb[0]));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; ntStatus = g_OrgHandler(DeviceObject, Irp);<br />
<br />
&nbsp;&nbsp;&nbsp; // 동기화를 위한 전역 카운트를 감소합니다.<br />
&nbsp;&nbsp;&nbsp; InterlockedDecrement(&amp;g_IRPEnterCount);<br />
<br />
&nbsp;&nbsp;&nbsp; return (ntStatus);<br />
}<br />
<br />
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)<br />
{<br />
&nbsp;&nbsp; &nbsp;NTSTATUS ntStatus;<br />
&nbsp;&nbsp; &nbsp;PDEVICE_OBJECT DeviceObject;<br />
<br />
&nbsp;&nbsp; &nbsp;// 드라이버가 언로드 될 수 있도록 합니다.<br />
&nbsp;&nbsp; &nbsp;DriverObject-&gt;DriverUnload = DriverUnload;<br />
<br />
&nbsp;&nbsp; &nbsp;// 예제로 훅킹하는 디바이스는 하드 디스크입니다. <br />
&nbsp;&nbsp; &nbsp;// ( 실제 하드 디스크에 섹터를 읽어주는 디바이스입니다. )<br />
&nbsp;&nbsp; &nbsp;//<br />
&nbsp;&nbsp; &nbsp;// 해당 디바이스 이름은 시스템에 따라서 다릅니다.<br />
&nbsp;&nbsp; &nbsp;// IRP_MJ_SCSI 를 훅킹합니다.<br />
&nbsp;&nbsp; &nbsp;if (IrpHookFormName(L"\\Device\\Ide\\IdeDeviceP1T0L0-17", IRP_MJ_SCSI, &amp;g_OrgHandler, NewIrpHandler) == TRUE)<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;KdPrint(("IrpHookFormName successed.\n"));<br />
&nbsp;&nbsp; &nbsp;}<br />
&nbsp;&nbsp; &nbsp;else<br />
&nbsp;&nbsp; &nbsp;{<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;KdPrint(("IrpHookFormName failed.\n"));<br />
&nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp;&nbsp; &nbsp;return STATUS_SUCCESS;<br />
}<br/><br/>tag : <a href="/tag/HOOK" rel="tag">HOOK</a>,&nbsp;<a href="/tag/IRPHOOK" rel="tag">IRPHOOK</a>,&nbsp;<a href="/tag/DeviceDriver" rel="tag">DeviceDriver</a>,&nbsp;<a href="/tag/IRP_MJ_SCSI" rel="tag">IRP_MJ_SCSI</a>			 ]]> 
		</description>
		<category>디바이스 드라이버</category>
		<category>HOOK</category>
		<category>IRPHOOK</category>
		<category>DeviceDriver</category>
		<category>IRP_MJ_SCSI</category>

		<comments>http://lain32.egloos.com/4451358#comments</comments>
		<pubDate>Sun, 19 Jul 2009 09:39:18 GMT</pubDate>
		<dc:creator>lain32</dc:creator>
	</item>
</channel>
</rss>
