<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Ishai's WebLog</title><subtitle type="html" /><id>http://blogs.msdn.com/ishai/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/ishai/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2004-06-08T20:53:00Z</updated><entry><title>Update on Virtual PC and profiling</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2005/01/14/353392.aspx" /><id>http://blogs.msdn.com/ishai/archive/2005/01/14/353392.aspx</id><published>2005-01-15T00:59:00Z</published><updated>2005-01-15T00:59:00Z</updated><content type="html">&lt;p&gt;Last year, Richard&amp;nbsp;&lt;A href="http://blogs.msdn.com/angryrichard/archive/2004/08/06/210178.aspx"&gt;explained&amp;nbsp;&lt;/a&gt; why sampling does not work on &lt;a href="http://www.microsoft.com/windows/virtualpc/default.mspx"&gt;Virtual PC&lt;/a&gt;.&amp;nbsp;&amp;nbsp; Since the sampling failure is quite catastrophic, we blocked all profiling on Virtual PC. &lt;/p&gt; &lt;p&gt;Some &lt;a href="http://lab.msdn.microsoft.com/vs2005/"&gt;Beta&lt;/a&gt; users noticed that we block profiling also for instrumentation-based profiling. If you are one of these people, I have good news and bad news for you.&lt;/p&gt; &lt;p&gt;The good news is that we will enable profiling instrumented applications on a Virtual PC. [Disclaimer: I am writing here about a product that is not yet released so this is not final]&lt;/p&gt; &lt;p&gt;The bad new is that this may not be a good idea to do that. The performance characteristics on a virtual machine can be different from a real machine. For example, I/O on a virtual machine takes longer as it virtualized. Virtual PC emulates a single, non-hyper threaded CPU. If your application is going to be deployed on a multi-processor server, you’d better profile on such environment and not on a single-CPU machine.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=353392" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="Software development" scheme="http://blogs.msdn.com/ishai/archive/tags/Software+development/default.aspx" /></entry><entry><title>Bugs that hide from debuggers</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/10/25/247471.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/10/25/247471.aspx</id><published>2004-10-25T23:11:00Z</published><updated>2004-10-25T23:11:00Z</updated><content type="html">&lt;p&gt;Sometimes running a program under a debugger makes it work. &amp;nbsp;&amp;nbsp;Running the same program without a debugger causes a failure or a crash. &amp;nbsp;&amp;nbsp;Here are some reasons why this can happen:&lt;/p&gt; &lt;p&gt;1.&amp;nbsp;&amp;nbsp; &lt;strong&gt;Timing &lt;/strong&gt;- attaching a debugging changes timing and can hide race conditions. &amp;nbsp;&amp;nbsp;Even without single-stepping and without using breakpoints, the debugger is affecting timing as it receives notifications from the operating system for every exception thrown,&amp;nbsp; creation of threads, loading dlls, etc. &amp;nbsp;&lt;/p&gt; &lt;p&gt;2.&amp;nbsp; &lt;strong&gt;Debug heaps&lt;/strong&gt; – when running under a debugger, the operating system automatically enables heap validation. &amp;nbsp;&amp;nbsp;This can help finding some types of heap corruption bugs, but sometimes have the opposite effect of hiding a race condition or use of already-free-memory on the heap. &amp;nbsp;&amp;nbsp;&amp;nbsp;This side effect can be avoided by using the –hd parameter (windows debugger) or by launching the process outside the debugger and attaching later.&amp;nbsp; You can get a similar effect on a process by using &lt;a href="http://www.microsoft.com/resources/documentation/WindowsServ/2003/all/techref/en-us/Default.asp?url=/Resources/Documentation/windowsserv/2003/all/techref/en-us/gflags_flags.asp"&gt;GFlags&lt;/a&gt;.&amp;nbsp; I’m not sure exactly which flags are enabled by the debugger, the following are likely candidates: &amp;nbsp;FLG_HEAP_ENABLE_FREE_CHECK, FLG_HEAP_VALIDATE_PARAMETERS, FLG_HEAP_ENABLE_TAIL_CHECK.&amp;nbsp; &amp;nbsp;&lt;/p&gt; &lt;p&gt;3.&amp;nbsp; &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/authorization_constants.asp"&gt;&lt;strong&gt;SeDebugPrivilege&lt;/strong&gt;&lt;/a&gt; – &amp;nbsp;The debugger enables SeDebugPrivilege in its process token. &amp;nbsp;&amp;nbsp;A debugger may need this privilege if it needs to open a process that belongs to a different user. &amp;nbsp;When a debugger creates a child process, that process inherits the privilege. &amp;nbsp;&amp;nbsp;Usually, even if you run as administrator, this privilege is disabled by default and needs to be explicitly enabled for the process.&amp;nbsp;&amp;nbsp;&amp;nbsp;When your process is launched by the debugger it has access&amp;nbsp;to some objects that it would otherwise fail to access.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=247471" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="Software development" scheme="http://blogs.msdn.com/ishai/archive/tags/Software+development/default.aspx" /></entry><entry><title>x64 calling convention and the disappearing process syndrome</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/08/24/219697.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/08/24/219697.aspx</id><published>2004-08-24T19:51:00Z</published><updated>2004-08-24T19:51:00Z</updated><content type="html">&lt;p&gt;&lt;A href="http://blogs.msdn.com/oldnewthing"&gt;Raymond Chen&lt;/a&gt; describes the parameter passing aspect of the &lt;A href="http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx"&gt;x64 calling convetions&lt;/a&gt;.&amp;nbsp;&amp;nbsp; But there is more than parameter passing to the calling convention.&amp;nbsp;&amp;nbsp; &lt;a href="http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_001864bc-0ea9-4257-aaf5-18af50ed020a.xml.asp"&gt;Exception handling&lt;/a&gt; is an important part of the calling convention.&lt;/p&gt; &lt;p&gt;A function that calls another function or needs to allocate stack space or requires exception handling (e.g. has a try statement) must have a prolog and an epilog.&amp;nbsp; It also has to have an entry in a special function-table.&amp;nbsp;&amp;nbsp; The function table includes unwind information – information that enables the exception-handling routings to unwind the stack and undo the effect of the function prolog.&amp;nbsp;&amp;nbsp;&amp;nbsp; In order for exception handling to work, there are limitations on function &lt;a href="http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_e171501e-f1e4-4939-9532-05464b0b8e77.xml.asp"&gt;prolog&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_82bc85c4-d247-4f57-b3d3-0f714f05ff26.xml.asp"&gt;epilog&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The fun begins when a function does not have correct unwind information.&amp;nbsp; If in addition to that, there is no debugger attached to the process, the system notifies the Win32 sub-system about the exception.&amp;nbsp;&amp;nbsp; The Win32 sub-system will simply kill the process. You will not see any Watson or JIT debugger dialog box.&amp;nbsp;&amp;nbsp; The process will just&amp;nbsp;disappear.&lt;/p&gt; &lt;p&gt;This happened to me last week.&amp;nbsp; I had an assembly thunk function that called some C++ code that had a race condition (which seems to happen only when a debugger is not attached).&amp;nbsp;&amp;nbsp; Debugging would have been much easier if I did not have an assembly thunk that did not play by the rules and did not have a function-table entry.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=219697" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="Software development" scheme="http://blogs.msdn.com/ishai/archive/tags/Software+development/default.aspx" /></entry><entry><title>Why doesn’t sampling show the actual time spent in each function?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/08/11/212824.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/08/11/212824.aspx</id><published>2004-08-11T17:46:00Z</published><updated>2004-08-11T17:46:00Z</updated><content type="html">&lt;p&gt;Some people have asked for a “wall clock time” column in the sampling &lt;A href="http://blogs.msdn.com/profiler"&gt;profiler &lt;/a&gt;report.&amp;nbsp;&amp;nbsp; Unfortunately, the actual time spent in a function cannot be reliably deduced from the collected data.&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;Sampling counts “hits” on a function when a certain event occurs.&amp;nbsp; By default, this event is a CPU cycle counter counting N cycles, but you can also sample based on the Nth page fault, the Nth system call. &amp;nbsp; &lt;p&gt;&lt;/p&gt;When an event occurs, if the CPU happens to be running in a process that is being sampled, &lt;b&gt;and&lt;/b&gt; is running user-mode code, this will count as a hit on the current function and every function above it on the stack.&amp;nbsp;&amp;nbsp;&amp;nbsp; The hit on the current function is counted as &lt;A href="http://blogs.msdn.com/profiler/archive/2004/06/09/152023.aspx"&gt;exclusive&lt;/a&gt;; the hit on the callers is counted as &lt;A href="http://blogs.msdn.com/profiler/archive/2004/06/09/152023.aspx"&gt;inclusive&lt;/a&gt;. &amp;nbsp; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Because of this, the number of hits does not represent the wall clock time spent in the function.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; A function that is blocked waiting on a resource, waiting for a different process (e.g. calling a remote process), or just calling an expensive system call, may get a number of hits that is not proportional to the time spent in the function. &lt;/p&gt;&lt;/span&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=212824" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="Software development" scheme="http://blogs.msdn.com/ishai/archive/tags/Software+development/default.aspx" /></entry><entry><title>There are no Safe Functions – only Safe Programming</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/07/20/189317.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/07/20/189317.aspx</id><published>2004-07-20T23:27:00Z</published><updated>2004-07-20T23:27:00Z</updated><content type="html">&lt;p&gt;The Platform SDK includes a set of string manipulation functions defined in &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/strings/usingstrsafefunctions.asp"&gt;strsafe.h&lt;/a&gt;.&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;These functions were added during the &lt;a href="http://www.microsoft.com/windowsserver2003/evaluation/overview/strategy/secpush.mspx"&gt;Windows Security push&lt;/a&gt;.&lt;span&gt;&amp;nbsp; &lt;/span&gt;The functions offer an alternative to the C run-time string functions which is more consistent, and less error-prone than the C standard functions.&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;But in order for the functions to actually be safe, they still must be used correctly.&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Wrongly used these functions are as unsafe as the old C runtime functions. &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;In order to use the functions safely the following must be true:&lt;/p&gt; &lt;ol type="1"&gt; &lt;li&gt;The first parameter is a pointer to a memory buffer, &lt;li&gt;The second parameter is the size of the buffer in&amp;nbsp;bytes if when the function name begins with StringCb.&lt;span&gt;&amp;nbsp; &lt;/span&gt;The second parameter is the size of the buffer in&amp;nbsp;chars if when function name begins with StringCch &lt;li&gt;The return code of the function is checked for errors&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;So when I see something like:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;font face="Courier New"&gt; &lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font face="Courier New"&gt;StringCbCopy(Foo, 2, “\\“);&lt;/font&gt; &lt;p&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;It immediately raises a red flag for me.&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Unless 2 happens to be the number of bytes in Foo, this is not a safe use of the function!&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;The second parameter here is not the number of bytes remaining in the buffer but rather the number of bytes needed from the second string.&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Usually, code like this is the results of someone who just converted the code from strncpy to StringCbCopy without making the necessary changes to actually benefit from the new API.&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Now consider the following code: &lt;/p&gt; &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;char FileName[MAX_PATH];&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;…&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;StringCbCopy(FileName, MAX_PATH, DirectoryName);&lt;/font&gt; &lt;p&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;Is this usage a safe use of the function?&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Only if you will never try to convert the file name and directory name to wide char. &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Although for a char, count of chars and count of bytes have the same numeric value, in this case MAX_PATH is a count of chars so either of the following would be better:&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;// Use Count of Chars&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;StringCChCopy(FileName, MAX_PATH, DirectoryName);&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;// Use a count of bytes &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;span&gt;&lt;font face="Courier New"&gt;StringCbCopy(FileName, sizeof(FileName), DirectoryName);&lt;/font&gt; &lt;p&gt;&lt;/p&gt;&lt;/span&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Each of the String APIs supports an Ex version that has output parameters returning a pointer to the terminating null at the end of the target string, and the remaining chars/bytes in the buffer.&lt;span&gt;&amp;nbsp; &lt;/span&gt;The Ex versions provide an alternative to doing the pointer arithmetic yourself which is error prone and dangerous.&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Program safely.&lt;/p&gt; &lt;p&gt;[edited 8-13-04]&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=189317" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="Software development" scheme="http://blogs.msdn.com/ishai/archive/tags/Software+development/default.aspx" /></entry><entry><title>ISA Server 2004</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/07/14/183153.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/07/14/183153.aspx</id><published>2004-07-14T17:18:00Z</published><updated>2004-07-14T17:18:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://www.microsoft.com/isaserver/"&gt;ISA Server 2004&lt;/A&gt;&amp;nbsp;is now available.&amp;nbsp;&amp;nbsp;&amp;nbsp; Lots of&amp;nbsp;&lt;A href="http://www.microsoft.com/isaserver/evaluation/whatsnew.asp"&gt;new and improved &lt;/A&gt;features.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=183153" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="ISA Server" scheme="http://blogs.msdn.com/ishai/archive/tags/ISA+Server/default.aspx" /></entry><entry><title>Why does the compiler generate a MOV  EDI, EDI instruction at the beginning of functions?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/06/24/165143.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/06/24/165143.aspx</id><published>2004-06-24T20:57:00Z</published><updated>2004-06-24T20:57:00Z</updated><content type="html">&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Why does the compiler generate a MOV&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;EDI, EDI instruction at the beginning of functions?&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;I&amp;#8217;ve recently noticed that on the XPSP2 Beta that I am running the function prologs look like this:&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MOV&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;EDI, EDI&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;PUSH&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;EBP&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;MOV&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;EBP, ESP&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The PUSH &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;EBP and MOV EBP, ESP instructions are standard frame establishment, but what is the purpose of the MOV EDI,EDI instruction? &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;Seems like a 2-byte NOP instruction.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;MOV EDI,EDI is indeed a 2-byte no-op that is there to enable hot-patching. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;It enables the application of a hot-fix to a function without a need for a reboot, or even a restart of a running application. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;Instead, at runtime, the 2-byte NOP is replaced by a short jump to a long jump instruction that jumps to the hot-fix function. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;A 2-byte instruction is required so that when patching the instruction pointer will not point in a middle of an instruction.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=165143" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author></entry><entry><title>Battered fries are considered “fresh vegetables”!?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/06/16/157298.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/06/16/157298.aspx</id><published>2004-06-16T17:24:00Z</published><updated>2004-06-16T17:24:00Z</updated><content type="html">Well, probably not by nutritionists, but the USDA, backed by a court decision says they are. (Above link will probably expire in few days). [typo corrected 15:00]...(&lt;a href="http://blogs.msdn.com/ishai/archive/2004/06/16/157298.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=157298" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author></entry><entry><title>Developing firewall and NAT friendly network applications</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ishai/archive/2004/06/08/151418.aspx" /><id>http://blogs.msdn.com/ishai/archive/2004/06/08/151418.aspx</id><published>2004-06-09T03:53:00Z</published><updated>2004-06-09T03:53:00Z</updated><content type="html">&lt;P&gt;Developing firewall and NAT friendly network applications&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;When I worked on &lt;A href="http://www.microsoft.com/isaserver/"&gt;ISA Server&lt;/A&gt; I've seen network applications that were incompatible with firewalls and NAT and were difficult or impossible to configure the firewall for, even when the firewall administrator wanted the application to pass through. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Below are some design considerations that can help make network applications more &amp;#8220;firewall/NAT friendly&amp;#8221;.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;For a client-server application that has request-reply semantics, the obvious choice would probably be to use HTTP since it is so commonly available. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Be warned that it is not a good idea to use port 80 for traffic which is not HTTP. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;While port 80 is usually open in firewalls, content is often inspected for validity or transparently redirected to proxy servers for caching purpose so using port 80 for a protocol which is not HTTP is not a good idea. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Things get more complicated if both the hosts that need to communicate could both be behind a NAT device or a firewall.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;From the firewall administrator point of view (and the end user who needs to request the administrator to open ports), it is better to have outbound connections than an inbound connection, and a fixed port is better than a port range. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;It is even better if you do not need to open any new port at all for that matter.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Again, be warned against overloading a well-known port with traffic that does not conform to the standard.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;I once encountered a P2P application that tried to use port 21 (assigned to &lt;A href="http://www.faqs.org/rfcs/rfc959.html"&gt;FTP&lt;/A&gt;). &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="http://www.microsoft.com/isaserver/"&gt;ISA Server&lt;/A&gt; blocked this application because it knows how to filter FTP and this P2P application was definitely not FTP.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Now if you absolutely have to receive inbound connections to your client application, here are few rules to consider&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;1. Have plan B ready.&lt;/B&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Firewall and routers from different vendors will behave differently, some will work, some will not. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Even with same vendor some will have stricter policy which will not allow inbound connections at all. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Plan for a fall-back to outbound connection or different protocol.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;2.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;gethostbyname() on the local machine does not return &lt;I&gt;the&lt;/I&gt; address for the local machine&lt;/B&gt;. &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;What this API returns is a &lt;I&gt;list&lt;/I&gt; of addresses. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;If the machine happens to have a single NIC you get the address. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;If the machine is multi-homed (as would be the case if the machine is used for &lt;A href="http://www.microsoft.com/windowsxp/pro/using/howto/networking/ics.asp"&gt;sharing Internet connections&lt;/A&gt;) then you get a list of addresses. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The first address on the list could be the internal private address that is not accessible from the outside world.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;So how do you get this address?&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;If you already have a connection with the other host, or with a host that is accessible to both, you can use getsockname() on that socket. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;If the client is behind an &lt;A href="http://www.microsoft.com/isaserver/"&gt;ISA Server&lt;/A&gt; and using &lt;A href="http://www.microsoft.com/resources/documentation/isa/2000/enterprise/proddocs/en-us/isadocs/m_p_p_enablewinsockapp.mspx"&gt;ISA Firewall Client&lt;/A&gt;, using this method will retrieve the &amp;#8220;external&amp;#8221; IP address of the ISA server. &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;This is good because you can later also bind() using this address which will cause the firewall client to send a bind request to the ISA server. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;If you call bind() with 0.0.0.0 as the IP address, the firewall client software has to guess whether this is a local or remote bind() and may guess wrong.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;3. UPnP - &lt;/B&gt;&lt;A href="http://www.microsoft.com/windowsxp/pro/using/howto/networking/ics.asp"&gt;ICF&lt;/A&gt; and modern routers support configuration of port mapping via UPnP. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;There are &lt;A href="http://www.knoxscape.com/Upnp/NAT.htm"&gt;APIs&lt;/A&gt; that can help.&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;This works great with home routers, but is not good for WANs or any network with more than one segment because UPnP is based on broadcasts and works only on a LAN.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;4. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Allocate from a port range. &lt;/B&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;While for the outbound case, a single port is preferred, for inbound you should take into account that a single port could already be in use by another user on the same machine (think about XP home with multiple user sessions open), or by another application on the machine. &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;In case of NAT, the port could be in use by another machine. &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;You may want to allocate from a range of ports instead of letting the system select an available port. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This can help the configuration of firewalls by limiting the outbound ports that need to be opened.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;5.&lt;/B&gt; &lt;B&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;UDP sessions&lt;/B&gt;. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Some NAT devices and firewalls generate a UDP &amp;#8220;session&amp;#8221; when a packet is sent outbound. &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;By sending a single UDP packet it may be possible to enable a UDP mapping on the NAT device. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/teredo.mspx"&gt;Teredo&lt;/A&gt;, for example, uses this technique.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=151418" width="1" height="1"&gt;</content><author><name>Ishai</name><uri>http://blogs.msdn.com/members/Ishai.aspx</uri></author><category term="ISA Server" scheme="http://blogs.msdn.com/ishai/archive/tags/ISA+Server/default.aspx" /></entry></feed>