<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>WebstersProdigy &#187; C</title>
	<atom:link href="http://webstersprodigy.net/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://webstersprodigy.net</link>
	<description>Updates every other Friday... usually</description>
	<lastBuildDate>Sat, 26 May 2012 06:58:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='webstersprodigy.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>WebstersProdigy &#187; C</title>
		<link>http://webstersprodigy.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://webstersprodigy.net/osd.xml" title="WebstersProdigy" />
	<atom:link rel='hub' href='http://webstersprodigy.net/?pushpress=hub'/>
		<item>
		<title>Calculating an Integer Overflow</title>
		<link>http://webstersprodigy.net/2012/04/13/calculating-an-integer-overflow/</link>
		<comments>http://webstersprodigy.net/2012/04/13/calculating-an-integer-overflow/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 18:19:51 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[integer]]></category>
		<category><![CDATA[overflow]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=998</guid>
		<description><![CDATA[I was playing an exploit game yesterday, and had to compute an exact value for an integer overflow, which made me think (when I&#8217;ve run into this before, I&#8217;ve just had to get &#8216;close enough&#8217;). In the binary, it compares some user input to the integer 9, which it must be &#8220;less than&#8221; call _atoi [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=998&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I was playing an exploit game yesterday, and had to compute an exact value for an integer overflow, which made me think (when I&#8217;ve run into this before, I&#8217;ve just had to get &#8216;close enough&#8217;). In the binary, it compares some user input to the integer 9, which it must be &#8220;less than&#8221;</p>
<blockquote><p>call    _atoi<br />
mov     [ebp+var_C], eax<br />
cmp     [ebp+var_C], 9<br />
jle     short loc_8  ; process input and reach overflow</p></blockquote>
<p>n is then multiplied by 4 to make room for 9 ints</p>
<blockquote><p>shl     eax, 2</p></blockquote>
<p>var_c is then used as the n parameter in memcpy</p>
<blockquote><p>void *memcpy(void *dest, const void *src, size_t n);</p></blockquote>
<p>The vulnerability is possible (at least in part) to the shl, which can be used to wrap the integer and bypass the jle check.  It&#8217;s fairly obvious there is an integer overflow here, and in fact, calculating n to be an exact value is also not difficult. So in my case I wanted n in the memcpy call to equal exactly 80. </p>
<p>The very first thing I did was to look at this http://en.wikipedia.org/wiki/Two&#8217;s_complement, which I remember having to do in school.  It&#8217;s not complicated, but once you start throwing algebra in&#8230; anyway, so instead of using math I just wrote a wrapper program on the same machine.</p>
<p><pre class="brush: cpp;">
#include &lt;limits.h&gt;
#include &lt;stdio.h&gt;

void main()
{
  //this should be 80. Sanity check
  int y =  -INT_MAX - INT_MAX + 78;
  printf(&quot;%dn&quot;, y); 

  printf(&quot;%dn&quot;, INT_MAX);
}
</pre><br />
which prints</p>
<blockquote><p>2147483647<br />
80</p></blockquote>
<p>Then just plop this in a calculator.  Remember to divide by 4 to undo the multiply</p>
<blockquote><p>&gt;&gt;&gt; (-2147483647*2 + 78)/4.0<br />
-1073741804.0</p></blockquote>
<p>I entered this in the appropriate place, and set a breakpoint on the call to memcpy. </p>
<blockquote><p>(gdb) x/d $esp+8<br />
0xbffff2b8:	80</p></blockquote>
<p>Success, we&#8217;ve managed to set n to 80. This one took more time to write out than to solve, but hey, maybe it will be useful for someone. Plus I needed a filler today&#8230; I have some cool stuff I&#8217;m working on, but it won&#8217;t be ready until at least next post, or maybe the post after :)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/998/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/998/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/998/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/998/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/998/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/998/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/998/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/998/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=998&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2012/04/13/calculating-an-integer-overflow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>Some Interesting URI Parsing Quirks and Open Redirects</title>
		<link>http://webstersprodigy.net/2012/03/16/some-interesting-uri-parsing-quirks-and-open-redirects/</link>
		<comments>http://webstersprodigy.net/2012/03/16/some-interesting-uri-parsing-quirks-and-open-redirects/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 21:36:50 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[GrayHat]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[owasp]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[redirect]]></category>
		<category><![CDATA[uri]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=979</guid>
		<description><![CDATA[Parsing the &#8220;relativeness&#8221; of a URI seems to be a pretty browser specific thing, and doing some quick tests there are several quirks that might be useful/dangerous. The Tangled Web (which is an awesome book) aludes to some of these. Some URI Quirks Let&#8217;s look at some tests with the URIs grabbed from the location [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=979&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Parsing the &#8220;relativeness&#8221; of a URI seems to be a pretty browser specific thing, and doing some quick tests there are several quirks that might be useful/dangerous. The Tangled Web (which is an awesome book) aludes to some of these.</p>
<h3>Some URI Quirks</h3>
<p>Let&#8217;s look at some tests with the URIs grabbed from the location header. The browsers I&#8217;m testing right now are IE9, Chrome 17 something, and Firefox 11.</p>
<p>All browsers are happy with this, and go to google.com</p>
<blockquote><p>header(&#8220;Location: //google.com&#8221;);</p></blockquote>
<p>Both Firefox and chrome truncate extra slashes<br />
So</p>
<blockquote><p>header(&#8220;Location: <a href="http://google.com">http:///////////////////////google.com</a>&#8220;);</p></blockquote>
<p>is completely happy.</p>
<p>IE is interesting, as it will be equally happy with and /</p>
<blockquote><p>header(&#8220;Location: <a href="https://google.com/">https:\\google.com\</a>&#8220;); &lt;&#8211; this works</p></blockquote>
<p>The spacing doesn&#8217;t seem to matter, so all browsers are happy with:</p>
<blockquote><p>header(&#8220;Location:                        <a href="http://google.com">http://google.com</a>&#8220;);</p></blockquote>
<p>as well as</p>
<blockquote><p>header(&#8220;Location:http://google.com&#8221;);</p></blockquote>
<p>My favorite is this. In chrome and Firefox</p>
<blockquote><p>header(&#8220;Location: http:google.com&#8221;);</p></blockquote>
<p>will redirect to a relative URI, but for whatever reason</p>
<blockquote><p>header(&#8220;Location: <a href="https://google.com">https:google.com</a>&#8220;);</p></blockquote>
<p>will redirect to google.com. wtf?</p>
<h3>Same Domain Redirect</h3>
<p>These parsing quirks can be useful for several attacks, and the first thing that came to mind for me was open redirects.  It&#8217;s a pretty common scenario to want to allow sites  redirecting based on the parameter as long as it&#8217;s in the same domain. It can be expensive to whitelist every URI (which would be ideal), so although that&#8217;s a great solution, I also think allowing redirects to your own domain is sometimes better than nothing &#8230;despite there being some risks associated with it, like giving an attacker a way to bypass the IE8 XSS filter <a href="http://packetstorm.wowhacker.com/papers/general/msie-xssbypass.pdf">http://packetstorm.wowhacker.com/papers/general/msie-xssbypass.pdf</a>.</p>
<p>So, below are some (broken) examples of websites trying to accomplish this, allowing a redirect but only to their own site.</p>
<p><strong>Broken Example 1 &#8211; startswith /</strong></p>
<p>One naive way to try to perform arbitrary on-site local redirects would be something like the following, which takes the redir query parameter and make sure it starts with a slash:</p>
<p><pre class="brush: php;">
$redir = $_GET['redir'];
#if redir starts with /
if (strpos($redir, &quot;/&quot;, 0) === 0)
header(&quot;Location: &quot; . $redir);
</pre></p>
<p>Obviously, this can be bypassed in all browsers with //google.com</p>
<p><strong>Broken Example 2 - No Semicolons, Can&#8217;t start with /, and in fact, don&#8217;t start with // either</strong></p>
<p>This PHP tries to prevent off-site redirects with the following snippet</p>
<p><pre class="brush: php;">
$redir = $_GET['redir'];
#make sure redir doesn't have slashes, and doesn't have semicolons
if ((strpos($redir, &quot;/&quot;, 0) != 0) and (strpos($redir, &quot;/&quot;, 1) != 1) and (strpos($redir, &quot;:&quot;) === false))
{
header(&quot;Location: &quot; . $redir);
}
</pre></p>
<p>Because you can prepend spaces, one way to bypass this is to send the following:</p>
<blockquote><p>redir=%20%20//google.com</p></blockquote>
<p><strong>Broken Example 3 &#8211; No Slashes at all</strong></p>
<p>Ok, what if there are no slashes are allowed at all? You can&#8217;t very well have <a href="http://blah.com">http://blah.com</a> without a slash, after all, so this intuitively might make sense. The code for this might look something like:</p>
<p><pre class="brush: php;">
$redir = $_GET['redir'];
#if no / in the string
if (strpos($redir, &quot;/&quot;) === false)
  header(&quot;Location: &quot; . $redir);
</pre></p>
<p>However, using the quirks above, this can be bypassed by using redir=https:google.com in FF and chrome, and it can be bypassed in IE with redir=\google.com</p>
<p><strong>Broken Example 4 &#8211; Built in Libraries:</strong></p>
<p>Surely there are libraries that solve this problem. Well, maybe there are, but there are certainly libraries people use to <em>try</em> to solve this problem, but they don&#8217;t do it as people expect (e.g. a library might call a URI relative when a browser treats it as absolute). Making a library that works well is a fundamentally tough problem because all these browsers have quirks and the library has to match all browsers. So is a library supposed to call <a href="https://google.com">https:google.com</a> a relative or a full uri? (it&#8217;s relative in IE but full in chrome and FF)</p>
<p>Here&#8217;s one C# example where someone might try to figure out if a URI is relative URI using the IsAbsoluteUri property in .net system.Uri.</p>
<p><pre class="brush: cpp;">
        static void Main(string[] args)
        {

            String[] uriArray = new String[] {
                &quot;//google.com/test.html&quot;,                 //relative
                &quot;\\google.com\test.html&quot;,              //relative
                &quot;/////////google.com/test.html&quot;,          //relative
                &quot;https:google.com&quot;,                       //relative
                &quot;http://google.com&quot;,                      //absolute
                &quot;http:///////////////////google.com&quot;,     //absolute
                &quot;           http://google.com&quot;            //absolute
            };

            foreach (String uriString in uriArray)
            {
                try
                {
                    Uri uri = new Uri(uriString, UriKind.Relative); //works
                    if (!uri.IsAbsoluteUri)
                    {
                        Console.WriteLine(&quot;is a relative URI: {0}&quot;, uriString);
                    }
                }
                catch (UriFormatException e)
                {
                    Console.WriteLine(&quot;not a relative URI: {0}&quot;, uriString);
                }
            }
        }
</pre></p>
<p><strong>Broken Example 5 &#8211; startswith Whitelisted Domain</strong></p>
<p>This is a classic example. Even though it doesn&#8217;t have much do do with parsing quirks, it can be subtle and illustrates an important point.  So say an application does the following to make sure the redirect is on the correct domain.</p>
<p><pre class="brush: cpp;">
String redir = Request[&quot;redir&quot;];
if (redir.StartsWith(&quot;http://goodsite.com&quot;))
{
	Response.Redirect(redir);
}
</pre></p>
<p>Can an attacker still exploit this? The answer is yes, by setting redir=http://goodsite.com.badsite.com/</p>
<h3>What&#8217;s the Right Way to do on-domain Redirects?</h3>
<p>So open redirects are in the owasp top ten, and they have some guidance here: <a href="https://www.owasp.org/index.php/Top_10_2010-A10-Unvalidated_Redirects_and_Forwards">https://www.owasp.org/index.php/Top_10_2010-A10-Unvalidated_Redirects_and_Forwards</a>. However, to summarize, it basically says to whitelist and don&#8217;t redirect. I do agree, but again, what if you want to do on-domain redirects? The best I can think of is to do something like this:</p>
<blockquote><p>startswith(http://goodsite.com/ || <a href="https://google.com/">https://goodsite.com/</a>)</p></blockquote>
<p>Note the trailing slash, which prevents broken example #5.  I don&#8217;t think it&#8217;s possible to redirect off-site with this type of code&#8230; but if someone knows otherwise, I&#8217;d definitely be interested in how to do it :)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/979/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=979&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2012/03/16/some-interesting-uri-parsing-quirks-and-open-redirects/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>Reverseme: Namegenme</title>
		<link>http://webstersprodigy.net/2010/06/13/reverseme-namegenme/</link>
		<comments>http://webstersprodigy.net/2010/06/13/reverseme-namegenme/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 03:31:45 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[GrayHat]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[IDA]]></category>
		<category><![CDATA[reverseme]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=680</guid>
		<description><![CDATA[This guy is here: http://crackmes.de/users/moofy/moofys_namegenme/ namegenme.zip I had a fairly hard time with this one for some reason, although the solution was right in front of my face&#8230; Most the logic for calculating the generation is in the function 00401852. The Serial is stored in a global variable, and the name is generated by taking [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=680&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This guy is here: http://crackmes.de/users/moofy/moofys_namegenme/</p>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!153&amp;parid=19794FAC33285FD5!109">namegenme.zip</a></p>
<p>I had a fairly hard time with this one for some reason, although the solution was right in front of my face&#8230;</p>
<p>Most the logic for calculating the generation is in the function 00401852. The Serial is stored in a global variable, and the name is generated by taking certain bytes from the serial and doing addition on them.</p>
<p>Here is all the relevant logic, although finding it was sort of a pain.</p>
<p><pre class="brush: cpp;">

.text:004018FD                 lea     eax, [ebp+var_10]
.text:00401900                 add     dword ptr [eax], 4
.text:00401903                 lea     eax, [ebp+var_14]
.text:00401906                 sub     dword ptr [eax], 3
.text:00401909                 lea     eax, [ebp+var_18]
.text:0040190C                 sub     dword ptr [eax], 2
.text:0040190F                 lea     eax, [ebp+var_1C]
.text:00401912                 add     dword ptr [eax], 2
.text:00401915                 lea     eax, [ebp+var_20]
.text:00401918                 dec     dword ptr [eax]
.text:0040191A                 lea     eax, [ebp+var_24]
.text:0040191D                 add     dword ptr [eax], 3
.text:00401920                 lea     eax, [ebp+var_28]
.text:00401923                 sub     dword ptr [eax], 2
.text:00401926                 lea     eax, [ebp+var_2C]
.text:00401929                 sub     dword ptr [eax], 4
.text:0040192C                 lea     eax, [ebp+var_30]
.text:0040192F                 add     dword ptr [eax], 3
.text:00401932                 lea     eax, [ebp+var_34]
.text:00401935                 inc     dword ptr [eax]
</pre></p>
<p>Here is a keygen written in C</p>
<p><pre class="brush: cpp;">
void main(int argc, char* argv[]) {

  char Name [10];
  char* ser = argv[1];
  if (argc != 2 || strlen(argv[1]) &lt; 21) {
    printf(&quot;Invalid serialn&quot;);
	return (-1);
  }

  Name[0] = ser[0] + 4;
  Name[1] = ser[1] - 3;
  Name[2] = ser[2] - 2;
  Name[3] = ser[6] + 2;
  Name[4] = ser[7] - 1;
  Name[5] = ser[8] + 3;
  Name[6] = ser[13] - 2;
  Name[7] = ser[14] - 4;
  Name[8] = ser[15] + 3;
  Name[9] = ser[20] + 1;
  Name[10] = &quot;&#092;&#048;&quot;;

  printf(&quot;Name: %sn&quot;, Name);
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/680/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/680/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/680/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/680/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/680/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/680/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/680/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=680&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2010/06/13/reverseme-namegenme/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>Reverseme: Easy Windows</title>
		<link>http://webstersprodigy.net/2010/06/08/reverseme-easy-windows/</link>
		<comments>http://webstersprodigy.net/2010/06/08/reverseme-easy-windows/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 03:51:49 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[GrayHat]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[crackmes]]></category>
		<category><![CDATA[keygen]]></category>
		<category><![CDATA[pe]]></category>
		<category><![CDATA[solution]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=668</guid>
		<description><![CDATA[To get back into the groove, I decided to try a crackme. After searching far and wide, I can&#8217;t seem to find where I got this from, other than crackmes.de.  One of my favorite sites. Crackme.zip &#60;&#8211; here it is in case it&#8217;s deleted. And the solution is, with no analysis: Ok, one hint. All the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=668&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>To get back into the groove, I decided to try a crackme. After searching far and wide, I can&#8217;t seem to find where I got this from, other than crackmes.de.  One of my favorite sites.</p>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!151&amp;parid=19794FAC33285FD5!109">Crackme.zip </a>&lt;&#8211; here it is in case it&#8217;s deleted.</p>
<p>And the solution is, with no analysis:</p>
<p><pre class="brush: cpp;">

#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int add_name_chars(string name) {
  int total = 0;
  for (int i=0; i&lt;name.length(); i++) {
    total += name[i];
  }
  return total;
}

int main() {
  string name;
  cout&lt;&lt;&quot;Name: &quot;;
  cin&gt;&gt;name;

  unsigned int ser1 = 31 * add_name_chars(name) / 629u + 44431400;
  while (ser1 &gt; 0x3b9ac9ff) {
    ser1 /= 10;
  }
  cout&lt;&lt;&quot;Serial 1: &quot;&lt;&lt;ser1&lt;&lt;endl;

  unsigned int ser2 = 82 * ser1 - 3;
  while (ser2 &gt; 0x1869f)  {
    ser2 /= 10;
  }

  cout&lt;&lt;&quot;Serial 2: &quot;&lt;&lt;ser2&lt;&lt;endl;
  return 0;
}
</pre></p>
<p>Ok, one hint. All the logic is at 004013BC. This was rated as 1, for newbies, but it still took me awhile to figure out. I thought it was fun.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/668/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/668/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/668/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/668/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/668/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/668/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/668/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/668/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=668&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2010/06/08/reverseme-easy-windows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>calling convention cheat sheet</title>
		<link>http://webstersprodigy.net/2010/01/21/calling-convention-cheat-sheet/</link>
		<comments>http://webstersprodigy.net/2010/01/21/calling-convention-cheat-sheet/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 02:21:50 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[compiler]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=655</guid>
		<description><![CDATA[cdecl, stdcall, fastcall, c++<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=655&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>cdecl, stdcall, fastcall, c++</p>
<p>Overgeneralization, but may be helpful.</p>
<ul>
<li><strong>cdecl:</strong> parameters right to left on the stack, caller places parameters and removes parameters. gcc uses this.</li>
<li><strong>stdcall:</strong> similar to cdecl, but callee removes function parameters from the stack when finished. Advantage, clean up code doesn&#8217;t need to be rewritten for each function. disadvantage, unknown number of parameters are impossible (printf) Microsoft compilers use this</li>
<li><strong>fastcall</strong> stdcall, but uses two parameters in cpu registers (ecx and then edx)</li>
<li><strong>c++</strong> &#8216;this&#8217; is passed in ecx (ms visual c++) or passed as first parameter (g++)</li>
</ul>
<p>More handy is this: http://en.wikipedia.org/wiki/X86_calling_conventions<br />
awesome</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/655/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/655/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/655/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/655/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/655/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/655/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/655/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=655&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2010/01/21/calling-convention-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>Finished RTOS similar to FreeRTOS</title>
		<link>http://webstersprodigy.net/2009/07/25/finished-rtos-similar-to-freertos/</link>
		<comments>http://webstersprodigy.net/2009/07/25/finished-rtos-similar-to-freertos/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 20:31:02 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[atmega16]]></category>
		<category><![CDATA[avr]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[rtos]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=558</guid>
		<description><![CDATA[This is an RTOS developed by myself, with some code taken from FreeRTOS. This is some of the most difficult code I have ever written, although it really doesn't do anything useful. Man, context switching in C can be a bear! It's like a programatic buffer overflow! (seriously, you do a function call and just pop off enough stuff to overwrite the instruction pointer).<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=558&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is an RTOS developed by myself, with some code taken from FreeRTOS. This is some of the most difficult code I have ever written, although it really doesn&#8217;t do anything useful. Man, context switching in C can be a bear! It&#8217;s like a programatic buffer overflow! (seriously, you do a function call and just pop off enough stuff to overwrite the instruction pointer).</p>
<h3>Framework</h3>
<blockquote><p>The purpose of this assignment is to begin implementing our RTOS.</p>
<p>You are to implement the first several functions and data items listed in the UIKAPI documentation: UIKInitialize, UIKAddTask, UIKRun, UIKDelay, and the internals UIKDispatcher, UIKIdle, UIKTickHandler, UIKTicknum, UIKTickLen, and UIKIntDepth. This will also involve the implementation of the context-switching mechanism you will use inside the process of switching tasks.</p>
<p>In order to demonstrate your scheduler and the use of the API, you can modify some of your earlier assignments to use the API, or write new tasks. You should be able to demonstrate the current execution of at least three tasks at once, all being scheduled by your system.</p></blockquote>
<p>The code will follow at the end, but first, a video demonstration.</p>
<span style="text-align:center; display: block;"><a href="http://webstersprodigy.net/2009/07/25/finished-rtos-similar-to-freertos/"><img src="http://img.youtube.com/vi/590vf6cGh8g/2.jpg" alt="" /></a></span>
<h3>Semaphores</h3>
<blockquote><p>The purpose of this assignment is to add counting semaphores to theUIKAPI. This assignment<br />
can be done in groups of up to two people.</p>
<p>You are to implement the following counting ssemaphore functions:</p>
<p>+ UIKSem* UIKSemCreate(); &#8211; will create and initialize a new counting semaphore. The<br />
new semaphore should be initialized to 1. The function should return a pointer to the<br />
new semaphore, or a value of -1 if there was problem creating the semaphore.<br />
+ void UIKSemPend(UIKSem* sem); &#8211; will perform the P(s) (wait or test or acquire) operation<br />
on the semaphore. This function should decrement the semaphore value, and if<br />
the result is negative, should block the requesting task.<br />
+ void UIKSemPost(UIKSem* sem); &#8211; will perfrmthe V (s) (signal or release) operation on<br />
the semophore. This function is the one that should be called when a task is leaving a<br />
critical section. It should increment the semaphore value, and if the result is less than or<br />
equal to zero, should unblock the highest priority task that is waiting on the semaphore<br />
by changing its state to ready.<br />
+ INT8 UIKSemValue(UIKSem* sem); &#8211; will return the current value of the semaphore.</p>
<p>In addition to implementing the semaphore functions, design a set of tasks that demonstrates<br />
the proper operation of your semaphore functions.</p></blockquote>
<p>The critical sections are implemented by disabling interrupts.  In this assignment, there is a task that delays in the middle of a semaphore lock to demonstrate the trace when two tasks are fighting for the same resource.</p>
<p>Alrighty, so here is a video demonstrating this:</p>
<span style="text-align:center; display: block;"><a href="http://webstersprodigy.net/2009/07/25/finished-rtos-similar-to-freertos/"><img src="http://img.youtube.com/vi/VLralBDFMnc/2.jpg" alt="" /></a></span>
<h3>Event Queues</h3>
<blockquote><p>The purpose of this assignment is to add event queues and the associated support routines to<br />
the UIKAPI. This is the last piece of the UIK we will implement &#8211; yeah!</p>
<p>A common requirement is for a task to wait until an event occurs. An event is usually some<br />
sort of externally-triggered operation, such as an I/O device requiring service or a timer going<br />
off. One possibility is for an interrupt service routine to set an event flag, then allow tasks to<br />
wait until that flag is set. Once the flag is set, the task can become ready.</p>
<p>An event flag group is an O/S global variable (byte) that represents events by bits. For the<br />
purpose of this exercise, only one event flag will be defined: Bit 0 represents a timer event.<br />
This flag should be set whenever an auxilliary timer goes off. For our implementation, this<br />
timer can be implemented using one of the timers built into the Atmel AVR, spearate from the<br />
timer you are using for the tick. You should write in ISR that handles an interrupt from this<br />
timer by setting bit 0 in the event flags variable.</p>
<p>You are to implement the following event functions:</p>
<p>+ void UIKAssocEvent(int Event); &#8211; will cause the task to become ¿associated¿ with<br />
the flag(s) specified by Event. Event is a value that specifies the bits representing one or<br />
more events that the task should be associated with. The task should then block until the<br />
event occurs.<br />
+ void UIKDisassocEvent(int Event); &#8211; causes the task to no longer be associated with<br />
the event. In other words, the task will not be scheduled when the event occurs.</p>
<p>In addition to implementing the semaphore functions, design an application that demonstrates<br />
the proper operation of your event functions.</p></blockquote>
<p>Events are fairly straightforward. project6 adds a timer0 event. taskblinky3 (in tasks.h/tasks.c) is associated with a timer0 overflow via a call to UIKAssocEvent (which sets the task to a wait state and associates the function with the flag). It uses a global flag, EVENT, to keep track of when an interupt occurs. Then, during the tick, if this EVENT flag is set then the function associated with this event will be set to ready.</p>
<p>Here is a video of this:<br />
<span style="text-align:center; display: block;"><a href="http://webstersprodigy.net/2009/07/25/finished-rtos-similar-to-freertos/"><img src="http://img.youtube.com/vi/suYJ2i7QOXM/2.jpg" alt="" /></a></span></p>
<h3>Code</h3>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!148&amp;parid=19794FAC33285FD5!140">lundeen_rtos.tar.gz</a></p>
<p>I guess I&#8217;ll post most of it inline here too, because why not?</p>
<p><pre class="brush: cpp;">
//main.c
/*
 * This is a simple demonstration of the uik api.
 * It schedules 3 simple tasks and lets the scheduler take over execution
 */

#include &quot;uik.h&quot;
#include &quot;tasks.h&quot;

/* As per the specs, TICKLEN is the number of 10^-9 seconds on a 1MHz chip */
/* as set below it 1 TICKLEN == 1/100 seconds */
const int TICKLEN = 10000;

/*declare vars in tasks.h */
extern uint8_t taskblinky_stack[64];
extern void taskblinky();
extern uint8_t taskblinky2_stack[64];
extern void taskblinky2();
extern uint8_t taskblinky3_stack[64];
extern void taskblinky3();
extern uint8_t taskcount_stack[80];
extern void taskcount();

extern UIKSem* portbsem;

void init_timer0() {
  /*prescaler/64*/
  TCCR0 |= ((1 &lt;&lt; CS01) | (1 &lt;&lt; CS00));
  /*overflow mode - about every 1/61 seconds */
  TIMSK |= (1 &lt;&lt; TOIE0);
}

void main(void) {
  int id;

  /*Initialize the ports */
  DDRB = 0xff;
  DDRD = 0x00;

  /*semaphore to protect portb */
  portbsem = UIKSemCreate();
  PORTB = 0xff;

  /*Initialize the RTOS - this sets up the timer */
  UIKInitialize(TICKLEN);

  /*Tell the RTOS about our tasks */
  id = UIKADDTask(&amp;taskblinky, 42, taskblinky_stack, 64);
  UIKRun(id);
  id = UIKADDTask(&amp;taskblinky2, 35, taskblinky2_stack, 64);
  UIKRun(id);
  id = UIKADDTask(&amp;taskblinky3, 99, taskblinky3_stack, 64);
  UIKRun(id);
  id = UIKADDTask(&amp;taskcount, 30, taskcount_stack, 80);
  UIKRun(id);

  /*this is an external event we make use of */
  init_timer0();

  /*this enables interupts, so doesn't need to be done in main */
  startrtos();
}

</pre></p>
<p><pre class="brush: cpp;">
//tasks.h
/*
 * This is a simple demonstration of the uik api.
 * It schedules 3 simple tasks and lets the scheduler take over execution
 */

#include &quot;uik.h&quot;
#include &quot;tasks.h&quot;

/* As per the specs, TICKLEN is the number of 10^-9 seconds on a 1MHz chip */
/* as set below it 1 TICKLEN == 1/100 seconds */
const int TICKLEN = 10000;

/*declare vars in tasks.h */
extern uint8_t taskblinky_stack[64];
extern void taskblinky();
extern uint8_t taskblinky2_stack[64];
extern void taskblinky2();
extern uint8_t taskblinky3_stack[64];
extern void taskblinky3();
extern uint8_t taskcount_stack[80];
extern void taskcount();

extern UIKSem* portbsem;

void init_timer0() {
  /*prescaler/64*/
  TCCR0 |= ((1 &lt;&lt; CS01) | (1 &lt;&lt; CS00));
  /*overflow mode - about every 1/61 seconds */
  TIMSK |= (1 &lt;&lt; TOIE0);
}

void main(void) {
  int id;

  /*Initialize the ports */
  DDRB = 0xff;
  DDRD = 0x00;

  /*semaphore to protect portb */
  portbsem = UIKSemCreate();
  PORTB = 0xff;

  /*Initialize the RTOS - this sets up the timer */
  UIKInitialize(TICKLEN);

  /*Tell the RTOS about our tasks */
  id = UIKADDTask(&amp;taskblinky, 42, taskblinky_stack, 64);
  UIKRun(id);
  id = UIKADDTask(&amp;taskblinky2, 35, taskblinky2_stack, 64);
  UIKRun(id);
  id = UIKADDTask(&amp;taskblinky3, 99, taskblinky3_stack, 64);
  UIKRun(id);
  id = UIKADDTask(&amp;taskcount, 30, taskcount_stack, 80);
  UIKRun(id);

  /*this is an external event we make use of */
  init_timer0();

  /*this enables interupts, so doesn't need to be done in main */
  startrtos();
}

lundeen@AnnieWilkes:~/classes/rtos/project6/project6$ ls
default  main.c  project6.aps  project6.avi  project6.aws  README  sourceLineMap.txt  tasks.c  tasks.h  uik.c  uik.h
lundeen@AnnieWilkes:~/classes/rtos/project6/project6$ cat tasks.h
/*This file contains prototypes of the tasks that will be added */

#ifndef TASKS_H
#define TASKS_H

#include &quot;uik.h&quot;
#include

/*semaphore to protect portb */
UIKSem* portbsem;

/*declare places to save contexts */
uint8_t taskblinky_stack[64] __attribute__((weak));
/*flash PORTB (tested with LEDs) */
void taskblinky();

/*declare places to save contexts - this has a forced conflict with blinky*/
uint8_t taskblinky2_stack[64] __attribute__((weak));
/*flash PORTB (tested with LEDs) */
void taskblinky2();

/*declare places to save contexts */
uint8_t taskblinky3_stack[64] __attribute__((weak));
/*flash PORTB (tested with LEDs) */
void taskblinky3();

/*count the lower bytes of PORTB up from 0 to 8 */
uint8_t taskcount_stack[80] __attribute__((weak));
void taskcount();

#endif

</pre></p>
<p><pre class="brush: cpp;">
//tasks.h
/*This file contains prototypes of the tasks that will be added */

#ifndef TASKS_H
#define TASKS_H

#include &quot;uik.h&quot;
#include

/*semaphore to protect portb */
UIKSem* portbsem;

/*declare places to save contexts */
uint8_t taskblinky_stack[64] __attribute__((weak));
/*flash PORTB (tested with LEDs) */
void taskblinky();

/*declare places to save contexts - this has a forced conflict with blinky*/
uint8_t taskblinky2_stack[64] __attribute__((weak));
/*flash PORTB (tested with LEDs) */
void taskblinky2();

/*declare places to save contexts */
uint8_t taskblinky3_stack[64] __attribute__((weak));
/*flash PORTB (tested with LEDs) */
void taskblinky3();

/*count the lower bytes of PORTB up from 0 to 8 */
uint8_t taskcount_stack[80] __attribute__((weak));
void taskcount();

#endif

</pre></p>
<p><pre class="brush: cpp;">
//uik.h
/*
 * uik.h contains the header for the uik kernel
 */

#ifndef UIK_H
#define UIK_H

#include
#include

#include
#include

#define max_numtasks 16

typedef enum { wait, ready, run, initialized } task_state;

typedef struct task_context {
  volatile task_state state;
  uint8_t priority;
  //stack_ptr includes registers, sreg, ip, - eg context
  uint8_t* stack_ptr;
  //delay is the amount of time the process must wait
  uint32_t delay;
} task_context;

/* for now, just make a static array for tcb
   TODO: make tcb into something better, like a linked list */
volatile task_context tcb[max_numtasks];

/*saves the current context */
void savecontext( ) __attribute__((naked));
/*restores the context of the taskid */
void restorecontext(uint8_t id) __attribute__((naked));

void UIKInitialize(uint16_t ticklen);
uint8_t UIKADDTask(void* task_ptr, uint8_t priority, uint8_t* buffer_ptr, uint16_t stack_size);
void UIKRun(uint8_t taskid);
void SIG_OUTPUT_COMPARE1A(void) __attribute__ ((signal, naked));
void tick(void);
void ticknodelay(void);
void startrtos(void) __attribute__ ((naked));
void UIKDelay(uint32_t ticks) __attribute__ ((naked));

/*the idle task should always be part of the tasklist */
uint8_t idletask_stack[64] __attribute__((weak));
void idletask();

/*semaphores */

typedef struct _UIKSem {
  uint8_t value;
} UIKSem;

UIKSem* UIKSemCreate();
unsigned char semtest(UIKSem* sem);
void UIKSemPend(UIKSem* sem);
void UIKSemPost(UIKSem* sem);
uint8_t UIKSemValue(UIKSem* sem);

/*Events */

/*MAX_EVENTS cannot be larger than the size of EVENT_FLAG*/
#define MAX_EVENTS 8
#define PORT0_OVERFLOW 0
/*bit 0 of event_flag is associated with a timer0 interrupt */
unsigned char EVENT_FLAG;

uint8_t ASS_BLOCK[MAX_EVENTS];
void UIKAssocEvent(uint8_t Event);
void UIKDisassocEvent(uint8_t Event);

#endif
</pre></p>
<p><pre class="brush: cpp;">
/*
 * uik.c contains the source for the uik kernel
 */

#include &quot;uik.h&quot;

int numtasks = 0;

/*0 is always the idle task, which is the default curr_task */
int curr_task = 0;

/*pointer to current task */
volatile uint8_t* currTCB;

/*
 * macro for saving the context: first saves sreg, disables interrupts
 * pushes all general purpose registers on the stack and saves where the
 * stack is at
 */

#define savecontext()
  asm volatile ( &quot;push  r0               nt&quot;
                 &quot;in    r0, __SREG__     nt&quot;
                 &quot;cli                    nt&quot;
                 &quot;push  r0               nt&quot;
                 &quot;push  r1               nt&quot;
                 &quot;clr   r1               nt&quot;
                 &quot;push  r2               nt&quot;
                 &quot;push  r3               nt&quot;
                 &quot;push  r4               nt&quot;
                 &quot;push  r5               nt&quot;
                 &quot;push  r6               nt&quot;
                 &quot;push  r7               nt&quot;
                 &quot;push  r8               nt&quot;
                 &quot;push  r9               nt&quot;
                 &quot;push  r10              nt&quot;
                 &quot;push  r11              nt&quot;
                 &quot;push  r12              nt&quot;
                 &quot;push  r13              nt&quot;
                 &quot;push  r14              nt&quot;
                 &quot;push  r15              nt&quot;
                 &quot;push  r16              nt&quot;
                 &quot;push  r17              nt&quot;
                 &quot;push  r18              nt&quot;
                 &quot;push  r19              nt&quot;
                 &quot;push  r20              nt&quot;
                 &quot;push  r21              nt&quot;
                 &quot;push  r22              nt&quot;
                 &quot;push  r23              nt&quot;
                 &quot;push  r24              nt&quot;
                 &quot;push  r25              nt&quot;
                 &quot;push  r26              nt&quot;
                 &quot;push  r27              nt&quot;
                 &quot;push  r28              nt&quot;
                 &quot;push  r29              nt&quot;
                 &quot;push  r30              nt&quot;
                 &quot;push  r31              nt&quot;
                 &quot;lds  r26, currTCB      nt&quot;
                 &quot;lds  r27, currTCB+1    nt&quot;
                 &quot;in    r0, 0x3d         nt&quot;
                 &quot;st    x+, r0           nt&quot;
                 &quot;in    r0, 0x3e         nt&quot;
                 &quot;st    x+, r0           nt&quot;
        );

/*
 * Opposite to savecontext().  Interrupts will have been disabled during
 * the context save so we can write to the stack pointer.
 */

#define restorecontext()
  asm volatile (    &quot;lds    r26, currTCB               nt&quot;
                    &quot;lds    r27, currTCB+1             nt&quot;
                    &quot;ld     r28, x+                    nt&quot;
                    &quot;out    __SP_L__, r28              nt&quot;
                    &quot;ld        r29, x+                 nt&quot;
                    &quot;out    __SP_H__, r29              nt&quot;
                    &quot;pop    r31                        nt&quot;
                    &quot;pop    r30                        nt&quot;
                    &quot;pop    r29                        nt&quot;
                    &quot;pop    r28                        nt&quot;
                    &quot;pop    r27                        nt&quot;
                    &quot;pop    r26                        nt&quot;
                    &quot;pop    r25                        nt&quot;
                    &quot;pop    r24                        nt&quot;
                    &quot;pop    r23                        nt&quot;
                    &quot;pop    r22                        nt&quot;
                    &quot;pop    r21                        nt&quot;
                    &quot;pop    r20                        nt&quot;
                    &quot;pop    r19                        nt&quot;
                    &quot;pop    r18                        nt&quot;
                    &quot;pop    r17                        nt&quot;
                    &quot;pop    r16                        nt&quot;
                    &quot;pop    r15                        nt&quot;
                    &quot;pop    r14                        nt&quot;
                    &quot;pop    r13                        nt&quot;
                    &quot;pop    r12                        nt&quot;
                    &quot;pop    r11                        nt&quot;
                    &quot;pop    r10                        nt&quot;
                    &quot;pop    r9                         nt&quot;
                    &quot;pop    r8                         nt&quot;
                    &quot;pop    r7                         nt&quot;
                    &quot;pop    r6                         nt&quot;
                    &quot;pop    r5                         nt&quot;
                    &quot;pop    r4                         nt&quot;
                    &quot;pop    r3                         nt&quot;
                    &quot;pop    r2                         nt&quot;
                    &quot;pop    r1                         nt&quot;
                    &quot;pop    r0                         nt&quot;
                    &quot;out    __SREG__, r0               nt&quot;
                    &quot;pop    r0                         nt&quot;
                );
/*
 * UIKInitialize sets up the timer, and adds the idle task to tcb
 */

void UIKInitialize(uint16_t ticklen) {
  int i;

  // setup timer - timer1 is used so we can use 16 bits
  TCCR1B |= (1 &lt;&lt; WGM12);
  //enable CTC interrupt
  TIMSK |= (1 &lt;&lt; OCIE1A);
  OCR1A = ticklen;

  //not default:timer runs with /64 resolution
  //TCCR1B |= ((1 &lt;&lt; CS10) | (1 &lt;&lt; CS11));
  //default: timer1 runs at 1MHz on the atmega16 so ticklen can be specified in microsecs
  TCCR1B |= (1 &lt;&lt; CS10);

  // add the idle task as the task with lowest priority */
  UIKADDTask(&amp;idletask, 255, idletask_stack, 64);

  //initialize the ASS_BLOCK so that there are no events associated
  //with anything - note interupts are not enabled yet
  for(i=0; i max_numtasks) {
    //error, tcb is not big enough, need to increase max_numtasks in uik.h
    return (-1);
  }
  //setup parameters
  //&quot;initialized&quot; could be changed to ready without much effect, but UIKRun would
  //not have to be called
  tcb[numtasks].state = initialized;
  tcb[numtasks].priority = priority;
  tcb[numtasks].delay = 0;

  // place a few known bytes on the bottom - useful for debugging
  // tcb[numtasks].stack_lptr = stack_ptr;
  tcb[numtasks].stack_ptr = stack_ptr - 1;

  // will be location of most significant part of stack address
  *stack_ptr = 0x11;
  stack_ptr--;
  // least significant byte of stack address
  *stack_ptr = 0x22;
  stack_ptr--;
  *stack_ptr = 0x33;
  stack_ptr--;

  // address of the executing function
  this_address = task_ptr;
  *stack_ptr   = this_address &amp; 0x00ff;
  stack_ptr--;
  this_address &gt;&gt;= 8;
  *stack_ptr = this_address &amp; 0x00ff;
  stack_ptr--;

  //simulate stack after a call to savecontext
  *stack_ptr = 0x00;  //necessary for reti to line up
  stack_ptr--;
  *stack_ptr = 0x00;  //r0
  stack_ptr--;
  *stack_ptr = 0x00;  //r1 wants to always be 0
  stack_ptr--;
  *stack_ptr = 0x02;  //r2
  stack_ptr--;
  *stack_ptr = 0x03;  //r3
  stack_ptr--;
  *stack_ptr = 0x04;  //r4
  stack_ptr--;
  *stack_ptr = 0x05;  //r5
  stack_ptr--;
  *stack_ptr = 0x06;  //r6
  stack_ptr--;
  *stack_ptr = 0x07;  //r7
  stack_ptr--;
  *stack_ptr = 0x08;  //r8
  stack_ptr--;
  *stack_ptr = 0x09;  //r9
  stack_ptr--;
  *stack_ptr = 0x10;  //r10
  stack_ptr--;
  *stack_ptr = 0x11;  //r11
  stack_ptr--;
  *stack_ptr = 0x12;  //r12
  stack_ptr--;
  *stack_ptr = 0x13;  //r13
  stack_ptr--;
  *stack_ptr = 0x14;  //r14
  stack_ptr--;
  *stack_ptr = 0x15;  //r15
  stack_ptr--;
  *stack_ptr = 0x16;  //r16
  stack_ptr--;
  *stack_ptr = 0x17;  //r17
  stack_ptr--;
  *stack_ptr = 0x18;  //r18
  stack_ptr--;
  *stack_ptr = 0x19;  //r19
  stack_ptr--;
  *stack_ptr = 0x20;  //r20
  stack_ptr--;
  *stack_ptr = 0x21;  //r21
  stack_ptr--;
  *stack_ptr = 0x22;  //r22
  stack_ptr--;
  *stack_ptr = 0x23;  //r23
  stack_ptr--;
  *stack_ptr = 0x24;  //r24
  stack_ptr--;
  *stack_ptr = 0x25;  //r25
  stack_ptr--;
  *stack_ptr = 0x26;  //r26
  stack_ptr--;
  *stack_ptr = 0x27;  //r27
  stack_ptr--;
  *stack_ptr = 0x28;  //r28
  stack_ptr--;
  *stack_ptr = 0x29;  //r29
  stack_ptr--;
  *stack_ptr = 0x30;  //r30
  stack_ptr--;
  *stack_ptr = 0x31;  //r31
  stack_ptr--;

  //store the address of the stack
  this_address = stack_ptr;
  *(tcb[numtasks].stack_ptr) = (this_address &amp; 0xff);
  this_address &gt;&gt;= 8;
  *(tcb[numtasks].stack_ptr + 1) = (this_address &amp; 0xff);

  numtasks++;

  //return the task id
  return(numtasks - 1);
}

/*
 * UIKRun is sort of unnecessary, but since it's in the specification API we will
 * force the call here, inventing a distinction between the &quot;initialized&quot; and
 * &quot;ready&quot; states.
 */

void UIKRun(uint8_t taskid) {
  //the scheduler will handle if/when it actually runs based on priority
  tcb[taskid].state = ready;
}

/*this is the scheduler - handled in an interrupt (other interupts are disabled) */
void SIG_OUTPUT_COMPARE1A(void) {
  //save the execution context - this disables interupts
  savecontext();
  tick();
  restorecontext();
  //reti re-enables interrupts
  asm volatile (&quot;reti&quot;);
}

/*
 * tick increments through tcb and does 2 tasks: it increments the delays and
 * finds the maximum ready task. One constraint is the tick should be long enough
 * that this has a chance to complete.
 */

void tick(void) {
  int i;
  //start with the high being the idle task, which is always ready
  //and has lowest priority
  int high = 0;

  for(i=0; i 0) {
	  tcb[i].delay--;
	  if(tcb[i].delay == 0) {
	    //the state should have been waiting
	    tcb[i].state = ready;
	  }
    }
    //if an event needs to be dealt with by marking the task as ready
	//and updating &quot;Event&quot;
	if(EVENT_FLAG != 0) {
	  //if tcb[i] in ASS_BLOCK, mark tcb[i] as ready
      //if xxxxxxx1
	  if((EVENT_FLAG &amp; (unsigned char)0x01) != 0) {
        tcb[ASS_BLOCK[0]].state = ready;
		//reset the bit to 0
		EVENT_FLAG &amp;= 0xFE;
      }
	  /*TODO, additional comparisons as events are added
	    see UIKAssocEvent */
	}

	//find highest priority task that's ready
    if(tcb[i].state == ready &amp;&amp; tcb[i].priority &lt; tcb[high].priority) {
	  high = i;
	}
  }
  //EVENT_FLAGS should all be dealt with now and their processes marked as ready
  curr_task = high;
  currTCB = tcb[high].stack_ptr;
}

/*
 * ticknodelay is the tick without decrementing delays
 * this is kind of a band-aid
 */

void ticknodelay(void) {
  int i;
  //start with the high being the idle task, which is always ready
  //and has lowest priority
  int high = 0;

  for(i=0; i&lt;numtasks; i++) {
    //if an event needs to be dealt with by marking the task as ready
	//and updating &quot;Event&quot;
	if(EVENT_FLAG != 0) {
	  //if tcb[i] in ASS_BLOCK, mark tcb[i] as ready
      //if xxxxxxx1
	  if((EVENT_FLAG &amp; (unsigned char)0x01) != 0) {
        tcb[ASS_BLOCK[0]].state = ready;
		//reset the bit to 0
		EVENT_FLAG &amp;= 0xFE;
      }
	  /*TODO, additional comparisons as events are added
	    see UIKAssocEvent */
	}

	//find highest priority task that's ready
    if(tcb[i].state == ready &amp;&amp; tcb[i].priority &lt; tcb[high].priority) {
	  high = i;
	}
  }
  //EVENT_FLAGS should all be dealt with now and their processes marked as ready
  curr_task = high;
  currTCB = tcb[high].stack_ptr;
}

/*
 * startrtos sets up the idletask, enables interrupts, and begins the idletask executing
 * it will be interupted if any other tasks exist on the first tick
 */

void startrtos(void) {
  //start with the idle process
  tcb[0].state = ready;
  currTCB = tcb[0].stack_ptr;

  //this is the idle process, it will be swapped out soon enough
  restorecontext();
  //enable interupts with the return
  asm volatile (&quot;reti&quot;);
}

/*
 * This is the interupt that is in charge of scheduling
 */

void UIKDelay(uint32_t ticks) {
  //save the execution context - this disables interupts
  savecontext();
  //if a -1 is passed it implies no time passes tick-wise
  if (ticks value = 1;
  return thissem;
}

/*
 * This is for UIKSemPend logic
 */

unsigned char semtest(UIKSem* sem) {
  if(sem-&gt;value &gt; 0) {
    //critical secion - must retest
	cli();
	if(sem-&gt;value &gt; 0) {
	  sem-&gt;value--;
	  sei(); //end critical section
	  return 1;
	}
  }
  return 0;
}

/*
 * This is the semaphore acquire
 */

void UIKSemPend(UIKSem* sem) {
  //wait until sem &gt; 0
  while (semtest(sem) == 0) {
    //delay current task, which is the one trying to access semaphore
	//implies highest priority task gets semaphore first
	UIKDelay(1);
  }
}

/*
 * This is the semaphore release
 */

void UIKSemPost(UIKSem* sem) {
  //critical section
  cli();
  sem-&gt;value++;
  sei(); //end critical section
  //theoretically shouldn't have to do anything
  //but just as to not have to wait for the next tick
  UIKDelay(0);
}

/*
 * This returns the current value of a semaphore
 */

uint8_t UIKSemValue(UIKSem* sem) {
  return sem-&gt;value;
}

/*
 * UIKAssocEvent associates an external event with the process that calls it
 * the events are defined in uik.h
 */

void UIKAssocEvent(uint8_t Event) {
  //one function can be associated with multiple events
  //but an event should only be associated with one function at a time
  //error checking does not exist to save space, but be wary

  //if you would like to error check, just verify if(ASS_BLOCK[i] != 255) for every bit
  //before setting it. also you would need to reenable interupts before returning

  if(Event == 0) {
    //succesfuly give them the nothing they ask for
	return;
  }
  //ASS_BLOCK and curr_task must be protected
  //unless we want a semaphore for curr_task, the best way seems to just be to disable
  //interupts
  cli();
  //set the state for waiting, since it's waiting for the event to occur
  tcb[curr_task].state = wait;

  //if xxxxxxx1
  if((Event &amp; 0x01) != 0) {
    ASS_BLOCK[0] = curr_task;
  }
  //if xxxxxx1x
  if((Event &amp; 0x02) != 0) {
    ASS_BLOCK[1] = curr_task;
  }
  //if xxxxx1xx
  if((Event &amp; 0x04) != 0) {
    ASS_BLOCK[2] = curr_task;
  }
  //if xxxx1xxx
  if((Event &amp; 0x08) != 0) {
    ASS_BLOCK[3] = curr_task;
  }
  //if xxx1xxxx
  if((Event &amp; 0x10) != 0) {
    ASS_BLOCK[4] = curr_task;
  }
  //if xx1xxxxx
  if((Event &amp; 0x20) != 0) {
    ASS_BLOCK[5] = curr_task;
  }
  //if x1xxxxxx
  if((Event &amp; 0x40) != 0) {
    ASS_BLOCK[6] = curr_task;
  }
  //if 1xxxxxxx
  if((Event &amp; 0x80) != 0) {
    ASS_BLOCK[7] = curr_task;
  }
  sei();
  //give up execution - a -1 allows the other processes not to tick
  UIKDelay(-1);
}

/*
 * UIKDissasocEvent disassociates a task with an external event
 */

void UIKDisassocEvent(uint8_t Event) {
  //a semaphore could easily be used in place of disabling interupts
  cli();
    //if xxxxxxx1
  if((Event &amp; 0x01) != 0) {
    ASS_BLOCK[0] = 255;
  }
  //if xxxxxx1x
  if((Event &amp; 0x02) != 0) {
    ASS_BLOCK[1] = 255;
  }
  //if xxxxx1xx
  if((Event &amp; 0x04) != 0) {
    ASS_BLOCK[2] = 255;
  }
  //if xxxx1xxx
  if((Event &amp; 0x08) != 0) {
    ASS_BLOCK[3] = 255;
  }
  //if xxx1xxxx
  if((Event &amp; 0x10) != 0) {
    ASS_BLOCK[4] = 255;
  }
  //if xx1xxxxx
  if((Event &amp; 0x20) != 0) {
    ASS_BLOCK[5] = 255;
  }
  //if x1xxxxxx
  if((Event &amp; 0x40) != 0) {
    ASS_BLOCK[6] = 255;
  }
  //if 1xxxxxxx
  if((Event &amp; 0x80) != 0) {
    ASS_BLOCK[7] = 255;
  }
  sei();
}

/*
 * timer0 overflowing is a hardware event that our event functionality handles
 */

ISR(TIMER0_OVF_vect) {
  //interupts are disabled since this is an interrupt so locking event_flag not necessary
  //the 0th bit is associated with timer0
  EVENT_FLAG |= (1 &lt;&lt; PORT0_OVERFLOW);
}
</pre></p>
<h3>Installation/Compilation</h3>
<p>Due to the complex nature of this program, it was compiled with AVR Studio on Windows XP. Although I certainly miss my usual development tools on Linux, the AVR studio debugger was much better in my opinion.</p>
<p>To compile, open project6.aps, select Build-&gt;Rebuild All. To copy to the Atmega16, click on the &#8220;AVR&#8221; sprite. Under Program -&gt;Flash, click the &#8220;Program&#8221; button and select the homework4_*.hex file.</p>
<p>Of course, everything should work under linux as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/558/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/558/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/558/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/558/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/558/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/558/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/558/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/558/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=558&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2009/07/25/finished-rtos-similar-to-freertos/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>execv-like system call</title>
		<link>http://webstersprodigy.net/2009/06/30/execv-like-system-call/</link>
		<comments>http://webstersprodigy.net/2009/06/30/execv-like-system-call/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 15:54:38 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=569</guid>
		<description><![CDATA[From the system man page, it explicitely says: Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Good advice, but sometimes you need to get stuff done anyway. This is experimenting with pam and execv from a stupid [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=569&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>From the system man page, it explicitely says:</p>
<blockquote><p>Do not use <strong>system</strong>() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity.</p></blockquote>
<p>Good advice, but sometimes you need to get stuff done anyway. This is experimenting with pam and execv from a stupid google apps pam module I wrote</p>
<p><pre class="brush: cpp;">

PID = fork();
if (PID == 0) {
  //child
  char* argvarray[4] = {progarg0, username, newpass, (char *) 0};
  execv(netprog, argvarray);
  if (debug == 1)
    printf(&quot;forking failure\n&quot;);
  report_error(1);
  return PAM_CRED_ERR;
}
else if (PID &lt; 0) {
  if (debug == 1)
    printf(&quot;unexpected error\n&quot;);
  report_error(1);
  return PAM_CRED_ERR;
}
 
wait(&amp;amp;execreturn);
//make sure this does exit properly and isn't killed
if (WIFEXITED(execreturn)) {
  rc = WEXITSTATUS(execreturn);
}
else {
  report_error(1);
  return PAM_CRED_ERR;
}
</pre></p>
<p>The first 18 lines emulate a system call. The rest is used to get the return value, which you would also need to do with a system call. Basically, it has close to the same functionality as if it were:</p>
<p><pre class="brush: cpp;">
system(&quot;programcall&quot;);
 
wait(&amp;amp;execreturn);
//make sure this does exit properly and isn't killed
if (WIFEXITED(execreturn)) {
  rc = WEXITSTATUS(execreturn);
}
else {
  report_error(1);
  return PAM_CRED_ERR;
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/569/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=569&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2009/06/30/execv-like-system-call/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>RTOS and the Parallax Propeller</title>
		<link>http://webstersprodigy.net/2009/05/26/rtos-and-the-parallax-propeller/</link>
		<comments>http://webstersprodigy.net/2009/05/26/rtos-and-the-parallax-propeller/#comments</comments>
		<pubDate>Tue, 26 May 2009 18:29:56 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[atmel]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[parallax]]></category>
		<category><![CDATA[propeller]]></category>
		<category><![CDATA[rtos]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=538</guid>
		<description><![CDATA[In CS 504:Real Time Operating Systems, the class built a functional Real Time Operating system based on the UIK API. In my implementation, I heavily relied on the source code of FreeRTOS. The process focused primarily on demonstrating the atmel processor, multitasking, and and basic interprocess communication, which are fundamental parts of an RTOS. In this project, the same problems are achieved with a very different architecture. Namely, all the first programming projects – generating a sound wave, counting LEDs, timing how long buttons were pressed, and handling hardware events – were programmed similarly and multi-tasked on the propeller chip. This project included interfacing with the ntsc and peripheral drivers, writing a sound driver, learning spin and propeller assembly, and comprehending the propeller architecture.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=538&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is an entry including a final project for CS504.</p>
<h3>Summary</h3>
<blockquote>
<p align="left">In CS 504:Real Time Operating Systems, the class built a functional Real Time Operating system based on the UIK API. In my implementation, I heavily relied on the source code of FreeRTOS. The process focused primarily on demonstrating the atmel processor, multitasking, and basic interprocess communication, which are fundamental parts of an RTOS.</p>
<p align="left">In this project, the same problems are achieved with a very different architecture. Namely, all the first programming projects – generating a sound wave, counting LEDs, timing how long buttons were pressed, and handling hardware events – were programmed similarly and multi-tasked on the propeller chip. This project included interfacing with the ntsc and peripheral drivers, writing a sound driver, learning spin and propeller assembly, and comprehending the propeller architecture.</p>
</blockquote>
<h3>Paper</h3>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!145&amp;parid=19794FAC33285FD5!140">https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!145&amp;parid=19794FAC33285FD5!140</a></p>
<h3>Code</h3>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!144&amp;parid=19794FAC33285FD5!140">https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!144&amp;parid=19794FAC33285FD5!140</a></p>
<h3>Demo and RTOS Report</h3>
<iframe src="https://docs.google.com/present/embed?id=dhnfxq99_302hkxk6qf7" frameborder="0" width="410" height="342"  marginheight="0" marginwidth="0"></iframe>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/538/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/538/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/538/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/538/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/538/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/538/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/538/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/538/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=538&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2009/05/26/rtos-and-the-parallax-propeller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>playing a scale with the atmega16</title>
		<link>http://webstersprodigy.net/2009/05/04/playing-a-scale-with-the-atmega16/</link>
		<comments>http://webstersprodigy.net/2009/05/04/playing-a-scale-with-the-atmega16/#comments</comments>
		<pubDate>Mon, 04 May 2009 03:51:22 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[atmega]]></category>
		<category><![CDATA[avr]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[rtos]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=526</guid>
		<description><![CDATA[A musical “note” is a waveform that has a certain fundamental frequency. A perfect sine wave consists only of the fundamental frequency, and sounds very “pure” or mellow, like a flute. For this project, you are to use interrupts to generate the notes of a musical scale, while at the same time using another interrupt to update a count. We will generate square waves by toggling a bit within a port on and off. Specifically, your program should play the notes from middle C to the next higher C, each of approximately one second in duration. These notes should be playing at the same time that an 8-bit binary count is being displayed in the LED’s, updating at approximately 1/4 second. <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=526&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Specification</h3>
<blockquote><p>The purpose of this assignment is to get further practice using interrupts, particularly concurrent interrupts. A musical “note” is a waveform that has a certain fundamental frequency. For example, the “A” above middle C on a piano has a frequency of 440 Hz, and middle C itself is approximately 261 Hz. On an equally tempered scale, each of the twelve notes is related to each other by a factor of 2 12 . A note that is an octave above another note is double the frequency of the lower note. A perfect sine wave consists only of the fundamental frequency, and sounds very “pure” or mellow, like a flute. Most waveforms consist of a fundamental and harmonics or overtones, which are additional frequencies above the fundamental. For instance, a square wave consists of the fundamental and multiples of the fundamental in decreasing amplitude. The distinctive sound of a violin is mostly a sawtooth wave (created as the rosin on the bow catches the string, then releases it), with other overtones (called dissonant overtones, due to the fact that they are not multiples of the fundamental) created by resonances in the wood.</p>
<p>For this assignment, you are to use interrupts to generate the notes of a musical scale, while at the same time using another interrupt to update a count. We will generate square waves by toggling a bit within a port on and off. Specifically, your program should play the notes from middle C to the next higher C, each of approximately one second in duration. These notes should be playing at the same time that an 8-bit binary count is being displayed in the LED’s, updating at approximately 1/4 second. As before, determine the code sizes, and estimate the percentages of time your ISR’s and “main” program takes of the total execution time. Also, for each note, estimate its accuracy &#8211; that is, how close is the note your program plays to the calculated frequency for the note.</p></blockquote>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!143&amp;parid=19794FAC33285FD5!140">Download the source here</a></p>
<h3>Compiling</h3>
<p>This code requires avrdude, avr-gcc, and objcopy are installed</p>
<p>To compile, type:</p>
<blockquote><p>make</p></blockquote>
<p>After it&#8217;s compiled, to install to a connected and powered on atmega16 board, type:</p>
<blockquote><p>make install</p></blockquote>
<p>Note Makefile may require some modification depending on your environment.</p>
<p>This program includes a demo called homework3_demo.avi.</p>
<h3>Program Size</h3>
<p>The ATmega16 provides 16K bytes of Programmable Flash Program Memory, 512 bytes eeprom, and 1K byte SRAM</p>
<p>make gives a 3982 byte executable. It contains the following headers:</p>
<blockquote><p>Section Headers:<br />
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al<br />
[ 0] NULL 00000000 000000 000000 00 0 0 0<br />
[ 1] .text PROGBITS 00000000 000074 000248 00 AX 0 0 2<br />
[ 2] .data PROGBITS 00800060 0002bc 000020 00 WA 0 0 1<br />
[ 3] .bss NOBITS 00800080 0002dc 000002 00 WA 0 0 1<br />
[ 4] .stab PROGBITS 00000000 0002dc 000378 0c 5 0 4<br />
[ 5] .stabstr STRTAB 00000000 000654 000054 00 0 0 1<br />
[ 6] .shstrtab STRTAB 00000000 0006a8 00003b 00 0 0 1<br />
[ 7] .symtab SYMTAB 00000000 00084c 000450 10 8 17 4<br />
[ 8] .strtab STRTAB 00000000 000c9c 0002f2 00 0 0 1</p></blockquote>
<p>#without space optimization<br />
Program: .text + .data + .bootloader == 618 bytes (3.8% Full)<br />
Data: .data + .bss + .noinit == 34 bytes (3.3% Full)</p>
<p>Here is most the code</p>
<p><pre class="brush: cpp;">
/* http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=50106
 * was a big help understanding the timer syntax
 *
 * also relied on the atmega16 manual and the #defines located in /usr/avr/include/avr */

#include &lt;avr/io.h&gt;
#include &lt;avr/interrupt.h&gt;

/*counter keeps track of how many overflows in timer0 = about a second */
int counter = 0;

/*number of ticks to make a note at 1 MHz*/

/*
At 1MHz, these are the number of ticks it takes to equal a given note

const int C_l = 3817/2;
const int D   = 3401/2;
const int E   = 3030/2;
const int F   = 2865/2;
const int G   = 2551/2;
const int A   = 2272/2;
const int B   = 2024/2;
const int C_h = 1912/2; */

//const long int notes[8] = {3817, 3401, 3030, 2865, 2551, 2272, 2024, 1912};
const long int notes[8] = {1908, 1700, 1515, 1432, 1275, 1136, 1012, 956};

void port_init() {
  /*PORTC is connected to the amplifier */
  /*PORTB is connected to the LEDs */
  DDRB  = 0xff;  /*11111111 for all output */
  DDRC  = 0xff;
  PORTC = 0xff;  /*all lights turned off   */
  PORTB = 0xff;  /*all lights turned off   */
}

void init_timer1() {
  /*setup timer1, this will measure the notes */
  TCCR1B |= (1 &lt;&lt; WGM12);
  /*Enable CTC interrupt */
  TIMSK |= (1 &lt;&lt; OCIE1A);
  /* OCR1A = 15625;*/
  OCR1A = notes[0]; /* Set CTC value to middle C to begin with */
  /*timer runs with a 1MHz resolution */
  TCCR1B |= (1 &lt;&lt; CS10);

}

void init_timer0() {
  /*prescaler/64*/
  TCCR0 |= ((1 &lt;&lt; CS01) | (1 &lt;&lt; CS00));
  /*overflow mode - about every 1/61 seconds */
  TIMSK |= (1 &lt;&lt; TOIE0);
}

void main (void) {
  port_init();
  init_timer0();
  init_timer1();

  /*Enable global interrupts */
  sei();

  while(1) {
    /*most logic is handled by the interrupts */
  }
}

/* toggle the LED for now, this is the musical note */
ISR(TIMER1_COMPA_vect) {
  /*toggle the output */
  PORTC = ~PORTC;
}

ISR(TIMER0_OVF_vect) {
  counter += 1;
  if (counter == 61) {
    /*count up to 8 for all 8 notes*/
    if (PORTB == 0xf8) {
      PORTB = 0xff;
    }
    else {
      PORTB--;
    }
    //OCR1A = notes[~PORTB];
    OCR1A = notes[~PORTB];
    counter = 0;
  }
}
</pre></p>
<p>Here is a short video demonstration:</p>
<span style="text-align:center; display: block;"><a href="http://webstersprodigy.net/2009/05/04/playing-a-scale-with-the-atmega16/"><img src="http://img.youtube.com/vi/H6ew1qtbq9M/2.jpg" alt="" /></a></span>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/526/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/526/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=526&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2009/05/04/playing-a-scale-with-the-atmega16/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
		<item>
		<title>avr interrupts</title>
		<link>http://webstersprodigy.net/2009/04/08/avr-interrupts/</link>
		<comments>http://webstersprodigy.net/2009/04/08/avr-interrupts/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 09:00:12 +0000</pubDate>
		<dc:creator>webstersprodigy</dc:creator>
				<category><![CDATA[Bits and Bytes]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[avr]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[interrupts]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[opertating system]]></category>
		<category><![CDATA[rtos]]></category>

		<guid isPermaLink="false">http://webstersprodigy.net/?p=484</guid>
		<description><![CDATA[The purpose of this assignment is to give you experience with the AVR’s timers and the use of interrupts. You are to repeat assignment #1, this time performing the timing using an interrupt-driven timer. You are to write an interrupt service routine (ISR) for one of the hardware timers on the AVR. Each time the timer interrupts, you should update a counter variable. Then, when determining the amount of time that the switch is held down, use the counter value. Then, use the counter again to determine how long to turn on the LED. As before, in addition to writing the code, determine the size of the code in your program, including main and the ISR.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=484&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This was also for homework..</p>
<p>From the specifications:</p>
<blockquote><p>The purpose of this assignment is to give you experience with the AVR’s timers and the use of interrupts. You are to repeat assignment #1, this time performing the timing using an interrupt-driven timer. You are to write an interrupt service routine (ISR) for one of the hardware timers on the AVR. Each time the timer interrupts, you should update a counter variable. Then, when determining the amount of time that the switch is held down, use the counter value. Then, use the counter again to determine how long to turn on the LED. As before, in addition to writing the code, determine the size of the code in your program, including main and the ISR.</p></blockquote>
<p>I found this site hugely helpful:   <a href="http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;file=viewtopic&amp;t=50106" target="_blank">http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;file=viewtopic&amp;t=50106</a></p>
<p>For reference, all <a title="stk500 avr atmega16 linux gcc hello, world" href="http://webstersprodigy.wordpress.com/2009/04/04/stk500-avr-atmega16-linux-gcc-hello-world/">the first assignment</a> did was to time how long you held down a button, wait a second, then to light up the lights for the same duration. The difference is this assignment uses timers and interrupts wheras the other just looped.</p>
<p><a href="https://skydrive.live.com/redir.aspx?cid=19794fac33285fd5&amp;resid=19794FAC33285FD5!142&amp;parid=19794FAC33285FD5!140">Here is a link to the source.</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/webstersprodigy.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/webstersprodigy.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/webstersprodigy.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/webstersprodigy.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/webstersprodigy.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/webstersprodigy.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/webstersprodigy.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/webstersprodigy.wordpress.com/484/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=webstersprodigy.net&#038;blog=35949064&#038;post=484&#038;subd=webstersprodigy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://webstersprodigy.net/2009/04/08/avr-interrupts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/be2c27a28b3788a3b9a7a8fa243d2978?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">webstersprodigy</media:title>
		</media:content>
	</item>
	</channel>
</rss>
