<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>홍가일보(KB)</title>
		<link>http://hongyver.pe.kr/ttblog/</link>
		<description>BLOG by Hongyver</description>
		<language>ko</language>
		<pubDate>Mon,  5 Oct 2009 13:16:09 +0900</pubDate>
		<generator>Textcube 1.7.8 : Release Candidate 1</generator>
		<image>
		<title>홍가일보(KB)</title>
		<url>http://hongyver.pe.kr/ttblog/attach/1/1346019476.jpg</url>
		<link>http://hongyver.pe.kr/ttblog/</link>
		<width>148</width>
		<height>200</height>
		<description>BLOG by Hongyver</description>
		</image>
		<item>
			<title>FileSystemFilterDriver 파일숨기기</title>
			<link>http://hongyver.pe.kr/ttblog/entry/FileSystemDriver-%ED%8C%8C%EC%9D%BC%EC%88%A8%EA%B8%B0%EA%B8%B0</link>
			<description>		&lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot;&gt;
		//&lt;![CDATA[

			var __getEmbedCode;
		
			if (typeof getEmbedCode == &quot;function&quot;) {
				
				__getEmbedCode = getEmbedCode;

				getEmbedCode = function(move, width, height, id, bg, FlashVars, menu, transparent, quality, bgcolor, allowScriptAccess, version) {
					if (transparent == undefined) transparent = &quot;opaque&quot;;
					return __getEmbedCode(move, width, height, id, bg, FlashVars, menu, transparent, quality, bgcolor, allowScriptAccess, version);
				}

			}
			
		//]]&gt;
		&lt;/script&gt;&lt;P&gt;&lt;STRONG&gt;ZwQueryDirectoryFile&lt;BR&gt;&lt;BR&gt;&lt;/STRONG&gt;Window XP이후 버전 에서 폴더내 파일 또는 폴더의 정보를 얻기 위한 과정은 ZwCreateFile 또는 ZwOpenFile을 통해 얻어진 handle을 통해 ZwQueryDirectoryFile 에서 디렉토리에 대한 파일 또는 폴더 정보를 query하여 얻는다.&lt;BR&gt;즉 윈도우에서 탐색기 혹은 cmd 창에서 dir 명령어도 Win32 API 에서 파일 및 폴더 정보를 얻어오는 과정과 사용된 API가 다르겠지만 결국 Native API 인 ZwQueryDirectoryFile 을 통해서 디렉토리내 파일 또는 폴더명을 얻는다는 이야기다.&lt;BR&gt;따라서 파일 또는 폴더를 숨기기 위해서는 ZwQueryDirectoryFile 함수를 Hooking 하여 원하는 파일 또는 폴더를 숨길수 있다는 이야기다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;IRP_MJ_DIRECTORY_CONTROL&lt;BR&gt;&lt;/STRONG&gt;&lt;BR&gt;Hooking을 하지 않고 파일필터 드라이버에서 파일 및 폴더를 숨기는 기능을 수행하기 위해서는 아래의 IRP funtion code를 참고하면 된다.&lt;BR&gt;&lt;BR&gt;IRP stack의 Major Function 이 &lt;STRONG&gt;IRP_MJ_DIRECTORY_CONTROL&lt;/STRONG&gt; &lt;BR&gt;IRP stack의 Minor Function 이 &lt;STRONG&gt;IRP_MN_QUERY_DIRECTORY&lt;/STRONG&gt; &lt;BR&gt;&lt;BR&gt;위의 두가지 Funtion code외에 &lt;STRONG&gt;FileInformationClass&lt;/STRONG&gt; 를 조사하여야 한다.&lt;BR&gt;&lt;BR&gt;IRP stack의 Parameters-&amp;gt;&lt;STRONG&gt;FileInformationClass&lt;/STRONG&gt; 가 &lt;STRONG&gt;FileBothDirectoryInformation&lt;BR&gt;&lt;/STRONG&gt;&lt;BR&gt;대부분의 win32에서의 폴더내의 파일 및 파일 열거에 대한 호출은 FileBothDirectoryInformation(VISTA에서는 FileIdBothDirectoryInformation 로 변경)이다. 따라서 대부분 FileBothDirectoryInformation로 원하는 처리(파일 또는 풀더 숨김)가 가능하지만 보다 강력한(?) 숨기기 기능을 원하다면 FilFullDirectoryInformation, FileNameInformation, FileDirectoryInfomation class도 대한 처리도 필요하지 않을까 싶다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;전처리&lt;/STRONG&gt;&lt;BR&gt;&lt;BR&gt;원하는 조건은 다 충족되었다.&lt;BR&gt;이제 파일 또는 폴더 숨기는 작업을 수행하여야 하는데 그전에 알아두어야 할 것이있다.&lt;BR&gt;&lt;BR&gt;조건이 만족된 지금 현재 상태는 File System Driver로 IRP를 넘겨 주기 전 이기 때문에 파일 및 폴더에 어떤 정보도 알지 못한다. 따라서 지금 처리할수 있는 작업은 폴더에 대한 접근 거부(STATUS_ACCESS_DENIED) 또는 폴더내 어떤 파일도 보여주지 않는 작업(STATUS_NO_SUCH_FILE)만이 가능하다.&lt;/P&gt;
&lt;P&gt;아래 그림에서 1번을 참고하면 되겠다.&lt;BR&gt;&lt;BR&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://hongyver.pe.kr/ttblog/attach/1/1053248325.jpg&quot; width=&quot;512&quot; height=&quot;266&quot; alt=&quot;사용자 삽입 이미지&quot; /&gt;&lt;/div&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;STRONG&gt;후처리&lt;/STRONG&gt;&lt;BR&gt;&lt;BR&gt;조건이 만족한 상태라면 파일 숨기는 기능을 처리해야 하지만 위의 전처리에서 설명했다시피 폴더 및 파일에 대한 정보를 아직 얻지 못한 상태이기때문에 어떠한 가공(?)도 할수 없다.&lt;BR&gt;따라서 IoSetCompletionRoutine 을 통해 IRP가 완료한 시점에 다시 호출받도록 설정하여 File System Driver가 모든 작업을 완료하고 나서 다시 호출될수 있도록 해야 한다.&lt;BR&gt;그래야만 File System Driver에서 얻어지 파일 또는 폴더에 대한 정보를 가공(?) 할수 있다.&lt;BR&gt;&lt;BR&gt;위의 그림에서 2번을 참고.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;완료루틴&lt;/STRONG&gt;&lt;BR&gt;&lt;BR&gt;IoSetCompletionRoutine 에서 설정한 대로 File System Driver에서 작업을 완료하고 완료루틴이 호출되면 원하는 파일 또는 폴더에 대한 작업을 수행한다.&lt;BR&gt;파일 또는 폴더에 대한 정보는 Irp-&amp;gt;UserBuffer 에 넘겨져 온다.&lt;BR&gt;이 정보를 제대로 파악하기 위해서는 아래의 parameter를 참고해야한다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;IrpSp-&amp;gt;Parameters.QueryDirectory.Length&lt;/STRONG&gt;&lt;BR&gt;버퍼의 길이 - METHOD_NEITHER를 사용하기 때문에 Irp-&amp;gt;UserBuffer 의 크기&lt;BR&gt;&lt;STRONG&gt;IrpSp-&amp;gt;Parameters.QueryDirectory.FileName&lt;BR&gt;&lt;/STRONG&gt;파일 열거를 위한 매칭패턴을 위해 사용됨. 첫 호출에만 제공됨. 그 이후 NULL이면 *, *.* 패턴과 동일시 됨&lt;BR&gt;&lt;STRONG&gt;IrpSp-&amp;gt;Parameters.QueryDirectory.FileInformationClass&lt;/STRONG&gt;&lt;BR&gt;결과에 대한 데이타 구조체 형식, MSDN 참고&lt;BR&gt;&lt;STRONG&gt;IrpSp-&amp;gt;Parameters.QueryDirectory.FileIndex&lt;BR&gt;&lt;/STRONG&gt;열거가 발생할 시작 index&lt;BR&gt;&lt;BR&gt;처음에 언급했던바처럼 &lt;STRONG&gt;FileBothDirectoryInformation&lt;/STRONG&gt; 에 대한 class 만 참고하다면&lt;BR&gt;pFileInfo = (PFILE_BOTH_DIR_INFORMATION) Irp-&amp;gt;UserBuffer 와 같은 casting 을 통해 pFileInfo 를 통해 파일 정보를 구할수 있다.(PFILE_BOTH_DIR_INFORMATION 는 각각의 파일에 대한 정보를 담고 있으며 &lt;STRONG&gt;NextEntryOffset&lt;/STRONG&gt;으로 다음 정보에 대한 offset값을 가지고 있다.)&lt;BR&gt;파일정보에서 특정파일을 숨기기 위해서는 NextEntryOffset 값을 건너 뛰도록 offset 값을 조작하여 파일을 숨긴다.&lt;BR&gt;&lt;BR&gt;주의해야 할점이라면 버퍼의 용량이 그다지 크지 않기 때문에 특정 폴더에 대한 query 시 폴더내 모든 파일(폴더)의 정보가 한번에 넘어오지 않는다. (경험상 약 30개 파일의 정보 단위로 넘어오는듯)&lt;BR&gt;한 폴더에 약 100개의 파일이 존재한다면 30개씩 약 4번에 걸쳐 모든 정보가 넘어온다.&lt;BR&gt;&lt;BR&gt;또한 Irp-&amp;gt;Flags parameter도 참고하여야 한다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;SL_RESTART_SCAN&lt;/STRONG&gt; 첫번째 부터 스캔&lt;BR&gt;&lt;STRONG&gt;SL_RETURN_SINGLE_ENTRY&lt;/STRONG&gt; 한개만 스캔&lt;BR&gt;&lt;STRONG&gt;SL_INDEX_SPECIFIED&lt;/STRONG&gt; FileIndex 에서 부터 스캔&lt;BR&gt;&lt;BR&gt;FindFirst/FindNext 과 같은 win api에서는 flags가 SL_RETURN_SINGLE_ENTRY 가 설정되어 파일이 한개만 조사되기 때문에구조체에 한개 파일의 정보만 담겨진다.&lt;BR&gt;따라서 NextEntryOffset 값을 조작하는데 유의해야한다. 이는 여러개의 파일정보가 있으나 숨기고자 하는 파일정보가 마지막에 위치하였을때도 마찬가지다.&lt;BR&gt;(편법으로 파일이름을 . 으로 대체하기도 했음)&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;code snippet&lt;BR&gt;&lt;BR&gt;&lt;/STRONG&gt;FileInformationClass 에 따라 FileName 및 FileNameLength 얻기&lt;BR&gt;&lt;BR&gt;switch(irpsp-&amp;gt;Parameters.QueryDirectory.FileInformationClass) &lt;BR&gt;{&lt;BR&gt;&amp;nbsp;case FileBothDirectoryInformation:&lt;BR&gt;&amp;nbsp; p = ((PFILE_BOTH_DIR_INFORMATION)buf)-&amp;gt;FileName;&lt;BR&gt;&amp;nbsp; len = &amp;amp;(((PFILE_BOTH_DIR_INFORMATION)buf)-&amp;gt;FileNameLength); &amp;nbsp; &lt;BR&gt;&amp;nbsp; sp = ((PFILE_BOTH_DIR_INFORMATION)buf)-&amp;gt;ShortName; &amp;nbsp; &lt;BR&gt;&amp;nbsp; slen = ((PFILE_BOTH_DIR_INFORMATION)buf)-&amp;gt;ShortNameLength; &amp;nbsp; &lt;BR&gt;&amp;nbsp; break; &amp;nbsp; &lt;BR&gt;&amp;nbsp;case FileFullDirectoryInformation: &amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; p = ((PFILE_FULL_DIR_INFORMATION)buf)-&amp;gt;FileName; &amp;nbsp; &lt;BR&gt;&amp;nbsp; len = &amp;amp;(((PFILE_FULL_DIR_INFORMATION)buf)-&amp;gt;FileNameLength); &amp;nbsp; &lt;BR&gt;&amp;nbsp; break; &amp;nbsp; &lt;BR&gt;&amp;nbsp;case FileDirectoryInformation: &amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; p = ((PFILE_DIRECTORY_INFORMATION)buf)-&amp;gt;FileName; &amp;nbsp; &lt;BR&gt;&amp;nbsp; len = &amp;amp;(((PFILE_DIRECTORY_INFORMATION)buf)-&amp;gt;FileNameLength); &amp;nbsp; &lt;BR&gt;&amp;nbsp; break; &amp;nbsp; &lt;BR&gt;&amp;nbsp;case FileIdBothDirectoryInformation: &amp;nbsp; &lt;BR&gt;&amp;nbsp; p = ((PFILE_ID_BOTH_DIR_INFORMATION )buf)-&amp;gt;FileName; &amp;nbsp; &lt;BR&gt;&amp;nbsp; len = &amp;amp;(((PFILE_ID_BOTH_DIR_INFORMATION )buf)-&amp;gt;FileNameLength); &amp;nbsp; &lt;BR&gt;&amp;nbsp; sp = ((PFILE_BOTH_DIR_INFORMATION)buf)-&amp;gt;ShortName; &amp;nbsp; &lt;BR&gt;&amp;nbsp; slen = ((PFILE_BOTH_DIR_INFORMATION)buf)-&amp;gt;ShortNameLength; &amp;nbsp; &lt;BR&gt;&amp;nbsp; break;&lt;BR&gt;...&lt;BR&gt;}&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;/P&gt;</description>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/772</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/FileSystemDriver-%ED%8C%8C%EC%9D%BC%EC%88%A8%EA%B8%B0%EA%B8%B0#entry772comment</comments>
			<pubDate>Sun, 14 Jun 2009 13:19:29 +0900</pubDate>
		</item>
		<item>
			<title>STATUS_MEDIA_WRITE_PROTECTED</title>
			<link>http://hongyver.pe.kr/ttblog/entry/STATUS_MEDIA_WRITE_PROTECTED</link>
			<description>파일 필터 드라이버 기능중에 이동저장장치(외장하드, USB저장장치등)에 쓰기금지기능이 있다.&lt;BR&gt;이동저장장치에서 자유롭게 읽기는 가능해도 쓰기는 안되게 하는 기능인데...&lt;BR&gt;이 기능이 다른 프로그램에서는 제대로 동작하는 한글2007에서는 원본파일을 강제로 2KB로 만들어 버린다.&lt;BR&gt;&lt;BR&gt;코드를 살펴보니 IRP_MJ_WRITE시 STATUS_ACCESS_DENIED를 리턴하여 쓰기금지 기능을 수행하고 있다.&lt;BR&gt;대체로 양호하게 동작을 수행하는데 유독 한글2007에서만 파일이 깨진다.&lt;BR&gt;&lt;BR&gt;Filemon, Filespy로 IRP를 들여다 봐도 별반 차이가 없고 왜 그럴까 하던차에 SD 메모리카드에 lock기능이 있길래 lock으로 설정을 하고 쓰기기능을 수행한 결과.&lt;BR&gt;&lt;BR&gt;눈에 띄는게 IRP_MJ_SET_INFORMATION의 FileEndOfFileInformation 일때STATUS_MEDIA_WRITE_PROTECTED 값을 리턴한다.&lt;BR&gt;&lt;BR&gt;MSDN에 이런 내용이 있다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;FileEndOfFileInformation&lt;/STRONG&gt;&lt;BR&gt;This is called when someone is trying to change the logical size of the stream. &lt;STRONG&gt;Note that when the cache manager’s lazy writer thread attempts to set a new end of file no oplock check is made. This is because the check will have been made previously when the real write request came in.&lt;BR&gt;&lt;/STRONG&gt;&lt;BR&gt;결국 이동저장장치에 쓰기금지를 하려면&lt;BR&gt;일반적으로 IRP_MJ_WRITE에서 막으면 되겠지만 프로그램에 따라(특히 한글2007 같이 cache를 사용한다면)...&lt;BR&gt;IRP_MJ_SET_INFORMATION(FileEndOfFileInformation)에서도 알맞는 처리를 해줘야 한다. &lt;BR&gt;&lt;BR&gt;NTSTATUS.H를 참조해서 STATUS_ACCESS_DENIED를 하던지...STATUS_MEDIA_WRITE_PROTECTED를 하던지 취향에 맞게 하면 되겠다.&lt;BR&gt;</description>
			<category>FileEndOfFileINformation</category>
			<category>IRP_MJ_SET_INFORMATION</category>
			<category>IRP_MJ_WRITE</category>
			<category>STATUS_ACCESS_DENIED</category>
			<category>STATUS_MEDIA_WRITE_PROTECTED</category>
			<category>파일쓰기금지</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/770</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/STATUS_MEDIA_WRITE_PROTECTED#entry770comment</comments>
			<pubDate>Fri,  5 Dec 2008 09:29:53 +0900</pubDate>
		</item>
		<item>
			<title>비주얼스튜디오 단축키 - 정의바로가기를 되돌리기 CTRL+*</title>
			<link>http://hongyver.pe.kr/ttblog/entry/%EB%B9%84%EC%A3%BC%EC%96%BC%EC%8A%A4%ED%8A%9C%EB%94%94%EC%98%A4-%EB%8B%A8%EC%B6%95%ED%82%A4-%EC%A0%95%EC%9D%98%EB%B0%94%EB%A1%9C%EA%B0%80%EA%B8%B0%EB%A5%BC-%EB%90%98%EB%8F%8C%EB%A6%AC%EA%B8%B0-CTRL</link>
			<description>코드를 분석하다가 보면...&lt;br /&gt;특정 함수나 변수명의 선언이나 정의를 보고 싶을때...&lt;br /&gt;무심코 &lt;STRONG&gt;F12&lt;/STRONG&gt;(&lt;STRONG&gt;CTRL+F12&lt;/STRONG&gt;) 또는 마우스 오른쪽을 눌러 &quot;&lt;STRONG&gt;선언으로 이동&lt;/STRONG&gt;&quot; 또는 &quot;&lt;STRONG&gt;정의로 이동&lt;/STRONG&gt;&quot;를 사용한다.&lt;br /&gt;그런데 문제는 대충 함수(변수)의 정의나 선언을 살펴보고 바로 이전으로 되돌아 가고 싶은데 북마크나 보고있던 부분의 line의 줄수를 특별히 기억해 두고 있지 안았다면 낭패&lt;br /&gt;늘 어디더라 하면서 찾기가 일쑤였는데...&lt;br /&gt;&lt;br /&gt;그럴땐 &lt;STRONG&gt;CTRL+*(&lt;/STRONG&gt;숫자패드의 *)를 눌러보자.&lt;br /&gt;그럼 이전 코드부분으로 되돌려진다.&lt;br /&gt;아마도 정의 또는 선언으로 이동할때 위치를 스택에 저장하는듯 하다.&lt;br /&gt;&lt;br /&gt;나도 어디선가 주워들은 내용인데 MSDN이며 구글링을 해도 찾지를 못하겠다.&lt;br /&gt;회사 동료가 보다가 신기해 하길래 포스팅.&lt;br /&gt;&lt;br /&gt;더불어 가급적 마우스를 안쓰고 키보드로 해결하려고 노력중인 단축키들...&lt;br /&gt;&lt;br /&gt;
&lt;BLOCKQUOTE&gt;블럭 주석달기&lt;br /&gt;&lt;STRONG&gt;CTRL+K&lt;/STRONG&gt;, &lt;STRONG&gt;CTRL+C&lt;/STRONG&gt; 주석 블럭 설정&lt;br /&gt;&lt;STRONG&gt;CTRL+K&lt;/STRONG&gt;, &lt;STRONG&gt;CTRL+U&lt;/STRONG&gt; 주석 블럭 해제&lt;br /&gt;&lt;br /&gt;마우스로 상단 파일이동이 아닌 키보드로 파일간 이동&lt;br /&gt;&lt;STRONG&gt;CTRL+TAB&lt;/STRONG&gt;, &lt;STRONG&gt;CTRL+SHIFT+TAB&lt;/STRONG&gt;&lt;br /&gt;&lt;br /&gt;중간중간 분석한 부분을 잊어버리지 않기 위해 북마크(가끔은 브레이크 포인터도 쓴다는...)&lt;br /&gt;&lt;STRONG&gt;F2&lt;/STRONG&gt;, &lt;STRONG&gt;CTRL+F2&lt;br /&gt;&lt;/STRONG&gt;&lt;br /&gt;창이동&lt;br /&gt;&lt;STRONG&gt;ALT+0&lt;/STRONG&gt; 소스코드창으로&lt;br /&gt;&lt;STRONG&gt;ALT+2&lt;/STRONG&gt; 출력창으로&lt;br /&gt;가장 필요한 찾기창은 CTRL+TAB으로 대신....(이거 단축키는 없나?)&lt;br /&gt;&lt;br /&gt;{ } 짝 찾기&lt;br /&gt;&lt;STRONG&gt;CTRL+]&lt;/STRONG&gt;&lt;/BLOCKQUOTE&gt;&lt;br /&gt;ps.&lt;br /&gt;디버깅시 실시간으로 GetLastError 값알아내기(이것도 회사동료가 신기해 하던...Debugging Applications 책 참조)&lt;br /&gt;조사&lt;FONT color=#000000&gt;식(watch)창의 이름(Name)에 &lt;STRONG&gt;@ERR&lt;/STRONG&gt; 값 입력&lt;/FONT&gt;&lt;br /&gt;</description>
			<category>단축키</category>
			<category>되돌아가기</category>
			<category>비주얼스튜디오</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/769</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/%EB%B9%84%EC%A3%BC%EC%96%BC%EC%8A%A4%ED%8A%9C%EB%94%94%EC%98%A4-%EB%8B%A8%EC%B6%95%ED%82%A4-%EC%A0%95%EC%9D%98%EB%B0%94%EB%A1%9C%EA%B0%80%EA%B8%B0%EB%A5%BC-%EB%90%98%EB%8F%8C%EB%A6%AC%EA%B8%B0-CTRL#entry769comment</comments>
			<pubDate>Thu, 25 Sep 2008 08:39:52 +0900</pubDate>
		</item>
		<item>
			<title>Windbg에서 조건문 bp</title>
			<link>http://hongyver.pe.kr/ttblog/entry/Windbg-%EC%A1%B0%EA%B1%B4%EB%AC%B8</link>
			<description>&lt;P&gt;MSDN 블러그를 보다 보니...&lt;br /&gt;Windgb로 조건문 bp 사용에 대해 자세한 설명을 해놓았다.&lt;br /&gt;&lt;FONT color=#800080&gt;&lt;A href=&quot;http://blogs.msdn.com/debuggingtoolbox/archive/2008/06/12/special-command-if-and-j-to-use-in-breakpoints-and-scripts.aspx&quot; target=_blank&gt;&lt;FONT color=#800080&gt;&lt;STRONG&gt;http://blogs.msdn.com/debuggingtoolbox/archive/2008/06/12/special-command-if-and-j-to-use-in-breakpoints-and-scripts.aspx&lt;br /&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;br /&gt;&lt;/FONT&gt;&lt;FONT color=#000000&gt;특정 지점에서 10번째 카운터에서 bp를 잡는 예제를 아래와 같이 써두었는데...&lt;br /&gt;&lt;br /&gt;&lt;/FONT&gt;&lt;FONT style=&quot;BACKGROUND-COLOR: #ffffff&quot; color=#000000&gt;&lt;STRONG&gt;r @$t0 = 0&lt;br /&gt;bp mtgdi!CBallThread::SingleStep &quot;r @$t0 = @$t0 + 1;.if(@$t0 &amp;gt; 0n10){.echo More than 10 times...}.else{ gc }&quot;&lt;br /&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;br /&gt;누군가 달아놓은 코멘트가 압권...&lt;br /&gt;&lt;br /&gt;&lt;STRONG&gt;bp mtgdi!CBallThread::SingleStep 10&lt;/STRONG&gt;&lt;br /&gt;&lt;br /&gt;딸랑 이 한줄이면 된단다.&lt;br /&gt;하아...&lt;A href=&quot;http://blogs.msdn.com/debuggingtoolbox/archive/2008/06/12/special-command-if-and-j-to-use-in-breakpoints-and-scripts.aspx&quot;&gt;&lt;br /&gt;&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;&lt;/P&gt;</description>
			<category>bp</category>
			<category>Set Breakpoint</category>
			<category>WinDBG</category>
			<category>조건문bp</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/768</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/Windbg-%EC%A1%B0%EA%B1%B4%EB%AC%B8#entry768comment</comments>
			<pubDate>Wed, 18 Jun 2008 08:38:20 +0900</pubDate>
		</item>
		<item>
			<title>Crash Dump Analysis  책 발매</title>
			<link>http://hongyver.pe.kr/ttblog/entry/Crash-Dump-Analysis-%EC%B1%85-%EB%B0%9C%EB%A7%A4</link>
			<description>언제가 회사에서 개발자 면접이 있을때 자리를 함께할 기회가 있었다.&lt;br /&gt;이런 저런 이야기를 하다 디버깅에 대한 이야기가 나왔는데...&lt;br /&gt;면접자가 말하기를...&lt;br /&gt;Windbg며 Softice며 쓸 필요가 있냐....코딩을 잘하면 된지...&lt;br /&gt;그자리에서는 그냥 웃고 말았는데...&lt;br /&gt;개발자에 있어서 디버깅은 설계와 구현 못지 않은 내공에 대한 기준이다.&lt;br /&gt;게다가 디버깅이란게 설계와 구현에 관한 만큼 정형화되어 있지도 않기 때문에...&lt;br /&gt;디버깅의 지식 습득이란게 경험외에는 다른 대안이 없다.&lt;br /&gt;디버깅은 그만큼 개발자의 경험을 반영한다고 하면 디버깅 능력을 무시 못하겠다.&lt;br /&gt;&lt;br /&gt;그런 의미에서 지금 소개하려는 &lt;A href=&quot;http://www.dumpanalysis.org/&quot; target=_blank&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff&gt;Dmitry Vostokov&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;라는 개발자가 쓴 &lt;FONT color=#0000ff&gt;&lt;STRONG&gt;&lt;A href=&quot;http://www.dumpanalysis.org/Memory+Dump+Analysis+Anthology+Volume+1&quot; target=_blank&gt;&lt;FONT color=#0000ff&gt;&lt;STRONG&gt;Crash Dump Analysis&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/FONT&gt;라는 책에 의미가 있다.&lt;br /&gt;디버깅 전반적인 내용은 아니지만 &quot;Crash Dump 파일 분석&quot;에 대한 실예제 글인데 틈틈히 블러그에 올린 글을 모아놓은 책이다.&lt;br /&gt;RSS로 구독하여 시간나면 읽어야지 하면서도 읽지 못했는데 책으로 나온다니 반가운 소식이다.&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://hongyver.pe.kr/ttblog/attach/1/1101311369.png&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;255&quot; width=&quot;381&quot; /&gt;&lt;/div&gt;&lt;br /&gt;사실은 &lt;A href=&quot;http://www.driveronline.org/&quot; target=_blank&gt;&lt;FONT color=#0000ff&gt;&lt;STRONG&gt;드라이버온라인&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;에 drost라는 분이 이 내용을 번역해서 종종 올리기도 하였는데 어쩌면 한글판도 기대해도 좋을지 모르겠다.&lt;br /&gt;</description>
			<category>CrashDumpAnalysis</category>
			<category>dmitryvostokov</category>
			<category>덤프</category>
			<category>디버깅</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/767</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/Crash-Dump-Analysis-%EC%B1%85-%EB%B0%9C%EB%A7%A4#entry767comment</comments>
			<pubDate>Wed, 16 Apr 2008 09:25:43 +0900</pubDate>
		</item>
		<item>
			<title>CrashFinder</title>
			<link>http://hongyver.pe.kr/ttblog/entry/CrashFinder</link>
			<description>회사동료가 help를 요청하길래 얼마전 이야기했던 &lt;A href=&quot;http://hongyver.pe.kr/ttblog/entry/DrWatson&quot; target=_blank&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff&gt;MAP파일 생성으로 에러 발생한곳 찾기&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;로 문제가 발생한곳을 찾으려고 했더니...&lt;br /&gt;2005 프로젝트에서 아무리해도 map 파일을 제대로 생성할수 없었다.&lt;br /&gt;&lt;br /&gt;포기할수 없어 구글링을 통해 알아보니...&lt;br /&gt;CrashFinder 라는 프로그램을 사용하면 굳이 복잡한 과정을 거치지 않아도 쉽게 알수 있다.&lt;br /&gt;에러가 발생한 곳의 주소를 입력하여 파일명와 에러난 줄번호를 바로 알수있다.&lt;br /&gt;(초간단 사용예는 &lt;A href=&quot;http://www.ecs.syr.edu/faculty/fawcett/handouts/estingSeminar/Chapter12And14_CodeAndDocs/CrashFinder.doc&quot; target=_blank&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff&gt;이곳&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;참조, 영문doc)&lt;br /&gt;&lt;br /&gt;&lt;A href=&quot;http://www.wintellect.com/cs/blogs/jrobbins/archive/2006/07/05/crashfinder-2-55-a-bug-fix-and-x64-support.aspx&quot; target=_blank&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff&gt;CrashFinder 다운받기&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;추가로 pdb 파일 생성에 관한 Bugs Layer 기사 참조&lt;br /&gt;&lt;A href=&quot;http://www.microsoft.com/msj/0498/bugslayer0498.aspx&quot;&gt;&lt;FONT color=#0000ff&gt;&lt;STRONG&gt;http://www.microsoft.com/msj/0498/bugslayer0498.aspx&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;글의 요지는...&lt;br /&gt;1. 디버그 심볼은 디버그 빌드에서만 생성할수 있는게 아니다. Release 빌드시도 pdb 생성하여 에러 발생시 심신을 편하게 하자.&lt;br /&gt;&lt;br /&gt;설정 방법은...&lt;br /&gt;cl.exe, C++ tab에서&lt;br /&gt;/Zi - Debug Info를 Program Database로 설정&lt;br /&gt;&lt;br /&gt;Link.exe, link탭에서&lt;br /&gt;/DEBUG - generate debuginfo 선택&lt;br /&gt;/PDB:&quot;파일명&quot; - user program data base 체크 및 이름추가&lt;br /&gt;&lt;br /&gt;2. reversing에 대한 염려도 없다. 프로그램은 약 1kb, pdb 파일이름만 기록&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://hongyver.pe.kr/ttblog/attach/1/1152780396.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;112&quot; width=&quot;500&quot; /&gt;&lt;p class=&quot;cap1&quot;&gt;PDB 생성하면서 Release 빌드&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://hongyver.pe.kr/ttblog/attach/1/1401735961.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;71&quot; width=&quot;500&quot; /&gt;&lt;p class=&quot;cap1&quot;&gt;PDB 생성하지 않고 Release 빌드&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;차이점은 NB10으로 시작하는 디버그헤더와 pdb path 만 추가되어있다.&lt;br /&gt;&lt;br /&gt;3. dll의 경우 rebase를 통한 로드주소 정리&lt;br /&gt;Debuggin Applications 책에서도 언급되었던 내용으로 상당수의 dll이 0x10000000에 로드되려하기 때문에 이로인한 부하를 줄이기 위해서 dll별 로드되는 주소를 설정.&lt;br /&gt;빌드시 설정하여도 되고 rebase.exe라는 유틸을 사용하여도 무방&lt;br /&gt;&lt;br /&gt;4. pdb와 exe 보관&lt;br /&gt;각 버전에 맞는 pdb와 exe를 보관&lt;br /&gt;소스관리툴을 사용하고 파일별 버전을 관리한다면 따로 보관하지 않아도 될듯하다.&lt;br /&gt;&lt;br /&gt;&lt;A href=&quot;http://www.wintellect.com/cs/blogs/jrobbins/archive/2006/07/05/crashfinder-2-55-a-bug-fix-and-x64-support.aspx&quot; target=_blank&gt;&lt;br /&gt;&lt;/A&gt;결론은...&lt;br /&gt;릴리즈 빌드시 pdb를 생성해서 배포하고(드라이버는 자동으로 pdb가 생성된다) dll은 시작주소를 기본값(0x10000000)이 아닌 다른 값(Debugging Application 책에 권장방법이 있다)으로 설정한다.&lt;br /&gt;에러발생시 Windbg를 사용할 여건이 안된다면 CrashFinder로 분석하고 여건이 허락한다면 Windbg를 통해 분석하자.&lt;br /&gt;</description>
			<category>CrashFinder</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/766</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/CrashFinder#entry766comment</comments>
			<pubDate>Wed, 13 Feb 2008 10:10:08 +0900</pubDate>
		</item>
		<item>
			<title>Nt vs Zw - Clearing confusion on the Native API</title>
			<link>http://hongyver.pe.kr/ttblog/entry/Nt-vs-Zw-Clearing-confusion-on-the-Native-API</link>
			<description>&lt;H4&gt;Preface&lt;/H4&gt;
&lt;P&gt;&lt;A class=external title=원문 href=&quot;http://www.osronline.com/article.cfm?id=257&quot;&gt;원문&lt;/A&gt;(OSR)의 글을 요약, 이해 정리한 글이다.&lt;/P&gt;
&lt;P&gt;아래의 4가지 시나리오를 통해 NtXxx 함수와 ZwXxx함수에 대해 알아보자.&lt;br /&gt;UserMode에서 NtXxx(NTDLL.DLL) 함수 호출하기&lt;br /&gt;UserMode에서 ZwXxx(NTDLL.DLL) 함수 호출하기 &lt;br /&gt;KernelMode에서 NtXxx(NTOSKRNL.EXE) 함수 호출하기&lt;br /&gt;KernelMode에서 ZwXxx(NTOSKRNL.EXE) 함수 호출하기&lt;/P&gt;
&lt;H4&gt;Calling From User Mode&lt;/H4&gt;
&lt;P class=MsoNormal style=&quot;TEXT-JUSTIFY: inter-ideograph; MARGIN: 0in 0in 0pt; TEXT-ALIGN: justify; mso-layout-grid-align: none&quot;&gt;NTDLL.DLL에서 NtXxx의 함수 NtReadFile을 Windbg에서 U 명령어를 통해 disassemble 한 결과는 아래와 같다.&lt;br /&gt;&lt;br /&gt;&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;
&lt;P class=MsoNormal style=&quot;TEXT-JUSTIFY: inter-ideograph; MARGIN: 0in 0in 0pt; TEXT-ALIGN: justify; mso-layout-grid-align: none&quot;&gt;0: kd&amp;gt; u ntdll!NtReadFile&lt;br /&gt;ntdll!NtReadFile:&lt;br /&gt;77f761e8 b8b7000000 &amp;nbsp; &amp;nbsp; &amp;nbsp;mov &amp;nbsp; &amp;nbsp; eax,0xb7&lt;br /&gt;77f761ed ba0003fe7f &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; edx,0x7ffe0300&lt;br /&gt;77f761f2 ffd2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; call &amp;nbsp;&amp;nbsp; edx&lt;br /&gt;77f761f4 c22400 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret &amp;nbsp; &amp;nbsp; 0x24&lt;/P&gt;
&lt;P class=MsoNormal style=&quot;TEXT-JUSTIFY: inter-ideograph; MARGIN: 0in 0in 0pt; TEXT-ALIGN: justify; mso-layout-grid-align: none&quot;&gt;&lt;br /&gt;0: kd&amp;gt; u ntdll!ZwReadFile&lt;br /&gt;ntdll!NtReadFile:&lt;br /&gt;77f761e8 b8b7000000 &amp;nbsp; &amp;nbsp; &amp;nbsp;mov &amp;nbsp; &amp;nbsp; eax,0xb7&lt;br /&gt;77f761ed ba0003fe7f &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; edx,0x7ffe0300&lt;br /&gt;77f761f2 ffd2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; call &amp;nbsp;&amp;nbsp; edx&lt;br /&gt;77f761f4 c22400 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret &amp;nbsp; &amp;nbsp; 0x24 &lt;/P&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal style=&quot;TEXT-JUSTIFY: inter-ideograph; MARGIN: 0in 0in 0pt; TEXT-ALIGN: justify; mso-layout-grid-align: none&quot;&gt;&lt;br /&gt;NtReadFile과 ZwReadFile은 0x77f761e8의 동일주소를 가르킨다.&lt;br /&gt;CALL EDX의 0x7ffe0300의 주소를 ln(list nearest symblos) 명령을 통해 심볼을 본다.&lt;br /&gt;&lt;br /&gt;&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;0: kd&amp;gt; ln 0x7ffe0300(7ffe0300) &amp;nbsp; SharedUserData!SystemCallStub &amp;nbsp;&lt;br /&gt;Exact matches:&lt;br /&gt;&amp;nbsp; &amp;nbsp; SharedUserData!SystemCallStub&lt;br /&gt;&lt;br /&gt;0: kd&amp;gt; u SharedUserData!SystemCallStub&lt;br /&gt;SharedUserData!SystemCallStub:&lt;br /&gt;7ffe0300 8bd4 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; edx,esp&lt;br /&gt;7ffe0302 0f34 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sysenter&lt;br /&gt;7ffe0304 c3 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; ret&lt;/DIV&gt;
&lt;P class=MsoNormal style=&quot;TEXT-JUSTIFY: inter-ideograph; MARGIN: 0in 0in 0pt; TEXT-ALIGN: justify; mso-layout-grid-align: none&quot;&gt;&lt;br /&gt;&lt;br /&gt;SystemCallStub이란 함수에서 SYSENTER(윈도우2000에서는 INT 2Eh)를 호출한다.&lt;br /&gt;&lt;br /&gt;&lt;STRONG&gt;SYSENTER(INTEL document)란?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&amp;nbsp;thread into Kernel Mode and executes the routine pointed to by the &lt;STRONG&gt;SYSENTER_EIP_MSR&lt;/STRONG&gt;, which is MSR 0x176.&lt;/BLOCKQUOTE&gt;
&lt;P&gt;커널로 전환하며 SYSENTER_EIP_MSR 레지스터가 가르키는 포인터 번지를 실행한다. &lt;br /&gt;&lt;br /&gt;rdmsr(read msr, msr은 model specific register) 명령어로 &lt;STRONG&gt;SYSENTER_EIP_MSR&lt;/STRONG&gt;를 살펴보면&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;0: kd&amp;gt; rdmsr 176&lt;br /&gt;msr[176] = 00000000:8053a270&lt;br /&gt;&lt;br /&gt;0: kd&amp;gt; ln 8053a270&lt;br /&gt;(8053a270) &amp;nbsp; nt!KiFastCallEntry &amp;nbsp; |&amp;nbsp; (8053a2fb) &amp;nbsp; nt!KiSystemService&lt;br /&gt;Exact matches:&lt;br /&gt;&amp;nbsp; &amp;nbsp; nt!KiFastCallEntry&lt;br /&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;br /&gt;결국 SYSENTER &lt;STRONG&gt;KiFastCallEntry&lt;/STRONG&gt;를 호출한다는걸 알수있다.&lt;br /&gt;&lt;br /&gt;&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;053a2f9 eb5c jmp &amp;nbsp; &amp;nbsp; nt!KiSystemService+0x5c (8053a357)&lt;/DIV&gt;
&lt;P&gt;KiFastCallEntry의 마지막(?)을 보면 &lt;STRONG&gt;KiSystemService&lt;/STRONG&gt;를 호출한다.&lt;br /&gt;&lt;br /&gt;아래는 OSR에서 제공한 windbg용 확장 DLL을 설치(windbg내 winext폴더에 복사)하여 !osrexts.sst를 사용하여 System Service Descriptor Table의 내용을 살펴보고 실제 주소를 disassemble한 예제이다.&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;0: kd&amp;gt; !osrexts.sst&lt;br /&gt;0: 0x805912c2&amp;nbsp; (nt!NtAcceptConnectPort)&lt;br /&gt;1: 0x805d87b0&amp;nbsp; (nt!NtAccessCheck)&lt;br /&gt;2: 0x805dc3e4&amp;nbsp; (nt!NtAccessCheckAndAuditAlarm)&lt;br /&gt;...&lt;br /&gt;b7: 0x8056b2ec&amp;nbsp; (nt!NtReadFile)&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;0: kd&amp;gt; u nt!NtReadFile&lt;br /&gt;nt!NtReadFile:&lt;br /&gt;8056b2ec 6a58 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;push &amp;nbsp;&amp;nbsp; 0x58&lt;br /&gt;8056b2ee 6858044e80 &amp;nbsp; &amp;nbsp; push &amp;nbsp;&amp;nbsp; 0x804e0458&lt;br /&gt;8056b2f3 e8e09ffcff &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; call &amp;nbsp;&amp;nbsp; nt!_SEH_prolog (805352d8)&lt;br /&gt;8056b2f8 33ff &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; xor &amp;nbsp; &amp;nbsp; edi,edi&lt;br /&gt;8056b2fa 897de4 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; [ebp-0x1c],edi&lt;br /&gt;8056b2fd 897de0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; [ebp-0x20],edi&lt;br /&gt;8056b300 897dd8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; [ebp-0x28],edi&lt;br /&gt;&lt;/DIV&gt;
&lt;H4&gt;요약 &lt;/H4&gt;
&lt;P&gt;User mode에서 &amp;nbsp;&lt;STRONG&gt;NtXxx&lt;/STRONG&gt; , &lt;STRONG&gt;ZwXxx&lt;/STRONG&gt; 호출은 결국 같은 루틴이다.&lt;br /&gt;EAX에 index, EDX에 argument pointer 설정&lt;br /&gt;&lt;STRONG&gt;SystemCallStub&lt;/STRONG&gt;&amp;nbsp;를 호출하여 &lt;STRONG&gt;SYSENTER&lt;/STRONG&gt;&amp;nbsp;호출&lt;br /&gt;&lt;STRONG&gt;SYSENTER&lt;/STRONG&gt; 는 인터럽트 방지하고 커널모드로 thread를 변경&amp;nbsp; &lt;STRONG&gt;SYSENTER_EIP_MSR&lt;/STRONG&gt; (XP SP1에서는 &lt;STRONG&gt;KiFastCallEntry&lt;/STRONG&gt;)를 호출&lt;br /&gt;&lt;STRONG&gt;KiFastCallEntry&lt;/STRONG&gt; 는 새로운 trap frame 형성, 인터럽트 사용가능후 &lt;STRONG&gt;KiSystemService&lt;/STRONG&gt; 호출&lt;br /&gt;&lt;STRONG&gt;KiSystemService&lt;/STRONG&gt; 는 EDX를 통해 파라미터를 전달받고 EAX의 인덱스에 따라 &lt;STRONG&gt;KiServiceTable&lt;/STRONG&gt;[EAX] 함수 호출&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Calling From Kernel Mode&lt;/STRONG&gt;&amp;nbsp;&lt;/H4&gt;
&lt;P&gt;NTOSKRNL.EXE에서 NtXxx의 함수 NtReadFile을 Windbg에서 U 명령어를 통해 disassemble 한 결과는 아래와 같다.&lt;br /&gt;(NTOSKRNL.EXE 모듈의 심볼명은 nt 이다. 이는 CPU 에 따라 NTOSKRNL.EXE의 이름이 변경되지만 심볼명은 nt 하나로 통일하기 위한것이 아닐까 라고 추정 - 이재홍님)&lt;br /&gt;&lt;br /&gt;&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;0: kd&amp;gt; u nt!NtReadFile&lt;br /&gt;nt!NtReadFile:&lt;br /&gt;8056b2ec 6a58 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; push &amp;nbsp;&amp;nbsp; 0x58&lt;br /&gt;8056b2ee 6858044e80 &amp;nbsp; &amp;nbsp; &amp;nbsp; push &amp;nbsp;&amp;nbsp; 0x804e0458&lt;br /&gt;8056b2f3 e8e09ffcff &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; call &amp;nbsp;&amp;nbsp; nt!_SEH_prolog (805352d8)&lt;br /&gt;8056b2f8 33ff &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; xor &amp;nbsp; &amp;nbsp; edi,edi &lt;/DIV&gt;
&lt;P&gt;NtReadFile은 원래 함수라고 보여진다. &lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;&lt;FONT face=arial,helvetica,sans-serif&gt;0: kd&amp;gt; u nt!ZwReadFile&lt;br /&gt;nt!ZwReadFile:&lt;br /&gt;80504d4c b8b7000000 &amp;nbsp; &amp;nbsp; mov &amp;nbsp; &amp;nbsp; eax,0xb7&lt;br /&gt;80504d51 8d542404 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lea &amp;nbsp; &amp;nbsp; edx,[esp+0x4]&lt;br /&gt;80504d55 9c &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; pushfd&lt;br /&gt;80504d56 6a08 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; push &amp;nbsp;&amp;nbsp; 0x8&lt;br /&gt;80504d58 e89e550300 &amp;nbsp; &amp;nbsp; call &amp;nbsp;&amp;nbsp; nt!KiSystemService (8053a2fb)&lt;br /&gt;80504d5d c22400 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret &amp;nbsp; &amp;nbsp; 0x24&lt;/FONT&gt;&lt;/DIV&gt;
&lt;P&gt;ZwReadFile은 이전에 보았던 코드와 유사하다.&lt;br /&gt;EAX에 index 번호 0xb7을 넣고 EDX에 argument pointer를 설정하고 PUSHFD(PUSH EFLAGS)후 &lt;STRONG&gt;KiSystemService&lt;/STRONG&gt; 바로 호출&lt;br /&gt;&lt;br /&gt;KernelMode이기 때문에 KernelMode로 전환하기 위한 SYSENTER와 KiFastCallEntry 생략되었다.&lt;/P&gt;
&lt;P&gt;아래그림은 EFLAGS&lt;IMG class=attachment title=eflags.jpg style=&quot;WIDTH: 710px; HEIGHT: 598px&quot; height=632 alt=eflags.jpg src=&quot;http://hongyver.springnote.com/pages/498435/attachments/228440&quot; width=753&gt;&lt;/P&gt;
&lt;H4&gt;요약 &lt;/H4&gt;
&lt;P&gt;Case A:&lt;br /&gt;Kernel Mode 에서 NtXxx 함수 호출&lt;br /&gt;PreviousMode 변경이 없다. &lt;br /&gt;Case B:&lt;br /&gt;Kernel Mode 에서&amp;nbsp; ZwXxxx 함수 호출 &lt;br /&gt;EAX에 index 번호 0xb7을 넣고 EDX에 argument pointer를 설정하고 PUSHFD(PUSH EFLAGS)후 &lt;STRONG&gt;KiSystemService&lt;/STRONG&gt; 바로 호출&lt;br /&gt;PreviousMode KernelMode로 설정 &lt;br /&gt;CALL KiServiceTable[EAX]&lt;br /&gt;&lt;br /&gt;중요한 차이는 &lt;STRONG&gt;KiSysstemService&lt;/STRONG&gt;를 통한 과정은 previous mode가 커널모드로 설정하는것이다.&lt;br /&gt;Nt를 바로 호출하는게 overhead가 없지만 Zw호출은 previousmode를 변경한다.&lt;/P&gt;
&lt;H4&gt;Previous Mode&lt;/H4&gt;
&lt;P&gt;Previous mode란 시스템이 시스템 서비스를 호출하는 곳의 모드를 결정하기 위한 indicator로 사용된다.&lt;br /&gt;Previous mode가 &amp;nbsp;User mode로 설정되면 시스템 서비스 처리 루틴은 호출은 User mode에서 호출되는것으로 인식하고 루틴으로 전달된 파라미터를 사용하기전에 유효성 검사를 필요로 한다.&lt;br /&gt;하지만 커널모드는 그러한 세밀한 조사를 하지 않고 유효하다고 가정한다. &lt;br /&gt;&lt;br /&gt;Previous Mode를 구하는 API&lt;br /&gt;&lt;/P&gt;
&lt;DIV style=&quot;BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cccccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #e7e7e7&quot;&gt;&amp;nbsp;KPROCESSOR_MODE &amp;nbsp;ExGetPreviousMode( VOID );&lt;/DIV&gt;
&lt;H4&gt;ZwXxx, NtXxx 호출시 실패하는 경우 &amp;nbsp;&lt;/H4&gt;
&lt;P&gt;NtXxx 함수를 직접 호출하면 previous mode를 변경되지 않기때문에 호출된 NtXxx 커널 시스템 서비스 루틴이 previous mode가 user mode로 설정된채 임의 user stack상에서 실행될수 있다. 이러한 호출은 Parameters의 유효성 확인 시도를 알지 못하기 때문에 호출실패가 발생할수 있다.&lt;br /&gt;또다른 문제점은 ProbeForRead, ProbeForWrite를 통해 메모리가 Usermode의 메모리인지를 검사할때 Previous mode가 user mode로 설정된 상태에서 시스템 서비스 NtXxx 함수 호출시 커널모드 버퍼를 인자로 넘겨준다면 STATUS_ACCESS_VIOLATION이 발생할수 있다.&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Sample Code&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;Sample code는 드라이버에서 c: 드라이버에 파일로 로그를 남기는 코드&lt;br /&gt;&lt;STRONG&gt;InitializeObjectAttribute함수를 통해 c: 드라이버에 파일에 대한 핸들생성&lt;/STRONG&gt;&lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : c)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;OL class=code&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=kw1&gt;switch&lt;/SPAN&gt; &lt;SPAN class=br0&gt;(&lt;/SPAN&gt;operation&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=br0&gt;{&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp;&lt;SPAN class=kw1&gt;case&lt;/SPAN&gt; IOCTL_OSR_ENABLE_LOGGING:&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw1&gt;if&lt;/SPAN&gt; &lt;SPAN class=br0&gt;(&lt;/SPAN&gt;!devExt-&amp;gt;LoggingEnabled&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=br0&gt;{&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;RtlInitUnicodeString&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;&amp;amp;logFileName, OSRNTAPI_LOGFILE&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co2&gt;#ifdef USER_HANDLE&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;InitializeObjectAttributes&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;&amp;amp;oa, &amp;amp;logFileName, OBJ_CASE_INSENSITIVE,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;, &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co2&gt;#else&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;InitializeObjectAttributes&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;&amp;amp;oa, &amp;amp;logFileName,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;, &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co2&gt;#endif&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;code = ZwCreateFile&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;&amp;amp;devExt-&amp;gt;LogFileHandle,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; GENERIC_WRITE | SYNCHRONIZE,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;amp;oa, &amp;amp;iosb, …&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;위의 예제에서 볼수 있듯이 핸들의 2가지가 생성될수 있다.&lt;br /&gt;&lt;br /&gt;첫번째는 User mode 상에서 생성된 핸들(같은 프로세스의 context상에서만 접근가능, 다른 프로세스 접근 불가능)과 OBJ_KERNEL_HANDLE의 옵션을 주고 생성한 커널핸들(모든 프로세스, 드라이버에서 접근가능)이 있다. &lt;br /&gt;&lt;STRONG&gt;&lt;br /&gt;응용프로그램에서 ReadFile 호출&lt;/STRONG&gt;&lt;br /&gt;드라이버 IRP_MJ_READ dispatch 함수, 드라이버에서 log write 시도&lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : c)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;OL class=code&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;PreviousMode = UserMode&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;code = NtWriteFile&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;devExt-&amp;gt;LogFileHandle,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;amp;iosb,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=br0&gt;(&lt;/SPAN&gt;PVOID&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;&lt;SPAN class=st0&gt;&quot;OsrRead: NtWriteFile&lt;SPAN class=es0&gt;\r&lt;/SPAN&gt;&lt;SPAN class=es0&gt;\n&lt;/SPAN&gt;&quot;&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; strlen&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;&lt;SPAN class=st0&gt;&quot;OsrRead: NtWriteFile&lt;SPAN class=es0&gt;\r&lt;/SPAN&gt;&lt;SPAN class=es0&gt;\n&lt;/SPAN&gt;&quot;&lt;/SPAN&gt;&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co2&gt;#ifdef USER_HANDLE&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp;ASSERT&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;code == STATUS_ACCESS_VIOLATION&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co2&gt;#else&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co1&gt;// OBJ_KERNEL_HANDLE&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp;ASSERT&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;code == STATUS_INVALID_HANDLE&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&lt;SPAN class=co2&gt;#endif&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;&lt;STRONG&gt;NtWriteFile 호출의 경우&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;#ifdef USER_HANDLE 정의시 (OBJ_KERNEL_HANDLE를 사용하지 않았을경우)&lt;/STRONG&gt;&lt;STRONG&gt;STATUS_ACCESS_VIOLATION&lt;/STRONG&gt; 에러발생&lt;br /&gt;넘겨진 파라미터는 커널버퍼이지만 PreviousMode가 User 이므로 ProbeForRead/Write 를 통해 유효성 검사에서 실패하여 발생&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;#ifdef USER_HANDLE 미정의시(OBJ_KERNEL_HANDLE를 사용했을경우)&lt;/STRONG&gt;&lt;STRONG&gt;STATUS_INVALID_HANDLE&lt;/STRONG&gt; 에러발생&lt;br /&gt;핸들생성시 커널핸들로 생성했지만 PreviousMode가 User 이므로 User모드 핸들에서는 커널핸들을 참조(찾을수 없다)할수없어 invalid 한 핸들에러 발생 &lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : c)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;OL class=code&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;PreviousMode = KernelMode &lt;SPAN class=br0&gt;(&lt;/SPAN&gt;KiSystemService에서 change&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;code = ZwWriteFile&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;devExt-&amp;gt;LogFileHandle,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;, &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;, &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;amp;iosb,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;PVOID&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;&lt;SPAN class=st0&gt;&quot;OsrRead: ZwWriteFile&lt;SPAN class=es0&gt;\r&lt;/SPAN&gt;&lt;SPAN class=es0&gt;\n&lt;/SPAN&gt;&quot;&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;strlen&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;&lt;SPAN class=st0&gt;&quot;OsrRead: ZwWriteFile&lt;SPAN class=es0&gt;\r&lt;/SPAN&gt;&lt;SPAN class=es0&gt;\n&lt;/SPAN&gt;&quot;&lt;/SPAN&gt;&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;,&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;, &lt;SPAN class=kw2&gt;NULL&lt;/SPAN&gt;&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI class=li1&gt;
&lt;DIV class=de1&gt;ASSERT&lt;SPAN class=br0&gt;(&lt;/SPAN&gt;code == STATUS_SUCCESS&lt;SPAN class=br0&gt;)&lt;/SPAN&gt;;&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;&lt;STRONG&gt;ZwWriteFile 호출의 경우&lt;br /&gt;&lt;/STRONG&gt;어떤 경우에서도 성공&lt;/P&gt;
&lt;H4&gt;Conclusion &amp;nbsp;&lt;/H4&gt;
&lt;P&gt;User mode에서는 어떤것을 사용하여도 무방하나 kernel mode에서는 ZwXxx를 사용하여 previous mode가 커널로 설정되어 유효성 검사를 거쳐 시스템 서비스 함수들이 호출되도록 하여야 한다.&lt;/P&gt;
&lt;H4&gt;ETC &lt;/H4&gt;
&lt;P&gt;MSDN에 따르면 Zw로 시작하는 해당함수를 호출한 프로세스의 대한 접근권한 체크를 하지 않습니다.&lt;br /&gt;&lt;A href=&quot;http://msdn2.microsoft.com/en-us/library/ms804352.aspx&quot;&gt;&lt;SPAN style=&quot;COLOR: #800080&quot;&gt;http://msdn2.microsoft.com/en-us/library/ms804352.aspx&lt;/SPAN&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P align=right&gt;이 글은 &lt;A href=&quot;http://hongyver.springnote.com/pages/498435&quot;&gt;스프링노트&lt;/A&gt;에서 작성되었습니다.&lt;/P&gt;</description>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/765</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/Nt-vs-Zw-Clearing-confusion-on-the-Native-API#entry765comment</comments>
			<pubDate>Tue, 16 Oct 2007 14:16:09 +0900</pubDate>
		</item>
		<item>
			<title>NativeAPI flowchart</title>
			<link>http://hongyver.pe.kr/ttblog/entry/NativeAPI-flowchart</link>
			<description>&lt;P&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://hongyver.pe.kr/ttblog/attach/1/1063480852.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;614&quot; width=&quot;600&quot; /&gt;&lt;/div&gt; &lt;/P&gt;
&lt;br /&gt;</description>
			<category>nativeapi</category>
			<category>ntxxx</category>
			<category>zwxxx</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/764</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/NativeAPI-flowchart#entry764comment</comments>
			<pubDate>Wed, 10 Oct 2007 09:42:26 +0900</pubDate>
		</item>
		<item>
			<title>Doxygen 주석 작성을 위한 빠른보기</title>
			<link>http://hongyver.pe.kr/ttblog/entry/Doxygen-%EC%A3%BC%EC%84%9D-%EC%9E%91%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-%EB%B9%A0%EB%A5%B8%EB%B3%B4%EA%B8%B0</link>
			<description>&lt;H4&gt;MainPage&lt;/H4&gt;
&lt;P&gt;생성된 doc의 처음 화면이다.&lt;br /&gt;보통 프로젝트 첫 화면이므로 전체 프로젝트에 한군데만 써 넣는다.&lt;/P&gt;
&lt;P&gt;/// @mainpage &amp;nbsp; doxygen 테스트 예제용 메인페이지&lt;br /&gt;/// @section intro 소개&lt;br /&gt;/// - 소개 &amp;nbsp; &amp;nbsp;&amp;nbsp; : &amp;nbsp; doxygen 을 사용하는 방법 설명&lt;br /&gt;/// @section Program 프로그램명&lt;br /&gt;/// - 프로그램명&amp;nbsp; : &amp;nbsp; doxygen test sample&lt;br /&gt;/// - 프로그램내용 &amp;nbsp;&amp;nbsp; : &amp;nbsp; 화면에 Hello World!을 출력한다.&lt;br /&gt;/// @section CREATEINFO 작성정보&lt;br /&gt;/// - 작성자 &amp;nbsp; &amp;nbsp;&amp;nbsp; : &amp;nbsp; infiniterun&lt;br /&gt;/// - 작성일 &amp;nbsp; &amp;nbsp;&amp;nbsp; : &amp;nbsp; 2005/04/18&lt;br /&gt;/// @section MODIFYINFO 수정정보&lt;br /&gt;/// - 수정자/수정일 &amp;nbsp; : 수정내역&lt;br /&gt;/// - infiniterun/2005.0418 &amp;nbsp;&amp;nbsp; : &amp;nbsp; &quot;Helo World&quot;에 &quot;!&quot;추가&lt;/P&gt;
&lt;H4&gt;파일&lt;/H4&gt;
&lt;P&gt;파일에 대한 설명이므로 파일의 맨처음 부분에 넣는다.&lt;/P&gt;
&lt;P&gt;/// @file &amp;nbsp; &amp;nbsp; doxygentest.c&lt;br /&gt;/// @brief &amp;nbsp;&amp;nbsp; doxygentest&amp;nbsp; 소스파일.&lt;/P&gt;
&lt;H4&gt;함수&lt;/H4&gt;
&lt;P&gt;함수의 기능과 리턴값을 설명하도록 한다.&lt;br /&gt;보통 간단하게 아래와 같이 작성한다.&lt;/P&gt;
&lt;P&gt;/// @brief string의 조사하여 babo라는 문구가 있는 찾는 함수&lt;br /&gt;/// @param char* str char*형의 string을 입력한다.&lt;br /&gt;/// @return boolean의 성공여부 , true이면 성공&lt;br /&gt;&lt;br /&gt;필요에 따라 다음의 기능도 있다.&lt;br /&gt;&lt;br /&gt;@author: 작성자 표시를 합니다.&lt;br /&gt;@date: 작성일등의 날짜 표시를 합니다. 직접 기술 해야 합니다.&lt;br /&gt;@see: 참고하는 함수/클래스등의 표시로 해당 항목(doxygen에서 존재하는)의 링크를 제공합니다.&lt;br /&gt;@return: 함수의 리턴값에 대한 설명&lt;br /&gt;@exception: exception처리에 대한 설명&lt;br /&gt;@throw: throw하는 객체나 변수등에 대한 설명&lt;br /&gt;@version; 버전설명&lt;br /&gt;@warning: 경고&lt;br /&gt;@bug: 버그에 대한 기술, 전체 항목의 @bug에 대해서 따로 리스트가 생성됩니다.&lt;br /&gt;@todo: 해야할일들에 대한 기술, 전체 항목의 @todo에 대한 리스트가 생성됩니다.&lt;br /&gt;@param: 함수의 파라미터 대한 정보를 기술 합니다.&lt;/P&gt;
&lt;P&gt;파라미터에 대한 설명은 아래와 같이 입력할수도 있다.&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=line&gt;int main(&lt;/SPAN&gt; &lt;SPAN class=line&gt;int &amp;nbsp;&amp;nbsp; argc, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; ///&amp;lt; 인자개수&lt;br /&gt;&lt;/SPAN&gt;&lt;SPAN class=line&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; char * argv[] )&amp;nbsp; &amp;nbsp; ///&amp;lt; 인자&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4&gt;Class, 구조체, 변수&lt;/H4&gt;
&lt;P&gt;가급적 class, 구조체, 변수(global변수)의 상단에 설명을 작성한다.&lt;br /&gt;/// 무엇을 하는 class, 구조체, 변수이다.&lt;br /&gt;&lt;br /&gt;class와 구조체는 아래와 같이도 작성할수 있다.&lt;br /&gt;/// @class 클래스 설명&lt;br /&gt;/// @struct&lt;br /&gt;/// 구조체 설명&lt;br /&gt;&lt;br /&gt;@brief 를 사용하여 설명을 작성할수도 있다.&lt;br /&gt;변수명의 경우 상단에 작성을 하지않고 변수명과 같은라인에서 작성하고 ///&amp;lt; 로도 설명을 작성할수 있다.&lt;br /&gt;int a; ///&amp;lt; 임의의 값&lt;/P&gt;
&lt;P&gt;단 함수내부에 있는 변수들에 대한 설명은 작성할수 없다.&lt;br /&gt;&lt;/P&gt;
&lt;H4&gt;태그사용&lt;/H4&gt;
&lt;P&gt;목록을 위한 점 표시&lt;br /&gt;/// - 원하는 내용&lt;/P&gt;
&lt;P&gt;강조를 위한 굵은글씨&lt;br /&gt;/// &amp;lt;b&amp;gt; 원하는 내용&amp;lt;/b&amp;gt;&lt;/P&gt;
&lt;P&gt;원하는 내용, 코드를 그대로 출력&lt;br /&gt;/// &amp;lt;pre&amp;gt;&lt;br /&gt;/// 원하는 내용&lt;br /&gt;/// &amp;lt;/pre&amp;gt;&lt;/P&gt;
&lt;H4&gt;Link&lt;/H4&gt;
&lt;P&gt;KLDP의 doxygen 강좌 - 설치,사용&lt;br /&gt;&lt;A href=&quot;http://wiki.kldp.org/wiki.php/Doxygen&quot;&gt;http://wiki.kldp.org/wiki.php/Doxygen&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;Doxygen wiki - 그래프 및 스타일시트 변경&lt;br /&gt;&lt;A class=external title=&quot; http://www.pie.pe.kr/cgi-bin/moin.cgi/Doxygen&quot; href=&quot;http://www.pie.pe.kr/cgi-bin/moin.cgi/Doxygen&quot;&gt;http://www.pie.pe.kr/cgi-bin/moin.cgi/Doxygen&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;Doxygen 문법 및 option 설정&lt;br /&gt;&lt;A class=external title=&quot; http://wiki.rabidus.net/ow.asp?Doxygen&quot; href=&quot;http://wiki.rabidus.net/ow.asp?Doxygen&quot;&gt;http://wiki.rabidus.net/ow.asp?Doxygen&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;Doxygend의 Link 페이지 정리&lt;br /&gt;&lt;A href=&quot;http://cse.kangnam.ac.kr/board/content.asp?idx=6291&amp;amp;GotoPage=5&amp;amp;table=bbs_free&quot;&gt;http://cse.kangnam.ac.kr/board/content.asp?idx=6291&amp;amp;GotoPage=5&amp;amp;table=bbs_free&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;Doxygen 홈페이지&lt;br /&gt;&lt;A href=&quot;http://www.doxygen.org/&quot; target=_blank&gt;http://www.doxygen.org/&lt;/A&gt;&lt;br /&gt;&lt;/P&gt;
&lt;P align=right&gt;이 글은 &lt;A href=&quot;http://hongyver.springnote.com/&quot;&gt;스프링노트&lt;/A&gt;에서 작성되었습니다.&lt;/P&gt;</description>
			<category>doxygen</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/763</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/Doxygen-%EC%A3%BC%EC%84%9D-%EC%9E%91%EC%84%B1%EC%9D%84-%EC%9C%84%ED%95%9C-%EB%B9%A0%EB%A5%B8%EB%B3%B4%EA%B8%B0#entry763comment</comments>
			<pubDate>Thu,  9 Aug 2007 11:31:48 +0900</pubDate>
		</item>
		<item>
			<title>DDKBUILD.CMD로 DDK빌드시 SOURCES 옵션</title>
			<link>http://hongyver.pe.kr/ttblog/entry/ddkbuild-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98</link>
			<description>&lt;P&gt;지난 포스팅에 &lt;A href=&quot;http://hongyver.pe.kr/ttblog/entry/비주얼스튜디오에서-DDK-build를&quot; target=_blank&gt;DDKBUILD.CMD&lt;/A&gt;를 통해 비주얼 스튜디오에서 드라이버 빌드를 하고 있는데...&lt;br /&gt;사용하다 불편한게 있어서 몇가지 알아내 SOURCES의 옵셥설정.&lt;br /&gt;&lt;br /&gt;&lt;STRONG&gt;MAP파일 생성하고 싶을때&lt;br /&gt;&lt;/STRONG&gt;&lt;br /&gt;SOURCES 파일에 아래 삽입&lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : text)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;DIV class=code&gt;LINKER_FLAGS=/MAP &lt;/DIV&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;&lt;STRONG&gt;&lt;br /&gt;빌드후 추가작업을 하고 싶을때(예제는 Post-build step 기능)&lt;/STRONG&gt;&lt;br /&gt;&lt;br /&gt;SOURCES 파일아래에 아래 삽입&lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : text)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;DIV class=code&gt;NTTARGETFILES=postbuild&lt;/DIV&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;makefile.inc 파일아래에 아래코드 삽입(생성된 파일복사하는 예제)&lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : text)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;DIV class=code&gt;postbuild:&lt;br /&gt;!if &quot;$(DDKBUILDENV)&quot; == &quot;chk&quot;&lt;br /&gt;&amp;nbsp; md ..\$(OUTDIR)&lt;br /&gt;&amp;nbsp; copy $(TARGET) ..\$(OUTDIR)\$(TARGETNAME).sys /Y /B&lt;br /&gt;!else&lt;br /&gt;&amp;nbsp; set&lt;br /&gt;&amp;nbsp; md ..\$(OUTDIR)&lt;br /&gt;&amp;nbsp; copy $(TARGET) ..\$(OUTDIR)\$(TARGETNAME).sys /Y /B&lt;br /&gt;!endif&lt;/DIV&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;&lt;STRONG&gt;Go To Definition 을 사용가능하게 하려면&lt;div class=&quot;imageblock right&quot; style=&quot;float: right; margin-left: 10px;&quot;&gt;&lt;img src=&quot;http://hongyver.pe.kr/ttblog/attach/1/1400465977.jpg&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;200&quot; width=&quot;159&quot; /&gt;&lt;/div&gt;(F12 또는 마우스 우클릭)&lt;/STRONG&gt;&lt;br /&gt;&lt;br /&gt;SOURCES 파일에 아래 코드 삽입&lt;/P&gt;
&lt;FIELDSET class=&quot;geshi r2&quot;&gt;&lt;LEGEND&gt;&lt;SPAN class=g_lang style=&quot;COLOR: #aaa&quot;&gt;(Language : text)&lt;/SPAN&gt;&lt;/LEGEND&gt;
&lt;DIV class=code&gt;BROWSER_INFO=1 &lt;br /&gt;BROWSERFILE=$(TARGETNAME).bsc -n &amp;nbsp;&lt;/DIV&gt;&lt;/FIELDSET&gt; 
&lt;P&gt;단 Project Setting에서 Browse info file name에 TARGETNAME과 확장자 .bsc가 있는지 확인하고 없으면 써준다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/P&gt;</description>
			<category>ddkbuild</category>
			<category>makefiel.inc</category>
			<category>postbuilds</category>
			<author>(hongyver)</author>
			<guid>http://hongyver.pe.kr/ttblog/762</guid>
			<comments>http://hongyver.pe.kr/ttblog/entry/ddkbuild-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98#entry762comment</comments>
			<pubDate>Thu, 21 Jun 2007 09:40:21 +0900</pubDate>
		</item>
	</channel>
</rss>
