<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Shellcode: finding the base address of kernel32 in Windows 7</title>
	<atom:link href="http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/feed/" rel="self" type="application/rss+xml" />
	<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/</link>
	<description>The blog for absolutely nothing!</description>
	<lastBuildDate>Fri, 25 Jun 2010 07:02:27 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
	<item>
		<title>By: Exploit writing tutorial part 9 : Introduction to Win32 shellcoding &#124; Peter Van Eeckhoutte&#39;s Blog</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-813</link>
		<dc:creator>Exploit writing tutorial part 9 : Introduction to Win32 shellcoding &#124; Peter Van Eeckhoutte&#39;s Blog</dc:creator>
		<pubDate>Fri, 25 Jun 2010 07:02:27 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-813</guid>
		<description>[...] This is what I meant with “think goal oriented”. The code does exactly what it needs to do, without imposing any restrictions. You can still use this code to execute something else, and the method to get the WinExec function address is generic. So my assumption that I needed to find 2 function addresses is wrong &#8211; all I really needed to focus on is getting calc executed.&#160; You can find more information on skylined’s approach to finding a function address here [...]</description>
		<content:encoded><![CDATA[<p>[...] This is what I meant with “think goal oriented”. The code does exactly what it needs to do, without imposing any restrictions. You can still use this code to execute something else, and the method to get the WinExec function address is generic. So my assumption that I needed to find 2 function addresses is wrong &#8211; all I really needed to focus on is getting calc executed.&#160; You can find more information on skylined’s approach to finding a function address here [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Aniway</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-634</link>
		<dc:creator>Aniway</dc:creator>
		<pubDate>Mon, 30 Nov 2009 15:26:30 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-634</guid>
		<description>Cheers:)</description>
		<content:encoded><![CDATA[<p>Cheers:)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SkyLined</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-633</link>
		<dc:creator>SkyLined</dc:creator>
		<pubDate>Mon, 30 Nov 2009 15:10:28 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-633</guid>
		<description>Ah, that makes sense: the code assumes that the &quot;ntdll.dll&quot; string is followed by bytes that do not contain a NULL byte at offset +12 from the start of the string. It appears this is true for all versions of Windows after w2k (though I have not tested them all to confirm this). It seems that win2k happens to have a NULL byte at this offset after the string, causing the code to mistakenly assume it is kernel32.dll. Checking for a WORD NULL at that location solves this. Thanks for the feedback!</description>
		<content:encoded><![CDATA[<p>Ah, that makes sense: the code assumes that the &#8220;ntdll.dll&#8221; string is followed by bytes that do not contain a NULL byte at offset +12 from the start of the string. It appears this is true for all versions of Windows after w2k (though I have not tested them all to confirm this). It seems that win2k happens to have a NULL byte at this offset after the string, causing the code to mistakenly assume it is kernel32.dll. Checking for a WORD NULL at that location solves this. Thanks for the feedback!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: aniway</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-628</link>
		<dc:creator>aniway</dc:creator>
		<pubDate>Fri, 27 Nov 2009 04:15:34 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-628</guid>
		<description>Hi Skylined,

Just let you know that I figured it out.

As the first module name being checked is ntdll.dll, on win2k, the unicode name and the data following it is as below:

&lt;CODE&gt;
6e 00 74 00 64 00 6c 00 6c 00 2e 00 64 00 6c 00 ntdll.dl
6c 00 00 00 42 00 08 00 00 01 &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; l.B..
&#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; ^^
This is the byte we are checking.
&lt;/CODE&gt;
As you can see, if we only check one byte, the code will think ntdll.dll is kernel32.dll. Checking 2 bytes fixes that problem.

Cheers,

Aniway</description>
		<content:encoded><![CDATA[<p>Hi Skylined,</p>
<p>Just let you know that I figured it out.</p>
<p>As the first module name being checked is ntdll.dll, on win2k, the unicode name and the data following it is as below:</p>
<p><code><br />
6e 00 74 00 64 00 6c 00 6c 00 2e 00 64 00 6c 00 ntdll.dl<br />
6c 00 00 00 42 00 08 00 00 01 &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; l.B..<br />
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ^^<br />
This is the byte we are checking.<br />
</code><br />
As you can see, if we only check one byte, the code will think ntdll.dll is kernel32.dll. Checking 2 bytes fixes that problem.</p>
<p>Cheers,</p>
<p>Aniway</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SkyLined</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-625</link>
		<dc:creator>SkyLined</dc:creator>
		<pubDate>Wed, 25 Nov 2009 15:21:32 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-625</guid>
		<description>I cannot think of any reason why the code would not work on Win2K nor any way how the change you suggest could change the behavior of the code in a way that would fix the issue. I haven&#039;t got a Win2K machine at the ready to test, so I&#039;ll take your word for it.

Thanks for the feedback!</description>
		<content:encoded><![CDATA[<p>I cannot think of any reason why the code would not work on Win2K nor any way how the change you suggest could change the behavior of the code in a way that would fix the issue. I haven&#8217;t got a Win2K machine at the ready to test, so I&#8217;ll take your word for it.</p>
<p>Thanks for the feedback!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: aniway</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-624</link>
		<dc:creator>aniway</dc:creator>
		<pubDate>Tue, 24 Nov 2009 18:08:52 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-624</guid>
		<description>Hi SkyLined,

I understand what you are saying;) theoretically, checking one byte should be enough and it saves one byte of space. But here is the whole story:

I was exploiting a java 0day using a simple calc.exe shellcode from metasploit. The shellcode worked well on Windows 2k and XP, but of course not on Windows 7. So I changed the shellcode as you posted and it worked on Windows 7, but kept failing on Windows 2k after that. I tried a few Win2k VM, same thing everywhere.

I tried to dig the problem out, but whenever there&#039;s olly attached to the affected application, the shellcode runs successfully!!! So I never see a case that really requires a 2 byte check.

As that&#039;s the only change I made to the shellcode, so I started to get picky at the code. The only thing I can think out was  that the one byte check might not be sufficient. So I changed it to check 2 bytes, and It worked. 

Is it possible that due to unininlized memory or whatever reason, there might happen to be one byte NULL at offset 0x18 for a shorter module name? Or there&#039;s any other reason you can think of?

Cheers,

Aniway</description>
		<content:encoded><![CDATA[<p>Hi SkyLined,</p>
<p>I understand what you are saying;) theoretically, checking one byte should be enough and it saves one byte of space. But here is the whole story:</p>
<p>I was exploiting a java 0day using a simple calc.exe shellcode from metasploit. The shellcode worked well on Windows 2k and XP, but of course not on Windows 7. So I changed the shellcode as you posted and it worked on Windows 7, but kept failing on Windows 2k after that. I tried a few Win2k VM, same thing everywhere.</p>
<p>I tried to dig the problem out, but whenever there&#8217;s olly attached to the affected application, the shellcode runs successfully!!! So I never see a case that really requires a 2 byte check.</p>
<p>As that&#8217;s the only change I made to the shellcode, so I started to get picky at the code. The only thing I can think out was  that the one byte check might not be sufficient. So I changed it to check 2 bytes, and It worked. </p>
<p>Is it possible that due to unininlized memory or whatever reason, there might happen to be one byte NULL at offset 0&#215;18 for a shorter module name? Or there&#8217;s any other reason you can think of?</p>
<p>Cheers,</p>
<p>Aniway</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SkyLined</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-622</link>
		<dc:creator>SkyLined</dc:creator>
		<pubDate>Sun, 22 Nov 2009 15:07:30 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-622</guid>
		<description>Hi Aniway,

Thanks for the feedback! I&#039;ve not tested this on Win2K, but I don&#039;t know why it would not work as-is.
The fix you suggest makes no sense to me, can you explain what the problem is and how this change solves it?

I designed the code to look for a UNICODE &#039;\0&#039; character in a string that only contains lower-ascii characters coverted to UNICODE. This means that one byte of each character is &lt;strong&gt;always&lt;/strong&gt; 0 and the code need only &lt;CODE&gt;CMP&lt;/CODE&gt; the other byte to 0 (&lt;CODE&gt;CL&lt;/CODE&gt;) to find this &#039;\0&#039; character. In this context, I don&#039;t understand why a &lt;CODE&gt;CMP&lt;/CODE&gt; with &lt;CODE&gt;CX&lt;/CODE&gt; adds any value and how this could solve any issue.

Cheers,

SkyLined</description>
		<content:encoded><![CDATA[<p>Hi Aniway,</p>
<p>Thanks for the feedback! I&#8217;ve not tested this on Win2K, but I don&#8217;t know why it would not work as-is.<br />
The fix you suggest makes no sense to me, can you explain what the problem is and how this change solves it?</p>
<p>I designed the code to look for a UNICODE &#8216;\0&#8242; character in a string that only contains lower-ascii characters coverted to UNICODE. This means that one byte of each character is <strong>always</strong> 0 and the code need only <code>CMP</code> the other byte to 0 (<code>CL</code>) to find this &#8216;\0&#8242; character. In this context, I don&#8217;t understand why a <code>CMP</code> with <code>CX</code> adds any value and how this could solve any issue.</p>
<p>Cheers,</p>
<p>SkyLined</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: aniway</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-620</link>
		<dc:creator>aniway</dc:creator>
		<pubDate>Sat, 21 Nov 2009 19:10:02 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-620</guid>
		<description>Thanks for sharing, SkyLined. It&#039;s a creative solution. I have tried it on windows 7, it worked beautifully. 

I&#039;m not sure whether you have tested it on windows 2k. I have to make the following change in order to make it work in my case: 

Original:
&lt;code&gt;CMP     [EDI + 0x18], CL&lt;/code&gt;          

New:
&lt;code&gt;CMP     [EDI + 0x18], CX&lt;/code&gt;

As we are checking the termination of UNICODE string, so I think the change is harmless.

Cheers &amp; regards,

Aniway</description>
		<content:encoded><![CDATA[<p>Thanks for sharing, SkyLined. It&#8217;s a creative solution. I have tried it on windows 7, it worked beautifully. </p>
<p>I&#8217;m not sure whether you have tested it on windows 2k. I have to make the following change in order to make it work in my case: </p>
<p>Original:<br />
<code>CMP     [EDI + 0x18], CL</code>          </p>
<p>New:<br />
<code>CMP     [EDI + 0x18], CX</code></p>
<p>As we are checking the termination of UNICODE string, so I think the change is harmless.</p>
<p>Cheers &#038; regards,</p>
<p>Aniway</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SkyLined</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-195</link>
		<dc:creator>SkyLined</dc:creator>
		<pubDate>Sun, 26 Jul 2009 16:35:21 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-195</guid>
		<description>@&lt;strong&gt;qwerty&lt;/strong&gt;: There is no version of Windows that will load another module with a 12 character name before &lt;a href=&quot;http://skypher.com/wiki/index.php/Hacking/Windows_internals/DLL/kernel32&quot; rel=&quot;nofollow&quot;&gt;kernel32.dll&lt;/a&gt;. That may change in future versions of Windows but for now it can be used to find it. This means that the above code will not fail (unless some existing versions of Windows put a bunch of NULLs after the name of &quot;ntdll.dll&quot; rather than non-NULL bytes, but I&#039;ve not seen this). 

Unfortunately, 20 bytes is a lot for a &lt;a href=&quot;http://skypher.com/wiki/index.php/Hacking/Shellcode&quot; rel=&quot;nofollow&quot;&gt;shellcode&lt;/a&gt;: it would mean a 10% size increase for mine.</description>
		<content:encoded><![CDATA[<p>@<strong>qwerty</strong>: There is no version of Windows that will load another module with a 12 character name before <a href="http://skypher.com/wiki/index.php/Hacking/Windows_internals/DLL/kernel32" rel="nofollow">kernel32.dll</a>. That may change in future versions of Windows but for now it can be used to find it. This means that the above code will not fail (unless some existing versions of Windows put a bunch of NULLs after the name of &#8220;ntdll.dll&#8221; rather than non-NULL bytes, but I&#8217;ve not seen this). </p>
<p>Unfortunately, 20 bytes is a lot for a <a href="http://skypher.com/wiki/index.php/Hacking/Shellcode" rel="nofollow">shellcode</a>: it would mean a 10% size increase for mine.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: qwerty</title>
		<link>http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/comment-page-1/#comment-194</link>
		<dc:creator>qwerty</dc:creator>
		<pubDate>Sun, 26 Jul 2009 15:08:35 +0000</pubDate>
		<guid isPermaLink="false">http://skypher.com/?p=153#comment-194</guid>
		<description>well, this is certainly true, wouldn&#039;t argue with you there.

i like this kind of code, don&#039;t get me wrong.

but i&#039;d say at some point in future, a length check might be insufficient, meaning extra code required for extra checks.

in certain situations, it would be ideal to use 1 byte hashes or even hardcoded addresses but this usually means less stable code.

&lt;pre&gt;
next_module:
    MOV     EBP, [ESI + 0x08]           ; EBP = InInitOrder[X].base_address
    MOV     EDI, [ESI + 0x20]           ; EDI = InInitOrder[X].module_name (unicode string)
    MOV     ESI, [ESI]                  ; ESI = InInitOrder[X].flink (next module)
    CMP     [EDI + 12*2], CL            ; modulename[12] == 0 ? strlen(&quot;kernel32.dll&quot;) == 12
    JNE     next_module                 ; No: try next module.
&lt;/pre&gt;
what happens if it finds ADVAPI32.DLL first? or some other module which happens to be same length as KERNEL32.DLL?

because of the 1 byte hashes, there can only be 256 possible values, it may resolve the wrong apis and crash.

this is a problem which might occur in process with large number of DLL loaded, hence why it may be better to have a good hashing algorithm and scan all modules.

the difference in size is not that big, maybe at most 20 bytes.</description>
		<content:encoded><![CDATA[<p>well, this is certainly true, wouldn&#8217;t argue with you there.</p>
<p>i like this kind of code, don&#8217;t get me wrong.</p>
<p>but i&#8217;d say at some point in future, a length check might be insufficient, meaning extra code required for extra checks.</p>
<p>in certain situations, it would be ideal to use 1 byte hashes or even hardcoded addresses but this usually means less stable code.</p>
<pre>
next_module:
    MOV     EBP, [ESI + 0x08]           ; EBP = InInitOrder[X].base_address
    MOV     EDI, [ESI + 0x20]           ; EDI = InInitOrder[X].module_name (unicode string)
    MOV     ESI, [ESI]                  ; ESI = InInitOrder[X].flink (next module)
    CMP     [EDI + 12*2], CL            ; modulename[12] == 0 ? strlen("kernel32.dll") == 12
    JNE     next_module                 ; No: try next module.
</pre>
<p>what happens if it finds ADVAPI32.DLL first? or some other module which happens to be same length as KERNEL32.DLL?</p>
<p>because of the 1 byte hashes, there can only be 256 possible values, it may resolve the wrong apis and crash.</p>
<p>this is a problem which might occur in process with large number of DLL loaded, hence why it may be better to have a good hashing algorithm and scan all modules.</p>
<p>the difference in size is not that big, maybe at most 20 bytes.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
