<?xml version="1.0" encoding="UTF-8" ?><feed xmlns="http://www.w3.org/2005/Atom">
   <title type="text">프로그래밍</title>
      <updated>2013-05-24T13:12:00+09:00</updated>
   <id>http://simples.kr/ITTalk/atom</id>
   <link rel="alternate" type="text/html" hreflang="ko" href="http://simples.kr/ITTalk"/>
   <link rel="self" type="application/atom+xml" href="http://simples.kr/ITTalk/atom"/>
   <generator uri="http://www.xpressengine.com/">XpressEngine</generator>
   <entry>
      <title>json 문법 체크 사이트</title>
      <id>http://simples.kr/43422</id>
      <published>2012-02-28T16:37:04+09:00</published>
      <updated>2012-02-28T16:37:04+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/43422"/>
      <link rel="replies" type="text/html" href="http://simples.kr/43422#comment"/>
      <author>
         <name>Lyn</name>
                  <uri>http://lunapiece.net</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://jsonlint.com/&quot;&gt;http://jsonlint.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;오류난 위치까지 찾아줌&lt;/p&gt;&lt;a href=&quot;http://jsonlint.com/&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://jsonlint.com/&quot;&gt;&lt;/a&gt;


&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>SCSI Miniport - IOCTL_SCSI_PASS_THROUGH_DIRECT ( Windows XP 64Bit, Windows 2003 Server 64Bit 버그 수정 )</title>
      <id>http://simples.kr/38951</id>
      <published>2011-06-11T10:27:09+09:00</published>
      <updated>2011-06-11T10:33:24+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/38951"/>
      <link rel="replies" type="text/html" href="http://simples.kr/38951#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;/////////////////////////////////////////////////////////////////&lt;br /&gt;/////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;// Windows Vista 64Bit 미만에 운영체제에서 ( Windows XP 64Bit, Windows 2003 Server 64Bit )&lt;br /&gt;// 32Bit 프로세스에서 IOCTL_SCSI_PASS_THROUGH_DIRECT 를 내릴 때 DeviceIoControl이 실패하게 되는데 이러한 문제점을 &lt;br /&gt;// 하드코딩하여 수정하는 코드입니다.&lt;br /&gt;//&lt;br /&gt;// 정확하게 말하자면 실패 위치는.. WinDbg로 디버깅을 하면서 차례대로 내려갔을 때..&lt;br /&gt;//&lt;br /&gt;// fffffadf`f543f48c e80ffaffff&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; SCSIPORT!SpHandleIoctlScsiPassThrough (fffffadf`f543eea0)&lt;br /&gt;//&lt;br /&gt;// SCSIPORT!SpHandleIoctlScsiPassThrough:&lt;br /&gt;// fffffadf`f543eea0 4883ec28&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sub&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rsp,28h&lt;br /&gt;// fffffadf`f543eea4 48895c2438&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; qword ptr [rsp+38h],rbx&lt;br /&gt;// fffffadf`f543eea9 4889742440&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; qword ptr [rsp+40h],rsi&lt;br /&gt;// fffffadf`f543eeae 488bf1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rsi,rcx&lt;br /&gt;// fffffadf`f543eeb1 488b4940&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcx,qword ptr [rcx+40h]&lt;br /&gt;// fffffadf`f543eeb5 48897c2448&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; qword ptr [rsp+48h],rdi&lt;br /&gt;// fffffadf`f543eeba 488bfa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rdi,rdx&lt;br /&gt;// fffffadf`f543eebd e84e0b0000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; SCSIPORT!SpSendPassThrough (fffffadf`f543fa10) &amp;lt;= 에러 발생위치&lt;br /&gt;//&lt;br /&gt;// fffffadf`f543fae2 e869720000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; SCSIPORT!PortSendPassThrough (fffffadf`f5446d50) &amp;lt; = 여기서 에러남&lt;br /&gt;//&lt;br /&gt;// fffffadf`f5446e8a e8a1000000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; SCSIPORT!PortPassThroughInitialize (fffffadf`f5446f30) &amp;lt;= 여기서 에러남&lt;br /&gt;//&lt;br /&gt;// SCSIPORT!PortPassThroughInitialize 함수내부에서&lt;br /&gt;// fffffadf`f5447151 3b4d08&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx,dword ptr [rbp+8] ss:0018:fffffadf`f6ea0b6c=00000001&lt;br /&gt;// 다음과 같이 값을 비교하게 되는데 dword ptr [rbp+8] ss:0018:fffffadf`f6ea0b6c 에 값이 0x01이어서 조건문에 의해 에러가 발생하게 됩니다.&lt;br /&gt;//&lt;br /&gt;// 클론시디에 경우에는&lt;br /&gt;/*&lt;br /&gt;.text:0000000000011CC7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; sub_16200&lt;br /&gt;.text:0000000000011CCC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcx, [rsp+1D8h+var_158]&lt;br /&gt;.text:0000000000011CD4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [rsp+1D8h+var_158], r12d&lt;br /&gt;.text:0000000000011CDC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; cs:RtlGetVersion &amp;lt;= 버전을 비교하는 함수를 호출..&lt;br /&gt;.text:0000000000011CE2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, r15d&lt;br /&gt;.text:0000000000011CE5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_11CF1&lt;br /&gt;.text:0000000000011CE7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [rsp+1D8h+var_154], 6 &amp;lt;= 6이라는 값을 비교하는걸 보니 dwMajorVersion와 비교할 가능성이 매우 높습니다.&lt;br /&gt;.text:0000000000011CEF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jnb&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_11D0D // 부호 없는 데이터, 작지 않을 때&lt;br /&gt;.text:0000000000011CF1&lt;br /&gt;.text:0000000000011CF1 loc_11CF1:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: HwFindAdapter+F1j &amp;lt;= 작으면 이곳이 호출됩니다.&lt;br /&gt;.text:0000000000011CF1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rax, [rbx+148h]&lt;br /&gt;.text:0000000000011CF8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs:qword_1A230, rax&lt;br /&gt;.text:0000000000011CFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rax, SetHalGetAdapter &amp;lt;= 그리고 SetHalGetAdapter 에 주소를 넣습니다.&lt;br /&gt;.text:0000000000011D06&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [rbx+148h], rax&lt;br /&gt;.text:0000000000011D0D loc_11D0D:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: HwFindAdapter+FBj&lt;br /&gt;.text:0000000000011D0D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, cs:dword_1A238&lt;br /&gt;.text:0000000000011D13&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [rsi+17F8h], eax&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;// 위에 코드가 실행 된 후에 HalGetAdapter 함수를 SCSIPort 내부에서 클론시디 드라이버에 있는 HalGetAdapter를 호출하게 되는데 어떻게 해서 그렇게 했는지 모르겠습니다.&lt;br /&gt;// 중요한것은 저렇게 루틴을 탔을 경우에만 IOCTL_SCSI_PASS_THROUGH_DIRECT가 전송이 되고 그렇지 않으면 전송이 되지 않습니다.&lt;br /&gt;//&lt;br /&gt;// dword ptr [rbp+8] ss:0018:fffffadf`f6ea0b6c &amp;lt;= 해당 주소를 조사한 결과&lt;br /&gt;// (UCHAR *)(g_pDriverObject-&amp;gt;DeviceObject-&amp;gt;DeviceExtension) + 0x3EC 위치에 값이 있었습니다.&lt;br /&gt;// 비교는 ecx 레지스터와 비교를 하게 되므로 32Bit 값일것입니다.&lt;br /&gt;// &lt;br /&gt;/////////////////////////////////////////////////////////////////&lt;br /&gt;/////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;#define HACK_IOCTL_SCSI_PASS_THROUGH_DIRECT_OFFSET 0x3EC&lt;br /&gt;&lt;br /&gt;PVOID g_HackDeviceExtensionPointer = NULL;&lt;br /&gt;&lt;br /&gt;VOID Hack64BitIOCTL_SCSI_PASS_THROUGH_DIRECT()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (g_HackDeviceExtensionPointer != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;H.A.C.K IOCTL_SCSI_PASS_THROUGH_DIRECT\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*(DWORD *)(((UCHAR *)g_HackDeviceExtensionPointer + HACK_IOCTL_SCSI_PASS_THROUGH_DIRECT_OFFSET)) = 0x00000011;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VOID InitHack64BitIOCTL_SCSI_PASS_THROUGH_DIRECT(PDRIVER_OBJECT pDriverObject)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;RTL_OSVERSIONINFOW rtlOsVersionInfoW;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ntStatus = RtlGetVersion(&amp;amp;rtlOsVersionInfoW);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (rtlOsVersionInfoW.dwMajorVersion &amp;lt; 6)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;g_HackDeviceExtensionPointer = pDriverObject-&amp;gt;DeviceObject-&amp;gt;DeviceExtension;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;NOTHING&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;InitHack64BitIOCTL_SCSI_PASS_THROUGH_DIRECT 함수에 인자 pDriverObject는 DriverEntry에서 받은 DriverObject를 넣으면 되며, HwFindAdapter에서 호출되어야 합니다.&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>커널레벨에서 IAT Hook</title>
      <id>http://simples.kr/38946</id>
      <published>2011-06-11T10:13:10+09:00</published>
      <updated>2011-06-11T10:13:10+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/38946"/>
      <link rel="replies" type="text/html" href="http://simples.kr/38946#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;오래전에 작업하고 더 이상 쓰지 않고 놔뒹굴고 있어서 이곳에 정리합니다.&lt;/p&gt;&lt;p&gt;32Bit, 64Bit 둘 다 정상적으로 동작합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;물론 64Bit에서는 패치가드가 보호하는 모듈은 후킹을 시도하지 말아야겠죠.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;후킹하려는 대상 모듈이 scsiport.sys이고 이 모듈이 ntoskrnl!IoCreateSymbolicLink 함수를 호출하는 것을&lt;/p&gt;&lt;p&gt;모두 후킹하고 싶다면 다음과 같이 코드를 작성합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;#define SCSIPORT_SYS_FILEPATH L&quot;\\SystemRoot\\System32\\drivers\\scsiport.sys&quot;&lt;br /&gt;#define SCSIPORT_SYS_FILENAME &quot;ScsiPort.sys&quot;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;PVOID pScsiPortImageAddress;&lt;br /&gt;&lt;br /&gt;ULONG uIoCreateSymbolicLinkRVA;&lt;br /&gt;ULONG uImageSize;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;// 전체 파일경로로부터 특정 모듈에 대한 IAT 함수(IoCreateSymbolicLink) RVA를 가져옵니다.&lt;br /&gt;uIoCreateSymbolicLinkRVA = IATFunctionRVAFromFile(SCSIPORT_SYS_FILEPATH, &quot;ntoskrnl&quot;, &quot;IoCreateSymbolicLink&quot;);&lt;br /&gt;if (uIoCreateSymbolicLinkRVA == 0)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;HookIoCreateSymbolicLinkHookForScsiPort : IATFunctionRVAFromFile fail.\n&quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return ;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;// 후킹하는 모듈에 메모리 주소를 가져옵니다.&lt;br /&gt;pScsiPortImageAddress = GetImageAddress(SCSIPORT_SYS_FILENAME, &amp;amp;uImageSize);&lt;br /&gt;if (pScsiPortImageAddress == NULL)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;HookIoCreateSymbolicLinkHookForScsiPort : GetImageAddress fail.\n&quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return ;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;// RVA가 이미지 크기보다 크다면 잘 못 된 값을 가져온 것입니다.&lt;br /&gt;if (uIoCreateSymbolicLinkRVA &amp;gt;= uImageSize)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;HookIoCreateSymbolicLinkHookForScsiPort : uIoCreateSymbolicLinkRVA &amp;gt;= uImageSize\n&quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return ;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;// IAT 후킹을 하며, Scsiport.sys에서 IoCreateSymbolicLink 함수를 호출 시 DummyIoCreateSymbolicLink함수가 호출되게 됩니다.&lt;br /&gt;ExchangeProtectedIATPointer((PVOID)((ULONG_PTR)pScsiPortImageAddress + (ULONG_PTR)uIoCreateSymbolicLinkRVA), DummyIoCreateSymbolicLink);&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;NTSTATUS &lt;br /&gt;&amp;nbsp; DummyIoCreateSymbolicLink(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IN PUNICODE_STRING&amp;nbsp; SymbolicLinkName,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IN PUNICODE_STRING&amp;nbsp; DeviceName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;hi DummyIoCreateSymbolicLink :)\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = MyIoCreateUnprotectedSymbolicLink(SymbolicLinkName, DeviceName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Successed.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ntStatus;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;/////////////////////////////////////////////////////////////////////////////////////////&lt;/p&gt;&lt;p&gt;// 여기서부터 불러다 쓰면 되는 함수가 정의되어 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;/////////////////////////////////////////////////////////////////////////////////////////&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ULONG IATFunctionRVAFromFile(WCHAR *FileName, UCHAR *ModuleName, UCHAR *FunctionName)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE FileHandle;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IMAGE_DOS_HEADER DosHeader;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // 참고 !! : NtImage.h 헤더를 Include하였고 내부적으로 64비트인지 32비트인지에 따라서 &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // IMAGE_NT_HEADERS는 IMAGE_NT_HEADERS32, IMAGE_NT_HEADERS64로 나누어집니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IMAGE_NT_HEADERS NTHeader;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IMAGE_SECTION_HEADER ImageSectionHeader;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IMAGE_IMPORT_DESCRIPTOR ImageImportDescriptor;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; PUCHAR pImageImportByNameBuffer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ImageImportByNameBufferLength;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG FunctionNameLength;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; PUCHAR pModuleNameBuffer;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ModuleNameLength;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ImportTableRVA;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ImportNameTableRVA;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // ImportNameTable 각 배열의 크기는 32비트 PE Format에 경우 32비트이며 64비트에 경우 64비트입니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG_PTR ImportNameTable;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; LARGE_INTEGER Offset;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; LARGE_INTEGER SectionHeaderOffset;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; LARGE_INTEGER ImportDescriptorOffset;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; LARGE_INTEGER ImportNameTableOffset;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int i;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int j;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int iCount;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (FileName == NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ModuleName == NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (FunctionName == NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; FunctionNameLength = strlen(FunctionName);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (FunctionNameLength == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleNameLength = strlen(ModuleName);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ModuleNameLength == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = IoOpenNormalFile(FileName, &amp;amp;FileHandle);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (FileHandle == NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ImageImportByNameBufferLength = FunctionNameLength + sizeof(USHORT);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; pImageImportByNameBuffer = ExAllocatePoolWithTag(PagedPool, ImageImportByNameBufferLength, POOL_TAG);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pImageImportByNameBuffer == NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; pModuleNameBuffer&amp;nbsp; = ExAllocatePoolWithTag(PagedPool, ModuleNameLength, POOL_TAG);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pModuleNameBuffer == NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(pImageImportByNameBuffer, 0);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; __try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.QuadPart = 0x00;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, &amp;amp;DosHeader, &amp;amp;Offset, sizeof(DosHeader)) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 올바른 시그내쳐를 갖고 있는지 확인합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (DosHeader.e_magic != 0x5A4D)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Invalid dos_header.\n&quot;));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // NTHeader 파일 오프셋을 구합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.QuadPart = DosHeader.e_lfanew;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, &amp;amp;NTHeader, &amp;amp;Offset, sizeof(NTHeader)) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 올바른 시그내쳐를 갖고 있는지 확인합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NTHeader.Signature != 0x00004550)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Invalid nt_header\n&quot;));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NTHeader.FileHeader.NumberOfSections == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 섹션의 개수가 0입니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Invalid NumberOfSections\n&quot;));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Import Table에 RVA 주소를 저장합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ImportTableRVA = NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SectionHeaderOffset.QuadPart = Offset.QuadPart + sizeof(NTHeader);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for (i = 0; i &amp;lt; (int)NTHeader.FileHeader.NumberOfSections; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, &amp;amp;ImageSectionHeader, 
&amp;amp;SectionHeaderOffset, sizeof(ImageSectionHeader)) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if 
((NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
 &amp;gt;= ImageSectionHeader.VirtualAddress)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;&amp;amp; 
(NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
 &amp;lt; (ImageSectionHeader.VirtualAddress + 
ImageSectionHeader.Misc.VirtualSize)))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 임포트 테이블에 해당하는 섹션을 찾았습니다.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // IMAGE_IMPORT_DESCRIPTOR 구조체가 있는 파일 오프셋을 구합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ImportDescriptorOffset.QuadPart = 
NTHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
 - ImageSectionHeader.VirtualAddress + 
ImageSectionHeader.PointerToRawData;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for (j = 0; j &amp;lt; 10; j++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, 
&amp;amp;ImageImportDescriptor, &amp;amp;ImportDescriptorOffset, 
sizeof(ImageImportDescriptor)) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (ImageImportDescriptor.OriginalFirstThunk == 0x00000000)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // NULL 임포트 디스크립터라면 임포트 테이블을 모두 순회한 것입니다.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 라이브러리 이름 RVA 주소에 대한 파일 오프셋을 구합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.QuadPart = ImageImportDescriptor.Name - 
ImageSectionHeader.VirtualAddress + ImageSectionHeader.PointerToRawData;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, pModuleNameBuffer, &amp;amp;Offset, ModuleNameLength) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (memcmp(pModuleNameBuffer, ModuleName, ModuleNameLength) == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // ntoskrnl 이 맞다면 원하는 임포트 디스크립터 테이블을 찾은 것입니다. ( RVA 주소에 대한 파일 오프셋을 구합니다. )&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ImportNameTableOffset.QuadPart = 
ImageImportDescriptor.OriginalFirstThunk - 
ImageSectionHeader.VirtualAddress + ImageSectionHeader.PointerToRawData;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; iCount = 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; while (TRUE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, 
&amp;amp;ImportNameTable, &amp;amp;ImportNameTableOffset, 
sizeof(ImportNameTable)) == FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (ImportNameTable == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 값이 0 이라면 모두 순회한 것입니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // IMAGE_IMPORT_BY_NAME 오프셋을 구합니다. ( RVA 주소에 대한 파일 오프셋을 구합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.QuadPart = ImportNameTable - 
ImageSectionHeader.VirtualAddress + ImageSectionHeader.PointerToRawData;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (IoReadNormalFile(FileHandle, 
pImageImportByNameBuffer, &amp;amp;Offset, ImageImportByNameBufferLength) ==
 FALSE)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (memcmp(pImageImportByNameBuffer + sizeof(USHORT), FunctionName, FunctionNameLength) == 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 찾았습니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (ImageImportDescriptor.FirstThunk
 + (iCount *&amp;nbsp; sizeof(PVOID))/* + NTHeader.OptionalHeader.ImageBase*/);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ImportNameTableOffset.QuadPart += sizeof(ImportNameTable);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; iCount++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 위에 while 문으로터 검색에 실패하였습니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 다음 임포트 디스크립터를 검색합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ImportDescriptorOffset.QuadPart += sizeof(ImageImportDescriptor);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 위에서 루프를 돌았지만 검색에 실패하였습니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 다음 섹션을 검사합니다.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SectionHeaderOffset.QuadPart += sizeof(ImageSectionHeader);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; __finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pModuleNameBuffer != NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(pModuleNameBuffer, POOL_TAG);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pImageImportByNameBuffer != NULL)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(pImageImportByNameBuffer, POOL_TAG);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;
}&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;PVOID GetImageAddress(CHAR *ImageFileName, ULONG *pImageSize)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS Status;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PRTL_PROCESS_MODULES ModuleInfo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PRTL_PROCESS_MODULE_INFORMATION ModuleEntry;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ReturnedLength;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG i;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID pImageAddress;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Figure out how much size we need&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = ZwQuerySystemInformation(SystemModuleInformation,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;ReturnedLength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (Status != STATUS_INFO_LENGTH_MISMATCH) return NULL;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Allocate a buffer large enough&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //ModuleInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnedLength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleInfo = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag(NonPagedPool, ReturnedLength, POOL_TAG);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!ModuleInfo) return NULL;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Now query the data again&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = ZwQuerySystemInformation(SystemModuleInformation,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleInfo,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReturnedLength,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;ReturnedLength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!NT_SUCCESS(Status))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(ModuleInfo, POOL_TAG);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Loop all the drivers&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (i = 0; i &amp;lt; ModuleInfo-&amp;gt;NumberOfModules; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Get the current entry and check if the pointer is within it&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleEntry = &amp;amp;ModuleInfo-&amp;gt;Modules[i];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (_stricmp(ModuleEntry-&amp;gt;FullPathName + ModuleEntry-&amp;gt;OffsetToFileName, ImageFileName) == 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 주소를 미리 얻은 후에 ExFreePoolWithTag 함수를 호출해야 합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // ( 그렇지 않으면 블루 스크린이 발생할 수 있습니다. )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pImageAddress = ModuleEntry-&amp;gt;ImageBase;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pImageSize != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; *pImageSize = ModuleEntry-&amp;gt;ImageSize;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(ModuleInfo, POOL_TAG);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (pImageAddress);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(ModuleInfo, POOL_TAG);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;void ExchangeProtectedIATPointer(PVOID IATPointerAddress, PVOID NewAddress)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PMDL pMdl;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUCHAR pBuffer;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pMdl = IoAllocateMdl(IATPointerAddress, sizeof(PVOID), FALSE, FALSE, NULL);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pMdl == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmBuildMdlForNonPagedPool(pMdl);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pBuffer = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pBuffer == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; IoFreeMdl(pMdl);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // InterlockedExchangePointer(&amp;amp;pBuffer, NewAddress);&amp;nbsp; &amp;lt;= 이렇게 하면 안되고&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // InterlockedExchangePointer(pBuffer, NewAddress); &amp;lt;= 이렇게 해야 합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 포인터의 값을 바꾸는것이 아니라 포인터가 가르키는 실제 값을 바꾸는 것이기 때문입니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 꼭 Interlocked 함수를 사용하지 않고 바로 대입해도 상관이 없습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 그러나 한 번에 대입되는 방식이 아닌 Byte단위나 Word 단위 등에 방식은 동기화 문제를 발생시킬 수 있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterlockedExchangePointer((PVOID *)pBuffer, NewAddress);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmUnmapLockedPages(pBuffer, pMdl);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IoFreeMdl(pMdl);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>DEVICE_OBJECT에 대한 보안 디스크립터 변경</title>
      <id>http://simples.kr/38943</id>
      <published>2011-06-11T09:42:12+09:00</published>
      <updated>2011-06-11T09:42:26+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/38943"/>
      <link rel="replies" type="text/html" href="http://simples.kr/38943#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;SCSI Miniport와 같은 프레임 워크를 이용하여 개발을 할 때 내부 프레임 워크에서 자동으로 DEVICE_OBJECT를 생성하게 됩니다.&lt;/p&gt;&lt;p&gt;이 때 생성되는 DEVICE_OBJECT에 보안 디스크립터 설정이 기본적으로 높게 잡혀져 있습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;따라서 어플리케이션에서 생성 된 DEVICE_OBJECT와 통신할 때 비스타 이상에서는 관리자 권한으로 실행하여,&lt;/p&gt;&lt;p&gt;해당 DEVICE_OBJECT와 통신을 해야 하는데, 이미 만들어진 DEVICE_OBJECT에 대한 보안 디스크립터 권한을&lt;/p&gt;&lt;p&gt;최소로 할당하여, 관리자 권한없이 접근할 수 있게 만들어주는 함수입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;BOOLEAN SetUnprotectedSecurityDescriptor(PDEVICE_OBJECT pDeviceObject)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE FileHandle;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SECURITY_DESCRIPTOR SecurityDescriptor;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 보호되지 않은 보안 디스크립터를 만드는 방법은 IoCreateUnprotectedSymbolicLink Windows 2000 소스코드를 참고하였습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;SecurityDescriptor, 0, sizeof(SECURITY_DESCRIPTOR));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = RtlCreateSecurityDescriptor(&amp;amp;SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = RtlSetDaclSecurityDescriptor(&amp;amp;SecurityDescriptor,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; TRUE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; TRUE);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //does not over-ride inheritable protection&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileHandle = NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ObOpenObjectByPointer(pDeviceObject,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; OBJ_KERNEL_HANDLE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WRITE_DAC,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KernelMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;FileHandle);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (FileHandle == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwSetSecurityObject(FileHandle, DACL_SECURITY_INFORMATION, &amp;amp;SecurityDescriptor);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return NT_SUCCESS(ntStatus);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>IE Cache 경로 변경하기</title>
      <id>http://simples.kr/38909</id>
      <published>2011-06-09T18:43:08+09:00</published>
      <updated>2011-06-09T18:51:16+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/38909"/>
      <link rel="replies" type="text/html" href="http://simples.kr/38909#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;IE Cache 경로를 변경하는 것은 문서화되어 있지 않으며, 분석을 통해서 진행하였습니다.&lt;/p&gt;&lt;p&gt;( 레지스트리 값을 바꾸는 방식이 아니라 인터넷 옵션에서 바로 변경하는 방식 )&lt;br /&gt;&lt;/p&gt;&lt;p&gt;분석 된 코드를 올립니다. ( Windows XP용 )&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;추가적인 내용은 아래에 주소에서 찾을 수 있습니다.&lt;/p&gt;&lt;p&gt;http://msdn.microsoft.com/en-us/library/ms905660.aspx&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;/*&lt;br /&gt;인터넷 익스폴로러 등록정보에서 캐시폴더의 위치를 변경하면 다음과 같은 함수를 이용하여 변경을 합니다.&lt;br /&gt;그러나 UpdateUrlCacheContentPath 함수가 Undocumented 되어 있으며 그냥 Undocumented되어 있는정도가 아니라&lt;br /&gt;이 함수를 사용하는 어떠한 정보도 MS및 구글에 없습니다. ReactOS에도 없습니다.&lt;br /&gt;다행이 인자가 엄청나게 간단해서 함수를 호출하는 방법을 알 수 있었습니다.&lt;br /&gt;&lt;br /&gt;UpdateUrlCacheContentPath 함수를 호출할때의 스택입니다.&lt;br /&gt;이 함수는 완전히 Undocumented 되어 있는 함수입니다.&lt;br /&gt;0007D664&amp;nbsp;&amp;nbsp; 69488538&amp;nbsp; RETURN to inetcpl.69488538 from inetcpl.6948EC10&lt;br /&gt;0007D668&amp;nbsp;&amp;nbsp; 0007DEB4&amp;nbsp; ASCII &quot;E:\Temporary Internet Files&quot; ( 유니코드가 아닙니다. 그냥 아스키문자열입니다. )&lt;br /&gt;0007D66C&amp;nbsp;&amp;nbsp; 00000001&lt;br /&gt;0007D670&amp;nbsp;&amp;nbsp; 00000000&lt;br /&gt;0007D674&amp;nbsp;&amp;nbsp; 000BDB98&lt;br /&gt;0007D678&amp;nbsp;&amp;nbsp; 00000001&lt;br /&gt;0007D67C&amp;nbsp;&amp;nbsp; 00000013&lt;br /&gt;0007D680&amp;nbsp;&amp;nbsp; 00000000&lt;br /&gt;0007D684&amp;nbsp;&amp;nbsp; 00000002&lt;br /&gt;0007D688&amp;nbsp;&amp;nbsp; 00000280&lt;br /&gt;0007D68C&amp;nbsp;&amp;nbsp; 005AE668&lt;br /&gt;0007D690&amp;nbsp;&amp;nbsp; 0007D6D4&lt;br /&gt;&lt;br /&gt;// UpdateUrlCacheContentPath 다음과 같은 방식으로 호출합니다.&lt;br /&gt;// 이전에도 말햇듯이 이 함수는 완전히 Undocumented 되어 있는 함수이므로 어떠한 문서에도 이 함수사용방법이 나와 있지 않습니다.&lt;br /&gt;6948EC0B&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC0C&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC0D&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC0E&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC0F&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC10&amp;nbsp;&amp;nbsp; 8BFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV EDI,EDI&lt;br /&gt;6948EC12&amp;nbsp;&amp;nbsp; 55&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUSH EBP&lt;br /&gt;6948EC13&amp;nbsp;&amp;nbsp; 8BEC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV EBP,ESP&lt;br /&gt;6948EC15&amp;nbsp;&amp;nbsp; A1 A02D4A69&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV EAX,DWORD PTR DS:[694A2DA0]&lt;br /&gt;6948EC1A&amp;nbsp;&amp;nbsp; 85C0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TEST EAX,EAX&lt;br /&gt;6948EC1C&amp;nbsp;&amp;nbsp; 75 1B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JNZ SHORT inetcpl.6948EC39&lt;br /&gt;6948EC1E&amp;nbsp;&amp;nbsp; 68 28264869&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUSH inetcpl.69482628&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; ASCII &quot;WININET.DLL&quot;&lt;br /&gt;6948EC23&amp;nbsp;&amp;nbsp; FF15 68104869&amp;nbsp;&amp;nbsp;&amp;nbsp; CALL DWORD PTR DS:[&amp;lt;&amp;amp;KERNEL32.LoadLibrar&amp;gt;; kernel32.LoadLibraryA&lt;br /&gt;6948EC29&amp;nbsp;&amp;nbsp; 33C9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XOR ECX,ECX&lt;br /&gt;6948EC2B&amp;nbsp;&amp;nbsp; 85C0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TEST EAX,EAX&lt;br /&gt;6948EC2D&amp;nbsp;&amp;nbsp; 0F95C1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SETNE CL&lt;br /&gt;6948EC30&amp;nbsp;&amp;nbsp; A3 A02D4A69&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV DWORD PTR DS:[694A2DA0],EAX&lt;br /&gt;6948EC35&amp;nbsp;&amp;nbsp; 85C9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TEST ECX,ECX&lt;br /&gt;6948EC37&amp;nbsp;&amp;nbsp; 74 22&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JE SHORT inetcpl.6948EC5B&lt;br /&gt;6948EC39&amp;nbsp;&amp;nbsp; 8B0D DC2D4A69&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV ECX,DWORD PTR DS:[694A2DDC]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; WININET.UpdateUrlCacheContentPath&lt;br /&gt;6948EC3F&amp;nbsp;&amp;nbsp; 85C9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TEST ECX,ECX&lt;br /&gt;6948EC41&amp;nbsp;&amp;nbsp; 75 1E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JNZ SHORT inetcpl.6948EC61&lt;br /&gt;6948EC43&amp;nbsp;&amp;nbsp; 68 AC264869&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUSH inetcpl.694826AC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; ASCII &quot;UpdateUrlCacheContentPath&quot;&lt;br /&gt;6948EC48&amp;nbsp;&amp;nbsp; 50&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUSH EAX&lt;br /&gt;6948EC49&amp;nbsp;&amp;nbsp; FF15 08114869&amp;nbsp;&amp;nbsp;&amp;nbsp; CALL DWORD PTR DS:[&amp;lt;&amp;amp;KERNEL32.GetProcAdd&amp;gt;; kernel32.GetProcAddress&lt;br /&gt;6948EC4F&amp;nbsp;&amp;nbsp; 8BC8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV ECX,EAX&lt;br /&gt;6948EC51&amp;nbsp;&amp;nbsp; 85C9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TEST ECX,ECX&lt;br /&gt;6948EC53&amp;nbsp;&amp;nbsp; 890D DC2D4A69&amp;nbsp;&amp;nbsp;&amp;nbsp; MOV DWORD PTR DS:[694A2DDC],ECX&lt;br /&gt;6948EC59&amp;nbsp;&amp;nbsp; 75 06&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JNZ SHORT inetcpl.6948EC61&lt;br /&gt;6948EC5B&amp;nbsp;&amp;nbsp; 33C0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XOR EAX,EAX&lt;br /&gt;6948EC5D&amp;nbsp;&amp;nbsp; 5D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; POP EBP&lt;br /&gt;6948EC5E&amp;nbsp;&amp;nbsp; C2 0400&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RETN 4&lt;br /&gt;6948EC61&amp;nbsp;&amp;nbsp; 5D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; POP EBP&lt;br /&gt;6948EC62&amp;nbsp;&amp;nbsp; FFE1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JMP ECX&lt;br /&gt;6948EC64&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC65&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC66&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC67&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;6948EC68&amp;nbsp;&amp;nbsp; CC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT3&lt;br /&gt;&lt;br /&gt;// 위 함수에 리턴타입은 void 형인 것 같으며. ( 아직 확실하지 않음.. ) 인자는 PCHAR를 인자로 받습니다.&lt;br /&gt;// 6948EC62&amp;nbsp;&amp;nbsp; FFE1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JMP ECX ( JMP [WININET.UpdateUrlCacheContentPath] )&lt;br /&gt;// 이 부분이 이 함수를 호출하는 부분입니다.&lt;br /&gt;// 그러나 CALL 명령어로 해야맞는걸로 알고 있습니다.&lt;br /&gt;// 위에서는 직접 CALL명령어 자체를 구현하고 있는 것으로 보이며 XP SP3에서는 바로 CALL를 합니다.&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;void&amp;nbsp; WalkCache()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 중국넘들이 작성한 소스코드입니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 그냥 URL캐시 리스트를 출력하는 코드이지만 Undocumented된 API를 호출하기 위해서&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 반드시 필요합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE byBuffer[20480];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LPINTERNET_CACHE_ENTRY_INFO lpInfo = LPINTERNET_CACHE_ENTRY_INFO(byBuffer);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD dwSize =&amp;nbsp; sizeof(byBuffer);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lpInfo-&amp;gt;dwStructSize = sizeof(INTERNET_CACHE_ENTRY_INFO);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE h;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOL bSuccess&amp;nbsp; = TRUE;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for&amp;nbsp;&amp;nbsp; (h = FindFirstUrlCacheEntryEx(NULL, 0, URLCACHE_FIND_DEFAULT_FILTER, 0, lpInfo, &amp;amp;dwSize, 0, 0, 0); h &amp;amp;&amp;amp; bSuccess;&amp;nbsp; bSuccess = FindNextUrlCacheEntryEx(h, lpInfo, &amp;amp;dwSize, 0, 0, 0))&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; dwSize = sizeof(byBuffer);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; TRACE(&quot;%s\n&quot;, lpInfo-&amp;gt;lpszSourceUrlName);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FindCloseUrlCache(h);&amp;nbsp; &lt;br /&gt;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;typedef int (__stdcall *UpdateUrlCacheContentPath)(CHAR *lpPath);&lt;br /&gt;BOOL SetInternetExplorerCacheFolder(CString strPath, BOOL bBackup)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HMODULE hModule;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UpdateUrlCacheContentPath pUpdateUrlCacheContentPath;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOL bResult;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bResult = TRUE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (strPath.GetLength() &amp;gt; 3)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (strPath.Right(1) == _T(&quot;\\&quot;))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strPath = strPath.Left(strPath.GetLength() - 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CStringA strAPath;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hModule = ::LoadLibrary(_T(&quot;wininet.dll&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (hModule == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pUpdateUrlCacheContentPath = (UpdateUrlCacheContentPath)::GetProcAddress(hModule, &quot;UpdateUrlCacheContentPath&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pUpdateUrlCacheContentPath == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ::FreeLibrary(hModule);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strAPath = strPath;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 주의 !! 이 함수 ( WalkCache )는 단순히 URL캐시를 출력하기 위한 용도로 호출하는 것이 아닙니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // UpdateUrlCacheContentPath함수를 호출하기전에 반드시 이 함수를 호출해주어야 합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // UpdateUrlCacheContentPath함수 내부적으로 글로벌 전역변수가 선언되어 있고 이 함수를 호출 시 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ECX레지스트리에 그 값을 저장하여 추후에 그 값을 액세스하게 됩니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 그러나 이 값은 NULL포인터를 기본적으로 갖고 있으며 WalkCache()함수를 호출해야 이값이 어떠한 포인터값을 가지게 됩니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 따라서 WalkCache와 UpdateUrlCacheContentPath함수는 하나에 통합된 함수라고 봐도 될 것 입니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // MS쪽에서 보자면 상당히 지저분하게 만들어진 Undocumented 된 API라고 볼 수 있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // UpdateUrlCacheContentPath함수는 모듈화가 전혀되어 있지 않습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 단, XP SP3이상부터는 모듈화가 되어 있어서 UpdateUrlCacheContentPath이 함수하나만 호출하여도 동작합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WalkCache();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pUpdateUrlCacheContentPath(strAPath.GetBuffer());&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ::FreeLibrary(hModule);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>32Bit 윈도우즈에서 실제 물리메모리크기 얻어오기</title>
      <id>http://simples.kr/38898</id>
      <published>2011-06-09T18:14:03+09:00</published>
      <updated>2011-06-09T18:32:50+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/38898"/>
      <link rel="replies" type="text/html" href="http://simples.kr/38898#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;32Bit 윈도우즈 에서는 4GB 이상에 물리 메모리가 장착되어 있을 때 사용가능한 물리 메모리가 3.25GB 정도로 표시가 됩니다.&lt;/p&gt;&lt;p&gt;( 단, 이 사용가능한 물리메모리는 PC 하드웨어에 따라서 약간 달라질 수 있습니다. )&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다음은 32Bit 윈도우즈 에서 4GB이상에 물리 메모리가 장착되어 있고 PAE 옵션이 활성화되어 있다면,&lt;/p&gt;&lt;p&gt;실제 물리 메모리크기를 읽어오는 방법입니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;MmGetPhysicalMemoryRanges 함수를 이용해서 윈도우즈에서 표시되는 실제 물리메모리 크기를 읽어오며,&lt;/p&gt;&lt;p&gt;그 후에 윈도우즈에서 인식하지 못 하는 물리 메모리크기를 추가로 얻어온 후 이를 합치게 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;GetPhysicalMemorySize 함수에 리턴값은 실제 물리메모리의 전체크기이며,&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;인자로 들어가는 &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;uWindowsReservedSize는 윈도우즈에서 인식하지 못 한 메모리 크기입니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;해당 소스는 커널레벨에서 작동하는 코드이며, 유저레벨에서 사용할 수 없습니다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;#define MEMORY_SCAN_START_ADDRESS ((ULONG64)4 * 1024 * 1024 * 1024)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;#define MEMORY_SCAN_BLOCK_SIZE ((ULONG64)1024 * 1024 * 16)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;// 이러한 상수는 적용해서는 안됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;// 3.25GB인 경우도 있고 3.5GB인 경우도 있고 PC마다 다르게 맵핑이 되어 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;//#define MEMORY_3_25GB_4GB_HARDWARE_MAPPED_IO_SIZE ((ULONG64)1024 * 1024 * 768);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;//#define MEMORY_HARDWARE_MAPPED_IO_START_ADDRESS ((ULONG64)3328 * 1024 * 1024);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;#define MI_CONVERT_PHYSICAL_TO_PFN(Va) (((ULONG)Va &amp;lt;&amp;lt; 3) &amp;gt;&amp;gt; 15) &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;typedef struct _PHYSICAL_MEMORY_RUN&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PFN_NUMBER BasePage;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PFN_NUMBER PageCount;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;typedef struct _PHYSICAL_MEMORY_DESCRIPTOR &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG NumberOfRuns;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PFN_NUMBER NumberOfPages; // NumberOfPages * PAGE_SIZE is physical memory size.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PHYSICAL_MEMORY_RUN Run[1]; // NumberOfRuns is the total entries.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ULONG64 GetPhysicalMemorySize(ULONG64 *uWindowsReservedSize);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;BOOLEAN IsPAEEnable()&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // CR4 레지스터를 체크하는 방법도 있지만 커널내부에서 체크를 해주는 함수가 지원됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 추후에 64비트 포팅을 위해 어셈블리 및 기계어는 사용하지 않는게 좋습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (ExIsProcessorFeaturePresent(PF_PAE_ENABLED));&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;ULONG64 GetPhysicalMemorySize(ULONG64 *uWindowsReservedSize)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PPHYSICAL_MEMORY_RANGE MmPhysicalMemoryRange;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PHYSICAL_ADDRESS AboveAddress;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SIZE_T MemoryBlockSize;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PFN_NUMBER NumberOfPages;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG64 uPhysicalMemorySize;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG64 uPhysicalMemoryBlockCount;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG NumberOfRuns;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG Run;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uPhysicalMemorySize = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmPhysicalMemoryRange = MmGetPhysicalMemoryRanges();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (MmPhysicalMemoryRange == NULL)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NumberOfRuns = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NumberOfPages = 0;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ((MmPhysicalMemoryRange[NumberOfRuns].BaseAddress.QuadPart != 0) &amp;amp;&amp;amp; (MmPhysicalMemoryRange[NumberOfRuns].NumberOfBytes.QuadPart != 0))&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NumberOfRuns++;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NumberOfPages += (PFN_NUMBER)BYTES_TO_PAGES(MmPhysicalMemoryRange[NumberOfRuns].NumberOfBytes.QuadPart);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NumberOfRuns == 0)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MemoryBlockSize = sizeof(ULONG) + sizeof(PFN_NUMBER) + sizeof(PHYSICAL_MEMORY_RUN) * NumberOfRuns;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmPhysicalMemoryBlock = ExAllocatePoolWithTag(NonPagedPool, MemoryBlockSize, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmPhysicalMemoryBlock-&amp;gt;NumberOfRuns = NumberOfRuns;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmPhysicalMemoryBlock-&amp;gt;NumberOfPages = NumberOfPages;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (Run = 0; Run &amp;lt; NumberOfRuns; Run++)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MmPhysicalMemoryBlock-&amp;gt;Run[Run].BasePage = (PFN_NUMBER)MI_CONVERT_PHYSICAL_TO_PFN(MmPhysicalMemoryRange[NumberOfRuns].BaseAddress.QuadPart);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MmPhysicalMemoryBlock-&amp;gt;Run[Run].PageCount = (PFN_NUMBER)BYTES_TO_PAGES(MmPhysicalMemoryRange[Run].NumberOfBytes.QuadPart);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uPhysicalMemorySize = MmPhysicalMemoryBlock-&amp;gt;NumberOfPages * PAGE_SIZE;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExFreePoolWithTag(MmPhysicalMemoryBlock, 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DbgPrint(&quot;Windows Based Memory Size : uPhysicalMemorySize %I64u\n&quot;, uPhysicalMemorySize);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 4GB 주소부터 메모리를 스캔합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AboveAddress.QuadPart = MEMORY_SCAN_START_ADDRESS;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IsPAEEnable() == TRUE)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 반드시 PAE가 활성화되어 있을 경우에만 접근합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 만약 PAE가 비활성화되어 있을 때 접근하게 되면 KMODE_EXCEPTION_NOT_HANDLED 블루스크린이 발생 할 수 있습니다. ( Windows 2000 계열에서 해당 블루 스크린이 발생하여 PAE를 체크하도록 변경한 것입니다. )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; while (TRUE)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID pVirtualAddress;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pVirtualAddress = MmMapIoSpace(AboveAddress, MEMORY_SCAN_BLOCK_SIZE, MmNonCached);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pVirtualAddress != NULL)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID pCheckAddress;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG uOldData;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 참고...&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // MmMapIoSpace 리턴받은 가상주소는 결국에는 물리 메모리주소를 가르키게 됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 여기서 중요한 부분은 만약 물리 메모리주소가 실제 하드웨어에 6GB 메모리가 설치되어 있고 7GB주소에 접근하려고 하여도&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 에러가 발생하지 않습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 이것은 윈도우즈 운영체제에서 관리하는 것이 아니며 CPU에서 발생하는 것입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 존재하지 않은 메모리에 접근하였다면 일반적으로 읽어온 데이터는 비트가 모두 1을 가집니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pCheckAddress = (UCHAR *)pVirtualAddress;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; uOldData = *(ULONG *)pCheckAddress;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // xor 연산을 한 후 값을 씁니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; *(ULONG *)pCheckAddress = *(ULONG *)pCheckAddress ^ 0x55AA55AA;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (*(ULONG *)pCheckAddress == uOldData)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // xor연산을 하여 값을 썼음에도 불구하고 이전 데이터와 동일하다면 이 메모리 주소는 존재하지 않는 메모리주소를 말합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MmUnmapIoSpace(pVirtualAddress, MEMORY_SCAN_BLOCK_SIZE);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 이 메모리 영역이 존재합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MmUnmapIoSpace(pVirtualAddress, MEMORY_SCAN_BLOCK_SIZE);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; AboveAddress.QuadPart += (ULONG64)((ULONG64)16 * 1024 * 1024);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (AboveAddress.QuadPart &amp;gt; MEMORY_SCAN_START_ADDRESS)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 4GB이후에 메모리 영역이 존재합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 적절한 계산을 통해 메모리 크기를 가져옵니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; uPhysicalMemorySize = AboveAddress.QuadPart - MEMORY_SCAN_START_ADDRESS + uPhysicalMemorySize;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (uWindowsReservedSize != NULL)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; *uWindowsReservedSize = (AboveAddress.QuadPart - MEMORY_SCAN_START_ADDRESS);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;PhysicalMemorySize : %I64uMB, ReservedSize : %I64u\n&quot;, uPhysicalMemorySize / 1024 / 1024, *uWindowsReservedSize / 1024 / 1024));&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;PhysicalMemorySize : %I64uMB\n&quot;, uPhysicalMemorySize / 1024 / 1024));&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return uPhysicalMemorySize;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>VMWare 탐지 기법 우회 - 2</title>
      <id>http://simples.kr/35057</id>
      <published>2011-04-04T10:32:01+09:00</published>
      <updated>2011-04-05T09:31:06+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/35057"/>
      <link rel="replies" type="text/html" href="http://simples.kr/35057#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-family: Gulim;&quot;&gt;대상이 되는 vmx 확장자를 가진 파일을 열어서 상황에 따라 다음 내용을 추가해줍니다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: Gulim;&quot;&gt;StarForce 3.xx - StarForce 5.7xx 버전에 VMWare 탐지를 우회하려고 하는 경우.. ( 게임 락관련 )&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;isolation.tools.getPtrLocation.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;isolation.tools.setPtrLocation.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;isolation.tools.setVersion.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;isolation.tools.getVersion.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_directexec = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_chksimd = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_ntreloc = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_selfmod = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_reloc = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_btinout = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_btmemspace = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_btpriv = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.disable_btseg = &quot;TRUE&quot;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;TheMida, WinLicense, VMProtect&lt;span style=&quot;font-weight: bold;&quot;&gt; &lt;/span&gt;로 패킹 된 프로그램에 대해 VMWare 탐지를 우회하려고 하는 경우...( 온라인 게임 관련 )&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.restrict_backdoor = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;disable_acceleration = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.vt32 = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;monitor_control.enable_svm = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;mks.enable3d = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;svga.vramsize = 67108864&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;vmmouse.present = &quot;FALSE&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>우분투에 IRC서버 설치후 닉네임 길이와 동접자 조절.</title>
      <id>http://simples.kr/28949</id>
      <published>2010-11-26T15:44:32+09:00</published>
      <updated>2010-11-26T17:20:04+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/28949"/>
      <link rel="replies" type="text/html" href="http://simples.kr/28949#comment"/>
      <author>
         <name>오랑캐꽃</name>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;이야~~ 심플즈에 리눅스 팁란이 생겼네요~~&lt;/p&gt;&lt;p&gt;얼마전 게임채팅에 써먹어볼까 싶어 우분투에 IRC 서버를 까느라 삽질한 내용이 있어서 함 올려봅니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일단 ircd는 ircu 를 사용하기로 했습니다. 설치는 간단히 이렇게..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;$ sudo apt-get install ircd-ircu&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;문제는 여기서부터인데, 닉네임의 최대값이 12자로 되어있군요. 저는 30자가 필요.&amp;nbsp;&lt;/p&gt;&lt;p&gt;설정 문서에 나온대로&amp;nbsp;/etc/ircd/ircd.conf 내에 features 안에 다음라인 삽입해 봤습니다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;features {&lt;/p&gt;&lt;p&gt;&amp;nbsp;.....&lt;/p&gt;&lt;p&gt;&amp;nbsp;&quot;NICKLEN&quot; = &quot;30&quot;;&lt;/p&gt;&lt;p&gt;};&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;하지만 이 설정은 ircd-ircu 의 소스중 ircd_def.h 에 정의된 값을 넘을 수 없습니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;여기에는 15로 정의되어있기 때문에 아무리 30자를 때려줘도 넘어가지 않지요.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;패키지로 설치한 ircd-ircu 는 지워버리고&amp;nbsp;소스를 받아 수정해봅시다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;일단 컴파일 환경을 만들어주고&lt;/div&gt;&lt;div&gt;$&amp;nbsp;sudo apt-get install build-essential&amp;nbsp;flex autoconf &amp;nbsp;bison&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;소스를 내려받아 압축을 풀어줍니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;$ wget http://prdownloads.sourceforge.net/undernet-ircu/ircu2.10.12.12.tar.gz&lt;/div&gt;&lt;div&gt;&lt;div&gt;$ tar xzf ircu2.10.12.12.tar.gz&lt;/div&gt;&lt;div&gt;$&amp;nbsp;cd ircu2.10.12.12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;여기서 ./include 안의 ircd_defs.h 에서 NICK_LEN 값을 30으로 수정해줍니다. (41번째 줄)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;#define NICKLEN &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 30&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;이제 다음과같이 해 주면 닉네임을 30자로 쓸 수 있는 데몬을 얻을 수 있습니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;$ ./configure&lt;/div&gt;&lt;div&gt;$&amp;nbsp;make all&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;../bin 에 컴파일된 ircd 실행파일이 들어갑니다. 이제 이놈의 버전을 출력해봅시다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;./ircd -v&amp;nbsp;&lt;/div&gt;&lt;div&gt;ircd u2.10.12.12&lt;/div&gt;&lt;div&gt;Event engines: epoll_*() poll()&lt;/div&gt;&lt;div&gt;Compiled for a maximum of 1020 connections.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;최대접속자가 1020으로 되어있습니다. 아쉬움이 있지요.&amp;nbsp;&lt;/div&gt;&lt;div&gt;이 내용은 ./configure 실행시 생성되는 config.h 에 기록되며,&amp;nbsp;&lt;/div&gt;&lt;div&gt;이 때 사용되는 configure.in 을 살펴보면 다음과 같은 값을 받아오도록 되어있습니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ulimit -Hn&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;한마디로 시스템에서 열 수 있는 파일갯수를 의미하지요.&amp;nbsp;&lt;/div&gt;&lt;div&gt;sudo&amp;nbsp;ulimit -n 4096 해주면 이 값이 바뀝니다만 재부팅하면 도로묵이죠.&amp;nbsp;&lt;/div&gt;&lt;div&gt;예전에는 이 값을 늘려주려면 커널을 새로 컴파일해야 했나본데... 전 그런건 모르고&amp;nbsp;&lt;/div&gt;&lt;div&gt;/etc/security/limits.conf 에 다음항목 추가한 뒤 재부팅해봅시다. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; hard &amp;nbsp; &amp;nbsp;nofile &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;4096&lt;/div&gt;&lt;div&gt;* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; soft &amp;nbsp; &amp;nbsp;nofile &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;4096&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;이제 ircd-ircu 를 재컴파일하면 최대접속자수가 늘어난 것을 볼 수 있습니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;마지막으로 닉네임에서 한글사용문제... 원래 irc 규정이 닉네임에서는 한글을 못써먹게 되어있습니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;한글 패치된 데몬들은 규격외의 물건들인 셈이죠.&amp;nbsp;&lt;/div&gt;&lt;div&gt;table_gen.c 를 들여다봅시다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;div&gt;116번 줄에보면 NTL_RICNK 의 속성을 설정하는 부분이 보입니다.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;moveMacro(NTL_DIGIT | NTL_ALPHA, NTL_IRCNK);&lt;/div&gt;&lt;div&gt;markString(NTL_IRCNK, &quot;-_`&quot;);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;숫자, 알파벳, 그리고 &quot; - _ ` &quot; 를 추가해주고 있지요. 따라서 여기에 &quot; + / &quot; 를 추가하면 UTF-7 사용이 가능해집니다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;markString(NTL_IRCNK, &quot;-_`+/&quot;);&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;사실 이것도 &quot;+/&quot; 때문에 규약을 어기는 건 마찬가지네요. ㅠㅠ;;&lt;/div&gt;&lt;div&gt;UTF-8이면 더 좋겠지만 어차피 게임내에서 자체 클라를 제공하기 때문에 일단 이정도로 만족하고 있습니다.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>VirtualBox에 우분투 설치 후에 내부 네트워크 접속 설정하기</title>
      <id>http://simples.kr/21200</id>
      <published>2010-09-10T15:32:29+09:00</published>
      <updated>2010-09-10T15:32:29+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/21200"/>
      <link rel="replies" type="text/html" href="http://simples.kr/21200#comment"/>
      <author>
         <name>esniper</name>
                  <uri>http://simples.kr</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;VirtualBox를 설치하면 Vmware처럼 가상 이더넷 카드가 내부에서 리얼머신과 가상머신과의 통신이 되도록 설정이 되어있지 않다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;설치하고 몇가지 설정만 해주면 간단하게 사용가능하다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;가상 OS의 설정창에서 네트워크 어댑터부분에서 어댑터 하나를 추가하고,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래와 같이 세팅해주면 된다. 호스트전용 어댑터로. 이렇게 해야 호스트머신(본인PC) -&amp;gt; 가상머신(설치한 우분투)로 접근가능 한 상태가 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;center&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/200/021/1.png&quot; alt=&quot;1.png&quot; class=&quot;iePngFix&quot; width=&quot;466&quot; height=&quot;338&quot; style=&quot;&quot; /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;center&gt;
&lt;/center&gt;&lt;br /&gt;&lt;/p&gt;&lt;/center&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그리고 우분투로 넘어가서 네트워크 세팅을 아래와 같이 추가해준다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;1. /etc/network/interfaces 파일을 연다.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;2. 아래 auto eht1 부분 추가해준다.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;================================&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;# The loopback network interface&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;auto lo&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;iface lo inet loopback&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;# The primary network interface&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;auto eth0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;iface eth0 inet dhcp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;auto eth1&lt;/p&gt;&lt;p&gt;iface eth1 inet static&lt;/p&gt;&lt;p&gt;address 192.168.56.105&lt;/p&gt;&lt;p&gt;netmask 255.255.255.0&lt;/p&gt;&lt;p&gt;gateway 192.168.56.1&lt;/p&gt;&lt;p&gt;dns-nameservers 168.126.63.1&lt;/p&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal; &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;&lt;p style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal; &quot;&gt;================================&lt;/span&gt;&lt;/p&gt;&lt;/strong&gt;&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3. /etc/init.d/networking rest&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal; &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;&lt;p style=&quot;display: inline !important; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;art&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: 돋움, Dotum, AppleGothic, sans-serif; line-height: 15px; color: rgb(62, 62, 62); &quot;&gt;&lt;strong style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; line-height: 1.3; font-family: 돋움, Dotum, AppleGothic, sans-serif; &quot;&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font class=&quot;Apple-style-span&quot; color=&quot;#3E3E3E&quot; face=&quot;돋움, Dotum, AppleGothic, sans-serif&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 15px;&quot;&gt;이렇게 서비스 재시작을 해주고나면 네트워크가 설정이 완료된다.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>VirtualBox에서 오른쪽 CTRL키 사용하기(VitualBox 호스트키)</title>
      <id>http://simples.kr/21196</id>
      <published>2010-09-10T15:17:55+09:00</published>
      <updated>2010-09-16T15:28:19+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/21196"/>
      <link rel="replies" type="text/html" href="http://simples.kr/21196#comment"/>
      <author>
         <name>esniper</name>
                  <uri>http://simples.kr</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;가상 OS를 설치할 수 있는&amp;nbsp;VirtualBox를 처음 설치하면 오른쪽 Ctrl키를 눌러서 가상OS에서 빠져나올 수 있다고 하는데,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;오른쪽 CTRL키가 안먹는 경우가 있습니다. 이럴땐 놀라지 마시고, Ctrl + Alt + Delete 키로 일단 급한대로 빠져나오시고,&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;오른쪽 CTRL키가 적용될 수 있도로 키보드 드라이버 옵션을 바꿔주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;장치관리자에서 키보드 보시면, 101키로 되어있는데 속성 들어가서 드라이버 업데이트를 누르고, 호환성 체크 푸시고 나오는 키보드 드라이버 목록에서 103/106키라고 적힌걸 선택해주면 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;center&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/196/021/1.png&quot; alt=&quot;1.png&quot; class=&quot;iePngFix&quot; width=&quot;595&quot; height=&quot;520&quot; style=&quot;&quot; /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/center&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>우분투 설치 후 putty에서 한글 안 깨지도록 설정하기</title>
      <id>http://simples.kr/21189</id>
      <published>2010-09-10T14:50:48+09:00</published>
      <updated>2010-09-10T14:50:48+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/21189"/>
      <link rel="replies" type="text/html" href="http://simples.kr/21189#comment"/>
      <author>
         <name>esniper</name>
                  <uri>http://simples.kr</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;보통 리눅스를 한글언어로 설치하고 나서 putty로 원격접속을 하면 한글이 깨지게 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이런 경우에 putty의 옵션을 2가지 바꿔주면 깔끔하게 한글이 출력된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;center&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/189/021/1.png&quot; alt=&quot;1.png&quot; class=&quot;iePngFix&quot; width=&quot;576&quot; height=&quot;565&quot; style=&quot;&quot; /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;center&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/189/021/2.png&quot; alt=&quot;2.png&quot; class=&quot;iePngFix&quot; width=&quot;456&quot; height=&quot;438&quot; style=&quot;&quot; /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/center&gt;&lt;/center&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>우분투 ssh or mysql 서버 접속지연이 있는 경우 해결책</title>
      <id>http://simples.kr/21187</id>
      <published>2010-09-10T14:37:46+09:00</published>
      <updated>2010-09-10T14:37:46+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/21187"/>
      <link rel="replies" type="text/html" href="http://simples.kr/21187#comment"/>
      <author>
         <name>esniper</name>
                  <uri>http://simples.kr</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;div&gt;SSH이나 Mysql을 클라이언트가 서버로 접속시에&amp;nbsp;어떤 곳에서는 그냥 바로 접속이 되는데,&amp;nbsp;어떤 것은 몇초 씩이나 지연이 되는 경우가 있었다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;그 원인은 SSH이나 Mysql 서비스 데몬이 접속한 클라이언트의 IP가 정상적인지&amp;nbsp;체크하기 위해서&amp;nbsp;Reverse DNS 체크를 하기 때문에 느려지는 것이였다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;해결책은 아래와 같이 환경설정을 수정해주면 된다.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;[SSH의 경우]&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;/etc/ssh/sshd_config&amp;nbsp;에&lt;/div&gt;&lt;div&gt;&lt;b&gt;UseDNS no&lt;/b&gt;&lt;/div&gt;&lt;div&gt;를 설정하거나 이미 있다면 yes를 no로 변경하면 된다.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;[Mysql의 경우]&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;mysql의 config 파일인 my.cnf에&lt;/div&gt;&lt;div&gt;[mysqld]&amp;nbsp;section에다가&amp;nbsp;&lt;/div&gt;&lt;div&gt;skip-name-resolve&lt;/div&gt;&lt;div&gt;한줄을 추가해주면 된다.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>고품질의 무료 아이콘들</title>
      <id>http://simples.kr/20886</id>
      <published>2010-09-08T10:15:38+09:00</published>
      <updated>2010-09-09T00:25:32+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/20886"/>
      <link rel="replies" type="text/html" href="http://simples.kr/20886#comment"/>
      <author>
         <name>esniper</name>
                  <uri>http://simples.kr</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;프로그래밍을 하다보면 내 바이너리를 이쁘게 장식해줄 아이콘이 항상 필요합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;요번에 보니 정말 이쁘고 좋은 아이콘들이 무료로 제공되는 사이트들이 있더라구요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;한번 구경들 해보세요~&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;개인에게만 무료이거나 상용으로 쓸 때 주의해야하는 것들이 섞여있으니 상용배포시에는 주의하세요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;http://sixrevisions.com/resources/50-amazing-free-icon-sets/&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://omercetin.deviantart.com/art/PixeloPhilia2-166570194&quot;&gt;&lt;img alt=&quot;PixeloPhilia2&quot; src=&quot;http://images.sixrevisions.com/2010/07/02-11_amazing_icon_sets_pixelophilia2.jpg&quot; width=&quot;550&quot; height=&quot;176&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://tatice.deviantart.com/art/Browsers-Navigateurs-160607320&quot;&gt;&lt;img alt=&quot;Browsers - Navigateurs&quot; src=&quot;http://images.sixrevisions.com/2010/07/02-49_amazing_icon_sets_browsers_navigateurs.jpg&quot; width=&quot;550&quot; height=&quot;238&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그리고 엄청난 양의 미니 아이콘도 아래 사이트에 가면 있습니다~&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.webdesignerdepot.com/2010/08/a-collection-of-mini-icon-sets/&quot;&gt;http://www.webdesignerdepot.com/2010/08/a-collection-of-mini-icon-sets/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;http://netdna.webdesignerdepot.com/uploads/2010/08/5.gif&quot; alt=&quot;5&quot;/&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Sysinternals - Filemon source code</title>
      <id>http://simples.kr/20035</id>
      <published>2010-09-04T19:01:49+09:00</published>
      <updated>2010-09-07T20:27:55+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/20035"/>
      <link rel="replies" type="text/html" href="http://simples.kr/20035#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px; color: rgb(102, 102, 102); font-family: Tahoma, 돋움, sans-serif; &quot;/&gt;&lt;p/&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px; color: rgb(102, 102, 102); font-family: Tahoma, 돋움, sans-serif; &quot;/&gt;꽤 오래된 소스코드이지만 하드에서 증발할 가능성이 있어서 이곳에 올립니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px; color: rgb(102, 102, 102); font-family: Tahoma, 돋움, sans-serif; &quot;/&gt;참고로 WDK Samples에 보면 Minispy라고 Filemon가 같은 역할을 하는 MiniFilter 드라이버 예제코드가 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px; color: rgb(102, 102, 102); font-family: Tahoma, 돋움, sans-serif; &quot;/&gt;&lt;/span&gt;


&lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Sysinternals - Regmon source code</title>
      <id>http://simples.kr/20023</id>
      <published>2010-09-04T17:50:20+09:00</published>
      <updated>2010-09-05T22:28:35+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/20023"/>
      <link rel="replies" type="text/html" href="http://simples.kr/20023#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;첨부파일에 포함시켰습니다.&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>PostQueuedCompletionStatus 함수에 실패 여부도 고려해야 할까?</title>
      <id>http://simples.kr/19988</id>
      <published>2010-09-04T12:14:27+09:00</published>
      <updated>2010-09-04T12:14:27+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19988"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19988#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;CreateIoCompletionPort 함수는 내부적으로 NtCreateIoCompletion 함수를 호출하게 되는데&lt;br /&gt;다음과 같이 생겼습니다. ( 디컴파일 결과만 보여줍니다. )&lt;br /&gt;&lt;br /&gt;NTSTATUS
 __stdcall NtCreateIoCompletion(PHANDLE IoCompletionHandle, ACCESS_MASK 
DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG 
NumberOfConcurrentThreads)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; void *v4; // ecx@2&lt;br /&gt;&amp;nbsp; PHANDLE v5; // edi@2&lt;br /&gt;&amp;nbsp; char v7; // al@1&lt;br /&gt;&amp;nbsp; int v8; // eax@6&lt;br /&gt;&amp;nbsp; int v9; // esi@7&lt;br /&gt;&amp;nbsp; HANDLE *v10; // eax@7&lt;br /&gt;&amp;nbsp; int PreviousMode; // [sp+1Ch] [bp-1Ch]@1&lt;br /&gt;&amp;nbsp; CPPEH_RECORD ms_exc; // [sp+20h] [bp-18h]@4&lt;br /&gt;&amp;nbsp; int v13; // [sp+10h] [bp-28h]@6&lt;br /&gt;&amp;nbsp; void *v14; // [sp+18h] [bp-20h]@7&lt;br /&gt;&lt;br /&gt;&amp;nbsp; v7 = *(_BYTE *)(*MK_FP(__FS__, 292) + 314);&lt;br /&gt;&amp;nbsp; LOBYTE(PreviousMode) = *(_BYTE *)(*MK_FP(__FS__, 292) + 314);&lt;br /&gt;&amp;nbsp; if ( v7 )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v5 = IoCompletionHandle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v4 = IoCompletionHandle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (unsigned int)IoCompletionHandle &amp;gt;= (unsigned int)MmUserProbeAddress )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v4 = MmUserProbeAddress;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_DWORD *)v4 = *(_DWORD *)v4;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ms_exc.disabled = -2;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; else&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v5 = IoCompletionHandle;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; v8 = ObCreateObject(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (int)IoCompletionObjectType,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (int)ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 48,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (int)&amp;amp;v13);&lt;br /&gt;&amp;nbsp; IoCompletionHandle = (PHANDLE)v8;&lt;br /&gt;&amp;nbsp; if ( v8 &amp;gt;= 0 )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v9 = v13;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KeInitializeQueue(v13, NumberOfConcurrentThreads);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_DWORD *)(v9 + 40) = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_BYTE *)(v9 + 44) = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v10 = (HANDLE *)ObInsertObject(v9, 0, DesiredAccess, 0, 0, &amp;amp;v14);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IoCompletionHandle = v10;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (signed int)v10 &amp;gt;= 0 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (_BYTE)PreviousMode )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *v5 = v14;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *v5 = v14;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return (NTSTATUS)IoCompletionHandle;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;함수를 열자마자 바로 실체가 나옵니다.&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;KeInitializeQueue&lt;/span&gt; 를 호출하는 것을 볼 수 있습니다.&lt;br /&gt;즉, IOCP를 초기화하는 과정은 어떠한 특수한 함수를 호출하는것도 아니며 그냥 커널에 있는 함수인&lt;br /&gt;KeInitializeQueue 함수를 호출하며 결국엔 커널에 큐잉모델을 단지 이용하는 것일뿐입니다.&lt;br /&gt;&lt;br /&gt;그렇다면 PostQueuedCompletionStatus 함수는 구지 안봐도 어떠한 함수를 호출할지 뻔하지만&lt;br /&gt;그래도 최종적으로 호출되는 코드는 다음과 같습니다.&lt;br /&gt;&lt;br /&gt;NTSTATUS
 __stdcall NtSetIoCompletion(HANDLE IoCompletionHandle, ULONG 
CompletionKey, ULONG CompletionValue, NTSTATUS Status, ULONG 
Information)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; signed int v5; // esi@1&lt;br /&gt;&amp;nbsp; NTSTATUS v7; // eax@1&lt;br /&gt;&amp;nbsp; int AccessMode; // [sp+4h] [bp-8h]@1&lt;br /&gt;&amp;nbsp; PVOID Object; // [sp+8h] [bp-4h]@1&lt;br /&gt;&lt;br /&gt;&amp;nbsp; LOBYTE(AccessMode) = *(_BYTE *)(*MK_FP(__FS__, 292) + 314);&lt;br /&gt;&amp;nbsp; v7 = ObReferenceObjectByHandle(IoCompletionHandle, 2u, IoCompletionObjectType, AccessMode, &amp;amp;Object, 0);&lt;br /&gt;&amp;nbsp; v5 = v7;&lt;br /&gt;&amp;nbsp; if ( v7 &amp;gt;= 0 )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v5 = IoSetIoCompletion((int)Object, CompletionKey, CompletionValue, Status, Information, 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ObfDereferenceObject();&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return v5;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;signed int __stdcall IoSetIoCompletion(int a1, int a2, int a3, int a4, int a5, int a6)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; return IoSetIoCompletionEx(a1, a2, a3, a4, a5, a6, 0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;igned int __stdcall IoSetIoCompletionEx(int a1, int a2, int a3, int a4, int a5, int a6, int a7)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; void *v7; // eax@1&lt;br /&gt;&amp;nbsp; signed int v8; // esi@1&lt;br /&gt;&lt;br /&gt;&amp;nbsp; v7 = (void *)a7;&lt;br /&gt;&amp;nbsp; v8 = 0;&lt;br /&gt;&amp;nbsp; if ( a7 || (v7 = IopAllocateMiniCompletionPacket(1, a6), v7) )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *((_DWORD *)v7 + 3) = a2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *((_DWORD *)v7 + 4) = a3;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *((_DWORD *)v7 + 5) = a4;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *((_DWORD *)v7 + 6) = a5;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KiInsertQueue(v7, 0, 0);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; else&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v8 = -1073741670;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return v8;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;보시다시피 KiInsertQueue를 호출합니다. ( 참고로 KeInsertQueue 함수는 KiInsertQueue를 내부적으로 호출하므로&lt;br /&gt;거의 동일하다고 보시면 됩니다. )&lt;br /&gt;&lt;br /&gt;그렇다면 이제 PostQueuedCompletionStatus 함수에 실패여부도 고려를 해야 할 상황입니다.&lt;br /&gt;가장 첫 번째로 IOCP핸들을 잘 못 넘겼을 경우인데 그 부분은 제외하겠습니다.&lt;br /&gt;또한 KeInsertQueue 함수자체도 에러코드를 리턴하지 않습니다.&lt;br /&gt;하지만 여기서 중요한 것은 위에서 IopAllocateMiniCompletionPacket 함수를 호출하는 부분입니다.&lt;br /&gt;다음과 같이 생겼습니다.&lt;br /&gt;&lt;br /&gt;PVOID __stdcall IopAllocateMiniCompletionPacket(int a1, char a2)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; SIZE_T ST04_4_0; // ST04_4@0&lt;br /&gt;&amp;nbsp; ULONG ST08_4_0; // ST08_4@0&lt;br /&gt;&amp;nbsp; EX_POOL_PRIORITY ST0C_4_0; // ST0C_4@0&lt;br /&gt;&amp;nbsp; int ST10_4_0; // ST10_4@0&lt;br /&gt;&amp;nbsp; int ST14_4_0; // ST14_4@0&lt;br /&gt;&amp;nbsp; int ST18_4_0; // ST18_4@0&lt;br /&gt;&amp;nbsp; int ST1C_4_0; // ST1C_4@0&lt;br /&gt;&amp;nbsp; PVOID result; // eax@2&lt;br /&gt;&amp;nbsp; POOL_TYPE v10; // ebx@2&lt;br /&gt;&amp;nbsp; int v11; // edi@2&lt;br /&gt;&amp;nbsp; int v12; // esi@2&lt;br /&gt;&amp;nbsp; int v13; // esi@3&lt;br /&gt;&amp;nbsp; PVOID v14; // [sp+10h] [bp-1Ch]@2&lt;br /&gt;&lt;br /&gt;&amp;nbsp; if ( a1 == 3 )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v10 = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ST0C_4_0 = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ST08_4_0 = 544236361;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ST04_4_0 = 40;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_8;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; v11 = *MK_FP(__FS__, 32);&lt;br /&gt;&amp;nbsp; v12 = *(_DWORD *)(*MK_FP(__FS__, 32) + 1496);&lt;br /&gt;&amp;nbsp; ++*(_DWORD *)(v12 + 12);&lt;br /&gt;&amp;nbsp; result = (PVOID)RtlpInterlockedPopEntrySList(ST10_4_0, ST14_4_0);&lt;br /&gt;&amp;nbsp; v14 = result;&lt;br /&gt;&amp;nbsp; v10 = 0;&lt;br /&gt;&amp;nbsp; if ( !result )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++*(_DWORD *)(v12 + 16);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v13 = *(_DWORD *)(v11 + 1500);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++*(_DWORD *)(v13 + 12);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = (PVOID)RtlpInterlockedPopEntrySList(ST18_4_0, ST1C_4_0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v14 = result;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !result )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++*(_DWORD *)(v13 + 16);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( a2 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a1 = 2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v14 = ExAllocatePoolWithQuotaTag(0, 0x1Cu, 0x20706349u);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = v14;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_9;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;LABEL_8:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = ExAllocatePoolWithTagPriority(v10, ST04_4_0, ST08_4_0, ST0C_4_0);&lt;br /&gt;LABEL_9:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( result == (PVOID)v10 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_10;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;LABEL_10:&lt;br /&gt;&amp;nbsp; *((_DWORD *)result + 2) = a1;&lt;br /&gt;&amp;nbsp; return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;첫 번째로 고려해야 할 함수는 RtlpInterlockedPopEntrySList 입니다.&lt;br /&gt;이 함수는 다음과 같이 생겼습니다.&lt;br /&gt;&lt;br /&gt;.text:00439378 ; __fastcall RtlpInterlockedPopEntrySList(x)&lt;br /&gt;.text:00439378&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public @RtlpInterlockedPopEntrySList@4&lt;br /&gt;.text:00439378 @RtlpInterlockedPopEntrySList@4 proc near&lt;br /&gt;.text:00439378&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: MiAllocateMdlPagesByLists(x,x,x,x,x,x,x)+183&lt;br /&gt;.text:00439378&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; KeAllocateInterrupt(x)+46&lt;br /&gt;.text:00439378&lt;br /&gt;.text:00439378 var_C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword ptr -0Ch&lt;br /&gt;.text:00439378&lt;br /&gt;.text:00439378&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; ExInterlockedPopEntrySList&lt;br /&gt;.text:00439379&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;br /&gt;.text:0043937A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp, ecx&lt;br /&gt;.text:0043937C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sub&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, 4&lt;br /&gt;.text:0043937F&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;br /&gt;.text:00439381&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [esp+0Ch+var_C], eax&lt;br /&gt;.text:00439381 @RtlpInterlockedPopEntrySList@4 endp ; sp-analysis failed&lt;br /&gt;&lt;br /&gt;전혀 고려대상이 아닙니다.&lt;br /&gt;단순한 인라인 함수정도로 생각하면 될것입니다.&lt;br /&gt;( 함수가 좀 길어서 다 올리지 않았습니다. 보시면 맨 마지막에 스택분석 실패라고 나온것을 볼 수 잇죠..&lt;br /&gt;&amp;nbsp; 밑에 코드가 사실은 더 있습니다. )&lt;br /&gt;&lt;br /&gt;그 다음에 마지막으로 고려해야 할 대상은 ExAllocatePoolWithQuotaTag 함수입니다.&lt;br /&gt;( ExAllocatePoolWithTagPriority 함수도 호출하는데 이 함수는 메모리가 부족하 경우 NULL을 리턴합니다. )&lt;br /&gt;이 함수는 특이하게도 메모리가 부족해서 함수가 실패할 경우 NULL을 리턴하는게 아니라&lt;br /&gt;예외 핸들러를 실행시킵니다.&lt;br /&gt;해당 함수가 디컴파일이 되어서 안 보이겠지만 사실은 예외 핸들러가 작성되어 있습니다.&lt;br /&gt;&lt;br /&gt;PAGE:00669EDA ; __stdcall IopAllocateMiniCompletionPacket(x, x)&lt;br /&gt;PAGE:00669EDA _IopAllocateMiniCompletionPacket@8 proc near&lt;br /&gt;PAGE:00669EDA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IoSetIoCompletionEx(x,x,x,x,x,x,x)+14&lt;br /&gt;PAGE:00669EDA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; IoAllocateMiniCompletionPacket(x,x)+9&lt;br /&gt;PAGE:00669EDA&lt;br /&gt;PAGE:00669EDA var_1C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword ptr -1Ch&lt;br /&gt;PAGE:00669EDA ms_exc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = CPPEH_RECORD ptr -18h&lt;br /&gt;PAGE:00669EDA arg_0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword ptr&amp;nbsp; 8&lt;br /&gt;PAGE:00669EDA arg_4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = byte ptr&amp;nbsp; 0Ch&lt;br /&gt;PAGE:00669EDA&lt;br /&gt;PAGE:00669EDA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 0Ch&lt;br /&gt;PAGE:00669EDC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; offset dword_44C338&lt;br /&gt;PAGE:00669EE1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; __SEH_prolog4&lt;br /&gt;PAGE:00669EE6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+arg_0], 3&lt;br /&gt;PAGE:00669EEA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jz&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; loc_669F74&lt;br /&gt;PAGE:00669EF0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edi, large fs:20h&lt;br /&gt;PAGE:00669EF7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esi, [edi+5D8h]&lt;br /&gt;PAGE:00669EFD&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dword ptr [esi+0Ch]&lt;br /&gt;PAGE:00669F00&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, esi&lt;br /&gt;PAGE:00669F02&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; @RtlpInterlockedPopEntrySList@4 ; RtlpInterlockedPopEntrySList(x)&lt;br /&gt;PAGE:00669F07&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+var_1C], eax&lt;br /&gt;PAGE:00669F0A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx, ebx&lt;br /&gt;PAGE:00669F0C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, ebx&lt;br /&gt;PAGE:00669F0E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jnz&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F88&lt;br /&gt;PAGE:00669F10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dword ptr [esi+10h]&lt;br /&gt;PAGE:00669F13&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esi, [edi+5DCh]&lt;br /&gt;PAGE:00669F19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dword ptr [esi+0Ch]&lt;br /&gt;PAGE:00669F1C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, esi&lt;br /&gt;PAGE:00669F1E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; @RtlpInterlockedPopEntrySList@4 ; RtlpInterlockedPopEntrySList(x)&lt;br /&gt;PAGE:00669F23&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+var_1C], eax&lt;br /&gt;PAGE:00669F26&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, ebx&lt;br /&gt;PAGE:00669F28&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jnz&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F88&lt;br /&gt;PAGE:00669F2A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dword ptr [esi+10h]&lt;br /&gt;PAGE:00669F2D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+arg_4], bl&lt;br /&gt;PAGE:00669F30&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jz&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F6A&lt;br /&gt;PAGE:00669F32&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+arg_0], 2&lt;br /&gt;PAGE:00669F39&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+ms_exc.disabled], ebx&lt;br /&gt;PAGE:00669F3C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 20706349h&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; Tag&lt;br /&gt;PAGE:00669F41&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 1Ch&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; NumberOfBytes&lt;br /&gt;PAGE:00669F43&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; PoolType&lt;br /&gt;PAGE:00669F44&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; _ExAllocatePoolWithQuotaTag@12 ; ExAllocatePoolWithQuotaTag(x,x,x)&lt;br /&gt;PAGE:00669F49&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+var_1C], eax&lt;br /&gt;PAGE:00669F4C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+ms_exc.disabled], 0FFFFFFFEh&lt;br /&gt;PAGE:00669F53&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F65&lt;br /&gt;PAGE:00669F55 ; ---------------------------------------------------------------------------&lt;br /&gt;PAGE:00669F55&lt;br /&gt;PAGE:00669F55 loc_669F55:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; DATA XREF: .text:0044C34C&lt;br /&gt;PAGE:00669F55&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;br /&gt;PAGE:00669F57&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax&lt;br /&gt;PAGE:00669F58&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retn&lt;br /&gt;PAGE:00669F59 ; ---------------------------------------------------------------------------&lt;br /&gt;PAGE:00669F59&lt;br /&gt;PAGE:00669F59 loc_669F59:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; DATA XREF: .text:0044C350&lt;br /&gt;PAGE:00669F59&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esp, [ebp+ms_exc.old_esp]&lt;br /&gt;PAGE:00669F5C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+ms_exc.disabled], 0FFFFFFFEh&lt;br /&gt;PAGE:00669F63&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx, ebx&lt;br /&gt;PAGE:00669F65&lt;br /&gt;PAGE:00669F65 loc_669F65:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+79&lt;br /&gt;PAGE:00669F65&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, [ebp+var_1C]&lt;br /&gt;PAGE:00669F68&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F84&lt;br /&gt;PAGE:00669F6A ; ---------------------------------------------------------------------------&lt;br /&gt;PAGE:00669F6A&lt;br /&gt;PAGE:00669F6A loc_669F6A:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+56&lt;br /&gt;PAGE:00669F6A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&lt;br /&gt;PAGE:00669F6B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 20706349h&lt;br /&gt;PAGE:00669F70&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 1Ch&lt;br /&gt;PAGE:00669F72&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F7E&lt;br /&gt;PAGE:00669F74 ; ---------------------------------------------------------------------------&lt;br /&gt;PAGE:00669F74&lt;br /&gt;PAGE:00669F74 loc_669F74:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+10&lt;br /&gt;PAGE:00669F74&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx, ebx&lt;br /&gt;PAGE:00669F76&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; Priority&lt;br /&gt;PAGE:00669F77&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 20706349h&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; Tag&lt;br /&gt;PAGE:00669F7C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 28h&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; NumberOfBytes&lt;br /&gt;PAGE:00669F7E&lt;br /&gt;PAGE:00669F7E loc_669F7E:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+98&lt;br /&gt;PAGE:00669F7E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; PoolType&lt;br /&gt;PAGE:00669F7F&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; _ExAllocatePoolWithTagPriority@16 ; ExAllocatePoolWithTagPriority(x,x,x,x)&lt;br /&gt;PAGE:00669F84&lt;br /&gt;PAGE:00669F84 loc_669F84:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+8E&lt;br /&gt;PAGE:00669F84&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, ebx&lt;br /&gt;PAGE:00669F86&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jz&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_669F8E&lt;br /&gt;PAGE:00669F88&lt;br /&gt;PAGE:00669F88 loc_669F88:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+34&lt;br /&gt;PAGE:00669F88&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; IopAllocateMiniCompletionPacket(x,x)+4E&lt;br /&gt;PAGE:00669F88&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, [ebp+arg_0]&lt;br /&gt;PAGE:00669F8B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [eax+8], ecx&lt;br /&gt;PAGE:00669F8E&lt;br /&gt;PAGE:00669F8E loc_669F8E:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: IopAllocateMiniCompletionPacket(x,x)+AC&lt;br /&gt;PAGE:00669F8E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; __SEH_epilog4&lt;br /&gt;PAGE:00669F93&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retn&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;br /&gt;PAGE:00669F93 _IopAllocateMiniCompletionPacket@8 endp ; sp-analysis failed&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이쯤에서 PostQueuedCompletionStatus 함수가 실패할 경우는 다음과 같이 요약됩니다.&lt;br /&gt;첫 번째로 핸들이 잘 못 될 경우 ( 그러나 프로그램 로직상에 문제로 발생할 수 있기 때문에 무시 )&lt;br /&gt;두 번째로 시스템 메모리가 부족 할 경우..&lt;br /&gt;&lt;br /&gt;시스템 메모리가 부족 할 경우에는 프로그래머의 잘 못으로 일어나는 현상이 아니므로&lt;br /&gt;PostQueuedCompletionStatus 함수는 반드시 실패할 수 있기 때문에 큐를 대기하는 쪽에서는&lt;br /&gt;이부분을 염두해 두어야 합니다. ( 물론 이렇게 코드를 작성하기가 매우 매우 힘들겠지만.. )&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>SetEvent 함수는 언제 실패할까?</title>
      <id>http://simples.kr/19984</id>
      <published>2010-09-04T12:11:59+09:00</published>
      <updated>2010-09-04T12:13:08+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19984"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19984#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;작업을 하다가 다음에 예제코드와 비슷한 코드를 작성하게 되었습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;thread1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;SetEvent(.......); // 이벤트를 시그널해줍니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;thread2&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;WaitForSingleObject(.....); // 시그널 될 때까지 기다립니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;매우 전형적인 코드입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;thread2에서는 기다리고 thread1는 이벤트를 시그널해줍니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그러나 여기서 한가지 문제가 생긴 부분은 너무 극단적인 상황까지 고려하는게 아닌가 생각되지만&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;SetEvent 함수에 원형은 다음과 같습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id=&quot;ctl00_MTCS_main_ctl01&quot;/&gt;&lt;pre class=&quot;libCScode&quot; style=&quot;white-space: pre-wrap;&quot; id=&quot;ctl00_MTCS_main_ctl01_code&quot; space=&quot;preserve&quot;/&gt;&lt;code style=&quot;font-weight: bold;&quot;/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;BOOL WINAPI SetEvent(&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;  __in  HANDLE hEvent&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;);&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;위에서 가장 중요한 부분은 리턴값이 BOOL이라는 것입니다.&lt;/span&gt;&lt;br /&gt;&lt;font size=&quot;4&quot;/&gt;&lt;span style=&quot;font-weight: bold; background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;즉, 이 함수는 실패할 수 있습니다.&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;실패할 수 있는 경우에 대해서 생각해보면 바로 떠오르것은 핸들을 잘 못 넘겼을 경우입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;하지만 그 외에 경우가 생긴다면 골치아파집니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;특히나 소켓 프로그래밍이라면 상당히 짜증나겠죠.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;예를 들어 메모리가 부족할 경우에 SetEvent가 실패해버리면 다른쪽에 스레드는 무한대기할지도 모릅니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;물론 메모리가 부족할 경우라는 것은 만약에 그럴지도 모른다는 경우이고 MSDN에 경우에는&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;GetLastError를 통해서 리턴값이 FALSE일 경우에는 에러코드를 확인하라고 나왔으며 정작&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;어떠한 경우에 에러가 발생할 수 있는지는 적혀있지 않습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;하지만 우리는 최악에 상황까지 고려해야할 경우 저 함수가 어떠한 경우에 실패할 수 있는지에 대해서&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;알아보고 그에 대한 상황에 대처할 수 있어야 할것입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그렇다면 저 함수가 어떠한 에러코드를 리턴하는지 알려면 결국엔 내부구현을 알아야 합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;따라서 해당 함수에 내부구현을 지금부터 따라가보겠습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;우선 SetEvent 함수는 Kernel32.dll에 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;다음과 같이 말입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653 ; BOOL __stdcall SetEventStub(HANDLE hEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public _SetEventStub@4&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653 _SetEventStub@4 proc near&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653 hEvent&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword ptr&amp;nbsp; 8&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71653&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edi, edi&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71655&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71656&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp, esp&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71658&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71659&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short _SetEvent@4 ; SetEvent(x)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71659 ; ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD7165B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; align 10h&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71660&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71660 ; BOOL __stdcall SetEvent(HANDLE hEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71660 _SetEvent@4:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: SetEventStub(x)+6&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71660&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; WerpRecoveryInProgress(x)+7D&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71660&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ds:__imp__SetEvent@4 ; SetEvent(x)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7DD71660 _SetEventStub@4 endp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;익스포트 되어 있는 SetEvent 함수는 SetEventStub 함수를 호출하고 실제 내부에 _SetEvent@4&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;로 점프하게 됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그리고 __imp__SetEvent 를 참조하여 다시 어딘가로 점프하게 됩니다. ( 임포트 테이블 )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그 어딘가는 결국엔 Kernelbas.dll 에 있는 SetEvent 함수입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;다음과 같이 생겼습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D ; BOOL __stdcall SetEvent(HANDLE hEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public _SetEvent@4&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D _SetEvent@4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; proc near&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: OutputDebugStringA(x)+1F7&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D hEvent&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = dword ptr&amp;nbsp; 8&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edi, edi&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86013F&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860140&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp, esp&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860142&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860144&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; [ebp+hEvent]&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860147&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; ds:__imp__NtSetEvent@8 ; NtSetEvent(x,x)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86014D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; test&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86014F&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_7D860156&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860151&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860153&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inc&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860154&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; short loc_7D86015E&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860156 ; ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860156&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860156 loc_7D860156:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: SetEvent(x)+12&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860156&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; push&amp;nbsp;&amp;nbsp;&amp;nbsp; eax&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D860157&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp; _BaseSetLastNTError@4 ; BaseSetLastNTError(x)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86015C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86015E&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86015E loc_7D86015E:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ; CODE XREF: SetEvent(x)+17&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86015E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ebp&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86015F&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retn&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;.text:7D86015F _SetEvent@4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; endp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;디컴파일 하면 다음과 같습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;BOOL __stdcall SetEvent(HANDLE hEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; int v1; // eax@1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; BOOL result; // eax@2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; v1 = NtSetEvent(hEvent, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; if ( v1 &amp;lt; 0 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BaseSetLastNTError(v1);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; return result;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;NtSetEvent 함수를 호출하고 있고 값이 0보다 작으면 에러입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;당연히 NtSetEvent는 ntdll.dll에 있겠고 시스템 콜을 호출하게 될것입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그리고 그 시스템콜은 ntoskrnl.exe에 있을것이고 이름도 NtSetEvent일것입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그 구현코드는 다음과 같습니다. ( 여기서부터는 디컴파일한 결과만 보여드리겠습니다. )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;NTSTATUS __stdcall NtSetEvent(HANDLE EventHandle, PULONG PreviousState)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; char v2; // al@1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; PULONG v3; // edi@1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; PULONG v4; // ecx@3&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; LONG v5; // esi@7&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; NTSTATUS v7; // eax@6&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; int AccessMode; // [sp+14h] [bp-20h]@1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; CPPEH_RECORD ms_exc; // [sp+1Ch] [bp-18h]@1&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; PVOID Event; // [sp+18h] [bp-1Ch]@6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; v2 = *(_BYTE *)(*MK_FP(__FS__, 292) + 314);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; LOBYTE(AccessMode) = *(_BYTE *)(*MK_FP(__FS__, 292) + 314);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; ms_exc.disabled = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; v3 = PreviousState;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; if ( PreviousState )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v2 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v4 = PreviousState;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( PreviousState &amp;gt;= MmUserProbeAddress )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v4 = MmUserProbeAddress;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *v4 = *v4;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; ms_exc.disabled = -2;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; v7 = ObReferenceObjectByHandle(EventHandle, 2u, ExEventObjectType, AccessMode, &amp;amp;Event, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; PreviousState = (PULONG)v7;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; if ( v7 &amp;gt;= 0 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v5 = KeSetEvent((PRKEVENT)Event, 1, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ObfDereferenceObject();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v3 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (_BYTE)AccessMode )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *v3 = v5;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *v3 = v5;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; return (NTSTATUS)PreviousState;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;NtSetEvent에 유출 된 Windows 2000 소스코드는 다음과 같습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;NTSTATUS&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;NtSetEvent (&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IN HANDLE EventHandle,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OUT PLONG PreviousState OPTIONAL&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;/*++&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;Routine Description:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function sets an event object to a Signaled state and attempts to&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; satisfy as many waits as possible.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;Arguments:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventHandle - Supplies a handle to an event object.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousState - Supplies an optional pointer to a variable that will&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; receive the previous state of the event object.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;Return Value:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; TBS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;--*/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID Event;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KPROCESSOR_MODE PreviousMode;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LONG State;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS Status;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#if DBG&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Sneaky trick here to catch sleazy apps (csrss) that erroneously call&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // NtSetEvent on an event that happens to be somebody else&apos;s &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // critical section. Only allow setting a protected handle if the low&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // bit of PreviousState is set.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OBJECT_HANDLE_INFORMATION HandleInfo;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Establish an exception handler, probe the previous state address if&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // specified, reference the event object, and set the event object. If&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the probe fails, then return the exception code as the service status.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Otherwise return the status value returned by the reference object by&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // handle routine.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Get previous processor mode and probe previous state address&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // if necessary.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousMode = KeGetPreviousMode();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#if DBG&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((PreviousMode != KernelMode) &amp;amp;&amp;amp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (ARGUMENT_PRESENT(PreviousState)) &amp;amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (PreviousState != (PLONG)1)) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProbeForWriteLong(PreviousState);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((PreviousMode != KernelMode) &amp;amp;&amp;amp; (ARGUMENT_PRESENT(PreviousState))) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProbeForWriteLong(PreviousState);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Reference event object by handle.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#if DBG&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = ObReferenceObjectByHandle(EventHandle,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EVENT_MODIFY_STATE,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExEventObjectType,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousMode,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;Event,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;HandleInfo);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(Status)) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((HandleInfo.HandleAttributes &amp;amp; 1) &amp;amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (PreviousState != (PLONG)1)) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#if 0&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // This is a protected handle. If the low bit of PreviousState is NOT set,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // break into the debugger&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DbgPrint(&quot;NtSetEvent: Illegal call to NtSetEvent on a protected handle\n&quot;);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DbgBreakPoint();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousState = NULL;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((KeGetPreviousMode() != KernelMode) &amp;amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (EventHandle != NULL) &amp;amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((NtGlobalFlag &amp;amp; FLG_ENABLE_CLOSE_EXCEPTIONS) ||&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (PsGetCurrentProcess()-&amp;gt;DebugPort != NULL))) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = KeRaiseUserException(STATUS_INVALID_HANDLE);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = ObReferenceObjectByHandle(EventHandle,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EVENT_MODIFY_STATE,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExEventObjectType,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousMode,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;Event,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NULL);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // If the reference was successful, then set the event object to the&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Signaled state, dereference event object, and write the previous&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // state value if specified. If the write of the previous state fails,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // then do not report an error. When the caller attempts to access the&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // previous state value, an access violation will occur.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(Status)) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; State = KeSetEvent((PKEVENT)Event, ExpEventBoost, FALSE);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ObDereferenceObject(Event);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ARGUMENT_PRESENT(PreviousState)) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *PreviousState = State;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } except(ExSystemExceptionFilter()) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // If an exception occurs during the probe of the previous state, then&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // always handle the exception and return the exception code as the status&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // value.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } except(ExSystemExceptionFilter()) {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return GetExceptionCode();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Return service status.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Status;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;거의 똑같다고 봐도 되겠습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;Windows 7에 있는코드인데 윈도우즈2000소스와 거의 똑같습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;여기서 PreviousState에 경우에는 인자를 NULL로 넘겼으니 상관이 없습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;체크할 필요가 없습니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;가장 먼저 체크해야 할 부분은 ObReferenceObjectByHandle 함수입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;이 함수가 언제 실패하느냐 여부를 알아야 합니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;WDK 문서를 보면 다음과 같은 에러코드가 정의되어 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;xml/&gt;&lt;/xml&gt;&lt;mshelp:attr name=&quot;TopicType&quot; value=&quot;apiref&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;TargetOS&quot; value=&quot;Windows&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;APIType&quot; value=&quot;Function&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;APILocation&quot; value=&quot;Wdm.h, Ntddk.h, Ntifs.h&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;APIName&quot; value=&quot;ObReferenceObjectByHandle&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;WdkCategory&quot; value=&quot;WdkKernel&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;CommunityContent&quot; value=&quot;1&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;EnableMachineTranslation&quot; value=&quot;1&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:keyword index=&quot;A&quot; term=&quot;k107_97ce2cea-8f20-4b30-996c-9ea268951aef.xml&quot;/&gt;&lt;/mshelp:keyword&gt;&lt;mshelp:keyword index=&quot;K&quot; term=&quot;ObReferenceObjectByHandle&quot;/&gt;&lt;/mshelp:keyword&gt;&lt;div class=&quot;hentry&quot;/&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;STATUS_SUCCESS &amp;lt;= 성공했습니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;indent1&quot;/&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;STATUS_OBJECT_TYPE_MISMATCH &amp;lt;= 핸들에 대한 타입이 잘 못 되었을 경우인데 API에서 해줌으로 &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;이 에러가 날 경우는 없습니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;indent1&quot;/&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;STATUS_ACCESS_DENIED &amp;lt;= 접근거부에러인데 우리가 만든 핸들을 우리가 접근하므로 이 에러는 발생하지 않습니다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;indent1&quot;/&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;STATUS_INVALID_HANDLE &amp;lt;= 핸들이 잘 못 된 경우입니다. 이 에러는 소프트웨어 로직상 핸들을 잘 못 넘겼을 경우에 발생하며&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;현재 우리가 알려고 하는것은 아주 특수한 경우에 발생할 수 있는 에러가 있는지 알기 위함이므로 무시합니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;따라서 ObReferenceObjectByHandle함수는 핸들을 잘 못 넘기지 않는 이상은 현재로써 에러가 발생하지 않을것이고&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;핸들을 잘 못 넘기는건 프로그램의 로직상 문제이므로 무시합니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그 다음에 호출하는 함수는 KeSetEvent 함수입니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;이 함수는 WDK에 문서에 보면 이 함수리턴값이 실패값이 들어간다는 말은 나와 있지 않습니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;그렇다면 좀 더 확실하게 알기 위해서 KeSetEvent 함수 내부를 보아야 합니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;내부 코드를 보기전에 PKEVENT는 다음과 같이 생겼습니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;typedef struct _KEVENT {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DISPATCHER_HEADER Header;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;} KEVENT, *PKEVENT, *PRKEVENT;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;typedef struct _DISPATCHER_HEADER {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Type;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // All (accessible via KOBJECT_TYPE)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Timer&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR TimerControlFlags;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Absolute&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Coalescable&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR KeepShifting&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Periodic timer&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR EncodedTolerableDelay : 5;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Periodic timer&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYSTRUCTNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Abandoned;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Queue&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN Signalling;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Gate/Events&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR ThreadControlFlags;&amp;nbsp; // Thread&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR CpuThrottled&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR CycleProfiling&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR CounterProfiling&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Reserved&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 5;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYSTRUCTNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Hand;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Timer&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Size;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // All other objects&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME2;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Timer&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR TimerMiscFlags;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#if !defined(_X86_)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Index&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : TIMER_EXPIRED_INDEX_BITS;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#else&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Index&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Processor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : TIMER_PROCESSOR_INDEX_BITS;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR Inserted&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; volatile UCHAR Expired&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYSTRUCTNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; union {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Thread&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN DebugActive;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN ActiveDR7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN Instrumented&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN Reserved2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 4;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN UmsScheduled&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN UmsPrimary&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYSTRUCTNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN DpcActive;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Mutant&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME3;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYSTRUCTNAME;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; volatile LONG Lock;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Interlocked&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } DUMMYUNIONNAME;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LONG SignalState;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Object lock&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LIST_ENTRY WaitListHead;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Object lock&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;} DISPATCHER_HEADER;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;LONG __stdcall KeSetEvent(PRKEVENT Event, KPRIORITY Increment, BOOLEAN Wait)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; LONG result; // eax@2&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; void *v5; // ebx@6&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; int v6; // edi@6&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; LONG v7; // edi@13&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; signed int v14; // [sp+10h] [bp-8h]@4&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; int v15; // [sp+14h] [bp-4h]@6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; _ESI = Event;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; if ( Event-&amp;gt;Header.Type &amp;amp; 0x7F )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v14 = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;LABEL_6:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v5 = v320;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(v15) = KeRaiseIrqlToDpcLevel();&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v6 = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ( 1 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _EAX = _ESI;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; __asm { lock bts dword ptr [eax], 7 }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !_CF )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++v6;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v6 &amp;amp; HvlLongSpinCountMask || !(HvlEnlightenments &amp;amp; 0x40) )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; __asm { pause }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HvlNotifyLongSpinWait(v6);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while ( (char)*(_DWORD *)&amp;amp;_ESI-&amp;gt;Header.Type &amp;lt; 0 );&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v7 = _ESI-&amp;gt;Header.SignalState;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ESI-&amp;gt;Header.SignalState = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !v7 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v14 == v7 )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; KiSignalSynchronizationObject(v5, _ESI);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; KiSignalNotificationObject(v5);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _EAX = -129;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __asm { lock and [esi], eax }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KiExitDispatcher(v5, Wait, 1, Increment, v15);&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return v7;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; result = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; if ( Event-&amp;gt;Header.SignalState != 1 || Wait )&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v14 = 1;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_6;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; return result;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;내부코드를 보면 Evente 객체에 SignalState 객체를 참고하거나 값을 변경할 뿐 에러를 리턴할 만한 부분은 없습니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;여기까지 왔다면 이제 결론이 나옵니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;SetEvent 함수를 사용 할 때 잘 못 된 핸들을 넘기지 않는 이상은 해당 리턴값이 FALSE를 리턴하지 않습니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;따라서 시스템이 특수한 상황 ( 메모리 부족 ) 에 에러가 발생할 소지가 없으므로 SetEvent 함수는 무조건&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;성공한다고 가정합니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;( 주의 : 예제코드에 한해서만 그렇다는 것이며 Event핸들은 여러 프로세스에 의해서 공유되는 코드로 작성하게&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; 된다면 접근거부 에러도 발생 할 수 있습니다. 그러나 이러한 부분은 프로그래머가 작성하게 되는 코드이므로&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);&quot;/&gt;&amp;nbsp; 마찬가지로 문제가 발생한다면 로직상에 문제이지 시스템에 특수한 상황에서 발생하는 에러는 아닙니다. )&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>커널모드 드라이버에서 사용하는 시간관련 매크로</title>
      <id>http://simples.kr/19982</id>
      <published>2010-09-04T12:10:21+09:00</published>
      <updated>2010-09-04T12:10:21+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19982"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19982#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;a href=&quot;http://www.osronline.com/article.cfm?article=261&quot;/&gt;http://www.osronline.com/article.cfm?article=261&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;#define ABSOLUTE(wait) (wait)&lt;br /&gt;&lt;br /&gt;#define RELATIVE(wait) (-(wait))&lt;br /&gt;&lt;br /&gt;#define NANOSECONDS(nanos) \&lt;br /&gt;(((signed __int64)(nanos)) / 100L)&lt;br /&gt;&lt;br /&gt;#define MICROSECONDS(micros) \&lt;br /&gt;(((signed __int64)(micros)) * NANOSECONDS(1000L))&lt;br /&gt;&lt;br /&gt;#define MILLISECONDS(milli) \&lt;br /&gt;(((signed __int64)(milli)) * MICROSECONDS(1000L))&lt;br /&gt;&lt;br /&gt;#define SECONDS(seconds) \&lt;br /&gt;(((signed __int64)(seconds)) * MILLISECONDS(1000L))
       &lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>화면캡쳐방지는 어떻게 구현될까?</title>
      <id>http://simples.kr/19980</id>
      <published>2010-09-04T12:09:22+09:00</published>
      <updated>2011-05-10T22:49:34+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19980"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19980#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;몇 년전부터 화면캡쳐방지를 해주는 솔루션들이 등장하기 시작했습니다.&lt;br /&gt;어떻게보면 좀 오래된 분야지만 아직까지도 완벽하게 화면캡쳐방지를 막는 것은 사실상 불가능합니다.&lt;br /&gt;그래도 어차피 100% 다 막을 수가 없기 때문에 적어도 99%정도는 막는다라는 취지에서 이러한 솔루션들이 등장하고 있습니다.&lt;br /&gt;&lt;br /&gt;화면캡쳐방지에 대해 거론하기 전에 우선 화면캡쳐를 어떻게 하는지 당연히 알고 있어야 합니다.&lt;br /&gt;방어를 할려면 공격방법을 먼저 알아야 되죠. 그래서 해킹보다 보안이라는것이 더 어려운 경우가 많습니다.&lt;br /&gt;&lt;br /&gt;화면캡쳐에 기본적인 주요 API는 3가지로 구현됩니다.&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;GetDC, BitBlt, ReleaseDC&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;화면캡쳐 프로그램들은 보통 이 3가지 API를 이용하여 화면캡쳐를 합니다.&lt;br /&gt;다음은 오픈캡쳐에서 사용하는 전체화면 캡쳐 방식입니다.&lt;br /&gt;&lt;br /&gt;procedure TCaptureEngine.ScreenCapture;&lt;br /&gt;const&lt;br /&gt;&amp;nbsp; // ** 윈도우 2000 이상에서 반투명화 된 윈도우를 캡쳐 할 수 있는 비트 플래그 ** //&lt;br /&gt;&amp;nbsp; // ** BitBlt 함수에서 OR 연산자를 통해서 사용한다 ** //&lt;br /&gt;&amp;nbsp; CAPTUREBLT = $40000000;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; CursorInfo: TCursorInfo;&lt;br /&gt;&amp;nbsp; piconinfo: TIconInfo;&lt;br /&gt;&amp;nbsp; DC: HDC;&lt;br /&gt;&amp;nbsp; scrRect: TRect;&lt;br /&gt;&amp;nbsp; CAPTUREBIT: Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; DC := GetDC(0);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; scrRect := Screen.DesktopRect;&lt;br /&gt;&amp;nbsp; FBackBuffer.SetSize(scrRect.Right - scrRect.Left, scrRect.Bottom - scrRect.Top);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; CAPTUREBIT := 0;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; if FTransparentCapture = True then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CAPTUREBIT := CAPTUREBLT;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; with FBackBuffer do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BitBlt(FBackBuffer.Canvas.Handle, 0, 0, FBackBuffer.Width,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FBackBuffer.Height, DC, scrRect.Left, scrRect.Top,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SRCCOPY or CAPTUREBIT);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; if FCaptureCursor = True then&lt;br /&gt;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CursorInfo := CaptureCursor;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetIconInfo(CursorInfo.hCursor, piconinfo);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CursorInfo.ptScreenPos := DesktopCoordinateToOriginCoordinate(CursorInfo.ptScreenPos);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DrawIcon(FBackBuffer.Canvas.Handle,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CursorInfo.ptScreenPos.X - piconinfo.xHotspot,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CursorInfo.ptScreenPos.Y - piconinfo.yHotspot, CursorInfo.hCursor);&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; FCaptureRect := Rect(0, 0, FBackBuffer.Width, FBackBuffer.Height);&lt;br /&gt;&lt;br /&gt;&amp;nbsp; ReleaseDC(0, DC);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;GetDC(0);을 호출하게 되면 전체화면에 대한 디바이스 컨텍스트 핸들을 흭득하게 됩니다. ( 듀얼모니터 포함 )&lt;br /&gt;그리고 BitBlt을 통해서 실제 화면DC에 있는 데이터를 비트맵인 FBackBuffer에 DC로 옮깁니다.&lt;br /&gt;그리고 마지막으로 ReleaseDC(0, DC);를 호출하여 할당한 디바이스 컨텍스트 자원을 해제하게 됩니다.&lt;br /&gt;&lt;br /&gt;위에서 보앗듯이 화면캡쳐는 이게 전부입니다. 추가적으로 구현되는 부분도 있겠지만 기본 베이스는 이게 끝입니다.&lt;br /&gt;화면캡쳐하는 방법에 대해서 알았으니 이제 화면캡쳐방지는 어떻게 구현해야 할지 생각해볼 차례입니다.&lt;br /&gt;&lt;br /&gt;우선적으로 떠오로는 것은 API Hooking이 필요하다라는것을 느낄것입니다.&lt;br /&gt;그리고 화면캡쳐방지에 대한 3가지 주요함수에 대해서 후킹에 필요성이 느껴질것입니다.&lt;br /&gt;&lt;br /&gt;그렇다면 어떠한 API를 후킹해야 할지 결정할 차례입니다.&lt;br /&gt;일단 ReleaseDC는 제외됩니다. 단순히 자원을 해제하게 되기 때문입니다.&lt;br /&gt;&lt;br /&gt;두 번째로 GetDC와 BitBlt이 있는데 이 함수를 다 후킹해야할지 하나만 후킹해야할지를 결정해야 합니다.&lt;br /&gt;보통 화면캡쳐방지를 만들려고 하면 실수하는 부분이 GetDC를 고려한다는 점인데 실제로 GetDC는 고려할 필요조차&lt;br /&gt;없습니다. 만약에 GetDC를 후킹한다면 결과적으로 그 DC를 얻을 때 마다 DC를 관리하는 리스트에 다 추가를 해줘야 &lt;br /&gt;되겠고 BitBlt이 호출되면 이 때 리스트에 대한 정보를 검색하여 이전에 GetDC를 이용하여 화면캡쳐를 시도하려는 DC였다면&lt;br /&gt;BitBlt을 실패시키겠죠. 그리고 ReleaseDC도 덩달아 후킹을 해야 합니다. 왜냐하면 자원이 해제되는 것을 체크하여 DC를&lt;br /&gt;관리하는 리스트에서 제거를 해주어야 하기 때문입니다.&lt;br /&gt;&lt;br /&gt;우선 왜 실수로 GetDC를 고려할려고 하였는지 생각해봐야 합니다.&lt;br /&gt;GetDC를 고려하는 이유는 &lt;span style=&quot;font-weight: bold;&quot;/&gt;BitBlt 함수가 호출 될 때 이게 화면캡쳐를 하기 위해 BitBlt를 하였는지 아니면 그냥 단순히&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;비트맵 복사를 할려고 하였는지 알수가 없기 때문입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;그렇다면 오로지 BitBlt만 후킹해서 함수를 호출한 프로그램이 화면을 캡쳐하려는것인지 비트맵을 복사하려고 하는것인지&lt;br /&gt;알아낼 수 있는 방법이 있는지를 찾아내야 합니다.&lt;br /&gt;그리고 &lt;span style=&quot;font-weight: bold;&quot;/&gt;실제로 상용 화면캡쳐 방지 솔루션에 경우에는 오로지 BitBlt 후킹만으로 화면캡쳐방지를 구현합니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;이것을 체크하기 위해 윈도우즈 API인 &lt;strong/&gt;GetObjectType 함수를 이용할수 있습니다.&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;이 함수는 인자로 받는 매개변수가 GDIObject로써 DC도 GDIObject에 포함되기 때문에 &lt;br /&gt;당연히 매개변수로 받을 수 있습니다. 그리고 이 함수가 리턴값들 중에 가장 중요한 리턴값은 &lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;OBJ_DC로 MSDN에 보면 이것은 Device context 를 의미합니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;즉, BitBlt를 후킹한 루틴에서는 넘어온 srcDC ( SourceDC ) 에 대해 GetObjectType으로 해당 DC에 타입을&lt;br /&gt;조사하여 OBJ_DC일 경우 원본 API를 호출하지 않으면 됩니다.&lt;br /&gt;&lt;br /&gt;다음과 같이 소스로 구현될것입니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;BOOL WINAPI MyBitBlt(&lt;br /&gt;&amp;nbsp; HDC hdcDest, // handle to destination DC&lt;br /&gt;&amp;nbsp; int nXDest,&amp;nbsp; // x-coord of destination upper-left corner&lt;br /&gt;&amp;nbsp; int nYDest,&amp;nbsp; // y-coord of destination upper-left corner&lt;br /&gt;&amp;nbsp; int nWidth,&amp;nbsp; // width of destination rectangle&lt;br /&gt;&amp;nbsp; int nHeight, // height of destination rectangle&lt;br /&gt;&amp;nbsp; HDC hdcSrc,&amp;nbsp; // handle to source DC&lt;br /&gt;&amp;nbsp; int nXSrc,&amp;nbsp;&amp;nbsp; // x-coordinate of source upper-left corner&lt;br /&gt;&amp;nbsp; int nYSrc,&amp;nbsp;&amp;nbsp; // y-coordinate of source upper-left corner&lt;br /&gt;&amp;nbsp; DWORD dwRop&amp;nbsp; // raster operation code&lt;br /&gt;)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (GetObjectType(hdcSrc) == OBJ_DC)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOL Result = 0;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RestoreAPI(g_hInst, &quot;gdi32.dll&quot;, &quot;BitBlt&quot;, OldBitBltCode);&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 그리고 원래의 API 함수를 호출 ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //if (hWnd == 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result = BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 다시 코드를 변경한다. ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterceptAPI(g_hInst, &quot;gdi32.dll&quot;, &quot;BitBlt&quot;, (DWORD)MyBitBlt, OldBitBltCode);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Result;&lt;br /&gt;}&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;위에서&lt;span style=&quot;font-weight: bold;&quot;/&gt; &lt;/span&gt;RestoreAPI는 후킹된 함수를 원래대로 되돌려주며 InterceptAPI는 다시 후킹을 하는 함수입니다.&lt;br /&gt;그리고 &lt;span style=&quot;font-weight: bold;&quot;/&gt;이러한 방식은 멀티 스레드에 매우 위험한 방법으로 실제 상용DRM에서는 이렇게 허접하게 만들면 안됩니다.-_-&lt;/span&gt;&lt;br /&gt;지금은 단순히 예제를 보여주기 위해 이렇게 코드가 작성되었다라고 이해해주시면 감사하겠습니다.&lt;br /&gt;( Detour 라이브러리를 쓰는것이 좋습니다. 그러나 API Hooking하는것 자체도 설명을 같이 할것이기 때문에 나중에&lt;br /&gt;&amp;nbsp; 이 부분은 다시 설명하겠습니다. )&lt;br /&gt;&lt;br /&gt;후킹을 하고 해제하는 함수는 다음과 같이 구현되어 있습니다.&lt;br /&gt;&lt;br /&gt;BOOL InterceptAPI(HMODULE hLocalModule, const char* c_szDllName, const char* c_szApiName, DWORD dwReplaced, char *OldCode)&lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD dwOldProtect;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 해당 함수의 시작 주소를 얻는다. ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD dwAddressToIntercept = (DWORD)GetProcAddress(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; GetModuleHandle((char*)c_szDllName), (char*)c_szApiName);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dwAddressToIntercept == 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; OutputDebugString(&quot;에러&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE *pbTargetCode = (BYTE *) dwAddressToIntercept;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE *pbReplaced = (BYTE *) dwReplaced;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 메모리의 권한을 변경 ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_WRITECOPY, &amp;amp;dwOldProtect);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 원래의 코드를 백업한다. ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memcpy(OldCode, pbTargetCode, 5);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 점프 코드를 삽입한다. ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *pbTargetCode++ = 0xE9; // jump rel32&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 주소는 내가 설정한 함수 주소 ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *((unsigned int *)(pbTargetCode)) = pbReplaced - (pbTargetCode +4);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_EXECUTE, &amp;amp;dwOldProtect);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FlushInstructionCache(GetCurrentProcess(), NULL, NULL);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OutputDebugString(&quot;InterceptAPI 완료&quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOL RestoreAPI(HMODULE hLocalModule, const char* c_szDllName, const char* c_szApiName, char *OldCode)&lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD dwOldProtect;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DWORD dwAddressToIntercept = (DWORD)GetProcAddress(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; GetModuleHandle((char*)c_szDllName), (char*)c_szApiName);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dwAddressToIntercept == 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE *pbTargetCode = (BYTE *) dwAddressToIntercept;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_WRITECOPY, &amp;amp;dwOldProtect);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ** 원래의 코드를 복구한다. ** //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memcpy(pbTargetCode, OldCode, 5);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; VirtualProtect((void *) dwAddressToIntercept, 5, PAGE_EXECUTE, &amp;amp;dwOldProtect);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FlushInstructionCache(GetCurrentProcess(), NULL, NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OutputDebugString(&quot;RestoreAPI 완료&quot;);;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;그리고 후킹용 DLL이 로드 될 때&lt;br /&gt;InterceptAPI(g_hInst, &quot;gdi32.dll&quot;, &quot;BitBlt&quot;,(DWORD)MyBitBlt, OldBitBltCode);&lt;br /&gt;해제 될 때,&lt;br /&gt;RestoreAPI(g_hInst, &quot;gdi32.dll&quot;, &quot;BitBlt&quot;, OldBitBltCode);&lt;br /&gt;를 해주어야 합니다.&lt;br /&gt;&lt;br /&gt;위와 같은 예제를 통해서 DLL을 만들어 인젝션을 시킨 후에 오픈캡쳐로 화면캡쳐를 시도하려고 하면&lt;br /&gt;그냥 흰색으로 나오거나 검은색나올것입니다. BitBlt 함수자체가 동작하지 않기 때문에 아예 복사자체가 안되기 때문입니다.&lt;br /&gt;&lt;br /&gt;이정도면 제가 보기엔 안정성을 제외하고서는 기능적으로 보았을때에는 거의 상용과 동일한 수준이라고 생각됩니다.&lt;br /&gt;그러나 추가적으로 하나의 API를 더 후킹해야 할 필요가 있습니다.&lt;br /&gt;일부 상용 DRM 솔루션은 바보같게도 WIndows XP에서 추가 된 새로운 API인 PrintWindow를 후킹하지 않는 바람에&lt;br /&gt;이 함수를 써서 우회가 가능하더군요.&lt;br /&gt;&lt;br /&gt;PrintWindow 함수는 화면상에 보이지 않고 가려져 있는 윈도우에 대해서도 화면을 캡쳐할 수 있는 매우 막강한 함수입니다.&lt;br /&gt;그냥 후킹해서 return TRUE; 해버리면 이것도 당연히 막히겠죠.&lt;br /&gt;&lt;br /&gt;추가적으로 상용 화면캡쳐방지 솔루션은 단순히 화면캡쳐만 막는게 아니라 화면캡쳐에 대한 영역을 보안하는 기능이 있습니다.&lt;br /&gt;즉, 전체화면에 대한 캡쳐가 안되는것이 아니라 보호하고 있는 대상이 웹브라우저라면 그 웹브라우저에 대한 부분만 캡쳐가&lt;br /&gt;안되도록 막는 기능입니다. 이거는 후킹하는 루틴에서 원본 함수를 호출 후 좌표계산을 통해 웹브라우저가 속한 영역에 대&lt;br /&gt;해 화면캡쳐를 하지 말라는 경고그림이라던지(-_-) 그런거를 그려넣으면 되겠죠.&lt;br /&gt;&lt;br /&gt;이전에도 말씀드렷다시피 지금 알려드린 예제는 안정성이 떨어지기 때문에 마이크로소프트사에서 만든&lt;br /&gt;API Hooking용 라이브러리를 쓰는 것이 좋습니다.&lt;br /&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://research.microsoft.com/en-us/projects/detours/&quot;/&gt;http://research.microsoft.com/en-us/projects/detours/&lt;/a&gt;&lt;br /&gt;만약에 델파이를 사용하신다면 매드훅 라이브러리를 쓰면 됩니다.&lt;br /&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://help.madshi.net/ApiCodeHooking.htm&quot;/&gt;http://help.madshi.net/ApiCodeHooking.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Detour 라이브러리에 경우에는 인터넷에 관련 글들이 많이 있고 매드훅 라이브러리는 상용 라이브러리이기 때문에&lt;br /&gt;제가 사용을 해보질 않아서 이 두 라이브러리에 대한 내용은 생략하겠습니다.&lt;br /&gt;&lt;br /&gt;그렇다면 이걸로 끝일까요?&lt;br /&gt;그렇지 않습니다. 단순히 API를 후킹했다고 해서 끝나지 않습니다.&lt;br /&gt;화면캡쳐를 하는 방식은 무궁무진하기 때문에 저 두 API만 후킹한다고 해서 끝나지 않습니다.&lt;br /&gt;다이렉트X를 이용한 화면캡쳐라던지 윈도우즈 미디어 API를 이용한 화면캡쳐등 여러가지가 있습니다.&lt;br /&gt;이 모든 것을 막을 수 없기 때문에 추가적으로 요구되는 사항이 바로 &lt;span style=&quot;font-weight: bold;&quot;/&gt;블랙리스트 &lt;/span&gt;개념입니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;블랙리스트 방식은 화면캡쳐와 관련 된 프로그램에 대한 식별할 수 있는 시그내쳐를 모두 모아서 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;이 시그내쳐와 맞는 프로세스가 발견되면 즉시 강제 종료시키는 방식입니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;이러한 시그내쳐중에 단순히 윈도우에 타이틀바 캡션정보를 이용하여 식별하는 방법이 있는데 허접하게 보일지 몰라도&lt;br /&gt;의외로 강력하며 최후에 수단이라고 보여집니다.-_-&lt;br /&gt;왜냐하면 일반 사용자는 직접 소스코딩을 할 수가 없기 때문에 프로그래머가 아닌 일반 사용자에 대해서는 좋은 방어&lt;br /&gt;수단이 될수가 있기 때문입니다. 물론 완벽하지는 않겠지만요. &lt;br /&gt;&lt;br /&gt;여기까지 화면캡쳐방지에 대한 글은 마치겠습니다.&lt;br /&gt;지금까지 설명한 내용은 실제로 상용으로 판매되고 있는 화면캡쳐방지 기법에 대한 기본 베이스입니다.&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>IRP Completion Hook</title>
      <id>http://simples.kr/19950</id>
      <published>2010-09-04T10:05:51+09:00</published>
      <updated>2010-09-04T12:16:29+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19950"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19950#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;이전에 설명한 IRP Hook 코드와는 크게 다른 부분은 없고 추가적으로&lt;br /&gt;완료 루틴을 훅킹하는 예제를 보여줍니다.&lt;br /&gt;완료 루틴을 훅킹함으로써 하드 디스크에서 어떠한 데이터를 읽었는지 알아내는 예제입니다.&lt;br /&gt;&lt;br /&gt;완료루틴에서 데이터를 가져올 때 지금과 같이 ATAPI.sys에 경우&lt;br /&gt;Irp-&amp;gt;MdlAddress 로부터 읽은 섹터를 가져오는데 이 때 MmGetSystemAddressForMdlSafe 함수를&lt;br /&gt;사용하면 안되고 자체적으로 해당 매크로를 구현해주었습니다.&lt;br /&gt;주석에도 나왓듯이 간혹 MDL_MAPPED_TO_SYSTEM_VA 플래그가 MDL에 포함 된 상태로&lt;br /&gt;오는 경우가 있기 때문입니다.&lt;br /&gt;만약 그런 경우가 발생하게 되면 다음과 같이 블루 스크린이 뜰 수 있습니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/950/019/b0072382_4a6ad2e2e6dc6.png&quot; alt=&quot;b0072382_4a6ad2e2e6dc6.png&quot; class=&quot;iePngFix&quot; width=&quot;640&quot; height=&quot;480&quot; style=&quot;&quot; /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;그리고 현재 ATAPI.sys를 훅킹하기 위해 \\Device\\Ide\\IdeDeviceP1T0L0-17 요런식으로&lt;br /&gt;디바이스 이름을 가져오는데 이렇게 가져오지 않고 다음과 같이 드라이버 오브젝트를 가져오는&lt;br /&gt;방식으로 해도 상관이 없습니다.&lt;br /&gt;&lt;br /&gt;UNICODE_STRING uniname;&lt;br /&gt;PDRIVER_OBJECT atapi_dev;&lt;br /&gt;&lt;br /&gt;NTSTATUS ntStatus;&lt;br /&gt;&lt;br /&gt;RtlInitUnicodeString(&amp;amp;uniname , L&quot;\\Driver\\Atapi&quot;);&lt;br /&gt;&lt;font face=&quot;GulimChe&quot;/&gt;ntStatus = ObReferenceObjectByName&lt;/font&gt;( &amp;amp;uniname , &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OBJ_CASE_INSENSITIVE , &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NULL , &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *IoDriverObjectType , &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; KernelMode ,&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NULL , &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (PVOID*)&amp;amp;atapi_dev);&lt;br /&gt;&lt;br /&gt;참고로 특정 PC에 경우에는 ATAPI.sys를 안 쓰고 자체 드라이버를 쓰는 경우도 있으니 참고바랍니다.&lt;br /&gt;&lt;br /&gt;IRP Completion Hook에 대해 어려운 부분이 없으므로 잡담은 그만하고 소스코드올립니다.&lt;br /&gt;&lt;br /&gt;#include &amp;lt;Wdm.h&amp;gt;&lt;br /&gt;#include &amp;lt;Scsi.h&amp;gt;&lt;br /&gt;&lt;br /&gt;//&lt;br /&gt;// 이 구조체에 필요한 데이터 변수들을 추가합니다.&lt;br /&gt;//&lt;br /&gt;typedef struct _MY_CONTEXT_DATA&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 이곳에 추가..&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID pNotUsedData;&lt;br /&gt;} MY_CONTEXT_DATA, *PMY_CONTEXT_DATA;&lt;br /&gt;&lt;br /&gt;typedef struct _HOOK_CONTEXT_DATA&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PIO_COMPLETION_ROUTINE pOrgCompletionRoutine;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID pOrgContext;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MY_CONTEXT_DATA MyContextData;&lt;br /&gt;} HOOK_CONTEXT_DATA, *PHOOK_CONTEXT_DATA;&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT g_HookDeviceObject = NULL;&lt;br /&gt;PDRIVER_DISPATCH g_OrgHandler = NULL;&lt;br /&gt;UCHAR g_HookMajorFunctionIndex = 0xFF;&lt;br /&gt;&lt;br /&gt;LONG g_IRPEnterCount = 0;&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated);&lt;br /&gt;&lt;br /&gt;BOOLEAN
 IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR 
MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, 
PDRIVER_DISPATCH pNewHandler);&lt;br /&gt;BOOLEAN IrpHookFormName(__in WCHAR 
*DeviceObjectName, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH
 *pOrgHandler, PDRIVER_DISPATCH pNewHandler);&lt;br /&gt;&lt;br /&gt;VOID IrpUnhook();&lt;br /&gt;&lt;br /&gt;NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp);&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PFILE_OBJECT FileObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNICODE_STRING Name;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OBJECT_ATTRIBUTES ObjectAttributes;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE FileHandle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IO_STATUS_BLOCK IoStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = NULL;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RtlInitUnicodeString(&amp;amp;Name, DeviceObjectName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (bRelated == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // IoGetDeviceObjectPointer는 내부적으로 IoGetRelatedDeviceObject 함수를 호출합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 따라서 DeviceObjectName 에 해당하는 디바이스 오브젝트 포인터를 얻어오는게 아니라 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 해당 디바이스 오브젝트에 대한 최상위 디바이스 오브젝트를 얻어옵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = IoGetDeviceObjectPointer(&amp;amp;Name, FILE_READ_ATTRIBUTES, &amp;amp;FileObject, &amp;amp;DeviceObject);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 실제 해당 이름을 가진 디바이스 오브젝트를 얻옵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeObjectAttributes(&amp;amp;ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;Name,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (HANDLE) NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (PSECURITY_DESCRIPTOR)NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwOpenFile(&amp;amp;FileHandle,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FILE_READ_ATTRIBUTES,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;amp;ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;amp;IoStatus,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FILE_NON_DIRECTORY_FILE);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 해당 디바이스 오브젝트를 열 수 없습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ObReferenceObjectByHandle(FileHandle,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; *IoFileObjectType,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KernelMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (PVOID *)&amp;amp;FileObject,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Windows 2000 소스코드 참고&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 실제 내부 구현도 이와 비슷하게 되어 있습니다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // If the file object was taken out against the mounted file system, it&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // will have a Vpb. Traverse it to get to the DeviceObject. Note that in&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // this case we should never follow FileObject-&amp;gt;DeviceObject, as that&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // mapping may be invalid after a forced dismount.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (FileObject-&amp;gt;Vpb != NULL &amp;amp;&amp;amp; FileObject-&amp;gt;Vpb-&amp;gt;DeviceObject != NULL) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = FileObject-&amp;gt;Vpb-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // If a driver opened a disk device using direct device open and &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // later on it uses IoGetRelatedTargetDeviceObject to find the&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // device object it wants to send an IRP then it should not get the&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // filesystem device object. This is so that if the device object is in the&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // process of being mounted then vpb is not stable.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else if (!(FileObject-&amp;gt;Flags &amp;amp; FO_DIRECT_DEVICE_OPEN) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb != NULL &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb-&amp;gt;DeviceObject != NULL) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // This is a direct open against the device stack (and there is no mounted&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // file system to strain the IRPs through).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = FileObject-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Driver unload.\n&quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 드라이버 언로드 루틴에서 호출됩니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IrpUnhook(TRUE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOLEAN
 IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR 
MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, 
PDRIVER_DISPATCH pNewHandler)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_IRPEnterCount = 0;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *pOrgHandler = DeviceObject-&amp;gt;DriverObject-&amp;gt;MajorFunction[MajorFunctionIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (*pOrgHandler == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_HookDeviceObject = DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; g_HookMajorFunctionIndex = MajorFunctionIndex;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterlockedExchangePointer(&amp;amp;(DeviceObject-&amp;gt;DriverObject-&amp;gt;MajorFunction[MajorFunctionIndex]), pNewHandler);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOLEAN
 IrpHookFormName(__in WCHAR *DeviceObjectName, __in UCHAR 
MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, 
PDRIVER_DISPATCH pNewHandler)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = MyIoGetDeviceObjectPointer(DeviceObjectName, FALSE);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (DeviceObject != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (IrpHook(DeviceObject, MajorFunctionIndex, pOrgHandler, pNewHandler));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VOID IrpUnhook(BOOLEAN DriverUnloadRoutine)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((g_HookDeviceObject == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; || (g_OrgHandler == NULL))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Not hooked.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // IRP 핸들러를 원래의 핸들러로 되돌려줍니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
 &amp;nbsp;&amp;nbsp;&amp;nbsp; 
InterlockedExchangePointer(&amp;amp;(g_HookDeviceObject-&amp;gt;DriverObject-&amp;gt;MajorFunction[g_HookMajorFunctionIndex]),
 g_OrgHandler);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (DriverUnloadRoutine == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; LARGE_INTEGER WaitTime;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WaitTime.QuadPart = -1 * 10 * 1000 * 1000;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 드라이버 언로드 루틴에서 이 함수가 호출되었다면&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // InterlockedExchangePointer 후에 바로 드라이버가 언로드 되므로&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 이 때 InterlockedExchangePointer를 하기전에 훅킹 핸들러가 실행되었고&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 그 후에 InterlockedExchangePointer함수가 리턴하게 되면&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 훅킹 핸들러를 원래대로 되돌려주었지만 현재 루틴이 실행중일 수 있으므로 이에 대한 동기화 처리를&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 진행합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; while (g_IRPEnterCount &amp;gt; 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 현재 훅킹루틴이 실행중에 있으므로 잠시 대기합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KeDelayExecutionThread(KernelMode ,FALSE, &amp;amp;WaitTime);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 마지막으로 한 번 더 대기합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KeDelayExecutionThread(KernelMode ,FALSE, &amp;amp;WaitTime);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS NewIoCompletionRoutine(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in_opt PVOID Context)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PHOOK_CONTEXT_DATA pHookContextData;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PIO_COMPLETION_ROUTINE pOrgCompletionRoutine;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID pOrgContext;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PIO_STACK_LOCATION pIoStackLocation;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR *pBuffer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG i, DataLength;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BOOLEAN bUnlock;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pHookContextData = (PHOOK_CONTEXT_DATA)Context;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pOrgCompletionRoutine = pHookContextData-&amp;gt;pOrgCompletionRoutine;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pOrgContext = pHookContextData-&amp;gt;pOrgContext;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pIoStackLocation = IoGetNextIrpStackLocation(Irp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pIoStackLocation-&amp;gt;MajorFunction == g_HookMajorFunctionIndex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (Irp-&amp;gt;MdlAddress != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Irp-&amp;gt;MdlAddress-&amp;gt;MdlFlags : %u\n&quot;, Irp-&amp;gt;MdlAddress-&amp;gt;MdlFlags));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 이 접근 방식을 사용하지 않습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 특정 상황에 경우 블루 스크린이 뜰 수 있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 왜냐하면 간혹 MDL이 이미 맵핑되어 있는 상태로 올 수가 있는데 이 때&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // MmUnmapLockedPages 함수를 호출해버리면 훅킹루틴에서 맵핑을 해제해 버리기 때문에&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 블루 스크린이 발생합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // ( 정확하게 말해서 Irp-&amp;gt;MdlAddress-&amp;gt;MdlFlags에 MDL_MAPPED_TO_SYSTEM_VA 플래그가&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp; 포함 된 상태인 경우가 어쩌다가 한 번씩 존재합니다. )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //pBuffer = MmGetSystemAddressForMdlSafe(Irp-&amp;gt;MdlAddress, NormalPagePriority);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (Irp-&amp;gt;MdlAddress-&amp;gt;MdlFlags &amp;amp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (MDL_MAPPED_TO_SYSTEM_VA |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MDL_SOURCE_IS_NONPAGED_POOL))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pBuffer = Irp-&amp;gt;MdlAddress-&amp;gt;MappedSystemVa;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bUnlock = FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pBuffer = MmMapLockedPagesSpecifyCache(Irp-&amp;gt;MdlAddress,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KernelMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MmCached,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FALSE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NormalPagePriority);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bUnlock = TRUE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pBuffer != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DataLength = Irp-&amp;gt;IoStatus.Information;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;ATAPI read databuffer. read length : %u\n&quot;, DataLength));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (DataLength &amp;gt; 5)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 읽은 데이터의 일부분만 출력합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DataLength = 5;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for (i = 0; i &amp;lt; DataLength; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;%#x\n&quot;, pBuffer[i]));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (bUnlock == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MmUnmapLockedPages(pBuffer, Irp-&amp;gt;MdlAddress);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;NewIoCompletionRoutine\n&quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (pOrgCompletionRoutine(DeviceObject, Irp, pOrgContext));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 동기화를 위한 전역 카운트를 증가시킵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterlockedIncrement(&amp;amp;g_IRPEnterCount);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 디바이스 오브젝트에 대한 필터링을 하였지만 상황에 따라 하지 않아야 할 수도 있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //if (DeviceObject == g_HookDeviceObject)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 우리가 원하는 DeviceObject에서 발생한 Irp입니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PIO_STACK_LOCATION pIoStackLocation;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pIoStackLocation = IoGetCurrentIrpStackLocation(Irp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pIoStackLocation-&amp;gt;MajorFunction == g_HookMajorFunctionIndex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 이곳에 원하는 코드를 작성합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 예제코드에서는 간단히 CDB에 대해서 출력하겠습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; switch (pIoStackLocation-&amp;gt;Parameters.Scsi.Srb-&amp;gt;Cdb[0])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case SCSIOP_READ:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // ATAPI.sys에 기본적인 읽기명령이 발생하였습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pIoStackLocation-&amp;gt;CompletionRoutine != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 예제에서는 완료루틴이 등록되어 있을 경우에만 완료 루틴을 훅킹합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PHOOK_CONTEXT_DATA pHookContextData;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pHookContextData = ExAllocatePoolWithTag(NonPagedPool, sizeof(HOOK_CONTEXT_DATA), &apos;tseT&apos;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pHookContextData != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pHookContextData-&amp;gt;pOrgCompletionRoutine = pIoStackLocation-&amp;gt;CompletionRoutine;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pHookContextData-&amp;gt;pOrgContext = pIoStackLocation-&amp;gt;Context;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pIoStackLocation-&amp;gt;CompletionRoutine = NewIoCompletionRoutine;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pIoStackLocation-&amp;gt;Context = pHookContextData;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // pIoStackLocation-&amp;gt;Control = SL_INVOKE_ON_SUCCESS;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = g_OrgHandler(DeviceObject, Irp);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 동기화를 위한 전역 카운트를 감소합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterlockedDecrement(&amp;amp;g_IRPEnterCount);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (ntStatus);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 드라이버가 언로드 될 수 있도록 합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DriverObject-&amp;gt;DriverUnload = DriverUnload;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 예제로 훅킹하는 디바이스는 하드 디스크입니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ( 실제 하드 디스크에 섹터를 읽어주는 디바이스입니다. )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 해당 디바이스 이름은 시스템에 따라서 다릅니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // IRP_MJ_SCSI 를 훅킹합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IrpHookFormName(L&quot;\\Device\\Ide\\IdeDeviceP1T0L0-17&quot;, IRP_MJ_SCSI, &amp;amp;g_OrgHandler, NewIrpHandler) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;IrpHookFormName successed.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;IrpHookFormName failed.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return STATUS_SUCCESS;&lt;br /&gt;}&lt;/p&gt;
&lt;p/&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>IRP Hook</title>
      <id>http://simples.kr/19948</id>
      <published>2010-09-04T10:02:46+09:00</published>
      <updated>2010-09-04T10:02:46+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19948"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19948#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;간단한 IRP Hook 코드입니다.&lt;br /&gt;해당 코드에 일부를 수정하여 다른 IRP를 손쉽게 훅킹할 수 있습니다.&lt;br /&gt;보통 저에 경우에는 다른 드라이버에 대한 값을 모니터링 할 때 많이 사용합니다.&lt;br /&gt;&lt;br /&gt;예제코드는 ATAPI.sys에 IRP_MJ_SCSI를 훅킹하고 있고 Cdb를 출력합니다.&lt;br /&gt;Cdb와 SCSI에 대한 설명은 IRP Hook 범위를 넘어가므로 이에 대한 설명을 하지 않겠습니다.&lt;br /&gt;&lt;br /&gt;개인적으로 만든 코드라서 개인적인 루틴도 추가되었습니다.&lt;br /&gt;예를 들어 IRP 핸들러 시작부분과 끝부분에 g_IRPEnterCount변수 사용 및&lt;br /&gt;IRPUnhook 시 이 변수를 체크합니다. &lt;br /&gt;이는 드라이버 동적 언로드 시 극악의 확률로 발생가능한 동기화문제를 막기 위해서입니다.&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;#include &amp;lt;Wdm.h&amp;gt;&lt;br /&gt;#include &amp;lt;Scsi.h&amp;gt;&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT g_HookDeviceObject = NULL;&lt;br /&gt;PDRIVER_DISPATCH g_OrgHandler = NULL;&lt;br /&gt;UCHAR g_HookMajorFunctionIndex = 0xFF;&lt;br /&gt;&lt;br /&gt;LONG g_IRPEnterCount = 0;&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated);&lt;br /&gt;&lt;br /&gt;BOOLEAN
 IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR 
MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, 
PDRIVER_DISPATCH pNewHandler);&lt;br /&gt;BOOLEAN IrpHookFormName(__in WCHAR 
*DeviceObjectName, __in UCHAR MajorFunctionIndex, __out PDRIVER_DISPATCH
 *pOrgHandler, PDRIVER_DISPATCH pNewHandler);&lt;br /&gt;&lt;br /&gt;VOID IrpUnhook();&lt;br /&gt;&lt;br /&gt;NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp);&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;PFILE_OBJECT FileObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;UNICODE_STRING Name;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OBJECT_ATTRIBUTES ObjectAttributes;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE FileHandle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IO_STATUS_BLOCK IoStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DeviceObject = NULL;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;RtlInitUnicodeString(&amp;amp;Name, DeviceObjectName);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (bRelated == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// IoGetDeviceObjectPointer는 내부적으로 IoGetRelatedDeviceObject 함수를 호출합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 따라서 DeviceObjectName 에 해당하는 디바이스 오브젝트 포인터를 얻어오는게 아니라 &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 해당 디바이스 오브젝트에 대한 최상위 디바이스 오브젝트를 얻어옵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ntStatus = IoGetDeviceObjectPointer(&amp;amp;Name, FILE_READ_ATTRIBUTES, &amp;amp;FileObject, &amp;amp;DeviceObject);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 실제 해당 이름을 가진 디바이스 오브젝트를 얻옵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;InitializeObjectAttributes(&amp;amp;ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;amp;Name,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(HANDLE) NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(PSECURITY_DESCRIPTOR)NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ntStatus = ZwOpenFile(&amp;amp;FileHandle,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; FILE_READ_ATTRIBUTES,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;amp;ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;amp;IoStatus,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; FILE_NON_DIRECTORY_FILE);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 해당 디바이스 오브젝트를 열 수 없습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ObReferenceObjectByHandle(FileHandle,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*IoFileObjectType,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KernelMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;(PVOID *)&amp;amp;FileObject,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// Windows 2000 소스코드 참고&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 실제 내부 구현도 이와 비슷하게 되어 있습니다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// If the file object was taken out against the mounted file system, it&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// will have a Vpb. Traverse it to get to the DeviceObject. Note that in&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// this case we should never follow FileObject-&amp;gt;DeviceObject, as that&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// mapping may be invalid after a forced dismount.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (FileObject-&amp;gt;Vpb != NULL &amp;amp;&amp;amp; FileObject-&amp;gt;Vpb-&amp;gt;DeviceObject != NULL) &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;DeviceObject = FileObject-&amp;gt;Vpb-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// If a driver opened a disk device using direct device open and &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// later on it uses IoGetRelatedTargetDeviceObject to find the&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// device object it wants to send an IRP then it should not get the&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// filesystem device object. This is so that if the device object is in the&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// process of being mounted then vpb is not stable.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;else if (!(FileObject-&amp;gt;Flags &amp;amp; FO_DIRECT_DEVICE_OPEN) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb != NULL &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb-&amp;gt;DeviceObject != NULL) &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;DeviceObject = FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// This is a direct open against the device stack (and there is no mounted&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// file system to strain the IRPs through).&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;else &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;DeviceObject = FileObject-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;Driver unload.\n&quot;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 드라이버 언로드 루틴에서 호출됩니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;IrpUnhook(TRUE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOLEAN
 IrpHook(__in PDEVICE_OBJECT DeviceObject, __in UCHAR 
MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, 
PDRIVER_DISPATCH pNewHandler)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;g_IRPEnterCount = 0;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;*pOrgHandler = DeviceObject-&amp;gt;DriverObject-&amp;gt;MajorFunction[MajorFunctionIndex];&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (*pOrgHandler == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;g_HookDeviceObject = DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;g_HookMajorFunctionIndex = MajorFunctionIndex;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;InterlockedExchangePointer(&amp;amp;(DeviceObject-&amp;gt;DriverObject-&amp;gt;MajorFunction[MajorFunctionIndex]), pNewHandler);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOLEAN
 IrpHookFormName(__in WCHAR *DeviceObjectName, __in UCHAR 
MajorFunctionIndex, __out PDRIVER_DISPATCH *pOrgHandler, 
PDRIVER_DISPATCH pNewHandler)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DeviceObject = MyIoGetDeviceObjectPointer(DeviceObjectName, FALSE);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (DeviceObject != NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return (IrpHook(DeviceObject, MajorFunctionIndex, pOrgHandler, pNewHandler));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VOID IrpUnhook(BOOLEAN DriverUnloadRoutine)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if ((g_HookDeviceObject == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;|| (g_OrgHandler == NULL))&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;Not hooked.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// IRP 핸들러를 원래의 핸들러로 되돌려줍니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;
 &amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;InterlockedExchangePointer(&amp;amp;(g_HookDeviceObject-&amp;gt;DriverObject-&amp;gt;MajorFunction[g_HookMajorFunctionIndex]),
 g_OrgHandler);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (DriverUnloadRoutine == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;LARGE_INTEGER WaitTime;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;WaitTime.QuadPart = -1 * 10 * 1000 * 1000;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 드라이버 언로드 루틴에서 이 함수가 호출되었다면&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// InterlockedExchangePointer 후에 바로 드라이버가 언로드 되므로&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 이 때 InterlockedExchangePointer를 하기전에 훅킹 핸들러가 실행되었고&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 그 후에 InterlockedExchangePointer함수가 리턴하게 되면&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 훅킹 핸들러를 원래대로 되돌려주었지만 현재 루틴이 실행중일 수 있으므로 이에 대한 동기화 처리를&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 진행합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;while (g_IRPEnterCount &amp;gt; 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 현재 훅킹루틴이 실행중에 있으므로 잠시 대기합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KeDelayExecutionThread(KernelMode ,FALSE, &amp;amp;WaitTime);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 마지막으로 한 번 더 대기합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KeDelayExecutionThread(KernelMode ,FALSE, &amp;amp;WaitTime);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS NewIrpHandler(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 동기화를 위한 전역 카운트를 증가시킵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterlockedIncrement(&amp;amp;g_IRPEnterCount);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 디바이스 오브젝트에 대한 필터링을 하였지만 상황에 따라 하지 않아야 할 수도 있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (DeviceObject == g_HookDeviceObject)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 우리가 원하는 DeviceObject에서 발생한 Irp입니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; PIO_STACK_LOCATION pIoStackLocation;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pIoStackLocation = IoGetCurrentIrpStackLocation(Irp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (pIoStackLocation-&amp;gt;MajorFunction == g_HookMajorFunctionIndex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 이곳에 원하는 코드를 작성합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 예제코드에서는 간단히 CDB에 대해서 출력하겠습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;DeviceObject : %p, Cdb : %#x\n&quot;, DeviceObject, pIoStackLocation-&amp;gt;Parameters.Scsi.Srb-&amp;gt;Cdb[0]));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = g_OrgHandler(DeviceObject, Irp);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 동기화를 위한 전역 카운트를 감소합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; InterlockedDecrement(&amp;amp;g_IRPEnterCount);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (ntStatus);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 드라이버가 언로드 될 수 있도록 합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;DriverObject-&amp;gt;DriverUnload = DriverUnload;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 예제로 훅킹하는 디바이스는 하드 디스크입니다. &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// ( 실제 하드 디스크에 섹터를 읽어주는 디바이스입니다. )&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// 해당 디바이스 이름은 시스템에 따라서 다릅니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;// IRP_MJ_SCSI 를 훅킹합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (IrpHookFormName(L&quot;\\Device\\Ide\\IdeDeviceP1T0L0-17&quot;, IRP_MJ_SCSI, &amp;amp;g_OrgHandler, NewIrpHandler) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;IrpHookFormName successed.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;KdPrint((&quot;IrpHookFormName failed.\n&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return STATUS_SUCCESS;&lt;br /&gt;}
       &lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>디바이스이름으로부터 PDEVICE_OBJECT 얻기</title>
      <id>http://simples.kr/19946</id>
      <published>2010-09-04T09:53:40+09:00</published>
      <updated>2010-09-07T11:19:13+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19946"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19946#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;글을 쓰기 앞서 IoGetDeviceObjectPointer라는 유용한 커널 함수가 존재하나 해당 함수는&lt;br /&gt;내부적으로 IoGetRelatedDeviceObject 함수를 호출함으로 이름에 해당하는 PDEVICE_OBJECT를&lt;br /&gt;리턴하는것이 아니라 이름에 해당하는 PDEVICE_OBJECT에 최상위 PDEVICE_OBJECT를 리턴합니다.&lt;br /&gt;&lt;br /&gt;예를 들어 atapi 드라이버에 다음과 같이 사용중인 디바이스 오브젝트가 3개가 있을 경우&lt;br /&gt;&quot;\\Device\\Ide\\IdeDeviceP1T0L0-17&quot;는 시디롬 장치의 디바이스 오브젝트인데&lt;br /&gt;IoGetDeviceObjectPointer 함수를 사용하면 0x817E4030 주소를 가진 PDEVICE_OBJECT를 리턴하는것이 아니라&lt;br /&gt;Attach 되어 있는 최상위 디바이스 오브젝트인 \\Driver\redbook ( unnamed - 디바이스 이름없음 ) 하게 됩니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;/p&gt;&lt;center/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/946/019/b0072382_4a617605c9a93.png&quot; alt=&quot;b0072382_4a617605c9a93.png&quot; class=&quot;iePngFix&quot; width=&quot;859&quot; height=&quot;387&quot; style=&quot;&quot; /&gt;&lt;p/&gt;&amp;nbsp;&lt;/p&gt;
&lt;/center&gt;&lt;br /&gt;&lt;p/&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;그러므로 디바이스 이름으로부터 정확한 포인터를 얻으려면 다음과 같은 방법으로 얻을 수 있습니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;#include &amp;lt;Wdm.h&amp;gt;&lt;br /&gt;&lt;br /&gt;PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PFILE_OBJECT FileObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNICODE_STRING Name;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OBJECT_ATTRIBUTES ObjectAttributes;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE FileHandle;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IO_STATUS_BLOCK IoStatus;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = NULL;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RtlInitUnicodeString(&amp;amp;Name, DeviceObjectName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (bRelated == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // IoGetDeviceObjectPointer는 내부적으로 IoGetRelatedDeviceObject 함수를 호출합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 따라서 DeviceObjectName 에 해당하는 디바이스 오브젝트 포인터를 얻어오는게 아니라 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 해당 디바이스 오브젝트에 대한 최상위 디바이스 오브젝트를 얻어옵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = IoGetDeviceObjectPointer(&amp;amp;Name, FILE_READ_ATTRIBUTES, &amp;amp;FileObject, &amp;amp;DeviceObject);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 실제 해당 이름을 가진 디바이스 오브젝트를 얻옵니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeObjectAttributes(&amp;amp;ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;Name,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (HANDLE) NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (PSECURITY_DESCRIPTOR)NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwOpenFile(&amp;amp;FileHandle,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FILE_READ_ATTRIBUTES,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;amp;ObjectAttributes,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;amp;IoStatus,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;FILE_NON_DIRECTORY_FILE);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 해당 디바이스 오브젝트를 열 수 없습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ObReferenceObjectByHandle(FileHandle,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; *IoFileObjectType,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KernelMode,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (PVOID *)&amp;amp;FileObject,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Windows 2000 소스코드 참고&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 실제 내부 구현도 이와 비슷하게 되어 있습니다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // If the file object was taken out against the mounted file system, it&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // will have a Vpb. Traverse it to get to the DeviceObject. Note that in&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // this case we should never follow FileObject-&amp;gt;DeviceObject, as that&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // mapping may be invalid after a forced dismount.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (FileObject-&amp;gt;Vpb != NULL &amp;amp;&amp;amp; FileObject-&amp;gt;Vpb-&amp;gt;DeviceObject != NULL) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = FileObject-&amp;gt;Vpb-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // If a driver opened a disk device using direct device open and &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // later on it uses IoGetRelatedTargetDeviceObject to find the&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // device object it wants to send an IRP then it should not get the&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // filesystem device object. This is so that if the device object is in the&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // process of being mounted then vpb is not stable.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else if (!(FileObject-&amp;gt;Flags &amp;amp; FO_DIRECT_DEVICE_OPEN) &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb != NULL &amp;amp;&amp;amp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb-&amp;gt;DeviceObject != NULL) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = FileObject-&amp;gt;DeviceObject-&amp;gt;Vpb-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // This is a direct open against the device stack (and there is no mounted&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // file system to strain the IRPs through).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = FileObject-&amp;gt;DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return DeviceObject;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(FileHandle);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;Driver unload.\n&quot;));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PDEVICE_OBJECT DeviceObject;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 드라이버가 언로드 될 수 있도록 합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DriverObject-&amp;gt;DriverUnload = DriverUnload;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DeviceObject = MyIoGetDeviceObjectPointer(L&quot;\\Device\\Ide\\IdeDeviceP1T0L0-17&quot;, FALSE);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;DeviceObject : %p\n&quot;, DeviceObject));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return STATUS_SUCCESS;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;MyIoGetDeviceObjectPointer 에 두 번째 인자가 TRUE을 경우에는 기존 IoGetDeviceObjectPointer 함수를&lt;br /&gt;사용하며 FALSE인 경우에는 이름에 해당하는  PDEVICE_OBJECT를 바로 얻어옵니다.&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>하드디스크에 존재하지 않는 드라이버 바이너리 가져오기</title>
      <id>http://simples.kr/19874</id>
      <published>2010-09-03T20:18:54+09:00</published>
      <updated>2010-09-05T22:07:51+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19874"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19874#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;어떤 보안 프로그램( nProtect, 키보드보안 ) 이나 SPTD를 사용하는 가상 시디 소프트웨어 ( Daemon, Alchol
 120% ) 에 경우에는 드라이버가 설치되어 있지만 윈도우즈 탐색기에 \\system32\\drivers\\에 가보면 해당 
드라이버 파일들이 존재하지 않는다는 것을 알 수 있습니다.&lt;br /&gt;&lt;br /&gt;데몬을 예로 들자면 다음과 같이 설치가 완료되면 장치 관리자에 저장소 컨트롤러가 추가되게 됩니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/874/019/b0072382_4971b1f3078e5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;500&quot; height=&quot;463&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;그러나 그림에서 보는 경로에 파일은 존재하지 않으며 gmer과 같은 루트킷 체크프로그램으로 파일 시스템을 직접적으로 읽어도 파일이 존재하지 않습니다.&lt;br /&gt;&lt;br /&gt;이러한 방식은 드라이버 파일을 숨기는 방식이 아니며 실제로 하드 디스크에 존재하지 않는 경우입니다.&lt;br /&gt;드라이버를 로드하면 로드 후 바로 파일을 하드 디스크상에 삭제함으로 메모리상에만 존재하게 되는 것입니다.&lt;br /&gt;&lt;br /&gt;이렇게 드라이버 파일을 바로 삭제하는 이유는 리버스 엔지니어링을 방지하기 위함인데 &lt;br /&gt;이러한 경우 어떻게 해당 드라이버 파일을 가져올 수 있는지에 대한 방법에 대해 소개할까합니다.&lt;br /&gt;&lt;br /&gt;사실 방법은 매우 간단하며 다음과 같은 시스템에서 제공해주는 함수를 이용하면 쉽게 드라이버 파일인 .sys를 흭득 할 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;xml/&gt;&lt;/xml&gt;&lt;mshelp:attr name=&quot;TopicType&quot; value=&quot;apiref&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;TargetOS&quot; value=&quot;Windows&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;APIType&quot; value=&quot;Function&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;APILocation&quot; value=&quot;Ntddk.h&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;APIName&quot; value=&quot;PsSetLoadImageNotifyRoutine&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;WdkCategory&quot; value=&quot;WdkKernel&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;CommunityContent&quot; value=&quot;1&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:attr name=&quot;EnableMachineTranslation&quot; value=&quot;1&quot;/&gt;&lt;/mshelp:attr&gt;&lt;mshelp:keyword index=&quot;A&quot; term=&quot;k108_287b9d79-8b77-40b6-8fe7-21ac3551e437.xml&quot;/&gt;&lt;/mshelp:keyword&gt;&lt;mshelp:keyword index=&quot;K&quot; term=&quot;PsSetLoadImageNotifyRoutine&quot;/&gt;&lt;/mshelp:keyword&gt;&lt;/p&gt;&lt;div class=&quot;hentry&quot;/&gt;&lt;br /&gt;&lt;h1/&gt;&lt;a name=&quot;k108_287b9d79-8b77-40b6-8fe7-21ac3551e437.xml&quot;/&gt;&lt;/a&gt;PsSetLoadImageNotifyRoutine&lt;/h1&gt;&lt;p style=&quot;padding: 2pt 4pt; background-color: rgb(221, 221, 221); background-image: none; background-repeat: repeat; background-attachment: scroll; background-position: 0% 0%; -moz-background-size: auto auto; font: 100% Courier New,Courier,mono; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; cursor: text;&quot; class=&quot;syntax&quot;/&gt;&lt;b/&gt;NTSTATUS&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;b/&gt;PsSetLoadImageNotifyRoutine(&lt;/b&gt;&lt;br /&gt;&lt;b/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IN&amp;nbsp;PLOAD_IMAGE_NOTIFY_ROUTINE&lt;/b&gt;&amp;nbsp;&amp;nbsp;&lt;i/&gt;&lt;a class=&quot;synParam&quot; href=&quot;http://lain32.egloos.com/4257742&quot;/&gt;NotifyRoutine&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;&lt;b/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;훅킹쪽에 관심이 있으신 분이라면 거의 알만한 함수죠..&lt;br /&gt;이 함수는 하나의 콜백함수를 인자로 받으며 이 콜백함수는 &lt;span style=&quot;font-weight: bold;&quot;/&gt;&quot;시스템에서 어떠한 모듈이 로드 될 때 ( Dll, Sys )&quot;&lt;/span&gt; 호출되게 됩니다.&lt;br /&gt;&lt;br /&gt;이쯤이면 거의 답이 나왔다시피 합니다.&lt;br /&gt;&lt;br /&gt;한 번 실제 구현코드를 보겠습니다.&lt;font face=&quot;monospace&quot;/&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;void CallBackLoadImageNotifyRoutine(__in PUNICODE_STRING FullImageName, __in HANDLE ProcessId, __in PIMAGE_INFO ImageInfo)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;{&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE hReadHandle;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE hWriteHandle;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHAR pFileBuffer[1024];&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS ntStatus;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IO_STATUS_BLOCK IoStatusBlock;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OBJECT_ATTRIBUTES ObjectAttributes;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LARGE_INTEGER Offset;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNICODE_STRING uniWritFileName;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;모듈이 로드되었습니다. : %ws ( Irql : %#x )\n&quot;, FullImageName-&amp;gt;Buffer, KeGetCurrentIrql()));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 드라이버의 파일은 확장자가 .sys 이므로 확장자가 s로 끝나는 이름이 있는지 확인합니다.&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((FullImageName-&amp;gt;Buffer[wcslen(FullImageName-&amp;gt;Buffer) - 1] == &apos;s&apos;)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; || (FullImageName-&amp;gt;Buffer[wcslen(FullImageName-&amp;gt;Buffer) - 1] == &apos;S&apos;))&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 드라이버 파일이 로드되었습니다.&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeObjectAttributes(&amp;amp;ObjectAttributes, FullImageName, OBJ_CASE_INSENSITIVE, NULL, NULL);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwCreateFile(&amp;amp;hReadHandle, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERIC_READ | SYNCHRONIZE,&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;ObjectAttributes,&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;IoStatusBlock, NULL,&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_ATTRIBUTE_NORMAL, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_SHARE_READ | FILE_SHARE_WRITE, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_OPEN, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;파일을 생성하지 못 하였습니다.\n&quot;));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.LowPart = 0;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.HighPart = 0;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; RtlInitUnicodeString(&amp;amp;uniWritFileName, L&quot;\\??\\C:\\Output.Sys&quot;);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InitializeObjectAttributes(&amp;amp;ObjectAttributes, &amp;amp;uniWritFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwCreateFile(&amp;amp;hWriteHandle, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERIC_WRITE | SYNCHRONIZE | FILE_APPEND_DATA, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;ObjectAttributes, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;IoStatusBlock, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL,&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_ATTRIBUTE_NORMAL, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_CREATE, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NULL, &lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;쓰기 파일을 생성 할 수 없음 %#x\n&quot;, ntStatus));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hReadHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; while (TRUE)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwReadFile(hReadHandle, NULL, NULL, NULL, &amp;amp;IoStatusBlock, pFileBuffer, 1024, &amp;amp;Offset, NULL);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if((NT_SUCCESS(ntStatus) == FALSE) || (IoStatusBlock.Information != 1024))&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
 &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwWriteFile(hWriteHandle, NULL, NULL, NULL, 
&amp;amp;IoStatusBlock, pFileBuffer, IoStatusBlock.Information, NULL, NULL);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hWriteHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hReadHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;루프를 빠져나갑니다.\n&quot;));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // 파일을 모두 작성하였으니 루프를 빠져나갑니다.&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hWriteHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hReadHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ntStatus = ZwWriteFile(hWriteHandle, NULL, NULL, NULL, &amp;amp;IoStatusBlock, pFileBuffer, 1024, NULL, NULL);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(ntStatus) == FALSE)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;쓰기 실패...\n&quot;));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hWriteHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ZwClose(hReadHandle);&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return ;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Offset.LowPart += 1024;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;완료...\n&quot;));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;}&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;void Hook()&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;{&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (NT_SUCCESS(PsSetLoadImageNotifyRoutine(CallBackLoadImageNotifyRoutine)) == TRUE)&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;성공...\n&quot;));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; KdPrint((&quot;실패...\n&quot;));&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;}&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;&lt;br /&gt;Hook() 이라는 함수는 DriverEntry와 같은 함수에서 호출하거나 또는 다른 &lt;/span&gt;&lt;/font&gt;PASSIVE_LEVEL에서 호출하면 됩니다.&lt;br /&gt;&lt;br /&gt;콜백함수에서는 파일의 이름에서 끝에 이름이 &apos;S&apos; 또는 &apos;s&apos;일 경우라면 &quot;Output.sys&quot;라는 파일로 &quot;C:\&quot; 루트에다가 드라이버 파일을 생성하게 됩니다.&lt;br /&gt;&lt;br /&gt;실제로 이 드라이버 파일을 컴파일하고 로드를 미리 시켜놓은 다음에 데몬을 설치하고 설치가 완료되면 가상 장치 업데이트&lt;br /&gt;창에서 드라이버를 로드하게 되는데 다음과 같이 DbgView에서 드라이버 파일이 로드됨을 볼 수 있습니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/874/019/b0072382_4971b1f3078e5_1.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;795&quot; height=&quot;463&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;완료라는 메세지가 출력되고 C드라이브에 가보면 다음과 같이 Outpup.sys가 생성되게 됩니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/874/019/b0072382_4971b1f3078e5_2.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;491&quot; height=&quot;222&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;국내에 보안 프로그램들도 위에서처럼 드라이버를 숨기게 됩니다.&lt;br /&gt;밑에 그림은 특정 은행에 들어갔을 때 키보드 보안 프로그램을 설치하게 되는데 이 때 로드 된 드라이버입니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/874/019/b0072382_4971b1f3078e5_3.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;853&quot; height=&quot;441&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;결론은 드라이버가 로드되기전에 &lt;font face=&quot;monospace&quot;/&gt;&lt;span style=&quot;font-family: 굴림;&quot;/&gt;PsSetLoadImageNotifyRoutine를 이용하면 로드 후 바로 삭제되는 로딩방식의 드라이버 파일을&lt;br /&gt;가져올 수 있다는 것입니다.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>DosPathNameToNtPathName</title>
      <id>http://simples.kr/19851</id>
      <published>2010-09-03T17:36:03+09:00</published>
      <updated>2010-09-03T17:36:03+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19851"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19851#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;Win32와 드라이버간에 통신을 할 때 Win32에서 드라이버에게 파일경로를 넘겨주어야 할 때가 있었는데 Win32에서&lt;br /&gt;C 드라이브를 경로에 경우 &quot;C:\\&quot;와 같이 접근하면 되지만 드라이버에서는 &quot;\\??\\C:\\&quot; 와 같이 접근을 해야 합니다.&lt;br /&gt;&lt;br /&gt;간단하게 위와 같은 경우에는 앞에 &quot;\\??\\&quot; 를 붙여주면 되지만 네트워크 공유 폴더에 경우에는 &lt;br /&gt;또 다른 방식으로 이름을 지정해 주어야 합니다.&lt;br /&gt;&lt;br /&gt;즉, 상황에 따라 Win32에서 파일 이름을 파싱하여 드라이버에서 인식 할 수 있는 이름으로 변환 후 드라이버에 넘겨주곤 하였는데&lt;br /&gt;좀 더 깔끔한 방법을 소개하려고 합니다.&lt;br /&gt;&lt;br /&gt;사실 조금만 생각해보면 Kernel32.CreateFileA는 Kernel32.CreateFileW를 호출하게 되고&lt;br /&gt;( Win32에서 유니코드와 그렇지 않은 API로 나뉘어지는데 유니코드가 아닌 함수는 내부적으로 유니코드로 변환하여&lt;br /&gt;&amp;nbsp; 유니코드용 함수를 호출하게 됩니다. 그래서 유니코드로 만들어진 프로그램이 빠르다는 말이 있죠.. )&lt;br /&gt;Kernel32.CreateFileW는 내부적으로 NtDll.NtCreateFile 를 호출할 것입니다.&lt;br /&gt;&lt;br /&gt;그리고 여기서 NtCreateFile은 파일이름을 인자로 받지 않습니다.&lt;br /&gt;즉, 그 전에 파일 이름이 NtPathName으로 변환된다는 말입니다.&lt;br /&gt;&lt;br /&gt;IDA로 Kernel32.DLL를 열어본 후 Export 된 CreateFileW에서 호출하는 함수들을 보면 다음과 같이 바로 눈에 띄는 함수가 있습니다. &lt;br /&gt;( 해당 Kernel32.DLL은 Windows XP SP2 입니다. 버전이 다른 운영체제에 경우에는 다른 함수를 사용하는 경우도 있습니다. )&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/851/019/b0072382_4971b1f3078e5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;710&quot; height=&quot;594&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;함수 이름에서 이미 무엇을 하는 함수인지 설명이 다 되어 있습니다.&lt;br /&gt;구글링을 조합한 해당 함수를 사용하는 예제코드는 다음과 같습니다.&lt;br /&gt;&lt;br /&gt;#include &amp;lt;Windows.h&amp;gt;&lt;br /&gt;typedef struct _UNICODE_STRING {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USHORT&amp;nbsp; Length;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USHORT&amp;nbsp; MaximumLength;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PWSTR&amp;nbsp; Buffer;&lt;br /&gt;} UNICODE_STRING, *PUNICODE_STRING;&lt;br /&gt;typedef BOOLEAN (__stdcall *RtlDosPathNameToNtPathName_U)(PCWSTR DosName, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; PUNICODE_STRING NtName,&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; PCWSTR *DosFilePath OPTIONAL,&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; PUNICODE_STRING NtFilePath );&lt;br /&gt;typedef void (__stdcall *RtlFreeUnicodeString)(&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PUNICODE_STRING UnicodeString&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RtlDosPathNameToNtPathName_U pRtlDosPathNameToNtPathName_U;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RtlFreeUnicodeString pRtlFreeUnicodeString;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HMODULE hModule;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNICODE_STRING NtName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hModule = ::LoadLibrary(_T(&quot;NtDLL.DLL&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (hModule == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;NTDLL을 로드 할 수 없습니다.\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (-1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pRtlDosPathNameToNtPathName_U = (RtlDosPathNameToNtPathName_U)::GetProcAddress(hModule, &quot;RtlDosPathNameToNtPathName_U&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pRtlDosPathNameToNtPathName_U == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;RtlDosPathNameToNtPathName_U API를 찾을 수 없습니다.\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (-1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pRtlFreeUnicodeString = (RtlFreeUnicodeString)::GetProcAddress(hModule, &quot;RtlFreeUnicodeString&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pRtlFreeUnicodeString == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;RtlFreeUnicodeString API를 찾을 수 없습니다.\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return (-1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pRtlDosPathNameToNtPathName_U(_T(&quot;\\\\10.1.26.15&quot;), &amp;amp;NtName, NULL, NULL) == FALSE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;pRtlDosPathNameToNtPathName_U 실패\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 가져온 이름을 출력&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ::MessageBoxW(0, NtName.Buffer, _T(&quot;확인&quot;), 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pRtlFreeUnicodeString(&amp;amp;NtName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;위에 코드를 통해서 DosPathName을 NtPathName으로 변경할 수 있습니다.&lt;br /&gt;예제 코드에서는 _T(&quot;\\\\10.1.26.15&quot;) 에 NtPathName를 얻으려고 하였습니다.&lt;br /&gt;&lt;br /&gt;실행결과는 다음과 같습니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/851/019/b0072382_4971b1f3078e5_1.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;218&quot; height=&quot;190&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold; font-style: italic;&quot;/&gt;참고로 이 함수는 유저레벨에서만 사용 할 수 있고 인자로 넘겨주는 경로가 존재하지 않아도 상관이 없습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold; font-style: italic;&quot;/&gt;즉, 경로를 드라이버에서 사용가능한 경로로 변환할 뿐 경로가 올바른지는 확인하지 않습니다. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;해당 함수가 Undocumented 된 API이긴 하지만 제가 테스트해봤을 때는 거의 모든 운영체제에서 돌아갔습니다.&lt;br /&gt;테스트한 운영체제는..&lt;br /&gt;Windows XP SP2, Windows 2003 Server, Windows XP 64Bit, Windows Vista 64Bit, Windows 7 64Bit 입니다.&lt;br /&gt;( 그냥 다 된다고 보시면 됩니다.-_- )&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>ZwQueryInformationFile을 비동기 파일핸들로 호출 시 STATUS_PENDING을 리턴할까?</title>
      <id>http://simples.kr/19844</id>
      <published>2010-09-03T17:32:38+09:00</published>
      <updated>2010-09-03T17:32:38+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19844"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19844#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;( 주의 : 이 글에서 디스어셈블리되는 커널은 Windows XP SP2 이며 . ZwQueryInformationFile호출시 
FileStandardInformation를 사용하였으므로 다른 인자를 사용하였다면 결과가 다르게 나타날 수 있습니다.&lt;b/&gt; &lt;/b&gt;)&lt;br /&gt;&lt;br /&gt;ZwCreateFile을 이용해 파일 핸들을 열 때 비동기적으로 열어야 하는 경우가 생겼습니다.&lt;br /&gt;&lt;br /&gt;이러한 경우 ZwReadFile로 파일을 읽을 때 두 번째 인자인 Event객체를 사용하여 WaitForSingleObject로 대기해야 하는 것으로 알고 있습니다.&lt;br /&gt;&lt;br /&gt;그
러나 ZwQueryInformationFile에 경우에는 Event객체가 존재하지 않습니다. 그렇다면 윈도우즈 
내부에서KeWaitForSingleObject을 호출 할 수도 있고 ( 만약에 비동기 모드로 파일의 핸들을 열었다면.. 
),KeWaitForSingleObject 호출하지 않고 STATUS_PENDING을 리턴 할수도 있습니다.&lt;br /&gt;&lt;br /&gt;내부적인 부분이라 알 수가 없고 STATUS_PENDING 리턴여부를 확실히 알아야 하기 때문에 WinDbg로 디버깅을 해보았습니다.&lt;br /&gt;&lt;br /&gt;우선 파일을 비동기 모드로 연 후 ZwQueryInformationFile을 호출하기 바로 전에 브레이크 포인트를 걸어둡니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/844/019/b0072382_4971b1f3078e5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;607&quot; height=&quot;327&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;ZwQueryInformationFile은 내부적으로 NtQueryInformationFile 파일을 호출할 것이므로 다음과 같은 WinDbg명령줄을 이용해 브레이크 포인트를 겁니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;bp nt!NtQueryInformationFile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;그리고 F5를 눌러서 한 번 실행시킵니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/844/019/b0072382_49a7de4994124.png&quot; alt=&quot;b0072382_49a7de4994124.png&quot; class=&quot;iePngFix&quot; width=&quot;577&quot; height=&quot;169&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;위에 그림에서 보는 위치에서 멈추게 됩니다.&lt;br /&gt;중요한건 콜스택을 잘 확인하여 내 드라이버에서 호출한 것이 맞는지 반드시 확인해보아야 합니다. ( 간혹 내 드라이버에서 호출하지 않은 경우가 있을 수 있습니다. )&lt;br /&gt;&lt;br /&gt;F11를 눌르거나 계속해서 디버깅을 해보면 결국엔 IRP를 전송하기 위해 nt!IofCallDriver를 호출하게 되므로 &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;bp nt!IofCallDriver&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;를 이용하여 다시 브레이크 포인트를 겁니다&lt;span style=&quot;font-weight: bold;&quot;/&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;그리고 다시 F5를 누릅니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/844/019/b0072382_4971b1f3078e5_1.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;606&quot; height=&quot;105&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;위와 마찬가지로 반드시 콜스택을 확인하여 내 드라이버에서 호출했는지 확인을 합니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt; 이 상태에서 콜 스택을 보게 되면 이 함수를 호출 후 리턴되는 주소를 확인 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/844/019/b0072382_4971b1f3078e5_2.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;462&quot; height=&quot;40&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;그림에서 하이라이트 된 부분이 리턴되는 주소이며 해당 주소에 디스어셈블리 된 코드를 보면 다음과 같습니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/844/019/b0072382_4971b1f3078e5_3.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;533&quot; height=&quot;247&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p/&gt;위에서 보시면 KeWaitForSingleObject라는 함수를 어떠한 조건의 의해서 호출한다는 것을 알 수 있습니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt; &lt;br /&gt;&lt;br /&gt;8057bc3c 8b4dd4 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; mov &amp;nbsp; &amp;nbsp; ecx,dword ptr [ebp-2Ch]&lt;br /&gt;8057bc3f e87452f7ff &amp;nbsp; &amp;nbsp;&amp;nbsp; call &amp;nbsp;&amp;nbsp; nt!IofCallDriver (804f0eb8)&lt;br /&gt;8057bc44 8945d8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; mov &amp;nbsp; &amp;nbsp; dword ptr [ebp-28h],eax&lt;br /&gt;8057bc47 817dd803010000&amp;nbsp; cmp &amp;nbsp; &amp;nbsp; dword ptr [ebp-28h],103h&lt;br /&gt;8057bc4e 0f85cc000000 &amp;nbsp;&amp;nbsp; jne &amp;nbsp; &amp;nbsp; nt!NtQueryInformationFile+0x528 (8057bd20)&lt;br /&gt;8057bc54 807de700 &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; cmp &amp;nbsp; &amp;nbsp; byte ptr [ebp-19h],0&lt;br /&gt;8057bc58 745e &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; je &amp;nbsp; &amp;nbsp;&amp;nbsp; nt!NtQueryInformationFile+0x4c0 (8057bcb8)&lt;br /&gt;8057bc5a 33ff &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; xor &amp;nbsp; &amp;nbsp; edi,edi&lt;br /&gt;8057bc5c 57 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; push &amp;nbsp;&amp;nbsp; edi&lt;br /&gt;8057bc5d 8b45dc &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; mov &amp;nbsp; &amp;nbsp; eax,dword ptr [ebp-24h]&lt;br /&gt;8057bc60 8b482c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; mov &amp;nbsp; &amp;nbsp; ecx,dword ptr [eax+2Ch]&lt;br /&gt;8057bc63 c1e902 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; shr &amp;nbsp; &amp;nbsp; ecx,2&lt;br /&gt;8057bc66 81e101ffffff &amp;nbsp;&amp;nbsp; and &amp;nbsp; &amp;nbsp; ecx,0FFFFFF01h&lt;br /&gt;8057bc6c 51 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; push &amp;nbsp;&amp;nbsp; ecx&lt;br /&gt;8057bc6d ff75cc &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; push &amp;nbsp;&amp;nbsp; dword ptr [ebp-34h]&lt;br /&gt;8057bc70 57 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; push &amp;nbsp;&amp;nbsp; edi&lt;br /&gt;8057bc71 83c05c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; add &amp;nbsp; &amp;nbsp; eax,5Ch&lt;br /&gt;8057bc74 50 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; push &amp;nbsp;&amp;nbsp; eax&lt;br /&gt;8057bc75 e8300ff8ff &amp;nbsp; &amp;nbsp;&amp;nbsp; call &amp;nbsp;&amp;nbsp; nt!KeWaitForSingleObject (804fcbaa)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;이 부분은 IofCallDriver에 리턴값을 넣는 부분입니다.&lt;br /&gt;리턴값은 NTSTATUS일 것 입니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;8057bc44 8945d8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; mov &amp;nbsp; &amp;nbsp; dword ptr [ebp-28h],eax&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;그 후에 다음과 같이 0x103값과 비교하는데 이 값은 &lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;8057bc47 817dd803010000&amp;nbsp; cmp &amp;nbsp; &amp;nbsp; dword ptr [ebp-28h],103h&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;다음과 같이 정의되어 있습니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;#define STATUS_PENDING ((NTSTATUS)0x00000103L) &amp;nbsp;&amp;nbsp; // winnt&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;즉, Pending여부를 체크한다는 것을 알 수 있습니다.&lt;br /&gt;Pending이 아니라면 8057bd20주소로 점프하게 됩니다. Pedning이라면 다시 밑에서 무언가를 비교하게 되는데 &lt;span style=&quot;font-weight: bold;&quot;/&gt;byte ptr [ebp-19h]&lt;/span&gt;에
있는 이 값에 따라서 KeWaitForSingleObject를 호출할지 말지를 결정하게 됩니다. 중요한 것은 제 경우 테스트할 때
 이 값은 0이 아니었으며 따라서 KeWaitForSingleObject를 호출하는 코드를 실행하게 됩니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt; &lt;/span&gt;또한 IofCallDriver호출 후 리턴한 후 강제적으로 eax레지스터에 STATUS_PENDING를 넣게 되면 KeWaitForSingleObject를 호출하게 됩니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;참고로 만약 파일핸들을 동기화 모드로 열었다면 위에서 말한 코드 부분이 실행되지 않습니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;&lt;br /&gt;결론은 ZwQueryInformationFile를 비동기 파일핸들로 호출 시에 내부적으로 STATUS_PENDING 여부를 체크하여 &lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;KeWaitForSingleObject로 대기합니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;또한 ReactOS소스코드를 보시면 위와 비슷하게 구현되어 있는 것을 볼 수 있습니다. 물론 실제 윈도우즈 코드와 ReactOS소스코드가 완전히 같지는 않다는 것에 주의해야 할 것입니다.&lt;span style=&quot;font-weight: bold;&quot;/&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>커널 디버거 탐지 기법 우회</title>
      <id>http://simples.kr/19842</id>
      <published>2010-09-03T17:29:28+09:00</published>
      <updated>2010-09-03T17:29:28+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19842"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19842#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;다음 코드 2줄로 우회가 가능합니다.&lt;br /&gt;&lt;br /&gt;extern PBOOLEAN KdDebuggerEnabled; // 선언..&lt;br /&gt;*KdDebuggerEnabled = FALSE; // 우회 코드&lt;br /&gt;&lt;br /&gt;KdDebuggerEnabled 변수를 직접적으로 접근하지 않는 방식을 사용하여도 이 방법은 통합니다.&lt;br /&gt;왜냐하면 결국엔 그 함수들은 저 전역변수를 참조하게 됩니다.&lt;br /&gt;심지어 WinDbg 조차도 저렇게 값을 임의로 바꾸면 Attach가 안됩니다.&lt;br /&gt;&lt;br /&gt;따라서 이러한 경우 커널 디버거는 우회가 되는데 WinDbg로 Attach 하여서 디버깅하는데 조금 문제가 생길것입니다.&lt;br /&gt;따라서 디버거를 탐지하는 코드가 실행되는 경우에는 우선 저렇게 전역변수를 FALSE로 바꾸고&lt;br /&gt;디버거 탐지코드가 실행되었다면 다시 KdDebuggerEnabled 커널 전역변수를 TRUE로 바꿔주면&lt;br /&gt;WinDbg로 Attach 도 되고 디버깅이 가능해집니다.&lt;br /&gt;&lt;br /&gt;커널 디버거를 탐지하는 대상 코드는 아래와 같고 이러한 코드는 이전에 말했듯이 내부적으로&lt;br /&gt;위에 커널 전역변수를 사용하므로 우회가 됩니다.&lt;br /&gt;&lt;br /&gt;bool __stdcall IsDebugPort(PVOID Object)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; void *pZwQueryInformationProcess; // eax@2&lt;br /&gt;&amp;nbsp; bool result; // eax@4&lt;br /&gt;&amp;nbsp; signed int bDebug; // [sp+10h] [bp-4h]@1&lt;br /&gt;&amp;nbsp; int v4; // [sp+Ch] [bp-8h]@2&lt;br /&gt;&amp;nbsp; UNICODE_STRING DestinationString; // [sp+4h] [bp-10h]@3&lt;br /&gt;&lt;br /&gt;&amp;nbsp; bDebug = 0;&lt;br /&gt;&amp;nbsp; if ( PsLookupProcessByProcessId(Object, &amp;amp;Object) &amp;gt;= 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
 &amp;amp;&amp;amp; ((ObOpenObjectByPointer(Object, 0, 0, 0, 0, 0, &amp;amp;v4), 
ObfDereferenceObject(Object), pZwQueryInformationProcess = (void 
*)g_ZwQueryInformationProcess, g_ZwQueryInformationProcess)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; || 
(RtlInitUnicodeString(&amp;amp;DestinationString, 
L&quot;ZwQueryInformationProcess&quot;), pZwQueryInformationProcess = 
MmGetSystemRoutineAddress(&amp;amp;DestinationString), 
g_ZwQueryInformationProcess = (int)pZwQueryInformationProcess, 
pZwQueryInformationProcess)) )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((int (__stdcall *)(int, signed int, signed int *, signed int, _DWORD))pZwQueryInformationProcess)(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v4,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;bDebug,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 이 함수에 두 번째 인자 ProcessDebugPort를 넘기고 있다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 즉, 이것은 디버그중인지 체크한다고 보면 될것이다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = bDebug == -1;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // -1(0xFFFFFFFF) 일 경우 디버깅중인 상태입니다.&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; else&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = 0;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; return result;&lt;br /&gt;}&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>VMWare 탐지 기법 우회</title>
      <id>http://simples.kr/19840</id>
      <published>2010-09-03T17:29:02+09:00</published>
      <updated>2011-02-25T14:36:02+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19840"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19840#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;pre/&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.trapkit.de/&quot;/&gt;http://www.trapkit.de/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;위에 사이트에 가시면 여러가지 VMWare 탐지 기법들에 대해서 소개하고 있고 맨 마지막으로 그 모든 탐지기법들을&lt;br /&gt;우회하는 방법에 대해서 설명하는데 우회하는 방법은 VMWare에 vmx 파일에 다음 설정을 추가하는 것입니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;isolation.tools.getPtrLocation.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;isolation.tools.setPtrLocation.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;isolation.tools.setVersion.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;isolation.tools.getVersion.disable = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_directexec = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_chksimd = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_ntreloc = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_selfmod = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_reloc = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_btinout = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_btmemspace = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_btpriv = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;monitor_control.disable_btseg = &quot;TRUE&quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>커널 모듈 리스트 가져오기</title>
      <id>http://simples.kr/19838</id>
      <published>2010-09-03T17:28:16+09:00</published>
      <updated>2010-11-07T17:46:06+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19838"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19838#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;루트킷 체크 프로그램인 gmer에 Modules탭에 보면은 현재 로드 된 커널 모듈을 볼 수 있습니다.&lt;br /&gt;회사에서 작업을 하다가 해당 기능이 좀 필요해서 간단하게 인터넷 뒤져서 짜집기한 코드입니다.&lt;br /&gt;( OpenRCE랑 Undocumented 사이트 참고하였습니다. )&lt;br /&gt;&lt;br /&gt;컴파일을 하실려면 ntdll.lib이 필요한데 해당 lib파일은 WDK에 있습니다.&lt;br /&gt;&lt;br /&gt;#include &amp;lt;Windows.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) &amp;gt;= 0)&lt;br /&gt;#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)&lt;br /&gt;&lt;br /&gt;typedef enum _SYSTEM_INFORMATION_CLASS &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemBasicInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemProcessorInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPerformanceInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemTimeOfDayInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPathInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemProcessInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemCallCountInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemDeviceInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemProcessorPerformanceInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemFlagsInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemCallTimeInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemModuleInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemLocksInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemStackTraceInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPagedPoolInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemNonPagedPoolInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemHandleInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemObjectInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPageFileInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemVdmInstemulInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemVdmBopInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemFileCacheInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPoolTagInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemInterruptInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemDpcBehaviorInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemFullMemoryInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemLoadGdiDriverInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemUnloadGdiDriverInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemTimeAdjustmentInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemSummaryMemoryInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemNextEventIdInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemEventIdsInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemCrashDumpInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemExceptionInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemCrashDumpStateInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemKernelDebuggerInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemContextSwitchInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemRegistryQuotaInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemExtendServiceTableInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPrioritySeperation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPlugPlayBusInformation,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemDockInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemPowerInformationRedefine, // 이름이 중복되어서 변경하였습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemProcessorSpeedInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemCurrentTimeZoneInformation, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemLookasideInformation&lt;br /&gt;} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;extern &quot;C&quot; NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IN SYSTEM_INFORMATION_CLASS SystemInformationClass,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OUT PVOID SystemInformation,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IN ULONG SystemInformationLength,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OUT PULONG ReturnLength OPTIONAL); &lt;br /&gt;&lt;br /&gt;typedef struct _RTL_PROCESS_MODULE_INFORMATION {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HANDLE Section;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID MappedBase;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PVOID ImageBase;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ImageSize;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG Flags;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USHORT LoadOrderIndex;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USHORT InitOrderIndex;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USHORT LoadCount;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; USHORT OffsetToFileName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHAR FullPathName[256];&lt;br /&gt;} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;&lt;br /&gt;&lt;br /&gt;typedef struct _RTL_PROCESS_MODULES {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG NumberOfModules;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RTL_PROCESS_MODULE_INFORMATION Modules[1];&lt;br /&gt;} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;&lt;br /&gt;&lt;br /&gt;BOOL PrintSystemModuleList()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NTSTATUS Status;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PRTL_PROCESS_MODULES ModuleInfo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PRTL_PROCESS_MODULE_INFORMATION ModuleEntry;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG ReturnedLength;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ULONG i;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = NtQuerySystemInformation(SystemModuleInformation,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NULL,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;ReturnedLength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (Status != STATUS_INFO_LENGTH_MISMATCH) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleInfo = (PRTL_PROCESS_MODULES)malloc(ReturnedLength);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = NtQuerySystemInformation(SystemModuleInformation,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleInfo,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReturnedLength,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;ReturnedLength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!NT_SUCCESS(Status)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; free(ModuleInfo);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (i = 0; i &amp;lt; ModuleInfo-&amp;gt;NumberOfModules; i++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleEntry = &amp;amp;ModuleInfo-&amp;gt;Modules[i];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;%s\n&quot;, ModuleEntry-&amp;gt;FullPathName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; free(ModuleInfo);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PrintSystemModuleList();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;/p&gt;&lt;p/&gt;}&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>IDA에서 Microsoft 바이너리 파일을 리버싱 할 때 디버그 심볼 포함하기</title>
      <id>http://simples.kr/19823</id>
      <published>2010-09-03T17:04:57+09:00</published>
      <updated>2010-09-05T21:19:51+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19823"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19823#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;WinDbg로 커널 드라이버를 디버깅해보신분이라면 MS에서 디버그 심볼을 자동으로 다운로드 받아 디버깅 시 디버그 심볼도 같이 포함되어 디버깅을 편하게 할 수 있다는 것을 알 수 있습니다.&lt;br /&gt;&lt;br /&gt;위
와 비슷하게 IDA에서 Microsoft사에서 만든 바이너리파일을 리버싱해야 할 경우가 있는데 이 때 Determina PDB 
Plugin for IDA Pro 라는 IDA 플러그인을 이용하면 IDA에서도 디버그 심볼을 포함시켜서 디버깅이 가능하게 됩니다.&lt;br /&gt;&lt;br /&gt;해당 플러그인은 다음 주소에서 받으실 수 있습니다.&lt;br /&gt;&lt;a href=&quot;http://www.openrce.org/downloads/details/203/Determina_PDB_Plugin_for_IDA_Pro&quot;/&gt;&lt;br /&gt;http://www.openrce.org/downloads/details/203/Determina_PDB_Plugin_for_IDA_Pro&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;파일을 다운로드 받으신 후 압축을 풀게 되면 폴더안에 Plugin 폴더안에 두 개의 폴더가 있고 각각의 폴더안에 pdb.plw, pdb.p64 라는 파일을 IDA가 설치 된 경로에서 Plugins 폴더로 복사합니다.&lt;br /&gt;&lt;br /&gt;그 후 다시 압축을 풀었던 경로로 가시면 detpdb.cfg라는 파일이 있는데 IDA가 설치 된 경로에 Cfg폴더로 복사합니다.&lt;br /&gt;&lt;br /&gt;그 후 detpdb.cfg라는 파일을 연 후 안에 내용을 다음과 같이 바꾸시게 되면 설치작업은 끝난 것입니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;//&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// Determina PDB plugin&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;//&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// Symbol search path in the format used by WinDbg debugger. If the option is&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// not set, DbgHelp will search the local directory and the paths in the&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// _NT_SYMBOL_PATH and _NT_ALTERNATE_SYMBOL_PATH environment variables.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// Download public symbols from the Microsoft symbol server and store them in&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// the C:\Symbols directory.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;DETPDB_SYMBOL_PATH = &quot;SRV*C:\\Symbols*http://msdl.microsoft.com/download/symbols&quot;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// Enable DbgHelp debugging output. Use Sysinternals DebugView to see it.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;/&gt;// DETPDB_DEBUG = YES&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그 후 간단하게 IDA에서 Win32k.sys 파일을 열어보시면 다음과 같이 디버그 심볼을 찾았고 해당 심볼들을 로드할 것인지 물어보는 창이 뜹니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/823/019/b0072382_4971b1f3078e5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;685&quot; height=&quot;556&quot; style=&quot;&quot; /&gt;
&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>IDA에 HexRay를 사용할 때의 주의점</title>
      <id>http://simples.kr/19821</id>
      <published>2010-09-03T17:03:47+09:00</published>
      <updated>2010-09-05T21:17:54+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19821"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19821#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;HexRay는 IDA플러그인으로써 지금까지 디스어셈블리 된 코드로만 리버싱을 했어야 했는데 HexRay에 의해서 C언어로 코드를 볼 수 있게 되었습니다.&lt;br /&gt;&lt;br /&gt;거
기다가 디컴파일 된 코드를 그대로 옮긴 후 컴파일을 하면 실제로 돌아가는 경우도 많이 있어서 상당히 대단하긴 한데 만약 특정 타켓
 프로그램을 완전히 리버싱해야 할 경우 ( 어떠한 프로그램에 기능을 내 프로그램에서 쓰고 싶을 경우 ) 디컴파일에 많은 부분에 
의존하여 해당 코드를 자신의 프로그램으로 옮기게 되는데 이 때 다음과 같은 부분에 주의해야 합니다.&lt;br /&gt;&lt;br /&gt;다음은 SCSI Miniport 드라이버 코드를 디컴파일 한 것입니다.&lt;br /&gt;&lt;br /&gt;void __stdcall sub_10546(PVOID HwDeviceExtension, int a2)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; int v2; // ebx@1&lt;br /&gt;&amp;nbsp; unsigned __int8 v3; // al@7&lt;br /&gt;&amp;nbsp; PVOID v4; // edi@7&lt;br /&gt;&amp;nbsp; char v5; // zf@13&lt;br /&gt;&amp;nbsp; signed int v6; // ST04_4@15&lt;br /&gt;&amp;nbsp; void *v7; // ST08_4@15&lt;br /&gt;&amp;nbsp; char v8; // ST0C_1@15&lt;br /&gt;&amp;nbsp; ULONG v9; // ecx@16&lt;br /&gt;&amp;nbsp; char v10; // al@25&lt;br /&gt;&amp;nbsp; int v11; // edx@26&lt;br /&gt;&amp;nbsp; int v12; // ecx@26&lt;br /&gt;&amp;nbsp; int v13; // ecx@11&lt;br /&gt;&amp;nbsp; int v14; // ecx@12&lt;br /&gt;&amp;nbsp; int v15; // ecx@21&lt;br /&gt;&amp;nbsp; int v16; // ecx@22&lt;br /&gt;&amp;nbsp; int v17; // edx@26&lt;br /&gt;&amp;nbsp; unsigned __int8 v18; // [sp+5h] [bp-67h]@17&lt;br /&gt;&amp;nbsp; int v19; // [sp+Ch] [bp-60h]@17&lt;br /&gt;&amp;nbsp; char v20; // [sp+4h] [bp-68h]@17&lt;br /&gt;&amp;nbsp; int v21; // [sp+10h] [bp-5Ch]@17&lt;br /&gt;&amp;nbsp; int v22; // [sp+14h] [bp-58h]@17&lt;br /&gt;&amp;nbsp; int v23; // [sp+18h] [bp-54h]@17&lt;br /&gt;&amp;nbsp; int v24; // [sp+1Ch] [bp-50h]@17&lt;br /&gt;&amp;nbsp; int v25; // [sp+20h] [bp-4Ch]@17&lt;br /&gt;&amp;nbsp; signed int v26; // [sp+24h] [bp-48h]@17&lt;br /&gt;&amp;nbsp; signed int v27; // [sp+64h] [bp-8h]@18&lt;br /&gt;&amp;nbsp; signed int v28; // [sp+68h] [bp-4h]@18&lt;br /&gt;&lt;br /&gt;&amp;nbsp; v2 = a2;&lt;br /&gt;&amp;nbsp; if ( !*(_BYTE *)(a2 + 5) )&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( *(_BYTE *)(a2 + 6) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(a2) = 33;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_32;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( *(_BYTE *)(a2 + 7) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(a2) = 32;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_32;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v4 = ScsiPortGetLogicalUnit(HwDeviceExtension, 0, 0, 0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v3 = *(_BYTE *)(v2 + 48);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (signed int)v3 &amp;gt; 37 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v3 != 40 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v3 != 42 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v15 = v3 - 47;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v15 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v16 = v3 - 53;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !v16 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_28;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v5 = v3 == 59;&lt;br /&gt;LABEL_24:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !v5 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_25;&lt;br /&gt;LABEL_28:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(a2) = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_32;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE3(v17) = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_WORD *)((char *)&amp;amp;v17 + 1) = *(_BYTE *)(v2 + 50);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(v17) = *(_BYTE *)(v2 + 51);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v11 = *(_BYTE *)(v2 + 53) | ((*(_BYTE *)(v2 + 52) | (v17 &amp;lt;&amp;lt; 8)) &amp;lt;&amp;lt; 8);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE3(v12) = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_WORD *)((char *)&amp;amp;v12 + 1) = *(_BYTE *)(v2 + 55);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(v12) = *(_BYTE *)(v2 + 56);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (unsigned int)(v12 + v11) &amp;gt; 0x4000 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_25;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v3 == 47 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_28;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v9 = v12 &amp;lt;&amp;lt; 9;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v8 = v3 == 40;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v7 = (char *)v4 + 512 * v11;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v3 == 37 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v8 = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v7 = &amp;amp;v27;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v27 = -12648448;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v28 = 131072;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v6 = 8;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( !v3 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto LABEL_28;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( v3 == 18 )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;v18, 0, 0x5Fu);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;첫 번째로 바로 위에 부분 memset이 있는데 v18이라는 변수는 &lt;br /&gt;unsigned __int8 v18; // [sp+5h] [bp-67h]@17&lt;br /&gt;이와 같이 선언되어 있습니다.&lt;br /&gt;&lt;br /&gt;당연히 memset을 할 경우 1바이트 짜리 변수이므로 에러가 발생하게 됩니다.&lt;br /&gt;사
실 보시다시피 [sp+5h]로 되어 있는데 v18은 1byte 짜리 변수가 아니라 스택의 0x5F 크기의 배열로 선언되어 있는 
변수일 가능성이 높습니다. 또한 v18밑에 선언 된 변수들은 각각의 변수들이 아니라 v18에 포함되는 변수입니다.&lt;br /&gt;&lt;br /&gt;다시 한 번 본다면..&lt;br /&gt;&lt;br /&gt;&amp;nbsp; unsigned __int8 v18; // [sp+5h] [bp-67h]@17&lt;br /&gt;&amp;nbsp; int v19; // [sp+Ch] [bp-60h]@17&lt;br /&gt;&amp;nbsp; char v20; // [sp+4h] [bp-68h]@17&lt;br /&gt;&amp;nbsp; int v21; // [sp+10h] [bp-5Ch]@17&lt;br /&gt;&amp;nbsp; int v22; // [sp+14h] [bp-58h]@17&lt;br /&gt;&amp;nbsp; int v23; // [sp+18h] [bp-54h]@17&lt;br /&gt;&amp;nbsp; int v24; // [sp+1Ch] [bp-50h]@17&lt;br /&gt;&amp;nbsp; int v25; // [sp+20h] [bp-4Ch]@17&lt;br /&gt;&amp;nbsp; signed int v26; // [sp+24h] [bp-48h]@17&lt;br /&gt;&amp;nbsp; signed int v27; // [sp+64h] [bp-8h]@18&lt;br /&gt;&amp;nbsp; signed int v28; // [sp+68h] [bp-4h]@18&lt;br /&gt;&lt;br /&gt;변수의 선언은 틀리지만 뒤에 주석이 처리 된 [sp+5h], [sp+Ch].......는 맞을 가능성이 높습니다.&lt;br /&gt;하지만 실제로 저렇게 변수를 선언한다고 해서 WDK 컴파일러에서 저런 스택을 만들지도 확실하지 않으므로 만약 v18에 경우에는&lt;br /&gt;배열로 선언되어야 할 것입니다.&lt;br /&gt;위에 상황과 프로그래머들이 작성하는 코드 스타일을 본다면&lt;br /&gt;&lt;br /&gt;BYTE pBuffer[0x5F];&lt;br /&gt;......&lt;br /&gt;memset(pBuffer, 0, sizeof(pBuffer)); 가 원본 코드일 가능성이 높습니다. ( 물론 배열이 아니라 구조체일가능성도 있겠죠.. 그러한 부분은 버퍼를 어떻게 사용하느냐에 따라 다른것이고.. )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;두 번째로... Signed와 Unsigned 와 관련해서 문제가 있을 수 있습니다.&lt;br /&gt;&lt;br /&gt;위에 코드에서..&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE3(v17) = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_WORD *)((char *)&amp;amp;v17 + 1) = *(_BYTE *)(v2 + 50);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(v17) = *(_BYTE *)(v2 + 51);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; v11 = *(_BYTE *)(v2 + 53) | ((*(_BYTE *)(v2 + 52) | (v17 &amp;lt;&amp;lt; 8)) &amp;lt;&amp;lt; 8);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE3(v12) = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *(_WORD *)((char *)&amp;amp;v12 + 1) = *(_BYTE *)(v2 + 55);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LOBYTE(v12) = *(_BYTE *)(v2 + 56);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( (unsigned int)(v12 + v11) &amp;gt; 0x4000 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이 부분은 밑에 디스어셈블리 코드와 같습니다.&lt;br /&gt;&lt;br /&gt;.text:00010678&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, edx&lt;br /&gt;.text:0001067A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dh, [ebx+32h]&lt;br /&gt;.text:0001067D&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dl, [ebx+33h]&lt;br /&gt;.text:00010680&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; shl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, 8&lt;br /&gt;.text:00010683&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, ecx&lt;br /&gt;.text:00010685&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; movzx&amp;nbsp;&amp;nbsp; ecx, byte ptr [ebx+35h]&lt;br /&gt;.text:00010689&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; shl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, 8&lt;br /&gt;.text:0001068C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, ecx&lt;br /&gt;.text:0001068E&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, ecx&lt;br /&gt;.text:00010690&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ch, [ebx+37h]&lt;br /&gt;.text:00010693&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl, [ebx+38h]&lt;br /&gt;.text:00010696&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esi, ecx&lt;br /&gt;.text:00010698&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lea&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, [esi+edx]&lt;br /&gt;.text:0001069B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, 4000h&lt;br /&gt;&lt;br /&gt;그리고 디컴파일 된 코드에서는 형변환을 다음과 같이 하고 있습니다.&lt;br /&gt;*(_BYTE *)&lt;br /&gt;&lt;br /&gt;_BYTE는 IDA에 HexRay에서 정의한 것인데 plugins\defs.h 파일에 정의되어 있으며 &lt;br /&gt;&lt;br /&gt;#define _BYTE&amp;nbsp; char&lt;br /&gt;&lt;br /&gt;위와 같이 선언되어 있습니다.&lt;br /&gt;&lt;br /&gt;즉, *(_BYTE *) = *(char *) 입니다.&lt;br /&gt;이것은 Sigined입니다.&lt;br /&gt;그러나 디스어셈블리 된 코드에서는 일부 데이터를 이동 시 movzx 명령어를 사용하고 있습니다.&lt;br /&gt;movzx명령어는 부호가 없는 Unsigined를 처리하므로 이러한 경우 문제가 발생합니다.&lt;br /&gt;&lt;br /&gt;실제로 저 코드를 WDK로 컴파일 후 WinDbg로 디스어셈블링 해보면&lt;br /&gt;movsx로 변환됩니다. 따라서 잘 못 된 결과를 초래할 수 있습니다.&lt;br /&gt;&lt;br /&gt;따라서 저런 경우에는 강제적으로 *(unsigned char *)로 바꿔서 컴파일해야 합니다.&lt;br /&gt;&lt;br /&gt;세번째로 간혹 디컴파일을 하게 되면 콜링 컨벤션이 제대로 안 나오는 경우가 있는데 다음과 같은 경우입니다.&lt;br /&gt;&lt;br /&gt;char __userpurge sub_10486&amp;lt;al&amp;gt;(int a1&amp;lt;esi&amp;gt;, char a2)&lt;br /&gt;&lt;br /&gt;이
러한 경우에는 stdcall 도 아니고 fastcall도 아니고 사용자 지정 콜링 컨벤션이므로 레지스터를 이용해 넘기는건지 어떻게
 파라메터를 전달해야 하는지 봐야합니다. 일단 대충 봐서는 esi레지스터를 사용해서 넘긴다는 것인데 웃긴건 함수호출하는 부분에서도
 esi레지스터에 어떤값이 들어갈지도 신경써야 한다는 겁니다. 즉, 디컴파일을 하면서 디스어셈블리 된 코드도 자세하게 봐야 
된다는거죠....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;하여튼 저같은 경우에 다른 드라이버를 리버싱할 경우 이런적이 있었습니다.&lt;br /&gt;적어도 두번째에 경우인 movsx, movzx에 따라서 형변환 관련 디컴파일 부분은 버그로 간주해야 될꺼 같습니다.&lt;br /&gt;&lt;br /&gt;HexRay 플러그인에 너무 기대는 부분도 있지만 그만큼 가치가 있는 플러그인입니다.&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>유저 레벨에서 API Hook 2부</title>
      <id>http://simples.kr/19814</id>
      <published>2010-09-03T17:01:25+09:00</published>
      <updated>2010-09-06T09:21:16+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19814"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19814#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;b/&gt;2부에서는 API Hooking을 하는 실무 기술을 다루지 않고 리버싱을 통한 Windows 내부적인 코드 설계 및 API Hooking에 문제점에 대해서 다루겠습니다.&lt;br /&gt;( API Hooking을 하려는 접근방법으로 API내부에 구조를 알기 위한것이 목적이라고 볼 수 있습니다. )&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;이전 1부에서 보왔던 소스코드를 보면 다음과 같이 일부분에 코드가 주석처리되어 있는 것을 볼 수 있습니다.&lt;br /&gt;&lt;/p&gt;&lt;pre/&gt;BOOL WINAPI MyExtTextOutW( __in HDC hdc, __in int x, __in int y, __in UINT options, &lt;br /&gt;__in_opt CONST RECT * lprect, __in_ecount(c) LPCWSTR lpString, &lt;br /&gt;__in UINT cbCount, __in_ecount_opt(c) CONST INT * lpDx)&lt;br /&gt;{&lt;br /&gt;	//if (cbCount == 0)&lt;br /&gt;	//{&lt;br /&gt;	//	return FALSE;&lt;br /&gt;	//}&lt;br /&gt;	/*HDC hDC;&lt;br /&gt;&lt;br /&gt;	hDC = ::GetDC(0);&lt;br /&gt;&lt;br /&gt;	::TextOutA(hDC, 0, 0, &quot;A&quot;, 1);&lt;br /&gt;	//::TextOutW(hDC, 0, 0, _T(&quot;A&quot;), 1);&lt;br /&gt;&lt;br /&gt;	::ReleaseDC(0, hDC);*/&lt;br /&gt;&lt;br /&gt;	return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;코드 강조가 제대로 되어 있지 않기 때문에 잘 보이지 않을 수도 있지만 return TRUE;를 제외한 모든 코드를 주석처리하였습니다.&lt;br /&gt;이것은 일부로 무언가를 보여주기 위해 주석처리를 한 것이며 다음과 같이 코드를 변경합니다.&lt;br /&gt;&lt;pre/&gt;BOOL WINAPI MyExtTextOutW( __in HDC hdc, __in int x, __in int y, __in UINT options, &lt;br /&gt;__in_opt CONST RECT * lprect, __in_ecount(c) LPCWSTR lpString, &lt;br /&gt;__in UINT cbCount, __in_ecount_opt(c) CONST INT * lpDx)&lt;br /&gt;{&lt;br /&gt;	HDC hDC;&lt;br /&gt;&lt;br /&gt;	hDC = ::GetDC(0);&lt;br /&gt;&lt;br /&gt;	::TextOutA(hDC, 0, 0, &quot;A&quot;, 1);&lt;br /&gt;	&lt;br /&gt;	::ReleaseDC(0, hDC);&lt;br /&gt;&lt;br /&gt;	return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p/&gt;그리고 이 상태에서 실행을 해봅니다. ( &lt;b/&gt;주의 : 작업중인 모든 내용이 다 날아갈 수 있습니다. DLL Injection이 되었고 ExtTextOutW를 호출하는 모든 프로그램이 강제종료 및 오류를 보여줄 것입니다. )&lt;/b&gt;&lt;br /&gt;실행을 해보시면 거의 화면상에 보이는 모든 프로그램에 오류가 발생하여 에러를 보여주는 것을 볼 수 있습니다.&lt;br /&gt;그렇다면 저 위에 함수들 중에 호출한 API중 어떠한 API를 호출하지 말아야 한다는 말인데 ::TextOutA(hDC, 0, 0, &quot;A&quot;, 1);를 주석처리하게 되면 정상적으로 실행됨을 볼 수 있습니다.&lt;br /&gt;&lt;br /&gt;TextOutA라는 함수와 ExtTextOutW라는 함수와 도대체 무슨 연관이 있길래 오류가 발생하는지 의문이 생길 것입니다.&lt;br /&gt;그렇다면 TextOutA라는 함수에 내부를 디버거로 따라가보면 왜 그러한 오류가 발생하는지 알 수 있습니다.&lt;br /&gt;&lt;br /&gt;TextOutA에 브레이크 포인트를 걸은 후 그 부분에서 멈추게 한 다음 ExtTextOutW에 브레이크를 걸게 되면&lt;br /&gt;TextOutA에 함수가 리턴하기전에 ExtTextOutW에 브레이크 포인트를 걸은 부분이 실행됨을 알 수 있습니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/814/019/b0072382_4971b1f3078e5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;684&quot; height=&quot;567&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;위에 그림에서는 Vista SP1에서의 TextOutA API 함수내부에 디스어셈블링 된 코드를 보여주며 그림에서 
보다시피call 0x768efc9b함수를 호출함으로 내부적으로 ExtTextOutW를 호출하는 것을 알 수 있습니다.&lt;br /&gt;&lt;b/&gt;즉, Microsoft에서 API를 설계할 때 유저레벨에서 동일한 성격의 API가 두개이상일 경우 이러한 API들중 확장되지 않은 API인 TextOutA는 확장된 API인 ExtTextOutW를 호출하게 됩니다.&lt;br /&gt;이것은 TextOutA에만 해당되는 사항이 아니며 DrawTextA에 경우도 마찬가지로 내부적으로 ExtTextOutW를 호출하게 됩니다.&lt;br /&gt;또한, 더 나아가서 xxxxx 라는 API가 있다면 xxxxxEx라는 API라는 함수가 있을 수 있는데 이름에도 보다시피 xxxxxEx API는 xxxxx API에 확장된 API이며&lt;br /&gt;이러한 API일 경우 xxxxx라는 API는 내부적으로 xxxxxEx라는 API를 호출할 가능성이 높습니다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;따라서 위에서 오류가 발생한 이유는 재귀호출에 의한 오류라는 것을 알 수 있습니다. 만약 API에 리버싱을 시도하지 않는다면 왜 그러한 오류가 발생했는지조차도 갈피를 못 잡게 되는 상황입니다.&lt;br /&gt;우리는 API Hooking을 한 후 가로챈 API가 호출된 시점에서 새로운 API호출을 필요로 할 때 이러한 구조를 잘 알고 ( 재귀호출에 가능성 및 기타 가능성 ) 호출을 해야만 합니다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;다음으로 넘어가서 현재의 API Hooking모듈을 보면 기능상으로 한가지 문제점이 있습니다.&lt;br /&gt;바로 API 는 가로챘지만 원본의 API를 호출하지 못하며 화면상에 모든 텍스트들이 출력이 되지 않는 문제점입니다.&lt;br /&gt;데이터를 가로챈 후 정상적으로 API를 호출하여 훅킹을 하지 않은 것과 같은 효과를 발생시켜야 하는데 이러한 코드가 들어가 있지 않은 것 입니다.&lt;br /&gt;( 사실 문제점은 이것말고도 한 두가지가 아니지만 밑에서 설명하겠습니다. )&lt;br /&gt;&lt;br /&gt;현재로써는 원본 소스코드에 일부 변형이 일어났기 때문에 ( 함수에 앞부분에 기계어 코드가 점프 코드로 변경 되어 있음 )그냥 함수를 호출했다가는 재귀호출을 하게 됩니다.&lt;br /&gt;&lt;br /&gt;따라서 이러한 경우 여러가지 방법이 있는데 첫 번째로 가장 쉬운 방법인 훅킹 된 함수가 호출되었을 때 원래의 원본 소스코드를 저장하여놓았다가 다시 원래대로 되돌린 후 원본을 호출하고&lt;br /&gt;호출이 되었다면 훅킹을 계속 하기 위해서 다시 Jmp코드를 심는 방법입니다.&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/814/019/b0072382_4971b1f3078e5_1.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;841&quot; height=&quot;576&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;b/&gt;그러나 위에서 제시한 방법은 다음과 같은 치명적인 문제점이 있습니다.&lt;br /&gt;&lt;br /&gt;첫 번째로 API Hooking을 하려는 대상 프로세스에 두 개의 스레드가 있고 이 스레드가 TextOutA를 같이 호출한다면&lt;br /&gt;원본 API 를 원래대로 되돌리고 난 후 다시 패칭을 하는 그 중간 시점에 운영체제에 멀티 태스킹이 발생하여 다른 스레드에서 TextOutA를 호출할 경우&lt;br /&gt;그 스레드에서 호출하는 API를 가로챌 수 없는 문제점이 있습니다.&lt;br /&gt;&lt;br /&gt;두 번째로 프로세스가 실행중에 코드를 변경시킬 경우 동기화이슈가 발생하게 되는데 이러한 패칭 스타일은 동기화 문제를 유발하여 CPU가 잘 못 된 기계어 코드를 실행시킬 수 있습니다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b/&gt;예를 들어, MyTextOutA에서 원본 소스코드로 되돌리는 코드가 실행 된 후 2번 스레드에서 TextOutA가 호출되었고 첫 번째 어셈블리 코드인 mov edi, edi가 호출되었으며 이 상태에서 멀티 태스킹이 발생하였고,&lt;br /&gt;이에 따라 다시 1번스레드인 Injection DLL 함수가 계속 실행됨으로 인해서 API 패칭을 다시 한 상태에서 또 다시 멀티 태스킹이 발생되어 2번 스레드가 실행되면 mov edi, edi 다음 코드가&lt;br /&gt;Jmp 를 하려는 대상 주소코드에 값을 가지고 있으므로 잘 못 된 기계어를 CPU에서 해석할 가능성이 있습니다.&lt;/b&gt;&lt;br /&gt;( 말이 상당히 복잡한데 동기화 문제는 테스트가 거의 불가능하므로 항상 이러한 방식으로 추측을 하여야 합니다. &lt;br /&gt;참고로 동기화 문제는 운영체제에서 멀티 태스킹을 지원하거나 CPU가 두개이상일 경우에만 발생하며 이러한 경우가 아니라면 동기화문제가 발생하지 않습니다.&lt;br /&gt;또
한 mov edi, edi라는 코드는 CPU에서 실행되는 하나의 기계어 코드 단위 ( atomic 기계어 )이므로 movedi, 
edi라는 코드가 실행이 끝나기 전까지는 해당 코드를 해석하는 CPU에서 다른 작업을 할 수 없습니다.&lt;br /&gt;설령 인터럽트가 발생하여도 mov edi, edi가 끝난후에 CPU에서 인터럽트 서비스 루틴을 호출한다는 의미입니다. )&lt;br /&gt;&lt;br /&gt;우리는 위에서 원본 소스코드로 되돌려서 API를 호출하는 패칭방식은 사용 할 수 없다는 것을 알았으며 ( 간혹 중국넘들이 만든 바이러스에서는 쓰이기도 합니다. )&lt;br /&gt;동기화 이슈를 피하기 위해 원본 소스코드를 되돌리는 것이 아닌 원본 소스코드를 다른 곳에 저장하는 방법이 있는데 이에 대해서 설명할려고 합니다.&lt;br /&gt;그림에서 보시다시피 플로우 차트는 다음과 같이 진행됩니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/814/019/b0072382_4971b1f3078e5_2.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;829&quot; height=&quot;628&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;b/&gt;그러나 위에서 제시한 방법은 다음과 같은 일부 문제점이 있습니다.&lt;br /&gt;( 자꾸 문제점에 대해서 말하게 되는데 사실 유저모드에서 API Hooking을 완벽하게 하는 것은 불가능합니다. 이것은 밑에서 설명하겠습니다. ) &lt;br /&gt;&lt;br /&gt;현재 API의 기계어 코드는 Windows XP SP2 이상을 대상으로 하여 위에서 보았듯이 Jmp 기계어 코드인 5Byte에 맞게&lt;br /&gt;API 코드가 패칭이 되고 5Byte만큼만 트램폴라인 함수에 복사하면 되지만 Windows XP SP2 미만에 버전에 운영체제에 경우에 패칭을 할 경우 정확히 5Byte만큼&lt;br /&gt;기계어 코드가 맞아 떨어지는 것이 아니라 mov edi, edi 코드가 제외됨으로 인해서 디스어셈블러가 중간에 반드시 개입되어야 하는 현상이 발생합니다. ( 기계어 코드에 길이를 계산해야 하므로.. )&lt;br /&gt;즉, 트램폴라인 스타일에 API 패칭은 반드시 디스어셈블러가 동원되어야 합니다.&lt;br /&gt;&lt;br /&gt;실제로 위에 방식은 Microsft사에서 진행되는 Detour 라는 API Hooking 프로젝트가 있는데 위와 같은 방식을 하고 있으며 디스어셈블러를 사용합니다.&lt;/b&gt;&lt;br /&gt;( 3부에서는 Detour를 이용하는 방법에 대해서 다루려고 하고 있습니다. 이미 만들어진 프로젝트가 있고 디스어셈블러를 만드는 방법에 대해서는 추가적인 문서를 더 작성해야 하기 때문입니다. )&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;다음으로 또 넘어가서 API Hooking시 발생하는 DLL Attach및 DLL Detach와 관련 된 문제점에 대해서 설명하려고 합니다.&lt;br /&gt;API Hooking은 특정한 API를 훅킹을 하려는 시점 또한 중요한데 만약 프로세스가 이미 떠있는 상태에서 API에 변경을 가하게 되면&lt;br /&gt;프로세스가 잘 못 된 기계어 코드를 극악의 확률로 실행될 가능성이 발생됩니다.&lt;br /&gt;( 사실 이러한 부분은 확률자체가 매우 낮으므로 이런 오류를 보기가 매우 힘듭니다. )&lt;br /&gt;&lt;br /&gt;예를 들어 프로세스가 TextOutA를 호출하였고 mov edi, edi가 호출되고 멀티 태스킹이 발생하여&lt;br /&gt;API Hooking을 시도하려는 코드가 실행된다면 당연히 이 부분의 코드는 Jmp코드로 변경될 것이며,&lt;br /&gt;다시 멀티 태스킹이 발생하여 mov edi, edi 다음에 기계어를 실행시킬려고 하다보니 잘 못 된 코드를 CPU에서 해석하게 되는것 입니다.&lt;br /&gt;CPU 자체에서 메모리에 값을 한 번에 변경시키는 atomic 기계어 코드를 제공하긴 하지만 mov edi, edi가 실행되고 멀티 태스킹이 발생하게 되면&lt;br /&gt;버스 잠금에 효과가 사라지므로 이 또한 효력을 발휘하지 못 하게 됩니다.&lt;br /&gt;이러한 부분은 Detach도 마찬가지로 겪게 되는 문제점입니다.&lt;br /&gt;따라서 API Hooking을 시도시에는 Attach를 할 경우 문제가 생기며 프로세스가 어떠한 API를 호출하기전.. 즉, 프로세스가 처음 실행되는 시점에&lt;br /&gt;API 패칭이 완료되어야 하며 프로세스가 끝나서 더 이상 API 를 호출하지 않는 시점에 API를 원래대로 복구시켜야 합니다.&lt;br /&gt;&lt;br /&gt;지금까지 API Hooking을 하면서 한가지 의문이 들 수 있을 것 입니다. ( 의문이 들지 않는다면 ................. 낭패.. )&lt;br /&gt;계속해서 mov edi, edi라는 코드가 언급되었는데 사실 edi 레지스터에 edi를 넣어도 전혀 의미가 없습니다.&lt;br /&gt;즉, 이 기계어 코드는 없어도 전혀 의미가 없습니다.&lt;br /&gt;( mov edi, edi 는 XP SP2이상에서 추가되었습니다. )&lt;br /&gt;&lt;br /&gt;또한 다른 API들을 보아도 모두다 똑같이 mov edi, edi가 앞에 들어가 있습니다.&lt;br /&gt;또한 더 조사해보면 mov edi, edi 바로 위에 nop가 깔려있는 것을 볼 수 있습니다.&lt;br /&gt;다음 그림에서 이에 대한 의문을 풀어줍니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/814/019/b0072382_4971b1f3078e5_3.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;704&quot; height=&quot;548&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;b/&gt;바로 Microsoft에서 런타임 핫패칭을 수행하기 위해서 이러한 코드들이 삽입되어 있는 것 입니다.&lt;/b&gt;&lt;br /&gt;런타임 핫패칭이라고 해도  API Hooking과는 크게 다른 부분이 없고 특정 함수에 문제가 발생하였을 때 특정 함수를 핫패칭하여 그 함수가 호출되면&lt;br /&gt;Jmp코드에 의해 원래의 함수가 호출되는것이 아닌 버그가 수정 된 함수가 호출되도록 하는 것 입니다.&lt;br /&gt;&lt;br /&gt;이것을 이용하게 되면 이전에 말하였던 프로세스가 실행중일 때 중간에 Attach를 시키는 문제점을 완벽한 동기화를 통해 해결 할 수 있습니다.&lt;br /&gt;이러한 Microsoft 핫패칭 스타일을 이용한 API Hooking은 다음과 같이 구현이 될 것 입니다.&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/814/019/b0072382_4971b1f3078e5_4.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;840&quot; height=&quot;696&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;&lt;p/&gt;위에서 설명하는 플로우 차트가 Microsoft에서 사용하는 핫패칭하는 방식이며 아무래도 리버서들을 통해서 알려지는 방식이기 때문에&lt;br /&gt;실제 Microsoft에서 하는 방식과 다를 수 있습니다. ( 위에서 설명하는 Microsoft핫패칭을 이용한 Hooking방식은 검증이 되지 않았으며 XP SP2 이상에서만 사용이 가능하다는 제약이 발생합니다. )&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>유저 레벨에서 API Hook 1부</title>
      <id>http://simples.kr/19798</id>
      <published>2010-09-03T16:50:13+09:00</published>
      <updated>2010-09-05T21:14:22+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19798"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19798#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;div/&gt;
&lt;p/&gt;이 문서에는 유저 레벨 즉, Ring 3권한에서 API Hook를 하는 방법에 대해서 설명합니다.&lt;br /&gt;( Ring 0권한에서 API Hook를 하는 방법에 대해서는 다음 문서에서 설명하겠습니다.&lt;br /&gt;혹시나 CPU에서 제공하는 Ring에 대해서 모르신다면 관련 문서를 먼저 읽어보기를 권합니다. )&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div/&gt;
&lt;p/&gt;API Hook과 관련하여 인터넷에서 자료들이 많이 있는 것이 사실이지만 설명이 너무 어렵거나&lt;br /&gt;관련 소스가 있어도 너무 불안정하게 돌아가는 경우가 많습니다. 따라서 간단한 API Hook를 구현해보고&lt;br /&gt;실제로 사용할 수 있는 Hook 코드에 대해서 설명하려고 합니다.&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;API Hook이란, Win32 애플리케이션에서 사용하는 API를 내가 만든 프로그램에서 가로챈 후&lt;br /&gt;가로챈 데이터의 내용을 보거나 또는 그 API를 호출하지 못 하도록 하는 것을 말합니다.&lt;br /&gt;API Hook을 하는 방법에는 다음과 크게 다음과 같이 두 가지 방법이 있습니다.&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;1. IAT( 임포트 어드레스 테이블 )&lt;br /&gt;애플리케이션에서 Win32 API를 호출하기 위해서는 API가 실제로 어느 위치에 해당하는지 알아야 합니다.&lt;br /&gt;이러한 API주소들은 IAT라는 곳에 저장되게 되고 이 테이블의 값을 통해서 애플리케이션에서는 API를 호출 할 수 있게 됩니다.&lt;br /&gt;이 때 이 테이블의 값을 수정해서 내가 원하는 주소로 점프하도록 하여 API함수를 가로챌 수 있습니다.&lt;br /&gt;이 방법은 API Hook중에서 가장 쉬운 방법이나 IAT를 참조하지 않고 API를 호출하는 애플리케이션이 있기 때문에&lt;br /&gt;실제로 사용하는건 불가능합니다. 대표적으로 델파이로 만들어진 프로그램은 IAT를 사용하지 않고 자체적으로&lt;br /&gt;테이블을 갖고 있고 그러한 테이블을 사용하기 때문에 델파이로 만들어진 애플리케이션은 훅이 불가능하게 됩니다. &lt;br /&gt;&lt;br /&gt;2. Trampoline Hook ( 트램폴라인 훅 )&lt;br /&gt;Trampoline Hook은 API 코드 자체를 변경하는 것을 의미합니다.&lt;br /&gt;코드 자체를 변경한다고 해서 많은 변경이 일어나는 것은 아니고 이전 문서에서 크랙미를 크랙했던 것과 비슷하게&lt;br /&gt;함수에 시작 코드앞에 5byte Jmp기계어 코드를 삽입하여 내가 만든 함수로 점프하도록 하는 것 입니다.&lt;br /&gt;이 방식은 매우 강력하며 하이퍼 스냅이나 스네그잇 같은 경우에는 TextOut계열의 API를 Hook하여 텍스트 캡쳐&lt;br /&gt;기능을 개발 할 수 있고, BitBlt를 Hook하여 화면 캡쳐 방지 모듈을 개발 할 수도 있습니다.&lt;br /&gt;즉, 상용 애플리케이션도 간혹 쓰이며 우리가 사용할 방법은 이 방식을 이용해 API Hook를 하게 될 것 입니다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p/&gt;본론으로 들어가기전에 Trampoline Hook이 어떠한 방식인지 이해하기 위해&lt;br /&gt;Trampoline Hook를 이용하는 애플리케이션이 어떠한 방식으로 API를 Hook는지 살펴보겠습니다.&lt;br /&gt;대상 애플리케이션은 하이퍼 스냅이며 우선 하이퍼 스냅을 띄웁니다.&lt;br /&gt;일단 이 상태에서 TextOutA에 API코드를 보면 다음과 같습니다.&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;668&quot; height=&quot;515&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;( 델파이 IDE에서 디버깅해보는 화면입니다. VC2005에서는 함수에 이름이 나오지 않기 때문에 사용하지 않았습니다. ) &lt;br /&gt;다음과 같은 코드로 이루어져 있다는 것을 보실 수 있으며 첫 부분은 mov edi, edi로 시작하게 됩니다. ( Windows xp sp2 기준. ) &lt;br /&gt;그렇다면 TextOutA가 하이퍼 스냅에 의해 훅이 되었을 경우 어떻게 바뀌는 보겠습니다. &lt;br /&gt;( 참고 : TextOutA가 훅이 되는 시점은 사용자가 하이퍼 스냅에게 텍스트 캡쳐 명령을 내린 후 훅이 되고 바로 훅이 해제 되게 됩니다.&lt;br /&gt;만약 테스트를 하려면 OnPaint 시점에 TextOutA를 호출하도록 하고 Text From an Object under Cursor메뉴를 이용해야 합니다. )&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5_1.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;668&quot; height=&quot;515&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;위와 같이 0xE9 xxxxx ( xx 는 내 함수가 있는 주소. 이 이미지에서 기계어 코드를 보시면 0xE9다음에 나오는 주소가 &lt;br /&gt;조금 이상하게 보일 수 있는데 0xE9에 경우는 상대주소를 사용하기 때문입니다. 이에 대해서는 다음에 설명하게 됩니다. )&lt;br /&gt;형태로 하이퍼 스냅이 만들어 놓은 코드로 점프시키도록 합니다.&lt;br /&gt;이 부분은 하이퍼 스냅에서 사용하는 Hook 함수 코드입니다.&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5_2.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;668&quot; height=&quot;515&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;또한 실제로, 이 주소에 모듈이 올라와 있는 것을 확인 할 수 있습니다. ( 주소는 시스템에 따라서 다를 수 있습니다. )&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5_3.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;668&quot; height=&quot;515&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;하이퍼스냅에서 사용하는 Trampoline Hook에 대해서 살펴보았는데 이 방식에 대해서 정리하자면 다음과 같습니다.&lt;br /&gt;&lt;b/&gt;&lt;br /&gt;1. Hooking하려는 대상에 API의 시작 코드가 jmp코드로 변경되었다. ( 0xE9, 0xXX, 0xXX, 0xXX, 0xXX ) &lt;br /&gt;2. 훅킹하려는 대상에 프로세스에 특정한 dll이 로드되었다. ( 이것을 Dll 인젝션이라고 부릅니다. ) &lt;br /&gt;3. 1번과 2번에 의해서 Hooking 된 API가 호출이 되면 jmp코드로 인해서 인젝션 된 dll에 코드가 실행된다. &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;API Hooking에 기본 흐름을 위에 3가지로 요약될 수 있습니다. ( 물론 원본 API호출까지 고려하자면 개수가 조금 늘어나게 됩니다. ) &lt;br /&gt;&lt;br /&gt;그렇다면 이제 본론으로 들어가서 API Hooking에 흐름을 파악하기 위해 코드를 작성해보겠습니다. &lt;br /&gt;여기서 하게 될 프로그램은 현재 실행중인 모든 윈도우에서 ExtTextOutW API를 Hooking하여 호출이 되지 않도록 하는 것 입니다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;display: inline !important; &quot;/&gt;위에 코드는 마이크로소프트 비주얼 스튜디오 2008로 컴파일 작성되었으며 메인 콘솔 프로그램과 인젝션용 Dll로 나누어집니다.&lt;/p&gt;&lt;p/&gt;&lt;/p&gt;&lt;p/&gt;따라서 그 이하 버전에서는 컴파일이 안될 수 있으니 폴더에 &quot;APIHookExample&quot;는 콘솔 프로그램으로 &lt;br /&gt;&quot;APIHookExampleDLL&quot;은 Dll 프로그램으로 하여 새 프로젝트를 생성해주시면 됩니다. &lt;br /&gt;&lt;br /&gt;( 여담이지만 저 같은 경우에는 메인UI는 델파이로, Dll에 경우에는 C++, C로 작성하는 스타일이라서 델파이 소스는 없습니다. &lt;br /&gt;물론 어려운 부분이 없기 때문에 델파이 사용자라도 충분히 컨버팅이 가능하다고 봅니다. &lt;br /&gt;루트킷 개발하시는 분들도 이런 스타일로 개발하시는 분들이 많습니다. 너무 하나에 언어를 중심으로 개발하는 것은 좋지 않으며 &lt;br /&gt;상황에 맞게 최적의 컴파일러를 사용하는 것이 좋습니다. 물론 우리나라에 실무 환경에서는 다 C++이기 때문에 힘들겠지만... ) &lt;br /&gt;&lt;br /&gt;우선 받은 소스에서 APIHookExample.cpp를 열어봅니다. &lt;br /&gt;&lt;/p&gt;&lt;pre/&gt;// APIHookExample.cpp : Defines the entry point for the console application.&lt;br /&gt;//&lt;br /&gt;&lt;br /&gt;#include &quot;stdafx.h&quot;&lt;br /&gt;#include &lt;windows/&gt;&lt;br /&gt;&lt;br /&gt;extern &quot;C&quot;&lt;br /&gt;{&lt;br /&gt;	__declspec(dllexport) void InstallHook();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;extern &quot;C&quot;&lt;br /&gt;{&lt;br /&gt;	__declspec(dllexport) void UninstallHook();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;	printf(&quot;API Hook 예제가 실행되었습니다.\n종료하려면 엔터를 입력하세요.&quot;);&lt;br /&gt;&lt;br /&gt;	InstallHook();&lt;br /&gt;	while (TRUE)&lt;br /&gt;	{&lt;br /&gt;		::Sleep(30);&lt;br /&gt;		if (GetKeyState(VK_RETURN) &amp;lt; 0)&lt;br /&gt;		{&lt;br /&gt;			break;&lt;br /&gt;		}&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	return 0;&lt;br /&gt;}	&lt;br /&gt;&lt;br /&gt;&lt;/windows&gt;&lt;/pre&gt;콘솔 애플리케이션으로써 InstallHook(), UninstallHook()함수를 임포트하고 있습니다. &lt;br /&gt;우선 InstallHook()함수만 호출하고 ::Sleep() 함수를 사용하여 기다리는 작업밖에 하지 않습니다. &lt;br /&gt;( 테스트 프로그램으로써 UninstallHook()를 호출해주지 않았습니다. ) &lt;br /&gt;코드가 너무 간단하므로 이제 Dll에 소스코드를 봅니다. &lt;br /&gt;APIHookExampleDLL.cpp파일을 엽니다. &lt;pre/&gt;&lt;stdio/&gt;&lt;tchar/&gt;&lt;br /&gt;// APIHookExampleDLL.cpp : Defines the entry point for the DLL application.&lt;br /&gt;//&lt;br /&gt;&lt;br /&gt;#include &quot;stdafx.h&quot;&lt;br /&gt;&lt;br /&gt;#include &lt;br /&gt;#include &lt;br /&gt;&lt;br /&gt;#ifdef _MANAGED&lt;br /&gt;#pragma managed(push, off)&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;// 모든 프로세스에서 공유 될 변수를 선언합니다.&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;#pragma data_seg(&quot;.APIHookSection&quot;)		&lt;br /&gt;HHOOK hHook = NULL;&lt;br /&gt;#pragma data_seg ()&lt;br /&gt;&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;// 전역으로 사용할 변수를 선언하였습니다.&lt;br /&gt;HINSTANCE g_hInst = 0;&lt;br /&gt;// API Hook을 한 후 훅을 해제시 원래의 코드로 되돌리기 위해&lt;br /&gt;// 선언하였습니다.&lt;br /&gt;BYTE cbOldCode[5] = { 0x00, };&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;// 기본적인 전역훅 루틴입니다.&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam) &lt;br /&gt;{&lt;br /&gt;	return CallNextHookEx( hHook, nCode, wParam, lParam); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;extern &quot;C&quot; __declspec(dllexport) void InstallHook()&lt;br /&gt;{&lt;br /&gt;	hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, g_hInst, 0); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;extern &quot;C&quot; __declspec(dllexport) void UninstallHook()&lt;br /&gt;{&lt;br /&gt;	UnhookWindowsHookEx(hHook);&lt;br /&gt;}&lt;br /&gt;/////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;BOOL WINAPI MyExtTextOutW( __in HDC hdc, __in int x, __in int y, __in UINT options, &lt;br /&gt;__in_opt CONST RECT * lprect, __in_ecount(c) LPCWSTR lpString, __in UINT cbCount, &lt;br /&gt;__in_ecount_opt(c) CONST INT * lpDx)&lt;br /&gt;{&lt;br /&gt;	//if (cbCount == 0)&lt;br /&gt;	//{&lt;br /&gt;	//	return FALSE;&lt;br /&gt;	//}&lt;br /&gt;	/*HDC hDC;&lt;br /&gt;&lt;br /&gt;	hDC = ::GetDC(0);&lt;br /&gt;&lt;br /&gt;	::TextOutA(hDC, 0, 0, &quot;A&quot;, 1);&lt;br /&gt;	//::TextOutW(hDC, 0, 0, _T(&quot;A&quot;), 1);&lt;br /&gt;&lt;br /&gt;	::ReleaseDC(0, hDC);*/&lt;br /&gt;&lt;br /&gt;	return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOL InstallAPIHook_ExtTextOutW()&lt;br /&gt;{&lt;br /&gt;	BYTE *pDrawTextWAddress;&lt;br /&gt;&lt;br /&gt;	DWORD dwOldProtect;&lt;br /&gt;	DWORD dw;&lt;br /&gt;&lt;br /&gt;	pDrawTextWAddress = (BYTE *)GetProcAddress(GetModuleHandle(_T(&quot;GDI32.Dll&quot;)), &quot;ExtTextOutW&quot;);&lt;br /&gt;	if (pDrawTextWAddress == NULL)&lt;br /&gt;	{&lt;br /&gt;		&lt;br /&gt;		::OutputDebugString(_T(&quot;ExtTextOutW API의 주소를 얻어오는데 실패하였습니다.&quot;));&lt;br /&gt;&lt;br /&gt;		return FALSE;&lt;br /&gt;	}&lt;br /&gt;	VirtualProtect(pDrawTextWAddress, 5, PAGE_WRITECOPY, &amp;amp;dwOldProtect);&lt;br /&gt;&lt;br /&gt;	memcpy(cbOldCode, pDrawTextWAddress, 5);&lt;br /&gt;&lt;br /&gt;	*pDrawTextWAddress = 0xE9;&lt;br /&gt;	pDrawTextWAddress++; &lt;br /&gt;	*((DWORD *)(pDrawTextWAddress)) = ((DWORD)MyExtTextOutW) - ((DWORD)pDrawTextWAddress +4);&lt;br /&gt;&lt;br /&gt;	VirtualProtect(pDrawTextWAddress, 5, dwOldProtect, &amp;amp;dw);&lt;br /&gt;&lt;br /&gt;	return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;BOOL UnInstallAPIHook_ExtTextOutW()&lt;br /&gt;{	&lt;br /&gt;	BYTE *pDrawTextWAddress;&lt;br /&gt;&lt;br /&gt;	DWORD dwOldProtect;&lt;br /&gt;	DWORD dw;&lt;br /&gt;&lt;br /&gt;	pDrawTextWAddress = (BYTE *)GetProcAddress(GetModuleHandle(_T(&quot;GDI32.Dll&quot;)), &quot;ExtTextOutW&quot;);&lt;br /&gt;	if (pDrawTextWAddress == NULL)&lt;br /&gt;	{&lt;br /&gt;		::OutputDebugString(_T(&quot;ExtTextOutW API의 주소를 얻어오는데 실패하였습니다.&quot;));&lt;br /&gt;&lt;br /&gt;		return FALSE;&lt;br /&gt;	}&lt;br /&gt;	VirtualProtect(pDrawTextWAddress, 5, PAGE_WRITECOPY, &amp;amp;dwOldProtect);&lt;br /&gt;&lt;br /&gt;	memcpy(pDrawTextWAddress, cbOldCode, 5);&lt;br /&gt;&lt;br /&gt;	VirtualProtect(pDrawTextWAddress, 5, dwOldProtect, &amp;amp;dw);&lt;br /&gt;&lt;br /&gt;	return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BOOL APIENTRY DllMain( HMODULE hModule,&lt;br /&gt;					  DWORD  ul_reason_for_call,&lt;br /&gt;					  LPVOID lpReserved&lt;br /&gt;					  )&lt;br /&gt;{&lt;br /&gt;	switch(ul_reason_for_call)&lt;br /&gt;	{&lt;br /&gt;	case DLL_PROCESS_ATTACH:&lt;br /&gt;		/////////////////////////////////////////////////////&lt;br /&gt;		// DLL이 해당 프로세스로 Attach되었습니다.&lt;br /&gt;		/////////////////////////////////////////////////////&lt;br /&gt;		g_hInst = hModule;&lt;br /&gt;&lt;br /&gt;		InstallAPIHook_ExtTextOutW();&lt;br /&gt;&lt;br /&gt;		break;&lt;br /&gt;&lt;br /&gt;	case DLL_PROCESS_DETACH:&lt;br /&gt;		/////////////////////////////////////////////////////&lt;br /&gt;		// DLL이 해당 프로세스로 Detach되었습니다.&lt;br /&gt;		/////////////////////////////////////////////////////&lt;br /&gt;		UnInstallAPIHook_ExtTextOutW();&lt;br /&gt;&lt;br /&gt;		break;&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#ifdef _MANAGED&lt;br /&gt;#pragma managed(pop)&lt;br /&gt;#endif	&lt;/tchar&gt;&lt;/stdio&gt;&lt;/pre&gt;
&lt;p/&gt;&lt;br /&gt;&lt;br /&gt;( 이 예제코드에서는 콘솔 프로그램에서 이 Dll파일을 임포트 함으로 DllMain함수가 실행되어 DLL_PROCESS_ATTACH인해 InstallAPIHook_ExtTextOutW()함수를 호출함으로써 &lt;br /&gt;자기자신까지도 API Hooking를 해버리는데 이 부분은 무시하도록 하겠습니다. ) &lt;br /&gt;&lt;br /&gt;소스코드를 보시면 생각했던것보다 너무나도 API Hooking 예제코드가 간단하다는 것을 볼 수 있습니다. &lt;br /&gt;한 페이지반밖에 되지 않는 예제 소스 코드입니다. &lt;br /&gt;&lt;br /&gt;그렇다면 하나하나씩 분석해보도록 하겠습니다. &lt;br /&gt;우선 메인 콘솔 애플리케이션에서 InstallHook함수를 호출하게 됩니다. &lt;br /&gt;이 함수는 SetWindowsHookEx를 호출하는데 WH_GETMESSAGE훅킹을 하게 됩니다. &lt;br /&gt;&lt;b/&gt;여기서 말씀드리고 싶은 것은 SetWindowsHookEx함수를 호출하게 되면 &lt;br /&gt;훅킹하려는 대상 프로세스에 SetWindowsHookEx를 호출한 Dll를 시스템에서 자동으로 Dll 인젝션시킨다는 것 입니다.&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;이렇게 함으로써 Dll 인젝션을 쉽게 구현 하였는데 사실 이 방법말고도 CreateRemoteThread API를 이용하여 특정 프로세스에 &lt;br /&gt;깔끔하게 Dll 인젝션을 할 수도 있습니다. &lt;br /&gt;&lt;br /&gt;Dll 인젝션이 되면 바로 DllMain에서 DLL_PROCESS_ATTACH 루틴을 타게 됩니다. &lt;br /&gt;그리고 이 루틴은 다시 InstallAPIHook_ExtTextOutW()함수를 호출하게 됩니다. 이 부분이 가장 중요한 부분이 되겠습니다. &lt;br /&gt;&lt;br /&gt;GetProcAddress()함수를 사용하여 GDI32.Dll에 있는 ExtTextOutW함수에 주소를 얻어옵니다. &lt;br /&gt;VirtualProtect(pDrawTextWAddress, 5, PAGE_WRITECOPY, &amp;amp;dwOldProtect); 를 통해 &lt;b/&gt;Copy-On-Write&lt;/b&gt;를 구현합니다. &lt;br /&gt;&lt;b/&gt;Copy-On-Write&lt;/b&gt;는 ExtTextOut()함수의 시작부분에서 5Byte만큼 구현하도록 하였습니다. &lt;br /&gt;즉, 이 5Byte부분은 우리가 바꿔야할 기계어 코드 메모리 영역인 것 입니다. &lt;br /&gt;&lt;br /&gt;&lt;b/&gt;Copy-On-Write는 매우 중요한 부분으로 Dll에 경우에는 모든 프로세스가 코드를 공유하게 되므로 메모리상에 &lt;br /&gt;Dll은 오직 하나만 올라오게 됩니다. &lt;br /&gt;그러나 부득이하게 Dll에 코드를 런타임시에 변경해야 하는 경우가 생기게 되는데 &lt;br /&gt;하나의 Dll에서 이 코드를 변경하게 되면 Dll이 메모리상에 하나만 올라가있으므로 ( 모든 프로세스가 공유하므로 ) &lt;br /&gt;모든 프로세스가 변경 된 코드에 영향을 받게 됩니다. &lt;br /&gt;이러한 경우 특정한 프로세스에 한해서 변경 된 코드 영역이 다른 물리 메모리를 가르키게 함으로써 &lt;br /&gt;다른 프로세스에서는 영향을 받지 않고 변경한 프로세스 자신만 영향을 받도록 합니다. &lt;br /&gt;이러한 방법은 운영체제에서 페이징 기능을 이용하여 제공하는 매커니즘이며 이와 관련 된 부분은 &lt;br /&gt;다른 추가적인 서적이나 문서를 참고할 것을 권장합니다. &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;( 여담이지만 이러한 운영체제 매커니즘을 가장 잘 이해하는 방법은 운영체제 서적을 보거나 &lt;br /&gt;운영체제 소스를 보는 것보다 직접 간단한 커널을 구현하여 멀티 태스킹 및 페이징 기능을 만들어보는게 가장 확실하게 이해 할 수 있습니다. ) &lt;br /&gt;&lt;br /&gt;갑자기 Copy-On-Write에 대해서 설명하다보니 내용이 많이 어려워졌는데 계속 해서 다음줄에 코드를 설명하겠습니다. &lt;br /&gt;&lt;br /&gt;memcpy(cbOldCode, pDrawTextWAddress, 5); 부분은 우리가 변경해야 할 기계어 코드에 5Byte를 백업두는 코드입니다. &lt;br /&gt;이것은 API Hooking 해제할 때 원래의 코드로 되돌리기 위함입니다. &lt;br /&gt;&lt;br /&gt;*pDrawTextWAddress = 0xE9; 부분은 Jmp기계어 코드를 사용한다는 의미입니다. &lt;br /&gt;&lt;br /&gt;그 다음에 *((DWORD *)(pDrawTextWAddress)) = ((DWORD)MyExtTextOutW) - ((DWORD)pDrawTextWAddress +4); &lt;br /&gt;구문은 Jmp를 해야 할 주소를 지정하게 됩니다. &lt;br /&gt;여기서 주소 지정을 할 때 보시면 MyExtTextOutW를 지정하는것이 아니라 MyExtTextOutW함수에 주소에서 &lt;br /&gt;(pDrawTextWAddress +4) 주소를 빼주는 것을 볼 수 있습니다. &lt;br /&gt;이것은 Jmp명령어가 절대 주소로 지정하는것이 아니라 상대 주소로 지정해야 한다는 것을 알 수 있습니다. &lt;br /&gt;&lt;br /&gt;다음 줄을 보시면 VirtualProtect(pDrawTextWAddress, 5, dwOldProtect, &amp;amp;dw);를 호출하는데 원래의 메모리 속성으로 되돌리게 합니다. &lt;br /&gt;( 메모리 속성이이라고 하니 메모리에 속성이라는 것이 있는가라는 의문을 가질 수 있는데 이것은 페이징이 제공하는 메모리 보호기능을 의미합니다. ) &lt;br /&gt;&lt;br /&gt;이 부분까지 완료가 되었다면 이제부터 ExtTextOutW함수를 호출하게 되면 우리의 MyExtTextOutW함수가 호출되게 됩니다. &lt;br /&gt;&lt;br /&gt;프로그램을 실행하면 다음과 같은 화면이 뜹니다. 여기서 엔터키를 입력하면 종료하게 되는데 윈도우즈 전역으로 엔터키를 감지함으로 &lt;br /&gt;다른 프로그램에서 엔터키를 입력하여도 종료하게 됩니다.&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5_4.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;669&quot; height=&quot;438&quot; style=&quot;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;윈도우즈 탐색기를 띄워보시면 MyExtTextOutW에서 아무것도 하지 않고 return TRUE;를 함으로 어떠한 문자열도 출력이 되지 않는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5_5.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;800&quot; height=&quot;600&quot; style=&quot;width: 680px; height: 456px;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;당연히 파이어 폭스에 경우에도 마찬가지입니다.&lt;/p&gt;
&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p/&gt;&lt;img src=&quot;http://simples.kr/files/attach/images/1936/798/019/b0072382_4971b1f3078e5_6.png&quot; alt=&quot;b0072382_4971b1f3078e5.png&quot; class=&quot;iePngFix&quot; width=&quot;1680&quot; height=&quot;1050&quot; style=&quot;width: 706px; height: 523px;&quot; /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p/&gt;간혹 출력되는 문자열이 있을 수 있는데 이것은 다른 Text출력 API함수를 사용하여서 그렇습니다. &lt;/p&gt;&lt;p/&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>윈도우즈 버전이 Windows XP SP2인지 확인하는 다른 방법</title>
      <id>http://simples.kr/19796</id>
      <published>2010-09-03T16:43:05+09:00</published>
      <updated>2010-09-05T21:13:35+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19796"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19796#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;이미 알고 계신분들이 많으시겠지만 Windows XP SP2이상부터 MS 핫패칭 기능이 들어가 있습니다.&lt;br /&gt;따라서 이에 대해 특정 함수에 대한 기계어 코드를 검사함으로써 Windows XP SP2이상인지 확인 할 수 있습니다.&lt;br /&gt;&lt;br /&gt;다음은 해당 코드입니다.&lt;br /&gt;&lt;br /&gt;#include &amp;lt;Windows.h&amp;gt;&lt;br /&gt;&lt;br /&gt;BOOL IsWindowsXpSp2AndLater()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HMODULE hModule;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UCHAR *pBitBltAddress;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hModule = ::LoadLibrary(_T(&quot;GDI32.DLL&quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (hModule == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pBitBltAddress = (UCHAR *)::GetProcAddress(hModule, &quot;BitBlt&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pBitBltAddress == NULL)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // MS HotPatching이 Windows XP SP2 이상부터 적용되었으므로 이에 대한 기계어 코드를 확인합니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (((*(pBitBltAddress - 5)) == 0x90) &amp;amp;&amp;amp; // nop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((*(pBitBltAddress - 4)) == 0x90) &amp;amp;&amp;amp; // nop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((*(pBitBltAddress - 3)) == 0x90) &amp;amp;&amp;amp; // nop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((*(pBitBltAddress - 2)) == 0x90) &amp;amp;&amp;amp; // nop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((*(pBitBltAddress - 1)) == 0x90) &amp;amp;&amp;amp; // nop&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((*pBitBltAddress) == 0x8B) &amp;amp;&amp;amp; ((*(pBitBltAddress + 1)) == 0xFF) // mov edi, edi&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return TRUE;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return FALSE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IsWindowsXpSp2AndLater() == TRUE)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;버전이 Windows XP SP2 이상입니다. ( 또는 Windows 2003 Server 이상 )\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf(&quot;버전이 Windows XP SP2 아래에 운영체제입니다.\n&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;해당 함수가 이미 훅킹을 당했을 경우 코드에 변조가 있을 수 있으므로 주의해야합니다.&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Hexray - Failures and troubleshooting</title>
      <id>http://simples.kr/19735</id>
      <published>2010-09-03T14:00:45+09:00</published>
      <updated>2010-09-03T14:00:45+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19735"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19735#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;http://www.hex-rays.com/manual/failures.shtml&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Intel i80x86 CPU Architecture</title>
      <id>http://simples.kr/19730</id>
      <published>2010-09-03T13:57:05+09:00</published>
      <updated>2010-09-03T13:57:20+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19730"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19730#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;한글자료입니다.&lt;img src=&quot;http://simples.kr/modules/editor/components/emoticon/tpl/images/msn/msn040.gif&quot; alt=&quot;emoticon&quot; style=&quot;&quot; /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;http://211.227.236.243/i80x86/i80x86%20Architecture.htm&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Keybaord Scan Codes Demystified</title>
      <id>http://simples.kr/19727</id>
      <published>2010-09-03T13:55:46+09:00</published>
      <updated>2010-09-03T13:55:46+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19727"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19727#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;이전에 간단한 운영체제를 만들 때 키보드 인터럽트 핸들러 구현 시 참고했던 사이트입니다.&lt;/p&gt;&lt;p/&gt;키보드 스캔 코드에 대해서 설명합니다.&lt;/p&gt;&lt;p/&gt;http://www.quadibloc.com/comp/scan.htm&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Bona Fide OSDev Documents</title>
      <id>http://simples.kr/19724</id>
      <published>2010-09-03T13:53:42+09:00</published>
      <updated>2010-09-03T13:53:42+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19724"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19724#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;예전에 간단한 운영체제를 개발하기 위해 발견한 사이트인데 pdf문서들이 많습니다.&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;http://www.osdever.net/documents.php?cat=0&amp;amp;sort=1&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>the Operating System resource center</title>
      <id>http://simples.kr/19721</id>
      <published>2010-09-03T13:52:05+09:00</published>
      <updated>2010-09-03T13:52:05+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19721"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19721#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;예전에 간단한 운영체제를 만들때 참조햇던 사이트로 pdf문서들이 많이 있습니다.&lt;/p&gt;&lt;p/&gt;http://www.nondot.org/sabre/os/articles&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Win32 Assembly Tutorials</title>
      <id>http://simples.kr/19718</id>
      <published>2010-09-03T13:49:45+09:00</published>
      <updated>2010-09-04T21:18:17+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19718"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19718#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;예전에 어셈블리를 참 좋아했었는데 지금은 기억도 나지 않는군요...&apos;&apos;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;win32 어셈블리 튜토리얼 문서입니다.&lt;br /&gt;&lt;p/&gt;http://win32assembly.online.fr/tutorials.html&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Mozilla - Accessibility/AT-Windows-API</title>
      <id>http://simples.kr/19715</id>
      <published>2010-09-03T13:43:48+09:00</published>
      <updated>2010-09-03T13:43:48+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19715"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19715#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://wiki.mozilla.org/Accessibility/AT-Windows-API&quot;/&gt;&lt;/a&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://wiki.mozilla.org/Accessibility/AT-Windows-API&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p/&gt;에전에 게코기반에 플러그인을 만들 때 접근성 API를 찾기 위해서 본 문서입니다.&lt;/p&gt;&lt;p/&gt;안타깝게도 그 당시에 파이어폭스가 1.5이었는데 IAccessible 인터페이스가 개판으로 구현되어 있어서 엄청나게&lt;/p&gt;&lt;p/&gt;버그가 많았습니다. 다행히 nsIAccessible로 지네들이 만든 인터페이스를 깔끔하게 구현을 해놨었구요-_-&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://wiki.mozilla.org/Accessibility/AT-Windows-API&quot;/&gt;https://wiki.mozilla.org/Accessibility/AT-Windows-API&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Intel® Threading Building Blocks: Documents</title>
      <id>http://simples.kr/19706</id>
      <published>2010-09-03T13:32:32+09:00</published>
      <updated>2010-09-03T13:32:32+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19706"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19706#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.threadingbuildingblocks.org/documentation.php&quot;/&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.threadingbuildingblocks.org/documentation.php&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p/&gt;멀티 스레드 프로그래밍할 때 쓰이는데 이 문서입니다. 시중에 나와있는 인텔 스레딩 빌딩 블록이라는 책이 하나있는데&lt;/p&gt;&lt;p/&gt;이 문서랑 내용이 똑같습니다.-_-&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.threadingbuildingblocks.org/documentation.php&quot;/&gt;http://www.threadingbuildingblocks.org/documentation.php&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/a&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Seagate - SCSI Commands Reference Manual</title>
      <id>http://simples.kr/19701</id>
      <published>2010-09-03T13:27:42+09:00</published>
      <updated>2010-09-03T13:27:42+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19701"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19701#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;시게이트에서 작성한 SCSI CDB에 대한 설명이 들어있습니다.&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>SCSI Multi-Media Commands - 5 (MMC-5)</title>
      <id>http://simples.kr/19697</id>
      <published>2010-09-03T13:26:04+09:00</published>
      <updated>2010-09-03T13:26:04+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19697"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19697#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;MMC-5 Technical Editor: Bill McFerrin, representing &lt;br /&gt;Royal Philips Electronics, NV &lt;/p&gt;&lt;p/&gt;&lt;br /&gt;&lt;/p&gt;&lt;p/&gt;MultiMedia Commands 관련 문서입니다.&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>AMD64 Architecture Programmer&apos;s Manual Volume</title>
      <id>http://simples.kr/19695</id>
      <published>2010-09-03T13:23:20+09:00</published>
      <updated>2010-09-03T13:23:20+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19695"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19695#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://developer.amd.com/documentation/guides/Pages/default.aspx&quot;/&gt;http://developer.amd.com/documentation/guides/Pages/default.aspx&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Intel® 64 and IA-32 Architectures Software Developer&apos;s Manuals</title>
      <id>http://simples.kr/19692</id>
      <published>2010-09-03T13:23:00+09:00</published>
      <updated>2010-09-03T13:23:00+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19692"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19692#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.intel.com/products/processor/manuals/index.htm&quot;/&gt;http://www.intel.com/products/processor/manuals/index.htm&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Mt. Fuji Commands for Multimedia Devices Version 7</title>
      <id>http://simples.kr/19687</id>
      <published>2010-09-03T13:22:18+09:00</published>
      <updated>2010-09-03T13:22:18+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19687"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19687#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;데몬이나 알콜과 같은 프로그램을 개발할 때 항상 펴놓고 있어야 할 메뉴얼입니다.&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Memory Management: What Every Driver Writer Needs to Know</title>
      <id>http://simples.kr/19683</id>
      <published>2010-09-03T13:18:27+09:00</published>
      <updated>2010-09-03T13:18:27+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19683"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19683#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/modules/editor/components/emoticon/tpl/images/msn/msn040.gif&quot; alt=&quot;emoticon&quot; style=&quot;&quot; /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Handling IRPs: What Every Driver Writer Needs to Know</title>
      <id>http://simples.kr/19679</id>
      <published>2010-09-03T13:17:28+09:00</published>
      <updated>2010-09-03T13:17:28+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19679"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19679#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;img src=&quot;http://simples.kr/modules/editor/components/emoticon/tpl/images/msn/msn040.gif&quot; alt=&quot;emoticon&quot; style=&quot;&quot; /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>MMC Get Event Status Notification and Windows</title>
      <id>http://simples.kr/19677</id>
      <published>2010-09-03T13:16:33+09:00</published>
      <updated>2010-09-03T13:16:33+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19677"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19677#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://www.microsoft.com/whdc/device/storage/gesn_imp.mspx&quot;/&gt;http://www.microsoft.com/whdc/device/storage/gesn_imp.mspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;참고 -&lt;br /&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\cdrom 경로에&lt;br /&gt;AutoRun에 값을 0으로 만드는 것은 Get Event Status Notification를 cdrom.sys에서 하위 드라이버에&lt;br /&gt;쿼리하지 않음을 의미합니다.&lt;br /&gt;자세한 사항은 Mt. Fuji Commands for Multimedia Devices Version 7 문서 참조&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Bypassing PatchGuard on windows x64</title>
      <id>http://simples.kr/19672</id>
      <published>2010-09-03T13:14:31+09:00</published>
      <updated>2010-09-03T13:14:31+09:00</updated>
      <link rel="alternate" type="text/html" href="http://simples.kr/19672"/>
      <link rel="replies" type="text/html" href="http://simples.kr/19672#comment"/>
      <author>
         <name>lain</name>
                  <uri>http://lain32.egloos.com/</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p/&gt;아마 안될꺼야...&lt;img src=&quot;http://simples.kr/modules/editor/components/emoticon/tpl/images/msn/msn010.gif&quot; alt=&quot;emoticon&quot; style=&quot;&quot; /&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
</feed> 
