<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>[Giagnocavo]Michael::Write() - IL</title>
    <link>http://www.atrevido.net/blog/</link>
    <description>Something about .NET.</description>
    <copyright>Michael Giagnocavo</copyright>
    <lastBuildDate>Tue, 22 Feb 2005 14:45:39 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>mggUNSPAM@telefinity.com</managingEditor>
    <webMaster>mggUNSPAM@telefinity.com</webMaster>
    <item>
      <trackback:ping>http://www.atrevido.net/blog/Trackback.aspx?guid=65edaf2b-6565-43bf-bfe8-b4ed20443c4b</trackback:ping>
      <pingback:server>http://www.atrevido.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.atrevido.net/blog/PermaLink,guid,65edaf2b-6565-43bf-bfe8-b4ed20443c4b.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://www.atrevido.net/blog/CommentView,guid,65edaf2b-6565-43bf-bfe8-b4ed20443c4b.aspx</wfw:comment>
      <wfw:commentRss>http://www.atrevido.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=65edaf2b-6565-43bf-bfe8-b4ed20443c4b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blogs.msdn.com/jmstall/">Mike Stall</a> just released a cool tool
for doing <a href="http://blogs.msdn.com/jmstall/archive/2005/02/21/377806.aspx">inline
IL in C#</a> (oh, and in VB). It's not full integration with the compiler (so it's
not a _msil() block or anything), but it's still very cool. 
</p>
        <img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=65edaf2b-6565-43bf-bfe8-b4ed20443c4b" />
      </body>
      <title>Inline IL! </title>
      <guid isPermaLink="false">http://www.atrevido.net/blog/PermaLink,guid,65edaf2b-6565-43bf-bfe8-b4ed20443c4b.aspx</guid>
      <link>http://www.atrevido.net/blog/2005/02/22/Inline+IL.aspx</link>
      <pubDate>Tue, 22 Feb 2005 14:45:39 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blogs.msdn.com/jmstall/"&gt;Mike Stall&lt;/a&gt; just released a cool tool
for doing &lt;a href="http://blogs.msdn.com/jmstall/archive/2005/02/21/377806.aspx"&gt;inline
IL in C#&lt;/a&gt; (oh, and in VB). It's not full integration with the compiler (so it's
not a _msil() block or anything), but it's still very cool. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=65edaf2b-6565-43bf-bfe8-b4ed20443c4b" /&gt;</description>
      <comments>http://www.atrevido.net/blog/CommentView,guid,65edaf2b-6565-43bf-bfe8-b4ed20443c4b.aspx</comments>
      <category>Code</category>
      <category>IL</category>
    </item>
    <item>
      <trackback:ping>http://www.atrevido.net/blog/Trackback.aspx?guid=ac03f447-d487-45a6-8119-dc4fa1e932e1</trackback:ping>
      <pingback:server>http://www.atrevido.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.atrevido.net/blog/PermaLink,guid,ac03f447-d487-45a6-8119-dc4fa1e932e1.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://www.atrevido.net/blog/CommentView,guid,ac03f447-d487-45a6-8119-dc4fa1e932e1.aspx</wfw:comment>
      <wfw:commentRss>http://www.atrevido.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ac03f447-d487-45a6-8119-dc4fa1e932e1</wfw:commentRss>
      <slash:comments>13</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One thing I had done before and decided to try again was inline (embedded? inline
isn't the right term exactly) ASM with C#. Remember, the CLR JITs your IL code down
to native code when it runs. There's no interpreter or likewise going on -- your C#
code is x86 when it runs (on an x86 platform). However, when writing in C#, it's rather
hard to get out to x86 directly. Probably the easiest way would be to use Managed
C++ and an inline asm section there. But, if you want to keep it all in C# (say, you
want something extra hard to decompile), you can achieve that.<br /><br />
[I must note, the more I learn of internals, the more I learn I need to learn more.
Thus hopefully, some true expert will read this and give me more insight.]<br /><br />
The most straightforward way that occurred to me was to use a delegate. As far as
I know, C# won't issue calli and ldftn IL opcodes for us in any way we can neatly
control. There will be ldftn when a delegate is created, but we can't set that value
directly. So instead, we'll create a delegate and modify it. Delegates have a private
field named “_methodPtr”. This, as far as I can tell, points to the code
to be executed by the delegate. It's important that our delegate is accurate regarding
the number of parameters, and the return value.<br /><br />
We will store our x86 in a byte array. Then, we'll pin the array, and stick the address
of the first element inside the delegate. When we call the delegate, everything will
be set.<br /><br />
As far as I can tell, methods in the CLR use the fastcall convention, so the first
two parameters will be in EDX and ECX. The return value is expected in EAX. My demo
is going to be simple, performing a ROR (ROtate Right) by 1 on the parameter and returning
that. 3 lines of ASM.<br /><br />
Compile with /unsafe obviously, else I'd be writing to secure@microsoft.com. I'm
not sure how terribly useful this is, but it seemed cool to me. At the very minimum,
it serves to tell people to STFU when they claim that C# / .NET can't do pointers,
or raw code, or whatever.<br /><br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Reflection;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> Program<br />
{<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">uint</span> Ret1ArgDelegate(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">uint</span> arg1);<br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">uint</span> PlaceHolder1(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">uint</span> arg1)
{ <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> 0;
}<br />
    <br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>[]
asmBytes <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>[]<br />
        {        <br />
0x89,0xD0, <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
MOV EAX,EDX</span><br />
0xD1,0xC8, <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
ROR EAX,1</span><br />
0xC3       <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
RET</span><br />
        };<br />
        <br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">unsafe</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Main(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
args)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">fixed</span>(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">byte</span>*
startAddress <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> &amp;asmBytes[0]) <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Take the address of our x86 code</span><br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Get the FieldInfo for "_methodPtr"</span><br />
            Type delType <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(Delegate);<br />
            FieldInfo
_methodPtr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> delType.GetField(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"_methodPtr"</span>,
BindingFlags.NonPublic <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">|</span> BindingFlags.Instance);<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Set our delegate to our x86 code</span><br />
            Ret1ArgDelegate
del <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Ret1ArgDelegate(PlaceHolder1);<br />
            _methodPtr.SetValue(del,
(IntPtr)startAddress);<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Enjoy</span><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">uint</span> n <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">uint</span>)0xFFFFFFFC;<br />
            n <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> del(n);<br />
            Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"{0:x}"</span>,
n);<br />
        }<br />
    }<br />
}<br /></span></p>
        <img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=ac03f447-d487-45a6-8119-dc4fa1e932e1" />
      </body>
      <title>Inline x86 ASM in C#</title>
      <guid isPermaLink="false">http://www.atrevido.net/blog/PermaLink,guid,ac03f447-d487-45a6-8119-dc4fa1e932e1.aspx</guid>
      <link>http://www.atrevido.net/blog/2005/01/28/Inline+X86+ASM+In+C.aspx</link>
      <pubDate>Fri, 28 Jan 2005 19:15:12 GMT</pubDate>
      <description>&lt;p&gt;
One thing I had done before and decided to try again was inline (embedded? inline
isn't the right term exactly) ASM with C#. Remember, the CLR JITs your IL code down
to native code when it runs. There's no interpreter or likewise going on -- your C#
code is x86 when it runs (on an x86 platform). However, when writing in C#, it's rather
hard to get out to x86 directly. Probably the easiest way would be to use Managed
C++ and an inline asm section there. But, if you want to keep it all in C# (say, you
want something extra hard to decompile), you can achieve that.&lt;br&gt;
&lt;br&gt;
[I must note, the more I learn of internals, the more I learn I need to learn more.
Thus hopefully, some true expert will read this and give me more insight.]&lt;br&gt;
&lt;br&gt;
The most straightforward way that occurred to me was to use a delegate. As far as
I know, C# won't issue calli and ldftn IL opcodes for us in any way we can neatly
control. There will be ldftn when a delegate is created, but we can't set that value
directly. So instead, we'll create a delegate and modify it. Delegates have a private
field named &amp;#8220;_methodPtr&amp;#8221;. This, as far as I can tell, points to the code
to be executed by the delegate. It's important that our delegate is accurate regarding
the number of parameters, and the return value.&lt;br&gt;
&lt;br&gt;
We will store our x86 in a byte array. Then, we'll pin the array, and stick the address
of the first element inside the delegate. When we call the delegate, everything will
be set.&lt;br&gt;
&lt;br&gt;
As far as I can tell, methods in the CLR use the fastcall convention, so the first
two parameters will be in EDX and ECX. The return value is expected in EAX. My demo
is going to be simple, performing a ROR (ROtate Right) by 1 on the parameter and returning
that. 3 lines of ASM.&lt;br&gt;
&lt;br&gt;
Compile with /unsafe obviously, else I'd be writing to secure@microsoft.com.&amp;nbsp;I'm
not sure how terribly useful this is, but it seemed cool to me. At the very minimum,
it serves to tell people to STFU when they claim that C# / .NET can't do pointers,
or raw code, or whatever.&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Reflection;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; Program&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;uint&lt;/span&gt; Ret1ArgDelegate(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;uint&lt;/span&gt; arg1);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;uint&lt;/span&gt; PlaceHolder1(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;uint&lt;/span&gt; arg1)
{ &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; 0;
}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;byte&lt;/span&gt;[]
asmBytes &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;byte&lt;/span&gt;[]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
0x89,0xD0, &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
MOV EAX,EDX&lt;/span&gt;
&lt;br&gt;
0xD1,0xC8, &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
ROR EAX,1&lt;/span&gt;
&lt;br&gt;
0xC3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
RET&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;unsafe&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Main(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
args)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;fixed&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;byte&lt;/span&gt;*
startAddress &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &amp;amp;asmBytes[0]) &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Take the address of our x86 code&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Get the FieldInfo for "_methodPtr"&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Type delType &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;typeof&lt;/span&gt;(Delegate);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FieldInfo
_methodPtr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; delType.GetField(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"_methodPtr"&lt;/span&gt;,
BindingFlags.NonPublic &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;|&lt;/span&gt; BindingFlags.Instance);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Set our delegate to our x86 code&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Ret1ArgDelegate
del &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Ret1ArgDelegate(PlaceHolder1);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_methodPtr.SetValue(del,
(IntPtr)startAddress);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Enjoy&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;uint&lt;/span&gt; n &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;uint&lt;/span&gt;)0xFFFFFFFC;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; del(n);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"{0:x}"&lt;/span&gt;,
n);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=ac03f447-d487-45a6-8119-dc4fa1e932e1" /&gt;</description>
      <comments>http://www.atrevido.net/blog/CommentView,guid,ac03f447-d487-45a6-8119-dc4fa1e932e1.aspx</comments>
      <category>Code</category>
      <category>IL</category>
    </item>
    <item>
      <trackback:ping>http://www.atrevido.net/blog/Trackback.aspx?guid=8315fa01-0286-47ce-a20b-fcc15eb297c3</trackback:ping>
      <pingback:server>http://www.atrevido.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.atrevido.net/blog/PermaLink,guid,8315fa01-0286-47ce-a20b-fcc15eb297c3.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://www.atrevido.net/blog/CommentView,guid,8315fa01-0286-47ce-a20b-fcc15eb297c3.aspx</wfw:comment>
      <wfw:commentRss>http://www.atrevido.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8315fa01-0286-47ce-a20b-fcc15eb297c3</wfw:commentRss>
      <slash:comments>13</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>Intro</strong>
          <br />
It's been a while since I wrote anything that interesting, so I figured for Thanksgiving,
I'd go ahead and do so. Merry Thanksgiving. The first article in this “series“ <a href="/blog/Trackback.aspx?guid=73204548-5970-46db-b7cf-76cd4c22c3b9">is
here</a>.<br /><br />
Cracking .NET programs can be just like cracking any other program. In this article,
I'm going to use the <a href="/blog/PermaLink.aspx?guid=ec99e239-8917-48e3-bd4f-af866b730150">same
approach</a> as I did last time. I threw together a quick little program called CrackMe2.
CrackMe2 has a really cool feature called “Reverse Text”, however, it's
only available to registered users. What's a poor boy to do?<br /><br /><strong>Target</strong><br />
First, we try registering. Since we don't have a valid code (we don't even know what
one looks like), we get an “Invalid serial.“ MessageBox. OK, so now we
know that the program does something when we click a button, and if the serial is
wrong, we get a MessageBox.<br /><br /><img src="/blog/content/binary/crackMe2Invalid.gif" border="0" /><br /><em>Darn, 123 didn't work.</em><br /><br />
Well, the first step in cracking is defining our target and it's location. Our target
is the code that's deciding to say “Invalid serial.” instead
of “You're registered!”. Where's the “bad code“ that
needs to be fixed? Well, with a .NET assembly, our first information is gained by
taking a look with IL DASM.<br /><br /><img src="/blog/content/binary/crackMe2ILDasmView.gif" border="0" /><br /><em>View of the obfuscated CrackMe2 assembly<br /><br /></em>Oh no! It's obfuscated (thanks to <a href="http://www.dotnetthis.com/Samples/Mangler.htm">Ivan
Medvedev's Mangler</a>). Let's assume this is a big application and that we'll never
find what we're looking for just by going through the IL. Just by glancing at the
hierarchy, we don't know that much more than when we started: There's a form with
code.<br /><br /><strong>Seeing past the names</strong><br />
Now certainly, we can do static analysis and try to find out where the bad code is.
One way would be by getting the strings (Ctrl+M in IL DASM, scroll to the bottom),
and then grep the IL for ldstr 
<TOKENNUMBER>
, and work from there. In fact, that's a pretty quick and easy way to locate certain
parts. However, lets pretend the strings are encrypted/dynamically generated,
and that's not viable. So, let's start debugging.<br /><br /><font face="Courier New">[Michael@MAO C:\]$ cordbg CrackMe2.exe<br />
Microsoft (R) Common Language Runtime Test Debugger Shell Version 1.1.4322.573<br />
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.</font></TOKENNUMBER></p>
        <p>
          <font face="Courier New">(cordbg) run CrackMe2.exe<br />
Process 4488/0x1188 created.<br />
Warning: couldn't load symbols for c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll<br />
[thread 0x1510] Thread created.<br />
Warning: couldn't load symbols for C:\CrackMe2.exe<br />
Warning: couldn't load symbols for c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll<br />
Warning: couldn't load symbols for c:\windows\assembly\gac\system\1.0.5000.0__b77a5c561934e089\system.dll</font>
        </p>
        <p>
          <font face="Courier New">[0004] mov        
ecx,98543Ch<br />
(cordbg)</font>
          <br />
          <br />
cordbg is a command line debugger that ships with the .NET Framework SDK, and it's
just loaded the CrackMe2.exe and related assemblies. Just like before, we're going
to go ahead and set a breakpoint and find out where we are in the program, and work
from there. So, let's breakpoint the MessageBox.Show function. We use IL-similar syntax
to specify the function name: NameSpace.ClassName::Method.<br /><br /><font face="Courier New">(cordbg) b System.Windows.Forms.MessageBox::Show<br />
Breakpoint #1 has bound to c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll.<br />
#1      c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll!System.Windows.Forms.MessageBox::Show:0     
Show+0x0(native) [active]<br />
(cordbg)<br /></font><br />
Then, we tell cordbg to go until it breaks by typing <font face="Courier New">go</font>.
The form comes up, and we enter a serial number: 123.<br /><br /><font face="Courier New">(cordbg) go<br />
Warning: couldn't load symbols for c:\windows\assembly\gac\system.drawing\1.0.5000.0__b03f5f7f11d50a3a\system.drawing.dll<br />
break at #1     c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll!System.Windows.Forms.MessageBox::Show:0     
Show+0x0(native) [active]<br />
Source not available when in the prolog of a function(offset 0x0)</font></p>
        <p>
          <font face="Courier New">[0000] push        edi<br />
(cordbg)<br /></font>
          <br />
Bingo, we're stopped at a MessageBox. We want to know who called this function, since
most likely, that will lead us to the critical code section we need to fix. So, we
ask cordbg <font face="Courier New">where</font> are we?<br /><br /><font face="Courier New">(cordbg) where<br />
Thread 0x1510 Current State:Normal<br />
0)* system.windows.forms!System.Windows.Forms.MessageBox::Show +0000 [no source information
available]<br />
               
owner=(0x00ac36b0) 
<CRACKME2.FORM1><br />
               
text=(0x00ad5854) "Invalid serial."<br />
1)  CrackMe2!CrackMe2.Form1::AAAAAAAAAAAAAAAAAAAA +0070 [no source information
available]<br />
               
AAAAAA=(0x00ac8400) 
<SYSTEM.WINDOWS.FORMS.BUTTON><br />
               
A=(0x00aca86c) 
<SYSTEM.EVENTARGS><br />
2)  system.windows.forms!System.Windows.Forms.Control::OnClick +005e [no source
information available]<br />
               
e=(0x00aca86c) 
<SYSTEM.EVENTARGS><br /></SYSTEM.EVENTARGS></SYSTEM.EVENTARGS></SYSTEM.WINDOWS.FORMS.BUTTON></CRACKME2.FORM1></font><em><CUT clarity="clarity" for="for"><br /></CUT></em><font face="Courier New">9)  system.windows.forms!ControlNativeWindow::OnMessage
+0013 [no source information available]<br />
               
m=(0x0012ef04) 
<SYSTEM.WINDOWS.FORMS.MESSAGE><br />
--- Managed transition ---<br /></SYSTEM.WINDOWS.FORMS.MESSAGE></font><br />
We see what's expected. Somewhere in Win32 code, a message was sent, and we see the
OnMessage called and bubbling up all the way to the Control::OnClick, and then user
code. We can look at all the arguments along the way, and that's useful for more complex
scenarios (say, when a registration function calls another passing the serial number
or validation code).<br /><br />
At any rate, we've got something to go on: The name of the function that calls the
MessageBox: CrackMe2.Form1::AAAAAAAAAAAAAAAAAAAA (20 A's). We're done with cordbg (<font face="Courier New">quit</font>).
Our next stop is to read the bad code.<br /><br /><strong>Looking at the bad code</strong><br />
Using IL DASM (see above), I navigate to the CrackMe2.Form1::AAAAAAAAAAAAAAAAAAAA method.
Inside is relatively straighforward code. First, there's a try/catch that has an Int32::Parse
call in it. The result is stored in local 0. So we now know the code is numeric. Immediately
after the catch handler, we have this snippet:<br /><font face="Courier New">  IL_0022:  ldloc.0<br />
  IL_0023:  ldc.i4.1<br />
  IL_0024:  and<br />
  IL_0025:  ldc.i4.1<br />
  IL_0026:  bne.un.s   IL_0035<br />
  IL_0028:  ldarg.0<br />
  IL_0029:  ldstr      "Invalid serial."<br />
  IL_002e:  call       valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult
[System.Windows.Forms]System.Windows.Forms.MessageBox::Show(class [System.Windows.Forms]System.Windows.Forms.IWin32Window,
string)<br /></font><br />
Load the local (the number entered), then load the number 1, and AND them. Then, load
one, and if they are not equal, jump to IL_0035. If they are equal, execute the following
instructions, which quite obviously say “Invalid serial.”. AND'ing a number
with 1 and comparing to 1 is a check to see if the number is odd. So, at this point,
we can write a keygenerator that produces... even numbers. A keygenerator is always
preferred to a patch, however, generally speaking, finding the algorithm might be
a bit harder. Then, there's always the possibility that the check actually does something
hard to fake (i.e., uses RSA or talks to a hardware dongle/web service). So, let's
go on and patch this code.<br /><br />
At IL_0035 (the target of the branch if the number is even), we have some code that
does activation work and then proceeds to say “Thank you...”. Simple sample.
Now, let's make the fix.<br /><br /><strong>Simple Patching</strong><br />
With IL DASM and IL ASM, we have a really easy way to make patches. Simply run ildasm
/out=CrackMe2.il CrackMe2.exe, and IL DASM will dump all the IL required for that
assembly to a nicely formatted file. All we have to do is goto the bad method and
fix up the IL. I think the most unintrusive fix would be to add “br IL_0035”
to the top of the method. That would branch immediately to the good code, and the
product would activate on any serial number entered.<br /><br />
However, some obfuscators try to stop IL DASM round tripping, and that might stop
some posers in their tracks. The IL obfuscator I'm going to give away for free will
do this, for example. (Actually, my free obfuscator would make this tutorial a bit
harder because of how it handles names -- we'd have to actually get a token instead.)<br /><br />
Assuming we can't use IL DASM/ASM, what can we do? Use a hex editor. 
<br /><br /><strong>Binary Patching</strong><br />
When we can't reassemble an entire program, we can patch certain opcodes instead.
Tools like OllyDbg have a built-in assembler so we can easily make patches to the
x86 code. For IL, I'm not aware of any such tool. Another issue with binary patching
IL is that we have to ensure the resulting IL is fully correct and is able to be JIT'd
to native code. If our patch ends up screwing with the IL in a way that makes it incorrect,
we'll get a runtime exception from the execution engine. Let's try to create a binary
patch that jumps from the beginning of the method right to the good code, at IL offset
0x0035.<br /><br />
First, in IL DASM, turn on “Show bytes”, under the View menu. This allows
us to see the actual bytes that make up the opcodes. Now, lets look at the beginning
of the critical function:<br /><br /><font face="Courier New">  // Method begins at RVA 0x2434<br />
  // Code size       78 (0x4e)<br />
  .maxstack  2<br />
  .locals init (int32 V_0)<br />
  .try<br />
  {<br />
    IL_0000:  /* 02   |                 
*/ ldarg.0<br />
    IL_0001:  /* 7B   | (04)000002      
*/ ldfld      class [System.Windows.Forms]System.Windows.Forms.TextBox
CrackMe2.Form1::AAAAAAAAAAAA<br />
    IL_0006:  /* 6F   | (0A)000026      
*/ callvirt   instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()<br />
    IL_000b:  /* 28   | (0A)000027      
*/ call       int32 [mscorlib]System.Int32::Parse(string)<br />
    IL_0010:  /* 0A   |                 
*/ stloc.0<br />
    IL_0011:  /* DE   | 0F              
*/ leave.s    IL_0022<br />
  }  // end .try<br /></font><br />
This code is protected in a try block. We could go and remove the try block, but that's
modifying more code. Generally speaking, we should aim to patch as little code as
possible to ensure we don't accidentally screw something up. So, we're going to deal
with the try block and fix it from within. The ECMA specifications for .NET will come
in handy here. Specifically, Partition III, CIL. This can be found in the .NET Framework
SDK folder, under “Tool Developers Guide\docs”. It's also available from
MSDN, <a href="http://msdn.microsoft.com/net/ecma/">here</a>. 
<br /><br />
The first instinct is to say, hey, let's change IL_0000 to a br to IL_0035, and NOP
out the remainder of the try block. However, that'd create illegal code, since you
can't branch out from a try block, you must use the leave opcode instead. So, let's
rewrite the method to simply leave to IL_0035. Here's the description of the leave
opcode:<br /><br /><em>The leave instruction unconditionally transfers control to target. Target is represented
as a signed offset (4 bytes for leave, 1 byte for leave.s) from the beginning of the
instruction following the current instruction.</em><br /><br />
The formats (in hex) are DD &lt;4 bytes&gt; for leave and DE &lt;1 byte&gt; (as shown
above), for leave.s. We'll use leave.s, just to be efficient :). Since the total size
for leave.s is 2 bytes, we calculate the offset to 0x35 from 0x02 (since our leave
instruction is at 0x00). Subtraction tells us we must have an offset of 0x33. Hence,
our leave instruction in hex looks like: DE 33. Since that'd leave the IL in an incorrect
state, we must nop out the rest of the try block. The hex for nop is 00.<br /><br />
Open the assembly in your favorite hex editor, and let's find the method. IL DASM
gives us the RVA, but for now we'll just search for a specific byte sequence. The
IL DASM Show bytes allows us to easily find our place. Do note that the way tokens
are displayed ((04)000002, for example), is reverse from how they are stored. Depending
on the size of the app, you might need to search on quite a large number of bytes,
since IL sequences are most likely repeated. For this case, we're going to search
on the last bit: “0A DE 0F”. No other matches found, so this is the one.<br /><br />
As when programming, in cracking we have many ways to solve a problem. Many of them
can be considered “right”. We could make a simple one-byte patch
by allowing any number as a valid serial. This has the merit of ensuring the local
int is assigned, and well, being only a one-byte edit. The leave.s opcode is at offset
0x11, so add 2 to that amount and we get 0x13. 0x35 - 0x13 = 0x22. So by changing
“0F” to “22”, we'd have our crack. However, let's stick to
the original plan and jump right to the good bits from the beginning.<br /><br />
In the hex editor, we back up a bit until we find the 02 7B 02 00 00 04 part (ldarg.0,
then load the textbox field). At the 02, we drop our leave.s IL_0035 payload, which
is DE 33. Then, we nop out (00) everything until the end of the 0A DE 0F part. The
resulting hex for the try block is thus: DE 33 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00. Save the file as CrackMe2.cracked.exe.<br /><br /><strong>Satisfaction</strong><br />
Run the program. Type in anything for the serial. “Thank you for registering.”
The second textbox activates. We've won access to the coveted “Reverse Text”
function. Write up an .NFO, ensuring to remind people to purchase software to
support the authors. Then kick back and play a game of KSpaceDuel.<br /><br />
Download the program itself (Right click and save as, since it's a .NET assembly and
IEExec will try to run it otherwise): <a href="/blog/content/binary/CrackMe2.exe">CrackMe2.exe
(24 KB)</a>. Or, download the source: <a href="/blog/content/binary/CrackMe2.cs.txt">CrackMe2.cs.txt
(4.81 KB)</a>.<br /><br />
Was this post interesting, helpful, stupid, or lame? Leave a comment and help me improve.
</p>
        <img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=8315fa01-0286-47ce-a20b-fcc15eb297c3" />
      </body>
      <title>Cracking code 3: Cracking an obfuscated .NET assembly</title>
      <guid isPermaLink="false">http://www.atrevido.net/blog/PermaLink,guid,8315fa01-0286-47ce-a20b-fcc15eb297c3.aspx</guid>
      <link>http://www.atrevido.net/blog/2004/11/26/Cracking+Code+3+Cracking+An+Obfuscated+NET+Assembly.aspx</link>
      <pubDate>Fri, 26 Nov 2004 05:22:20 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;Intro&lt;/strong&gt;
&lt;br&gt;
It's been a while since I wrote anything that interesting, so I figured for Thanksgiving,
I'd go ahead and do so. Merry Thanksgiving. The first article in this &amp;#8220;series&amp;#8220; &lt;a href="/blog/Trackback.aspx?guid=73204548-5970-46db-b7cf-76cd4c22c3b9"&gt;is
here&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
Cracking .NET programs can be just like cracking any other program. In this article,
I'm going to use the &lt;a href="/blog/PermaLink.aspx?guid=ec99e239-8917-48e3-bd4f-af866b730150"&gt;same
approach&lt;/a&gt; as I did last time. I threw together a quick little program called CrackMe2.
CrackMe2 has a really cool feature called &amp;#8220;Reverse Text&amp;#8221;, however, it's
only available to registered users. What's a poor boy to do?&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Target&lt;/strong&gt;
&lt;br&gt;
First, we try registering. Since we don't have a valid code (we don't even know what
one looks like), we get an &amp;#8220;Invalid serial.&amp;#8220; MessageBox. OK, so now we
know that the program does something when we click a button, and if the serial is
wrong, we get a MessageBox.&lt;br&gt;
&lt;br&gt;
&lt;img src="/blog/content/binary/crackMe2Invalid.gif" border=0&gt;
&lt;br&gt;
&lt;em&gt;Darn, 123 didn't work.&lt;/em&gt;
&lt;br&gt;
&lt;br&gt;
Well, the first step in cracking is defining our target and it's location. Our target
is the code that's deciding to&amp;nbsp;say&amp;nbsp;&amp;#8220;Invalid serial.&amp;#8221; instead
of &amp;#8220;You're registered!&amp;#8221;.&amp;nbsp;Where's the &amp;#8220;bad code&amp;#8220; that
needs to be fixed? Well, with a .NET assembly, our first information is gained by
taking a look with IL DASM.&lt;br&gt;
&lt;br&gt;
&lt;img src="/blog/content/binary/crackMe2ILDasmView.gif" border=0&gt;
&lt;br&gt;
&lt;em&gt;View of the obfuscated CrackMe2 assembly&lt;br&gt;
&lt;br&gt;
&lt;/em&gt;Oh no! It's obfuscated (thanks to &lt;a href="http://www.dotnetthis.com/Samples/Mangler.htm"&gt;Ivan
Medvedev's Mangler&lt;/a&gt;). Let's assume this is a big application and that we'll never
find what we're looking for just by going through the IL. Just by glancing at the
hierarchy, we don't know that much more than when we started: There's a form with
code.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Seeing past the names&lt;/strong&gt;
&lt;br&gt;
Now certainly, we can do static analysis and try to find out where the bad code is.
One way would be by getting the strings (Ctrl+M in IL DASM, scroll to the bottom),
and then grep the IL for ldstr 
&lt;TOKENNUMBER&gt;
, and work from there. In fact, that's a pretty quick and easy&amp;nbsp;way to locate&amp;nbsp;certain
parts.&amp;nbsp;However, lets pretend the strings are encrypted/dynamically generated,
and that's not viable. So, let's start debugging.&lt;br&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;[Michael@MAO C:\]$ cordbg CrackMe2.exe&lt;br&gt;
Microsoft (R) Common Language Runtime Test Debugger Shell Version 1.1.4322.573&lt;br&gt;
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;(cordbg) run CrackMe2.exe&lt;br&gt;
Process 4488/0x1188 created.&lt;br&gt;
Warning: couldn't load symbols for c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll&lt;br&gt;
[thread 0x1510] Thread created.&lt;br&gt;
Warning: couldn't load symbols for C:\CrackMe2.exe&lt;br&gt;
Warning: couldn't load symbols for c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll&lt;br&gt;
Warning: couldn't load symbols for c:\windows\assembly\gac\system\1.0.5000.0__b77a5c561934e089\system.dll&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;[0004] mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ecx,98543Ch&lt;br&gt;
(cordbg)&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
cordbg is a command line debugger that ships with the .NET Framework SDK, and it's
just loaded the CrackMe2.exe and related assemblies. Just like before, we're going
to go ahead and set a breakpoint and find out where we are in the program, and work
from there. So, let's breakpoint the MessageBox.Show function. We use IL-similar syntax
to specify the function name: NameSpace.ClassName::Method.&lt;br&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;(cordbg) b System.Windows.Forms.MessageBox::Show&lt;br&gt;
Breakpoint #1 has bound to c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll.&lt;br&gt;
#1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll!System.Windows.Forms.MessageBox::Show:0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Show+0x0(native) [active]&lt;br&gt;
(cordbg)&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
Then, we tell cordbg to go until it breaks by typing &lt;font face="Courier New"&gt;go&lt;/font&gt;.
The form comes up, and we enter a serial number: 123.&lt;br&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;(cordbg) go&lt;br&gt;
Warning: couldn't load symbols for c:\windows\assembly\gac\system.drawing\1.0.5000.0__b03f5f7f11d50a3a\system.drawing.dll&lt;br&gt;
break at #1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll!System.Windows.Forms.MessageBox::Show:0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Show+0x0(native) [active]&lt;br&gt;
Source not available when in the prolog of a function(offset 0x0)&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;[0000] push&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edi&lt;br&gt;
(cordbg)&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
Bingo, we're stopped at a MessageBox. We want to know who called this function, since
most likely, that will lead us to the critical code section we need to fix. So, we
ask cordbg &lt;font face="Courier New"&gt;where&lt;/font&gt; are we?&lt;br&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;(cordbg) where&lt;br&gt;
Thread 0x1510 Current State:Normal&lt;br&gt;
0)* system.windows.forms!System.Windows.Forms.MessageBox::Show +0000 [no source information
available]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
owner=(0x00ac36b0) 
&lt;CRACKME2.FORM1&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
text=(0x00ad5854) "Invalid serial."&lt;br&gt;
1)&amp;nbsp; CrackMe2!CrackMe2.Form1::AAAAAAAAAAAAAAAAAAAA +0070 [no source information
available]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
AAAAAA=(0x00ac8400) 
&lt;SYSTEM.WINDOWS.FORMS.BUTTON&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
A=(0x00aca86c) 
&lt;SYSTEM.EVENTARGS&gt;
&lt;br&gt;
2)&amp;nbsp; system.windows.forms!System.Windows.Forms.Control::OnClick +005e [no source
information available]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
e=(0x00aca86c) 
&lt;SYSTEM.EVENTARGS&gt;
&lt;br&gt;
&lt;/font&gt;&lt;em&gt;
&lt;CUT clarity for&gt;
&lt;br&gt;
&lt;/em&gt;&lt;font face="Courier New"&gt;9)&amp;nbsp; system.windows.forms!ControlNativeWindow::OnMessage
+0013 [no source information available]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
m=(0x0012ef04) 
&lt;SYSTEM.WINDOWS.FORMS.MESSAGE&gt;
&lt;br&gt;
--- Managed transition ---&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
We see what's expected. Somewhere in Win32 code, a message was sent, and we see the
OnMessage called and bubbling up all the way to the Control::OnClick, and then user
code. We can look at all the arguments along the way, and that's useful for more complex
scenarios (say, when a registration function calls another passing the serial number
or validation code).&lt;br&gt;
&lt;br&gt;
At any rate, we've got something to go on: The name of the function that calls the
MessageBox: CrackMe2.Form1::AAAAAAAAAAAAAAAAAAAA (20 A's). We're done with cordbg&amp;nbsp;(&lt;font face="Courier New"&gt;quit&lt;/font&gt;).
Our next stop is to read the bad code.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Looking at the bad code&lt;/strong&gt;
&lt;br&gt;
Using IL DASM (see above), I navigate to the CrackMe2.Form1::AAAAAAAAAAAAAAAAAAAA&amp;nbsp;method.
Inside is relatively straighforward code. First, there's a try/catch that has an Int32::Parse
call in it. The result is stored in local 0. So we now know the code is numeric. Immediately
after the catch handler, we have this snippet:&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp; IL_0022:&amp;nbsp; ldloc.0&lt;br&gt;
&amp;nbsp; IL_0023:&amp;nbsp; ldc.i4.1&lt;br&gt;
&amp;nbsp; IL_0024:&amp;nbsp; and&lt;br&gt;
&amp;nbsp; IL_0025:&amp;nbsp; ldc.i4.1&lt;br&gt;
&amp;nbsp; IL_0026:&amp;nbsp; bne.un.s&amp;nbsp;&amp;nbsp; IL_0035&lt;br&gt;
&amp;nbsp; IL_0028:&amp;nbsp; ldarg.0&lt;br&gt;
&amp;nbsp; IL_0029:&amp;nbsp; ldstr&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Invalid serial."&lt;br&gt;
&amp;nbsp; IL_002e:&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult
[System.Windows.Forms]System.Windows.Forms.MessageBox::Show(class [System.Windows.Forms]System.Windows.Forms.IWin32Window,
string)&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
Load the local (the number entered), then load the number 1, and AND them. Then, load
one, and if they are not equal, jump to IL_0035. If they are equal, execute the following
instructions, which quite obviously say &amp;#8220;Invalid serial.&amp;#8221;. AND'ing a number
with 1 and comparing to 1 is a check to see if the number is odd. So, at this point,
we can write a keygenerator that produces... even numbers. A keygenerator is always
preferred to a patch, however, generally speaking, finding the algorithm might be
a bit harder. Then, there's always the possibility that the check actually does something
hard to fake (i.e., uses RSA or talks to a hardware dongle/web service). So, let's
go on and patch this code.&lt;br&gt;
&lt;br&gt;
At IL_0035 (the target of the branch if the number is even), we have some code that
does activation work and then proceeds to say &amp;#8220;Thank you...&amp;#8221;. Simple sample.
Now, let's make the fix.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Simple Patching&lt;/strong&gt;
&lt;br&gt;
With IL DASM and IL ASM, we have a really easy way to make patches. Simply run ildasm
/out=CrackMe2.il CrackMe2.exe, and IL DASM will dump all the IL required for that
assembly to a nicely formatted file. All we have to do is goto the bad method and
fix up the IL. I think the most unintrusive fix would be to add &amp;#8220;br IL_0035&amp;#8221;
to the top of the method. That would branch immediately to the good code, and the
product would activate on any serial number entered.&lt;br&gt;
&lt;br&gt;
However, some obfuscators try to stop IL DASM round tripping, and that might stop
some posers in their tracks. The IL obfuscator I'm going to give away for free will
do this, for example. (Actually, my free obfuscator would make this tutorial a bit
harder because of how it handles names -- we'd have to actually get a token instead.)&lt;br&gt;
&lt;br&gt;
Assuming we can't use IL DASM/ASM, what can we do? Use a hex editor. 
&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Binary Patching&lt;/strong&gt;
&lt;br&gt;
When we can't reassemble an entire program, we can patch certain opcodes instead.
Tools like OllyDbg have a built-in assembler so we can easily make patches to the
x86 code. For IL, I'm not aware of any such tool. Another issue with binary patching
IL is that we have to ensure the resulting IL is fully correct and is able to be JIT'd
to native code. If our patch ends up screwing with the IL in a way that makes it incorrect,
we'll get a runtime exception from the execution engine. Let's try to create a binary
patch that jumps from the beginning of the method right to the good code, at IL offset
0x0035.&lt;br&gt;
&lt;br&gt;
First, in IL DASM, turn on &amp;#8220;Show bytes&amp;#8221;, under the View menu. This allows
us to see the actual bytes that make up the opcodes. Now, lets look at the beginning
of the critical function:&lt;br&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp; // Method begins at RVA 0x2434&lt;br&gt;
&amp;nbsp; // Code size&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 78 (0x4e)&lt;br&gt;
&amp;nbsp; .maxstack&amp;nbsp; 2&lt;br&gt;
&amp;nbsp; .locals init (int32 V_0)&lt;br&gt;
&amp;nbsp; .try&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0000:&amp;nbsp; /* 02&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
*/ ldarg.0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0001:&amp;nbsp; /* 7B&amp;nbsp;&amp;nbsp; | (04)000002&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
*/ ldfld&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class [System.Windows.Forms]System.Windows.Forms.TextBox
CrackMe2.Form1::AAAAAAAAAAAA&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0006:&amp;nbsp; /* 6F&amp;nbsp;&amp;nbsp; | (0A)000026&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
*/ callvirt&amp;nbsp;&amp;nbsp; instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_000b:&amp;nbsp; /* 28&amp;nbsp;&amp;nbsp; | (0A)000027&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
*/ call&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int32 [mscorlib]System.Int32::Parse(string)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0010:&amp;nbsp; /* 0A&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
*/ stloc.0&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0011:&amp;nbsp; /* DE&amp;nbsp;&amp;nbsp; | 0F&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
*/ leave.s&amp;nbsp;&amp;nbsp;&amp;nbsp; IL_0022&lt;br&gt;
&amp;nbsp; }&amp;nbsp; // end .try&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
This code is protected in a try block. We could go and remove the try block, but that's
modifying more code. Generally speaking, we should aim to patch as little code as
possible to ensure we don't accidentally screw something up. So, we're going to deal
with the try block and fix it from within. The ECMA specifications for .NET will come
in handy here. Specifically, Partition III, CIL. This can be found in the .NET Framework
SDK folder, under &amp;#8220;Tool Developers Guide\docs&amp;#8221;. It's also available from
MSDN, &lt;a href="http://msdn.microsoft.com/net/ecma/"&gt;here&lt;/a&gt;. 
&lt;br&gt;
&lt;br&gt;
The first instinct is to say, hey, let's change IL_0000 to a br to IL_0035, and NOP
out the remainder of the try block. However, that'd create illegal code, since you
can't branch out from a try block, you must use the leave opcode instead. So, let's
rewrite the method to simply leave to IL_0035. Here's the description of the leave
opcode:&lt;br&gt;
&lt;br&gt;
&lt;em&gt;The leave instruction unconditionally transfers control to target. Target is represented
as a signed offset (4 bytes for leave, 1 byte for leave.s) from the beginning of the
instruction following the current instruction.&lt;/em&gt;
&lt;br&gt;
&lt;br&gt;
The formats (in hex) are DD &amp;lt;4 bytes&amp;gt; for leave and DE &amp;lt;1 byte&amp;gt; (as shown
above), for leave.s. We'll use leave.s, just to be efficient :). Since the total size
for leave.s is 2 bytes, we calculate the offset to 0x35 from 0x02 (since our leave
instruction is at 0x00). Subtraction tells us we must have an offset of 0x33. Hence,
our leave instruction in hex looks like: DE 33. Since that'd leave the IL in an incorrect
state, we must nop out the rest of the try block. The hex for nop is 00.&lt;br&gt;
&lt;br&gt;
Open the assembly in your favorite hex editor, and let's find the method. IL DASM
gives us the RVA, but for now we'll just search for a specific byte sequence. The
IL DASM Show bytes allows us to easily find our place. Do note that the way tokens
are displayed ((04)000002, for example), is reverse from how they are stored. Depending
on the size of the app, you might need to search on quite a large number of bytes,
since IL sequences are most likely repeated. For this case, we're going to search
on the last bit: &amp;#8220;0A DE 0F&amp;#8221;. No other matches found, so this is the one.&lt;br&gt;
&lt;br&gt;
As when programming, in cracking we have many ways to solve a problem. Many of them
can be considered &amp;#8220;right&amp;#8221;.&amp;nbsp;We could make a simple one-byte patch
by allowing any number as a valid serial. This has the merit of ensuring the local
int is assigned, and well, being only a one-byte edit. The leave.s opcode is at offset
0x11, so add 2 to that amount and we get 0x13. 0x35 - 0x13 = 0x22. So by changing
&amp;#8220;0F&amp;#8221; to &amp;#8220;22&amp;#8221;, we'd have our crack. However, let's stick to
the original plan and jump right to the good bits from the beginning.&lt;br&gt;
&lt;br&gt;
In the hex editor, we back up a bit until we find the 02 7B 02 00 00 04 part (ldarg.0,
then load the textbox field). At the 02, we drop our leave.s IL_0035 payload, which
is DE 33. Then, we nop out (00) everything until the end of the 0A DE 0F part. The
resulting hex for the try block is thus:&amp;nbsp;DE 33 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00. Save the file as CrackMe2.cracked.exe.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;Satisfaction&lt;/strong&gt;
&lt;br&gt;
Run the program. Type in anything for the serial. &amp;#8220;Thank you for registering.&amp;#8221;
The second textbox activates. We've won access to the coveted &amp;#8220;Reverse Text&amp;#8221;
function.&amp;nbsp;Write up an .NFO, ensuring to remind people to purchase software to
support the authors. Then kick back and play a game of KSpaceDuel.&lt;br&gt;
&lt;br&gt;
Download the program itself (Right click and save as, since it's a .NET assembly and
IEExec will try to run it otherwise): &lt;a href="/blog/content/binary/CrackMe2.exe"&gt;CrackMe2.exe
(24 KB)&lt;/a&gt;. Or, download the source: &lt;a href="/blog/content/binary/CrackMe2.cs.txt"&gt;CrackMe2.cs.txt
(4.81 KB)&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
Was this post interesting, helpful, stupid, or lame? Leave a comment and help me improve.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=8315fa01-0286-47ce-a20b-fcc15eb297c3" /&gt;</description>
      <comments>http://www.atrevido.net/blog/CommentView,guid,8315fa01-0286-47ce-a20b-fcc15eb297c3.aspx</comments>
      <category>Code</category>
      <category>IL</category>
      <category>Security</category>
    </item>
    <item>
      <trackback:ping>http://www.atrevido.net/blog/Trackback.aspx?guid=f470710e-684e-474c-9ef0-26d807ff91a3</trackback:ping>
      <pingback:server>http://www.atrevido.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.atrevido.net/blog/PermaLink,guid,f470710e-684e-474c-9ef0-26d807ff91a3.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://www.atrevido.net/blog/CommentView,guid,f470710e-684e-474c-9ef0-26d807ff91a3.aspx</wfw:comment>
      <wfw:commentRss>http://www.atrevido.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f470710e-684e-474c-9ef0-26d807ff91a3</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Well, after quite some time, we've finally sent out the first beta of <a href="http://www.invisisource.net/">InvisiSource</a>.
It's an encrypted loader/obfuscator that I've been working on for quite some time.
The reason it's been taking so long is that when we approach obfuscation, we try to
make the obfuscation break as many rules as possible, to make the code even harder
to reverse engineer. Unfortunately, it's quite easy to break too many rules and end
up with something that won't run in every scenario. Over the past while, I've discovered
many tricks that'd throw quite a screwball at a potential cracker. Unfortunately,
the conditions on them make them unsuitable for every app. Other factors that took
a while: debugging encrypted code and obfuscated code is, by design, hard :). 
<br /><br />
Anyways, we're going to be giving out Xbox systems to the top three beta testers (which
is a good amount, considering the size of the tester pool). So, head on over to <a href="http://www.invisisource.net/">www.invisiSource.net</a> and
sign up!
</p>
        <img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=f470710e-684e-474c-9ef0-26d807ff91a3" />
      </body>
      <title>InvisiSource Beta Shipping - Win an Xbox</title>
      <guid isPermaLink="false">http://www.atrevido.net/blog/PermaLink,guid,f470710e-684e-474c-9ef0-26d807ff91a3.aspx</guid>
      <link>http://www.atrevido.net/blog/2004/07/08/InvisiSource+Beta+Shipping+Win+An+Xbox.aspx</link>
      <pubDate>Thu, 08 Jul 2004 07:08:41 GMT</pubDate>
      <description>&lt;p&gt;
Well, after quite some time, we've finally sent out the first beta of &lt;a href="http://www.invisisource.net/"&gt;InvisiSource&lt;/a&gt;.
It's an encrypted loader/obfuscator that I've been working on for quite some time.
The reason it's been taking so long is that when we approach obfuscation, we try to
make the obfuscation break as many rules as possible, to make the code even harder
to reverse engineer. Unfortunately, it's quite easy to break too many rules and end
up with something that won't run in every scenario. Over the past while, I've discovered
many tricks that'd throw quite a screwball at a potential cracker. Unfortunately,
the conditions on them make them unsuitable for every app. Other factors that took
a while: debugging encrypted code and obfuscated code is, by design, hard :). 
&lt;br&gt;
&lt;br&gt;
Anyways, we're going to be giving out Xbox systems to the top three beta testers (which
is a good amount, considering the size of the tester pool). So, head on over to &lt;a href="http://www.invisisource.net/"&gt;www.invisiSource.net&lt;/a&gt; and
sign up!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=f470710e-684e-474c-9ef0-26d807ff91a3" /&gt;</description>
      <comments>http://www.atrevido.net/blog/CommentView,guid,f470710e-684e-474c-9ef0-26d807ff91a3.aspx</comments>
      <category>IL</category>
      <category>Misc. Technology</category>
      <category>Security</category>
    </item>
    <item>
      <trackback:ping>http://www.atrevido.net/blog/Trackback.aspx?guid=fa034496-339a-44c1-800d-6184d11de8d1</trackback:ping>
      <pingback:server>http://www.atrevido.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.atrevido.net/blog/PermaLink,guid,fa034496-339a-44c1-800d-6184d11de8d1.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://www.atrevido.net/blog/CommentView,guid,fa034496-339a-44c1-800d-6184d11de8d1.aspx</wfw:comment>
      <wfw:commentRss>http://www.atrevido.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fa034496-339a-44c1-800d-6184d11de8d1</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was going to write a series about learning MSIL (Microsoft Intermediate Language,
or simply “IL“), and then get into more advanced topics.  However,
I found a good tutorial (and no doubt there's more if I use Google for am minute)
at CodeGuru, called <a href="http://www.codeguru.com/Csharp/.NET/net_general/il/article.php/c4635">MSIL
Tutorial</a>.  It should be enough to get people up to some speed.<br /><br />
I'll be writing some articles about how people actually attack programs, starting
with nice x86 assembler, and then showing how attacks against .NET programs can use
many of the same vectors.  I'll show how, even with some weak obfuscation (and
by weak I mean pretty much every product currently available), crackers still have
an easier time on .NET than on native x86/Win32.  Then I'll talk about some mitigation
techniques that can be used to make things somewhat harder.
</p>
        <img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=fa034496-339a-44c1-800d-6184d11de8d1" />
      </body>
      <title>Learning MSIL</title>
      <guid isPermaLink="false">http://www.atrevido.net/blog/PermaLink,guid,fa034496-339a-44c1-800d-6184d11de8d1.aspx</guid>
      <link>http://www.atrevido.net/blog/2004/02/29/Learning+MSIL.aspx</link>
      <pubDate>Sun, 29 Feb 2004 17:43:53 GMT</pubDate>
      <description>&lt;p&gt;
I was going to write a series about learning MSIL (Microsoft Intermediate Language,
or simply &amp;#8220;IL&amp;#8220;), and then get into more advanced topics.&amp;nbsp; However,
I found a good tutorial (and no doubt there's more if I use Google for am minute)
at CodeGuru, called &lt;a href="http://www.codeguru.com/Csharp/.NET/net_general/il/article.php/c4635"&gt;MSIL
Tutorial&lt;/a&gt;.&amp;nbsp; It should be enough to get people up to some speed.&lt;br&gt;
&lt;br&gt;
I'll be writing some articles about how people actually attack programs, starting
with nice x86 assembler, and then showing how attacks against .NET programs can use
many of the same vectors.&amp;nbsp; I'll show how, even with some weak obfuscation (and
by weak I mean pretty much every product currently available), crackers still have
an easier time on .NET than on native x86/Win32.&amp;nbsp; Then I'll talk about some mitigation
techniques that can be used to make things somewhat harder.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.atrevido.net/blog/aggbug.ashx?id=fa034496-339a-44c1-800d-6184d11de8d1" /&gt;</description>
      <comments>http://www.atrevido.net/blog/CommentView,guid,fa034496-339a-44c1-800d-6184d11de8d1.aspx</comments>
      <category>Code</category>
      <category>Security</category>
      <category>IL</category>
    </item>
  </channel>
</rss>