<?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/"
	>

<channel>
	<title>Rants, Rambles, and Rhinos</title>
	<atom:link href="http://samuelkerr.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://samuelkerr.com</link>
	<description>Charging into the blog-o-sphere!</description>
	<lastBuildDate>Fri, 17 May 2013 23:25:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Let&#8217;s talk about anti virus detection: Kaspersky DNS cache detection</title>
		<link>http://samuelkerr.com/?p=394</link>
		<comments>http://samuelkerr.com/?p=394#comments</comments>
		<pubDate>Thu, 16 May 2013 23:37:37 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[anti virus]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[dns cache]]></category>
		<category><![CDATA[Kaspersky]]></category>
		<category><![CDATA[malware]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=394</guid>
		<description><![CDATA[I&#8217;ve been playing around with some basic HTTP programs lately and noticed that Kaspersky flags them as viruses for some reason. I did some investigation and learned why and how to get around those detections. I wanted to download a Web page in a program I&#8217;m writing for Windows. Windows provides some APIs to do [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with some basic HTTP programs lately and noticed that Kaspersky flags them as viruses for some reason. I did some investigation and learned why and how to get around those detections.</p>
<p><span id="more-394"></span></p>
<p>I wanted to download a Web page in a program I&#8217;m writing for Windows. Windows provides some APIs to do this, like <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384091(v=vs.85).aspx" target="_blank">WinHttpConnect</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384098(v=vs.85).aspx" target="_blank">WinHttpOpen</a>, etc. Great, shouldn&#8217;t be an issue, right?</p>
<p>I copied some sample code from Microsoft to do a GET request and changed it to fit my needs. Awesome, this is super simple! However, Kaspersky flags my program as potentially malicious for using the DNS cache.</p>
<p>Now, it is beyond me how Kaspersky detects what is essentially sample code as malicious. And for doing DNS? Maybe if I&#8217;m hitting known malware websites, but I was hitting google.com. Any ways, that&#8217;s besides the point, so let&#8217;s move on with our lives and fix this AV detection, shall we?</p>
<p>Now, since we&#8217;re getting flagged for using the DNS cache, is there a way to get around that? After some MSN sifting, turns out there is! A function called <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682016(v=vs.85).aspx" target="_blank">DnsQuery</a>() (duh&#8230;) can execute DNS requests for us. More importantly, there is a flag to bypass the DNS cache. So its a matter of using this call, bypassing the DNS cache, then simply passing raw IP addresses to other system calls (like <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa384091(v=vs.85).aspx" target="_blank">WinHttpConnect</a>).</p>
<p>Voila, no more AV detection! Some source code is below. If you have anymore tips or advice about AV avoidance, please leave a comment!</p>
<p>Notes: I was unable to get the codes to trigger on Windows 7, only on Windows XP, which is weird. I was using a trial version of Kaspersky PURE, so it might have been related to something specific about the signatures and algorithms used for those specific version? Not sure.</p>
<p><strong>TL;DR:</strong> If Kaspersky flags your application as malicious for using the DNS cache, using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682016(v=vs.85).aspx" target="_blank">DnsQuery</a>() and the bypass cache option for your DNS queries, should be a good way to get around it.</p>
<p>Original Code:<br />
<code><br />
// Specify an HTTP server.<br />
WCHAR host[] = L"www.google.com";<br />
if (hSession)<br />
<nbsp;/><nbsp;/><nbsp;/><nbsp;/>hConnect = WinHttpConnect( hSession, host, INTERNET_DEFAULT_HTTP_PORT, 0);<br />
</code></p>
<p>No DNS Cache Code:<br />
<code><br />
DNS_STATUS status;<br />
PDNS_RECORD pDnsRecord;<br />
PIP4_ARRAY pSrvList = NULL;<br />
WORD wType = DNS_TYPE_A;<br />
char* pOwnerName;<br />
char pReversedIP[255];<br />
char DnsServIp[255];<br />
DNS_FREE_TYPE freetype;<br />
freetype = DnsFreeRecordListDeep;<br />
IN_ADDR ipaddr;<br />
WCHAR unicodeIpAddr[50];</p>
<p>ZeroMemory(unicodeIpAddr,50);</p>
<p>// Calling function DnsQuery to query Host or PTR records<br />
status = DnsQuery(pOwnerName,<br />
wType,<br />
DNS_QUERY_BYPASS_CACHE,<br />
pSrvList,<br />
&amp;pDnsRecord,<br />
NULL); </p>
<p>if (status){<br />
if(wType == DNS_TYPE_A)<br />
printf("Failed to query the host record for %s and the error is %d \n", pOwnerName, status);<br />
else<br />
printf("Failed to query the PTR record and the error is %d \n", status);<br />
} else {<br />
if(wType == DNS_TYPE_A) {<br />
//convert the Internet network address into a string<br />
//in Internet standard dotted format.<br />
ipaddr.S_un.S_addr = (pDnsRecord-&gt;Data.A.IpAddress);<br />
printf("The IP address of the host %s is %s \n", pOwnerName,inet_ntoa(ipaddr));</p>
<p>// Convert to Unicode<br />
mbstowcs(unicodeIpAddr, inet_ntoa(ipaddr), 50);</p>
<p>// Free memory allocated for DNS records.<br />
DnsRecordListFree(pDnsRecord, freetype);<br />
}<br />
else {<br />
printf("The host name is %s \n",(pDnsRecord-&gt;Data.PTR.pNameHost));</p>
<p>// Free memory allocated for DNS records.<br />
DnsRecordListFree(pDnsRecord, freetype);<br />
}<br />
}<br />
LocalFree(pSrvList);</p>
<p><strong>// Now do the HTTP connect with a raw IP address instead of a host name<br />
if (hSession)<br />
hConnect = WinHttpConnect( hSession, unicodeIpAddr, INTERNET_DEFAULT_HTTP_PORT, 0);</strong><br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=394</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring the analog to digital converter (ADC) on AVR chips</title>
		<link>http://samuelkerr.com/?p=390</link>
		<comments>http://samuelkerr.com/?p=390#comments</comments>
		<pubDate>Sun, 03 Feb 2013 23:58:27 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=390</guid>
		<description><![CDATA[While trying to figure out how to use the ADC on my AVR microcontrollers (not Arduino, raw AVRs!), I kept finding a variety of tutorials with examples that just didn&#8217;t work for me. I eventually got it working, so thought I would share, hoping it would help someone else eventually! I am using an ATmega32U4 [...]]]></description>
			<content:encoded><![CDATA[<p>While trying to figure out how to use the ADC on my AVR microcontrollers (not Arduino, raw AVRs!), I kept finding a variety of tutorials with examples that just didn&#8217;t work for me. I eventually got it working, so thought I would share, hoping it would help someone else eventually!</p>
<p>I am using an ATmega32U4 (awesome chip!), but these steps should be appropriate for most AVRs.  Note that my clock is running at 8 MHz. If you change the clock speed, make sure to change the prescalar value.</p>
<pre>ADCSRA |= (1 &lt;&lt; ADPS2) | (1 &lt;&lt; ADPS1); // prescalar = 64
ADMUX |= (1 &lt;&lt; REFS0); // reference voltage from internal source
ADMUX |= (1 &lt;&lt; ADLAR); // 8 bits, instead of 10
ADCSRA |= (1 &lt;&lt; ADATE); // free running
ADCSRA |= (1 &lt;&lt; ADEN); // enable ADC
ADCSRA |= (1 &lt;&lt; ADSC); // start A2D conversions</pre>
<p>Note that this code works for a continuously running, non-interrupt driven ADC program. If you want to use single shot conversions or interrupt driven ADC, you will need to change these lines appropriately. I might add that as another post eventually.</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=390</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A couple of different ways to get EXE name from PID in Windows</title>
		<link>http://samuelkerr.com/?p=370</link>
		<comments>http://samuelkerr.com/?p=370#comments</comments>
		<pubDate>Tue, 30 Oct 2012 00:52:01 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=370</guid>
		<description><![CDATA[I&#8217;ll preface this post with the fact that it will be fairly technical. I have been trying to write a Windows program which can get the EXE path of a specified process ID (PID). I found a couple different ways, so thought I would go through them here. So, while going through this process, I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll preface this post with the fact that it will be fairly technical. I have been trying to write a Windows program which can get the EXE path of a specified process ID (PID). I found a couple different ways, so thought I would go through them here.</p>
<div id="attachment_371" class="wp-caption alignleft" style="width: 211px"><a href="http://samuelkerr.com/wp-content/uploads/2012/10/White_rhino_closeup1.jpg"><img class="size-medium wp-image-371" title="White_rhino_closeup1" src="http://samuelkerr.com/wp-content/uploads/2012/10/White_rhino_closeup1-201x300.jpg" alt="" width="201" height="300" /></a><p class="wp-caption-text">This Rhino is curious to find EXE paths of applications</p></div>
<p><span id="more-370"></span></p>
<p>So, while going through this process, I found 2 different ways of doing this, both from the Internet and combing through MSDN documentation. If you just want to get the full EXE path of a certain PID, turns out it is very simple. If you want to get a full <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx">PROCESSENTRY32 </a>structure however, it&#8217;s a little more challenging.</p>
<p>First, the easier solution of just getting the full EXE path. Turns out there is a lovely system call called <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684919(v=vs.85).aspx">QueryFullProcessImageName</a> that does exactly what I wanted. (Of course, I only found this after hours of searching and doing the other way, but that is besides the point.) It&#8217;s almost comical how easy it is to use:</p>
<pre>DWORD PID = 1337; // something here
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, PID);

DWORD value = MAX_PATH;
char buffer[MAX_PATH];
QueryFullProcessImageName(hProcess, 0, buffer, &amp;value);
printf("EXE Path: %s\n", buffer);</pre>
<p>Simple, right?</p>
<p>The only downside to this method is that you only get the full EXE path, nothing else. For more information, you might want to fill a PROCESSENTRY32 structure, which can be done in a few steps:</p>
<ol>
<li>Create a snapshot of all processes with CreateToolhelp32Snapshot()</li>
<li>Iterate through all processes with Process32First() and Process32Next()</li>
</ol>
<p>A source example of this would look like:</p>
<pre>DWORD PID = 1337; // something here

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, PID);
if(hSnapshot)
{
    peInfo.dwSize = sizeof(peInfo); // this line is REQUIRED
    BOOL nextProcess = Process32First(hSnapshot, &amp;peInfo);
    bool found = false;
    while(nextProcess)
    {
	if(peInfo.th32ProcessID == PID)
	{
	    found = true;
	    break;
	}
	nextProcess= Process32Next(hSnapshot, &amp;peInfo);
    }
    if(found)
    {
        printf("%s",peInfo.szExeFile);
    }
    CloseHandle(hSnapshot);
}</pre>
<p>
What is happening in this code sample is that a <em>snapshot</em> is being taken of the current processes in the system. If the iterated process has the desired PID, the process is examined. Information about a process is stored in the PROCESSENTRY32 structure. There are a lot of interesting pieces of information in that structure, but we are only concerned with the szExeFile field, which is the EXE name of the application. Note that it is only the application, not the full path, such as &#8216;itunes.exe&#8217;, not &#8216;C:\Program Files\iTunes\iTunes.exe&#8217;. If you want the full path, use the first solution presented above.</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=370</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Standing under an Arch Sounds like a headache&#8230;</title>
		<link>http://samuelkerr.com/?p=362</link>
		<comments>http://samuelkerr.com/?p=362#comments</comments>
		<pubDate>Tue, 02 Oct 2012 22:38:56 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=362</guid>
		<description><![CDATA[Read on for a tale of my initial frustration, ever incresaing despair, and eventual victory in this tale of my configuration of audio devices in a Windows 7 VM guest on top of an Arch Linux host. A few months ago, I installed the Windows 8 RC on my computer. Call me crazy, right? It [...]]]></description>
			<content:encoded><![CDATA[<p>Read on for a tale of my initial frustration, ever incresaing despair, and eventual victory in this tale of my configuration of audio devices in a Windows 7 VM guest on top of an Arch Linux host.
</p>
<p><a href="http://samuelkerr.com/wp-content/uploads/2012/10/Baby-black-rhino.jpg"><img src="http://samuelkerr.com/wp-content/uploads/2012/10/Baby-black-rhino.jpg" alt="This rhino is so happy that he can now use his audio software in his VM" title="Baby-black-rhino" width="277" height="254" class="alignright size-full wp-image-367" /></a><br />
<span id="more-362"></span></p>
<p>
A few months ago, I installed the Windows 8 RC on my computer. Call me crazy, right? It was OK, but I didn&#8217;t like it enough to pay for it. So, I decided to take the plunge and install Arch Linux on my computer and commit to sticking with it for at least a month. Initial set up went fine, as I have run and <a href="http://samuelkerr.com/?p=196" title="I've passed under the Linux Arch!" target="_blank">set up Arch before</a>. However, I gave up as some critical programs I need would not work in Wine and virtualization was a lot slower in 2009. Windows 8 was going to expire anyways, so I figured why not try Arch again instead of going back to Windows 7.
</p>
<p>
I recently bought a <a href="http://www.native-instruments.com/#/products/producer/maschine/" target="_blank">Maschine from Native Instruments</a>, but when I tried to install the software in Wine, no go. Fine, I&#8217;ll just fire up a Windows 7 virtual machine for it. The software went fine, but for some reason, the Maschine driver was not able to start and exited with error code 10.
</p>
<p>
I have had driver problems before, so I simply re-installed the driver. Still nothing. About 3 hours of more failed attempts and I&#8217;m this close to going back to Windows 7. I posted a question on the forum for help and went to bed.
</p>
<p>
Today, I was playing around with VirtualBox again after getting some help on various forums. Turns out, in VirtualBox, you must enable EHCI (Enhanced Host Controller Interface) support for the VM. Sure enough, I had it disabled on my VM. I found the setting by looking under the USB settings for the VM and enabling it. I also had to make a USB filter for the Maschine so VirtualBox knew which devices to talk to using EHCI. After I did that, my Windows VM started the driver! Great! *BUZZ* Nope. True, the Maschine now works, but whenever I press a button, there is about a half second lag before any sound plays. Clearly, unacceptable.
</p>
<p>
Turns out, using the WASAPI sound drivers that come with Windows was the problem. To fix this, I installed <a href="http://www.asio4all.com/" target="_blank">ASIO4ALL</a>, which is an alternative audio driver. Accepting the default settings immediately fixed the problems I was having! Now I have immediate feedback from all my MIDI stuff in my VM and the audio is crystal clear!
</p>
<p>
This adventure was a lot more irritating than my blog probably makes it sound, so I&#8217;m really glad I was able to remedy the situation. Hopefully this helps someone else out!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=362</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A quick tip for the Couch (CouchDB that is)</title>
		<link>http://samuelkerr.com/?p=342</link>
		<comments>http://samuelkerr.com/?p=342#comments</comments>
		<pubDate>Thu, 06 Sep 2012 21:38:27 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=342</guid>
		<description><![CDATA[I have been playing around with CouchDB lately as a new tecnology. It is a NoSQL database that stores everything as a &#8216;document&#8217;, rather than as a row like a traditional relationship based database, such as MySQL. What is also cool about CouchDB is that it uses a REST API. That is, every request and [...]]]></description>
			<content:encoded><![CDATA[<p>I have been playing around with <a href="http://www.couchdb.apache.org" title="CouchDB" target="_blank">CouchDB</a> lately as a new tecnology. It is a NoSQL database that stores everything as a &#8216;document&#8217;, rather than as a row like a traditional relationship based database, such as MySQL. What is also cool about CouchDB is that it uses a REST API. That is, every request and operation is done through HTTP, so it works with essentially every language. <a href="https://en.wikipedia.org/wiki/NoSQL" title="NoSQL" target="_blank">NoSQL</a> is new to me, but I am liking it so far!</p>
<div id="attachment_343" class="wp-caption alignleft" style="width: 269px"><a href="http://samuelkerr.com/wp-content/uploads/2012/09/rhino.jpg"><img class="size-full wp-image-343" title="rhino" src="http://samuelkerr.com/wp-content/uploads/2012/09/rhino.jpg" alt="" width="259" height="194" /></a><p class="wp-caption-text">This rhino wishes he had a comfortable couch to lay on.</p></div>
<p>I am actually using my CouchDB instance as both my database and webserver. Since CouchDB has a REST API and everything in CouchDB is a document, so there is no reason why you cannot simply ues the browser to send an HTTP request and return HTML pages directly from the database! Pretty neat to eliminate Apache, PHP, and MySQL from the web stack and instead use just CouchDB.</p>
<p>Anyways, I have been chugging along merrily, serving static HTML pages or show functions from my database, until I started to use the list functions that CouchDB offers.</p>
<p>Specifically, I was having trouble getting it to return an HTML header, rather than just plaintext.</p>
<p>To solve this, you must format your list function as: </p>
<pre>function(head, req)
{
    provides('html', function() {
    ... The list function ...
    send(data);
});
}</pre>
<p>This tells the list function to send HTTP headers along with the data, rather than just the data itself.</p>
<p>This took me a while to figure it out, so hopefully it helps you!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=342</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Can&#8217;t find the constant you&#8217;re looking for? Check www.namethatwindowsconstant.com!</title>
		<link>http://samuelkerr.com/?p=330</link>
		<comments>http://samuelkerr.com/?p=330#comments</comments>
		<pubDate>Tue, 14 Aug 2012 18:35:35 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[tools python namethatwindowsconstant]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=330</guid>
		<description><![CDATA[Sometimes I read MSDN entries and wonder what the numeric value of a constant, such as GENERIC_READ, is. However, MSDN usually does not list this information, so I am forced to dive into header files. Well, I got quite sick of doing this, so I whipped up a few Python scripts and made a database [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes I read MSDN entries and wonder what the numeric value of a constant, such as GENERIC_READ, is. However, MSDN usually does not list this information, so I am forced to dive into header files.</p>
<div id="attachment_338" class="wp-caption alignright" style="width: 310px"><a href="http://samuelkerr.com/wp-content/uploads/2012/08/rhino-2.jpg"><img class="size-medium wp-image-338" title="rhino-2" src="http://samuelkerr.com/wp-content/uploads/2012/08/rhino-2-300x225.jpg" alt="Fatigued Rhino" width="300" height="225" /></a><p class="wp-caption-text">He is so sick of looking up constants by hand</p></div>
<p>Well, I got quite sick of doing this, so I whipped up a few Python scripts and made a database of a lot of the Windows constants.</p>
<p>I do not claim that 100% of them are there, but on the initial import, I found over 100,000, so there are quite a few! In the future, I will be adding POSIX and other constants, as well as some of the Windows constants I missed. Parsing all the headers was a pretty interesting task, so I might publish another entry on it here in the future.</p>
<p>I thought this database might be helpful to others, so I am publicly publishing it at <a title="www.namethatwindowsconstant.com" href="http://www.namethatwindowsconstant.com" target="_blank">www.namethatwindowsconstant.com</a>.</p>
<p>Enjoy <img src='http://samuelkerr.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=330</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Homemade MIDI Controller!</title>
		<link>http://samuelkerr.com/?p=314</link>
		<comments>http://samuelkerr.com/?p=314#comments</comments>
		<pubDate>Thu, 05 Jan 2012 16:33:26 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=314</guid>
		<description><![CDATA[Since I have been home over winter break, I felt like doing a little bit of fun hacking. As a few of my posts have shown, I am fairly interested in hardware oriented projects, so I thought I would try another. I have several AVR chips and support supplies laying around, so I thought I would [...]]]></description>
			<content:encoded><![CDATA[<p>Since I have been home over winter break, I felt like doing a little bit of fun hacking. As a <a title="Websites, Propellers, and Sweet Music!" href="http://samuelkerr.com/?p=228">few </a><a title="One architecture to rule them all… Or at least rule my free time" href="http://samuelkerr.com/?p=243">of </a>my <a title="First steps with an FPGA!" href="http://samuelkerr.com/?p=207">posts </a>have shown, I am fairly interested in hardware oriented projects, so I thought I would try another. I have several <a href="http://www,atmel.com/avr">AVR</a> chips and support supplies laying around, so I thought I would use them. Recently, I have also been playing around with DJing. It is fairly common to use a <a href="http://www.guitarcenter.com/DJ-Controllers---Interfaces-DJ-Gear.gc">controller</a> to control a DJing setup, but they are all fairly expensive. Since they are just a collection of buttons, knows, and faders, I decided it would be interesting to try to make my own.</p>
<div id="attachment_315" class="wp-caption alignright" style="width: 310px"><a href="http://samuelkerr.com/wp-content/uploads/2012/01/mf_5.jpg"><img class="size-medium wp-image-315" title="MidiFighter" src="http://samuelkerr.com/wp-content/uploads/2012/01/mf_5-300x199.jpg" alt="" width="300" height="199" /></a><p class="wp-caption-text">My inspiration for this project</p></div>
<p>This post will cover what I did for the various parts as well as some of the interesting bits of code, so that you can make your own!</p>
<p><span id="more-314"></span></p>
<p>The majority of DJing software and controller use what is called <a href="http://en.wikipedia.org/wiki/MIDI">MIDI</a> (Musical Instrument Digital Interface) to control interact with each other. In fact, most digital instruments also use this standard when plugged into a computer. Rather than transmitting analog sound data, the instrument will transmit MIDI commands, which could be of the types &#8216;note on&#8217;, &#8216;note off&#8217;, &#8216;pitch bend&#8217;, or one of many others. This greatly simplifies processing the signals as well as reduces the sheer amount of data that needs to be sent; MIDI messages are typically three bytes, as compared to how large an audio stream would be.</p>
<p style="text-align: left;">The first step to the project was to make sure that my computer could talk through a MIDI interface to my circuit. MIDI is a fairly uncommon peripheral on computers, so I had to go to Sam Ash to buy a 1&#215;1 MidiSport, which provides 1 MIDI In/Out port and plugs into a USB port. Easy enough. I also purchased the <a href="http://www.sparkfun.com/products/9598">MIDI Breakout Board</a> from Sparkfun, which allows my ATtiny2313 AVR chip to connect to the MIDI cables.</p>
<div id="attachment_316" class="wp-caption alignleft" style="width: 310px"><a href="http://samuelkerr.com/wp-content/uploads/2012/01/09598-04.jpg"><img class="size-medium wp-image-316" title="MIDI Breakout Board" src="http://samuelkerr.com/wp-content/uploads/2012/01/09598-04-300x300.jpg" alt="" width="300" height="300" /></a><p class="wp-caption-text">This was a really handy board to have</p></div>
<p style="text-align: left;">MIDI is actually just a fancy serial port connection that runs at 31250 baud, and I already had some code for doing that type of communication (as shown below), so the step of transmitting data wasn&#8217;t all that complicated. I DID run into a <em>gotcha</em> in that I needed to apply voltage to the MIDI breakout board as well as a data line. That took me about a day to figure out. Anyways, here is the code:</p>
<pre>void init_uart()
{
	/* Initialize the UART */
   UBRRH = (unsigned char)(15 &gt;&gt; 8);//(unsigned char)((unsigned int)((F_CPU / 16.0 / MIDI_BAUD)-1) &gt;&gt; 8);
   UBRRL = (unsigned char)(15);//(unsigned char)((F_CPU / 16.0 / MIDI_BAUD)-1);

   UCSRB = (1 &lt;&lt; RXEN) | (1 &lt;&lt; TXEN);

   UCSRC = (0 &lt;&lt; USBS) | (0 &lt;&lt; UCSZ2) | (1 &lt;&lt; UCSZ1) | (1 &lt;&lt; UCSZ0);
}

void usart_send_byte(uint8_t u8Data)
{
	// Wait if a byte is being transmitted
	 while (!(UCSRA &amp; (1 &lt;&lt; UDRE)));

	// Transmit data
	UDR = u8Data;
}

uint8_t usart_receive_byte()
{
	// Wait until a byte has been received
	while (!(UCSRA &amp; (1 &lt;&lt; RXC)));

	// Return received data
	return UDR;
}</pre>
<p>After I had the micro controller talking over the MIDI port, I thought it would be exciting to actually have some buttons, rather than just hard coding sequences of notes. So, I got on DigiKey and bought a 4&#215;4 keypad. I had never used a &#8216;matrix keypad&#8217; before, but thought it couldn&#8217;t be too complicated. Boy was I wrong. The way a (4&#215;4) matrix keypad works is that there are 8 I/O lines. 4 correspond to a row each and the other 4 correspond to a column each. When a button is pressed, a circuit is completed between the appropriate row and column pins. By detecting which pins are connected, the micro controller can deduce which specific button is pushed.</p>
<div id="attachment_317" class="wp-caption alignright" style="width: 310px"><a href="http://samuelkerr.com/wp-content/uploads/2012/01/Grayhill-88BB2.jpg"><img class="size-medium wp-image-317" title="Grayhill 88 Keypad" src="http://samuelkerr.com/wp-content/uploads/2012/01/Grayhill-88BB2-300x300.jpg" alt="" width="300" height="300" /></a><p class="wp-caption-text">A basic 4x4 matrix keypad</p></div>
<p>There are <a href="http://www.8051projects.net/keypad-interfacing/introduction.php">other sites</a> on the internet that explain a little bit more of the theory behind matrix keypads, so I won&#8217;t repeat them here. However, I could not get any of the sample code I found to work, so I had to end up writing my own. Before providing the code, I will explain the setup I was using. I was using PORTB on the ATtiny2313 to handle all 8 pins of the keypad, PB0-PB3 were the columns (H,G,F, and E, respectively) while PB4-PB7 were the rows (J, K, L, and M, respectively). I did not use any external resistors, despite some sites suggesting I do so.</p>
<pre>/************************************************************************/
/* Returns which button is pressed. Indexed, 0-15. 0xFE if none is pressed*/
/************************************************************************/
uint8_t button_pressed()
{
	/*
		// outputs (columns) low 4 bits
		E - PB0
		F - PB1
		G - PB2
		H - PB3

		// inputs (rows) high 4 bits
		J - PB4
		K - PB5
		L - PB6
		M - PB7
	*/

	/* Everything is an input */
	DDRB = 0x0;

	/* Columns are Hi-Z */
	PORTB = 0x0;

	/* Rows are pulled high */
	PORTB = PORTB | 0xF0;

	/* For each column */
	uint8_t c;
	for(c = 0; c &lt; 4; c++)
	{
		/* Turn this column into an output. It will be a low output. */
		DDRB = DDRB | (1 &lt;&lt; c);

		/* For each row */
		uint8_t r;
		for(r = 0; r &lt; 4; r++)
		{
			uint8_t pins = PINB;

			/* Is this row low? (binary left shift by the row count + 4 to get into high nibble */
			if(! (pins &amp; (1 &lt;&lt; (r+4) ) ) )
			{
				/* If yes, */

				/* Return this button */
				return 15 - (r*4 + c); // Subtracting the value from 15 flips it so that the upper left is 0 and bottom right is 15
			}
			else
			{
				/* If no, */
				/* Continue */
			}
		}

		/* Turn this column back to Hi-Z */
		DDRB = 0;
	}

	return 0xFE;
}</pre>
<p style="text-align: left;">After I was able to figure out how to interface with the 4&#215;4 matrix keypad, I was able to configure each button to send a unique message to the computer. Currently, I am using <a href="http://www.native-instruments.com/products/dj/traktor/">Traktor</a> for my DJ software and I have  it set up so each button causes a different function in Traktor; one button loops 8 bars, another performs a pitch bend, others fire off samples, and I haven&#8217;t figured out what to do with the rest!</p>
<div id="attachment_318" class="wp-caption alignleft" style="width: 179px"><a href="http://samuelkerr.com/wp-content/uploads/2012/01/387328_2460269072143_1414650085_32069741_2045463324_n.jpg"><img class="size-medium wp-image-318" title="MIDI Controller" src="http://samuelkerr.com/wp-content/uploads/2012/01/387328_2460269072143_1414650085_32069741_2045463324_n-169x300.jpg" alt="" width="169" height="300" /></a><p class="wp-caption-text">The final results of the MIDI controller project.</p></div>
<p style="text-align: left;">The final result of my project looks like the picture to the left. It was a lot of fun to build and work on this project. For an extension, I might try to make a PCB, rather than a breadboard for all the components. I would also like to put a USB to MIDI chip directly on the board, rather than using an external one. That would be more convenient and I&#8217;m sure cheaper. Also, it would be fun to make a nice enclosure of some kind or to have fancier buttons than what I am currently using.</p>
<p style="text-align: left;">Leave me a comment and let me know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=314</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Disk Images! Or, the quickest way to get a headache on a Mac!</title>
		<link>http://samuelkerr.com/?p=292</link>
		<comments>http://samuelkerr.com/?p=292#comments</comments>
		<pubDate>Wed, 02 Mar 2011 15:51:58 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=292</guid>
		<description><![CDATA[Lately, I have been doing work with the Pistachio L4 microkernel as part of my research. This requires building various disk images, installing GRUB, and running them inside of a virtual machine. Initially, I was using Linux to do this, since it had all the tools ready to go and was what everyone else was [...]]]></description>
			<content:encoded><![CDATA[<p>Lately, I have been doing work with the <a href="http://www.l4ka.org/65.php" target="_blank">Pistachio</a> L4 microkernel as part of my research. This requires building various disk images, installing GRUB, and running them inside of a <a href="http://en.wikipedia.org/wiki/Virtual_machine">virtual machine</a>. Initially, I was using Linux to do this, since it had all the tools ready to go and was what everyone else was using. However, I have a Mac, so I wanted to be able to use that, rather than SSHing into a server all the time. I didn&#8217;t think it would be a big deal, just install the same tools on my Mac, right? Wrong! What follows is the odyssey of what I&#8217;ve gone through to do this. Hopefully, it will help anyone else facing a similar circumstance.</p>
<p><span id="more-292"></span>The main problem I ran into with this task is that Mac&#8217;s do not have loop devices and the losetup program. On Linux, these let you mount a disk image, such as a CD ISO or  a raw hard drive image,  to a folder. You can then easily mount the image, copy files, then unmount the image and be done. Since Macs do not have these loopback devices, it wouldn&#8217;t be possible to just build the losetup program either.</p>
<p>On a Mac, you can play with ISOs and other images using Disk Utility. For a bootable hard drive image, there is no filesystem on the disk initially, so there is nothing for Mac to mount. Too bad.</p>
<p>However, there is a set of tools called <a href="http://www.gnu.org/software/mtools/" target="_blank">mtools</a>, which allow you to play with DOS formatted images, i.e. <a href="http://en.wikipedia.org/wiki/File_Allocation_Table" target="_blank">FAT</a>, which will work for my needs. They are especially helpful on Linux systems, since you can use them without being a root user, unlike losetup. Luckily, they are GNU open source, so there was a glimmer of hope that these may work on Mac. I tried <a href="http://mxcl.github.com/homebrew/" target="_blank">Homebrew</a> and <a href="http://www.macports.org/" target="_blank">MacPorts</a>, but neither worked. There was source available though, so I could try building them myself.</p>
<p>Normally, GNU software is easy to install. Just do &#8216;./configure; make; make install&#8217; and that&#8217;s it on a Linux system. Macs are a little different from Linux though, so sometimes this doesn&#8217;t work. In this case, I kept getting compile errors when running make. Something to do with the iconv library and not linking properly. I suspect that is from Apple providing a slightly different version of the library. Fortunately, this was an optional library, so I simply excluded it from the rebuild and tried again. Voila, it built and I now have mtools.</p>
<p>The next step was to create a hard drive image. This sounds simple, but it takes some math to make one of the proper size. It is important that the disk has less than 1023 cylinders, or else GRUB will complain later on.  I found a <a href="http://www.csgnetwork.com/mediasizecalc.html" target="_blank">calculator online</a> to help do this. For my needs, I only needed about a 10 MB disk, so I used the values: 4 heads, 500 cylinders, 10 sectors per track, and 512 per sector. This gives a 10.24 MB disk size. Great.</p>
<p>I made a raw file of the proper size with the command:</p>
<pre>dd if=/dev/zero of=disk.img bs=512 count=20000</pre>
<p>That command spits out disk.img, which will be the hard drive image we are working with. However, it is just filled with zeros right now, so mtools needed to format it. I pulled my hair out trying to figure out the right command line options for this. I kept confusing the -s flag for the number of sectors, but it&#8217;s actually number of sectors PER TRACK. That&#8217;s kind of a big deal. Anyways, here are the commands I used to get mtools to play nice:</p>
<pre>
<div id="_mcePaste">echo 'drive a: file="disk.img"' &gt; mtoolsrc</div>
<div id="_mcePaste">MTOOLSRC=./mtoolsrc mformat -t 2000 -s 10 -h 4 a:</div>
</pre>
<p>Now, the disk is formatted with a FAT filesystem (at least as far as I understand it).  However, there are no files on it, so it&#8217;s pretty boring. First, we need to install GRUB, which is a bootloader, so that we can boot this stupid disk (At this point, I have done about 10 hours of Googling, compiling, and yelling). In the mtools package, there are two commands called &#8216;mmd&#8217; and &#8216;mcopy&#8217;. These can make a directory and copy files for us. Exciting, I know. Here are the steps to copy GRUB (legacy) to the disk. Note that you must already have the files downloaded. You can grab them <a href="http://grub.enbug.org/GrubLegacy">here</a>. For grub.conf, you will have to play with that and make one yourself. There are tutorials, so I omit directions here.</p>
<pre> MTOOLSRC=./mtoolsrc mmd a:/boot
MTOOLSRC=./mtoolsrc mmd a:/boot/grub
MTOOLSRC=./mtoolsrc mcopy stage1 a:/boot/grub
MTOOLSRC=./mtoolsrc mcopy stage2 a:/boot/grub
MTOOLSRC=./mtoolsrc mcopy grub.conf a:/boot/grub</pre>
<p>Well, now we have a hard disk image with GRUB on it, we&#8217;re done right? WRONG. Grub is <em>stored</em> on the disk, but not <em>installed</em> on the disk. To actually install it, we have to boot the disk and run some GRUB commands.</p>
<p>But how can we boot the disk if GRUB isn&#8217;t installed? Point for you if you asked that. We now need to go grab a bootable GRUB floppy. We&#8217;re only interested in the GRUB command line, so any will do. There is one from <a href="http://www.jamesmolloy.co.uk/downloads/floppy.img" target="_blank">here</a> that will work.</p>
<p>Now that we have the disk with GRUB stored on it and a bootable floppy, let&#8217;s finally start the virtual machine and install GRUB. I&#8217;m going to use QEMU. If you&#8217;re using something else, QEMU commands won&#8217;t help you, so use <a href="http://wiki.qemu.org/Main_Page" target="_blank">QEMU</a> instead. First, boot the disk and floppy with the command:</p>
<pre>qemu -hda disk.img -fda /floppy.img -boot order=a</pre>
<p>That will start QEMU with both the floppy and hard disk inserted and boot the floppy. When the floppy first boots up, hit &#8216;c&#8217; on the keyboard to get a command line. That&#8217;s all we actually needed the floppy for. Now, on the command line, enter the commands:</p>
<pre>root (hd0,0)
setup (hd0,0)</pre>
<p>Some text should fly by and if there are no errors, GRUB will now be installed. You can check by running QEMU again, but without the floppy disk and seeing what happens. Hopefully, you will get a boot screen, in which case you are done. You can now copy files as needed to the disk using &#8216;mcopy&#8217; how we did before.</p>
<p>If you get errors about disk size and cylinders, use the command &#8216;geometry (hd0,0)&#8217; to get some more information, when at the GRUB command line.</p>
<p>Well, I hope that helps someone else out there. I had no end of problems getting that to work. However, I can now use disk images so I can work on&#8230;. Well, I forgot what I was originally doing, it was so long ago!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=292</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reverse Engineering the Master Boot Record</title>
		<link>http://samuelkerr.com/?p=262</link>
		<comments>http://samuelkerr.com/?p=262#comments</comments>
		<pubDate>Mon, 26 Jul 2010 14:40:58 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[General Computing]]></category>
		<category><![CDATA[Reverse Engineering]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=262</guid>
		<description><![CDATA[One day, I was curious about how the computer system goes from booting to actually loading up an operating system. Obviously, it must retrieve the operating system from disk at some point, so I decided to investigate this. The first step in this process is reading the MBR, or Master Boot Record of the hard [...]]]></description>
			<content:encoded><![CDATA[<p>One day, I was curious about how the computer system goes from booting to actually loading up an operating system. Obviously, it must retrieve the operating system from disk at some point, so I decided to investigate this. The first step in this process is reading the MBR, or <a href="http://en.wikipedia.org/wiki/Master_boot_record">Master Boot Record</a> of the hard drive. The MBR is used to store data about where the OS is stored on the drive. </p>
<p>I figured the MBR would be interesting to learn a little bit more about, so I decided to load it up into <a href="http://www.hex-rays.com/idapro/">IDA Pro</a>, a tool for disassembling programs, and see what I could find out.<br />
<div id="attachment_274" class="wp-caption alignleft" style="width: 272px"><a href="http://samuelkerr.com/wp-content/uploads/2010/07/Baby-rhino-6078359.jpg"><img src="http://samuelkerr.com/wp-content/uploads/2010/07/Baby-rhino-6078359-262x300.jpg" alt="" title="Baby-rhino-6078359" width="262" height="300" class="size-medium wp-image-274" /></a><p class="wp-caption-text">This baby rhino was also curious about MBRs.</p></div><br />
I learned a lot and had a lot of fun, so I&#8217;m presenting it here to share my results.</p>
<p><span id="more-262"></span></p>
<p>For this analysis, I assume that you are familiar with the x86 architecture and assembly. If not, WikiBooks has some great information about it <a href="http://en.wikibooks.org/wiki/X86_Assembly">here</a>. I am also using IDA Pro to do this. I have tried to provide comments and labeling in my IDA work, but I also explain each block of code separately.</p>
<p>The first step in figuring out the MBR was to actually get a copy of it I could work with. To do this, I used <a href="http://www.hexworkshop.com/">Hex Workshop</a>, which offers a way to do a binary copy of hard disks. The MBR is always located as the first sector of the disk, so I used Hex Workshop and extracted this file. It is only 1 sector long, so it is a mere 512 bytes.</p>
<p>After looking at <a href="http://en.wikipedia.org/wiki/Master_boot_record">Wikipedia</a>, I figured out the MBR structure was:</p>
<pre>
0000h - 01B7h       Code Area (440 bytes)
01B8h - 01BBh       Disk Signature (4 bytes)
01BCh - 01BDh       Generally Zeroed out (2 bytes)
01BEh - 01FDh       List of Partition Records (4 16-byte structures)
01FEh - 01FFh       MBR Signature (2 bytes - Must be AA55h)
</pre>
<p>The above structure is what gets loaded into memory and executed. The code area is going to do a few different things, which I look at below. The disk signature can be used to uniquely identify a hard disk. The partition records define different operating systems and partitions on the hard disk. Have you ever noticed how you have to jump through some hoops if you want to have more than 4 operating systems or partitions on your computer? Well, that&#8217;s because you only have 4 partition records available. The MBR signature helps illustrate that this is in fact an MBR structure.</p>
<p>The partition records are a pretty important part of the MBR, so I also examined their structure. It is:</p>
<pre>
0000h - 0000h    Status byte (80h for bootable, 00h for non-bootable, others are invalid) (1 byte)
0001h - 0003h    CHS address of first absolute sector (3 bytes)
0004h - 0004h    Partition type (1 byte)
0005h - 0007h    CHS address of last absolute sector (3 bytes)
0008h - 000Bh    LBA of first absolute sector (4 bytes)
000Ch - 000Fh    Number of sectors in partition (4 bytes)
</pre>
<p>That is a pretty simple structure; just a start and stop address, length, and a few informational bytes. The CHS format is a little confusing though. CHS stands for Cylinder-Head-Sector and defines an address inside of a physical hard drive. You can read more about CHS here. The LBA address stands for Logical Block Address. LBA is a format to linearly address space on the hard drive, rather than defining 3 separate numbers for Cylinder-Head-Sector format. More information about LBA is here.</p>
<p>After examining the file MBR structure, I loaded the binary file into IDA Pro. Since it is a binary file, IDA doesn&#8217;t know where the correct segments or entry points are, or even if it is 16 or 32 bit code. Since we don&#8217;t have an OS yet, we know that this code is 16 bit. Looking at the MBR structure, the code starts at the very first byte of the file. Knowing this, I configured IDA and converted the first few bytes to code. I got the following:</p>
<pre>
s0:0000 ; ---------------------------------------------------------------------------
s0:0000
s0:0000 ; Segment type: Pure code
s0:0000 seg000          segment byte public 'CODE' use16
s0:0000                 assume cs:seg000
s0:0000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
s0:0000                 xor     ax, ax          ; Zero out AX
s0:0002                 mov     ss, ax          ; Set SS to 0
s0:0004                 mov     sp, 7C00h       ; Set SP to 7C00h
s0:0007                 mov     es, ax          ; Set ES to 0
s0:0009                 mov     ds, ax          ; Set DS to 0
s0:000B                 mov     si, 7C00h       ; Source for the copy
s0:000E                 mov     di, 600h        ; This is the destination for the copy
s0:0011                 mov     cx, 200h        ; We want to copy 200h bytes, which is the length
s0:0011                                         ;    of one sector, i.e. the whole MBR.
s0:0014                 cld                     ; Clear Direction Flag
s0:0015                 rep movsb               ; Copies CX bytes from [SI] to [DI]
s0:0015                                         ;    i.e. from [7C00h] to [600h]
s0:0017                 push    ax              ; New value for CS
s0:0018
s0:0018 loc_18:                                 ; New value for IP
s0:0018                 push    61Ch
s0:001B                 retf                    ; Pops the top of the stack into IP then pops CS
s0:001B	                                        ;    off next.
s0:001B                                         ;    i.e. we will run from 0000h:61Ch,
s0:001B                                         ;    which is where we just copied ourselves to.
s0:001B                                         ;
s0:001B                                         ; Execution continues at the next instruction.
</pre>
<p>I have tried to add a lot of comments to show what is going on. Essentially though, what this is doing is copying the MBR from 0000h:7C00h to 0000:600h. This is necessary, because it will later load the OS to 0000h:7C00h, so it needs to get itself out of the way. It does this using the &#8216;rep movsb&#8217; which does a binary copy of 200 bytes from SI (7C00h) to DI (600h).</p>
<p>An interesting part about the code above is the way that the &#8216;retf&#8217; instruction is used. This does what is known as a &#8216;far jump&#8217;. This means it not only jumps to a different instruction address, but also a different code segment. Both of these values are popped off of the stack, with the offset being on top and the new segment being second. Before the retf instruction, the program pushes 0 and then &#8217;61Ch&#8217; onto the stack to setup for this far jump. This may seem strange, but since it just copied all the program data to 0000h:0600h, 61Ch is actually the offset to the instruction directly after the retf in the binary.</p>
<p>The next few instructions are:</p>
<pre>
s0:001C                 sti                     ; Enable interrupts
s0:001D                 mov     cx, 4           ; This will be used for the loop.
s0:001D                                         ;    We only want to examine 4 partition records.
s0:0020                 mov     bp, 7BEh        ; This is the offset to the first partition
s0:0020                                         ;   record.
s0:0020                                         ; In the MBR structure, the first partition
s0:0020                                         ;    record is at base+1BEh,
s0:0023                                              so it is 600h + 1BEh = 7BEh
s0:0023
</pre>
<p>First thing this code does is to enable <a href="http://en.wikipedia.org/wiki/Interrupt">interrupts</a> so that it can be interrupted if necessary. Next, it sets the CX register to 4 and BP to 7BEh. BP is the offset to the partition records (there is a description of these records <a href="http://en.wikipedia.org/wiki/Master_boot_record">here</a>). CX is indicating that we will only examine 4 records (since there are only 4 in the MBR). So this is setting up to iterate over the 4 partition records to find the bootable one that we want.</p>
<p>After this is a loop that tries to find a bootable partition entry. The code is:</p>
<pre>
s0:0023 loc_23:                                 ; CODE XREF: seg000:0030j
s0:0023                 cmp     byte ptr [bp+0], 0 ; Compares the status byte to 0
s0:0027                 jl      short FoundBootableEntry ; Jumps if the status flag is not 0.
s0:0027                                         ;    This will happen if the MSB of [bp+0]
s0:0027                                         ;    is 1, essentially saying that if it
s0:0027                                         ;    is 0x80, it will jump.
s0:0027                                         ;
s0:0027                                         ; This jump indicates that we have found the
s0:0027                                         ;    bootable partition.
s0:0029                 jnz     PrintInvalidPartitionTable ; It's not 0x80 and it's not 0x0, so
s0:0029                                         ;    it's invalid. Jump to an error state.
s0:002D                 add     bp, 10h         ; Go to the next partition record.
s0:0030                 loop    loc_23          ; Loop while CX != 0
s0:0032                 int     18h             ; TRANSFER TO ROM BASIC
s0:0032                                         ; causes transfer to ROM-based BASIC (IBM-PC)
s0:0032                                         ; often reboots a compatible; often has no effect
s0:0034                                         ; at all
</pre>
<p>Remember how above we moved the offset of 7BEh into BP? That is so this loop can then examine the partition records. The comparison is checking the status byte of the partition record and comparing it to 0. If it is 0, the first jump will not be taken, nor will the second jump, so 10h is added to BP and the loop is restarted. Advancing the BP register means that we will examine a different partition record. If, after 4 iterations, we have still not found a bootable partition entry, an &#8216;int 18h&#8217; call will be made. On old IBM PCs, this would run a BASIC interpreter from ROM, but few computers have this. So essentially, an int 18h call will just stop the system. Imagine that, if you have no bootable entries, you&#8217;re computer won&#8217;t boot!</p>
<p>If the status byte of the parition record was in fact 80h, the first jump would have been taken. The JL instruction does a jump if the status flag is set to 1. This flag will get set by the previous CMP instruction if the high order bit is set in the status byte, i.e. the status byte is 80h. If the entries status byte is neither 80h or 00h, a jump is made to the PrintInvalidPartitionTable location. I&#8217;ll talk about that a little bit, but it&#8217;s pretty boring (it just prints an error message); when a bootable entry is found, things are much more fun.</p>
<p>The next block of code is run when a bootable entry is found. Here it is:</p>
<pre>
s0:0034 FoundBootableEntry:                     ; CODE XREF: seg000:0027j
s0:0034                                         ; seg000:00AEj
s0:0034                 mov     [bp+0], dl      ; Save the drive number for later
s0:0034                                         ;    Note that since this will most likely be the
s0:0034                                         ;    first hard drive, DL will probably be 0x80
s0:0037                 push    bp
s0:0038                 mov     byte ptr [bp+11h], 5
s0:003C                 mov     byte ptr [bp+10h], 0 ; This is a sentinel value for later
s0:0040
s0:0040 loc_40:                                 ; DATA XREF: seg000:014Fr
s0:0040                 mov     ah, 41h ; 'A'
s0:0042                 mov     bx, 55AAh
s0:0045                 int     13h             ; DISK - Installation Check
s0:0045                                         ;   CF set on error
s0:0045                                         ;   CF cleared on success
s0:0045                                         ;   BX = AA55 if installed
s0:0045                                         ;   AH = major version of extensions
s0:0045                                         ;   CX = API subset
s0:0045                                         ;   DH = Extension version
s0:0047                 pop     bp
s0:0048                 jb      short AttemptLoadFromDisk ; Jump if Below (CF=1)
s0:004A                 cmp     bx, 0AA55h      ; DATA XREF: seg000:0045r
s0:004A                                         ; seg000:007Er ...
s0:004A                                         ; Compare Two Operands
s0:004E                 jnz     short AttemptLoadFromDisk ; Jump if Not Zero (ZF=0)
s0:0050                 test    cx, 1           ; Logical Compare
s0:0054                 jz      short AttemptLoadFromDisk ; Jump if Zero (ZF=1)
s0:0056                 inc     byte ptr [bp+10h] ; This acts like a sentinel value
s0:0056                                         ;    for whether or not the INT 13
s0:0056                                         ;    extended read is installed
s0:0059
</pre>
<p>First part of this block does is moves the DL register into where the entry&#8217;s status byte used to be. I wasn&#8217;t really too sure what was going on here for a long time, since if it overwrites the partition record, won&#8217;t it not boot correctly next time? Well, it turns out that the first hard drive is represented by 80h, so most of the time, things will be fine. I don&#8217;t have 2 hard drives, so I&#8217;m not sure what would happen if you had two hard drives and had your bootable entry on the second hard drive. I suspect that the 2nd hard drive would just have its own MBR and would run that instead. Running code on 1 hard drive and loading data from another hard drive seems a little bit silly anyways, so I&#8217;m pretty sure that&#8217;s whats going on. If you know more, please leave a comment!</p>
<p>Next, the code saves the partition record to the stack and moves the values 5 and 0 into the status byte. The 5 indicates the number of attempts that will be made to read from disk later. Multiple attempts will be made because the disk read might fail while the disk spins up. The 0 value is a sentinel value for whether or not the BIOS supports the extended interrupt 13h feature. This is an advanced, easier way to load lots of data from disk into memory, but not all BIOSs support it. The code above runs several different checks and if they all succeed, it stores a 1 where it had just stored a 0, indicating the extended read feature is supported. If any of those checks fails, it just jumps down a few lines and continues executing and will use the older method.</p>
<p>The next section of code loads the first sector of the OS into memory, using a different method depending on whether or not the extended read is supported. Here it is:</p>
<pre>
s0:0059 AttemptLoadFromDisk:                    ; CODE XREF: seg000:0048j
s0:0059                                         ; seg000:004Ej ...
s0:0059                 pushad                  ; Save all our registers for a little bit
s0:005B                 cmp     byte ptr [bp+10h], 0 ; Did our sentinel value get changed?
s0:005F                 jz      short InstallationFailed ; DATA XREF: seg000:0032r
s0:005F                                         ; Jump if Zero (ZF=1)
s0:0061                 push    large 0         ; LBA of 0
s0:0067                 push    large dword ptr [bp+8] ; DATA XREF: seg000:00E5r
s0:0067                                         ; seg000:0125r
s0:0067                                         ; Transfer buffer
s0:0067                                         ;    This is also the LBA of first absolute sector
s0:0067                                         ;    in the MBR partition record
s0:006B                 push    0               ; Transfer buffer
s0:006E                 push    7C00h           ; Number of blocks
s0:006E                                         ;    Note that only the first byte is relevant,
s0:006E                                         ;    and the second is ignored, so we are only
s0:006E                                         ;    reading 7Ch
s0:0071                 push    1               ; Reserved
s0:0074                 push    10h             ; Packet is size 10h
s0:0077                 mov     ah, 42h ; 'B'
s0:0079                 mov     dl, [bp+0]      ; Drive number
s0:007C                 mov     si, sp          ; Point to the address packet we just made
s0:007E                 int     13h             ; DISK - Extended Read
s0:007E                                         ;
s0:007E                                         ;    Reads DS:SI into a disk appress packet
s0:007E                                         ;      a disk address packet is:
s0:007E                                         ;      00 BYTE: Size of packet (10h or 18h)
s0:007E                                         ;      01 BYTE: Reserved
s0:007E                                         ;      02 WORD: Number of blocks to transfer
s0:007E                                         ;      04 DWORD: Transfer buffer
s0:007E                                         ;      08 QWORD: Starting absolute block number (LBA)
s0:007E                                         ;      10 QWORD: 64-bit flat address of transfer buffer (optional, used if the DWORD at 04 is FFFFh:FFFFh)
s0:007E                                         ;
s0:007E                                         ;    CF cleared if successful
s0:007E                                         ;    AH = 0 on success
s0:0080                 lahf                    ; Preserve the flags for a second
s0:0081                 add     sp, 10h         ; Pop the address packet we were using off the stack
s0:0084                 sahf                    ; Store AH into Flags Register
s0:0085                 jmp     short PostDiskReadState ; Jump
s0:0087 ; ---------------------------------------------------------------------------
s0:0087
s0:0087 InstallationFailed:                     ; CODE XREF: seg000:005Fj
s0:0087                 mov     ax, 201h        ; The extended read interrupt is not installed,
s0:0087                                         ;    so use the legacy version
s0:0087                                         ; AH = 2 (Disk read sectors into memory)
s0:0087                                         ; AL = 1 (Read 1 sector)
s0:008A                 mov     bx, 7C00h       ; This is the destination buffer
s0:008D                 mov     dl, [bp+0]      ; Drive number
s0:0090                 mov     dh, [bp+1]      ; These 3 bytes are a CHS structure
s0:0093                 mov     cl, [bp+2]
s0:0096                 mov     ch, [bp+3]
s0:0099                 int     13h             ; DISK - READ SECTORS INTO MEMORY
s0:0099                                         ; AL = number of sectors to read, CH = track, CL = sector
s0:0099                                         ; DH = head, DL = drive, ES:BX -> buffer to fill
s0:0099                                         ; Return: CF set on error, AH = status, AL = number of sectors read
</pre>
<p>Right away, a comparison is done against the sentinel value. If it is 0 (indicating no extended read), a jump is taken to the InstallationFailed label. If the extended read is supported, an &#8220;address packet&#8221; is set up for the interrupt and then the int 13h call is made, performing the read. This was actually a pretty tricky section to figure out, mostly because I found all the documentation about address packets was pretty confusing. After the extended read is completed, the code jumps to the PostDiskReadState location. I expect there are a few errors in my comments about the address packet, which I might try to figure out more about later.</p>
<p>Both the extended read and the non-extended read code do essentially the same thing though. They load the first sector of the bootable partition into memory at 0000h:7C00h. This will most likely be the operating system&#8217;s loader which will get things started up properly. Before we jump to the OS though, first we have a little bit of maintenance to do, to make sure we are set up and good to go.</p>
<p>After the disk reads are done, we need to make sure that everything succeeded, which is what this block of code does:</p>
<pre>
s0:009B PostDiskReadState:                      ; CODE XREF: seg000:0085j
s0:009B                 popad                   ; Restore all our registers
s0:009D                 jnb     short DiskReadSuccess ; Jump if CF = 0
s0:009D                                         ;    i.e. The interrupt we just executed (either one)
s0:009D                                         ;    just succeeded.
s0:009F                 dec     byte ptr [bp+11h] ; Remember this was set to 5 before?
s0:009F                                         ;    This is looping and trying the disk several times,
s0:009F                                         ;    (it might have failed while the disk spun up)
s0:00A2                 jnz     short ReattemptDiskRead ; Jump if Not Zero (ZF=0)
s0:00A4                 cmp     byte ptr [bp+0], 80h ; 'Ç' ; Is this drive letter 80h, i.e. the
s0:00A4                                                    ; first hard drive?
s0:00A8                 jz      PrintErrorLoadingOperatingSystem ; Jump if Zero (ZF=1)
s0:00AC                 mov     dl, 80h ; 'Ç'   ; Re-try on the first hard drive
s0:00AE                 jmp     short FoundBootableEntry ; Jump
s0:00B0 ; ---------------------------------------------------------------------------
s0:00B0
s0:00B0 ReattemptDiskRead:                      ; CODE XREF: seg000:00A2j
s0:00B0                 push    bp
s0:00B1                 xor     ah, ah          ; Logical Exclusive OR
s0:00B3                 mov     dl, [bp+0]
s0:00B6                 int     13h             ; DISK - RESET DISK SYSTEM
s0:00B6                                         ; DL = drive (if bit 7 is set both hard disks and
s0:00B6                                         ;   floppy disks reset)
s0:00B6                                         ;
s0:00B6                                         ; This is important so we can try the read again
s0:00B8                 pop     bp
s0:00B9                 jmp     short AttemptLoadFromDisk ; Jump
</pre>
<p>For both style of disk reads, if the operation succeeded, the carry flag will be cleared. As such, there is a JNB instruction that is taken if the load succeeded and jumps to the DiskReadSuccess location. If not, the counter we previously set to 5 is decremented. Remember how I talked about that the disk read might fail sometimes? This code is taking into account the drive being busy, not being spun up, or any other reason by just re-trying a few times. If however, it has failed after the 5 attempts, something is wrong. A comparison is then made to see if we are on the first hard drive by comparing the drive letter we wrote to [BP+0] with 80h. If it is, there is a problem loading the OS, so we print an error message. If not, we change the DL register to 80h, indicating the first hard drive, and try the whole process again.</p>
<p>The ReattemptDiskRead code is pretty straightforward. All it does is resets the disk system and jumps back to the AttemptLoadFromDisk location. Pretty simple, huh?</p>
<p>Hopefully the disk read will succeed though, and the code will get to the DiskReadSuccess location. We are very close to actually jumping to the OS in that case. Here is the code:</p>
<pre>
s0:00BB DiskReadSuccess:                        ; CODE XREF: seg000:009Dj
s0:00BB                 cmp     word ptr ds:7DFEh, 0AA55h ; We just loaded new code to 7C00h. Check
s0:00BB                                         ;    to see if it has the bootable signature AA55.
s0:00BB                                         ;    This signature indicates a VBR, which indicates
s0:00BB                                         ;    an operating system
s0:00C1                 jnz     short PrintMissingOperatingSystem ; The last two bytes are NOT AA55h
s0:00C1                                                           ; so there is no OS.
s0:00C1                                         ;    Print an error message.
s0:00C3                 push    word ptr [bp+0]
s0:00C6                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00C9                 jnz     short CheckForTPM ; Jump if Not Zero (ZF=0)
s0:00CB                 cli                     ; Disable interrupts for a while
s0:00CC                 mov     al, 0D1h ; '-'
s0:00CE                 out     64h, al         ; AT Keyboard controller 8042.
s0:00CE                                         ;    Enables writing the output port
s0:00D0                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00D3                 mov     al, 0DFh ; '¯'
s0:00D5                 out     60h, al         ; AT Keyboard controller 8042.
s0:00D5                                         ;    Enables writing to the status register
s0:00D7                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00DA                 mov     al, 0FFh        ; Enable A20 memory line
s0:00DC                 out     64h, al         ; AT Keyboard controller 8042.
s0:00DC                                         ; Reset the keyboard and start internal diagnostics
s0:00DE                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00E1                 sti                     ; Enable interrupts
s0:0156 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
s0:0156
s0:0156
s0:0156 CheckKeyboardSystemFlag proc near       ; CODE XREF: seg000:00C6p
s0:0156                                         ; seg000:00D0p ...
s0:0156                 sub     cx, cx          ; CX = 0
s0:0158
s0:0158 CheckByte2:                             ; CODE XREF: CheckKeyboardSystemFlag+8j
s0:0158                 in      al, 64h         ; AT Keyboard controller 8042.
s0:015A                 jmp     short $+2       ; Jump
s0:015C                 and     al, 2           ; Logical AND
s0:015E                 loopne  CheckByte2      ; Loop while rCX != 0 and ZF=0
s0:0160                 and     al, 2           ; Logical AND
s0:0162                 retn                    ; Return Near from Procedure
s0:0162 CheckKeyboardSystemFlag endp
</pre>
<p>This code first checks to see that we did, in fact load an OS and not just some garbage into memory by checking for the AA55h signature. If it is not there, we print an error message. Otherwise, we&#8217;re going to fiddle with the keyboard controller a bit. This code makes several calls to the CheckKeyboardSystemFlag function, which basically loops until the keyboard controller is ready to talk to to the CPU. I&#8217;m a little fuzzy on what the output to the ports is doing, but I&#8217;m pretty sure that it is enabling the <a href="http://en.wikipedia.org/wiki/A20_line">A20 address line</a>, which enables larger amounts of memory to be used. It&#8217;s a pretty common task and there are write-ups all over the Internet, so I won&#8217;t go into it.</p>
<p>After the MBR is done fiddling with the keyboard controller, it decides to check for a <a href="http://en.wikipedia.org/wiki/Trusted_Platform_Module">Trusted Platform Module</a>. The TPM is used to do several security related things, such as for Windows BitLocker encryption. There is a lot of complex documentation, so after I figured out that this was TPM code, I decided not to investigate it further. It is listed below:</p>
<pre>
s0:00E2 CheckForTPM:                            ; CODE XREF: seg000:00C9j
s0:00E2                 mov     ax, 0BB00h
s0:00E5                 int     1Ah
s0:00E7                 and     eax, eax        ; Logical AND
s0:00EA                 jnz     short JumpToLoadedMemory ; Jump if Not Zero (ZF=0)
s0:00EC                 cmp     ebx, 41504354h  ; Compare Two Operands
s0:00F3                 jnz     short JumpToLoadedMemory ; Jump if Not Zero (ZF=0)
s0:00F5                 cmp     cx, 102h        ; Compare Two Operands
s0:00F9                 jb      short JumpToLoadedMemory ; Jump if Below (CF=1)
s0:00FB                 push    large 0BB07h
s0:0101                 push    large 200h
s0:0107                 push    large 8
s0:010D                 push    ebx
s0:010F                 push    ebx
s0:0111                 push    ebp
s0:0113                 push    large 0
s0:0119                 push    large 7C00h
s0:011F                 popad                   ; Pop all General Registers (use32)
s0:0121                 push    0
s0:0124                 pop     es
s0:0125                 int     1Ah             ; This makes a call to the TPM
</pre>
<p>The code first checks for the presence of a TPM module. If it is not there, it jumps to the JumpToLoadedMemory location, otherwise it makes a call to the TPM.</p>
<p>Well, ladies and gentlement, thanks for sticking with me. After all that, we are finally ready to jump to the operating system that we loaded into memory. It&#8217;s very simple, so without further adieu:</p>
<pre>
s0:0127 JumpToLoadedMemory:                     ; CODE XREF: seg000:00EAj
s0:0127                                         ; seg000:00F3j ...
s0:0127                 pop     dx
s0:0128                 xor     dh, dh          ; Logical Exclusive OR
s0:012A                 jmp     far ptr 0:7C00h ; Jump to the code we have loaded
</pre>
<p>That&#8217;s it?! Yup, that&#8217;s it. Anti-climactic, though I guess Master Boot Records aren&#8217;t supposed to be entertaining.</p>
<p>There is some more code that I didn&#8217;t talk about yet, because it has to do with printing the error messages out. I&#8217;m not going to explain it here, since I&#8217;m already over 3000 words and I&#8217;m sure you&#8217;re sick of reading. Here it is:</p>
<pre>
s0:0131 PrintMissingOperatingSystem:            ; CODE XREF: seg000:00C1j
s0:0131                 mov     al, ds:7B7h
s0:0134                 jmp     short DisplayErrorMessage ; Jump
s0:0136 ; ---------------------------------------------------------------------------
s0:0136
s0:0136 PrintErrorLoadingOperatingSystem:       ; CODE XREF: seg000:00A8j
s0:0136                 mov     al, ds:7B6h
s0:0139                 jmp     short DisplayErrorMessage ; Jump
s0:013B ; ---------------------------------------------------------------------------
s0:013B
s0:013B PrintInvalidPartitionTable:             ; CODE XREF: seg000:0029j
s0:013B                 mov     al, ds:7B5h
s0:013E
s0:013E DisplayErrorMessage:                    ; CODE XREF: seg000:0134j
s0:013E                                         ; seg000:0139j
s0:013E                 xor     ah, ah          ; Clear out the high byte of the AX register.
s0:0140                 add     ax, 700h        ; We now point to 700h + whatever offset we were given
s0:0140                                         ;    above.
s0:0143                 mov     si, ax
s0:0145
s0:0145 PrintErrorStringLoop:                   ; CODE XREF: seg000:0151j
s0:0145                 lodsb                   ; Load byte at DS:SI into AL
s0:0146                 cmp     al, 0           ; Is the next byte 0? We're looking at a 0 terminated
s0:0146                                         ;     string, so this is important.
s0:0148                 jz      short HaltSystem ; Jump if Zero (ZF=1)
s0:014A                 mov     bx, 7
s0:014D                 mov     ah, 0Eh
s0:014F                 int     10h             ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
s0:014F                                         ; AL = character, BH = display page (alpha modes)
s0:014F                                         ; BL = foreground color (graphics modes)
s0:0151                 jmp     short PrintErrorStringLoop ; Jump
s0:0153 ; ---------------------------------------------------------------------------
s0:0153
s0:0153 HaltSystem:                             ; CODE XREF: seg000:0148j
s0:0153                                         ; seg000:0154j
s0:0153                 hlt                     ; This stops the computer.
s0:0154                 jmp     short HaltSystem ; Jump
s0:0156
s0:0162 ; ---------------------------------------------------------------------------
s0:0163 aInvalidPartiti db 'Invalid partition table',0
s0:017B aErrorLoadingOp db 'Error loading operating system',0
s0:019A aMissingOperati db 'Missing operating system',0
s0:01B3                 db    0
s0:01B4                 db    0
s0:01B5                 db  63h ; c             ; Redirect to the error message at 63h,
s0:01B5                                         ;    i.e. "Invalid Partition Table"
s0:01B6                 db  7Bh ; {             ; Redirect to the error message at 7Bh,
s0:01B6                                         ;    i.e. "Error loading operating system"
s0:01B7                 db  9Ah ; Ü             ; Redirect to the error message at 9Ah,
s0:01B7                                         ;    i.e. "Missing operating system"
</pre>
<p>I realize that a blog post is a pretty difficult way to explain an RE task like this well. As such, I&#8217;m going to make my IDA Pro database available for download <a href="http://samuelkerr.com/wp-content/uploads/2010/07/MBR.idb">here</a>. If you don&#8217;t have IDA, there is a free version (which I use) available <a href="http://www.hex-rays.com/idapro/idadownfreeware.htm">here</a>. It is missing quite a few features, but the price is right, and for work like this (16-bit MBR code), a lot of the newer features aren&#8217;t even relevant.</p>
<p>If you&#8217;re interested, you could do this analysis on your own computer. Depending on your computer&#8217;s manufacturer, you might have some small differences, but those are what makes it fun, right? To get started, get the <a href="http://www.bpsoft.com/downloads/">trial</a> of Hex Workshop, extract the MBR (it&#8217;s the first sector on the disk), then use the free version of IDA Pro to examine it. Happy hunting!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=262</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>PEAR, my first publication!</title>
		<link>http://samuelkerr.com/?p=256</link>
		<comments>http://samuelkerr.com/?p=256#comments</comments>
		<pubDate>Wed, 30 Jun 2010 01:15:07 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[General Computing]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=256</guid>
		<description><![CDATA[During my time at school, I participate in research. I have been doing this since freshman year, and have been co-author on a few papers, but have never been lead author. Well, that is now changing. Yesterday, I submitted a paper to the 2010 ACM DIM (Digital Identity Management) workshop. My paper was  about a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://samuelkerr.com/wp-content/uploads/2010/06/The_Biting_Pear_of_Salamanca_by_ursulav.jpg"><img class="alignright size-medium wp-image-257" title="The_Biting_Pear_of_Salamanca_by_ursulav" src="http://samuelkerr.com/wp-content/uploads/2010/06/The_Biting_Pear_of_Salamanca_by_ursulav-225x300.jpg" alt="" width="225" height="300" /></a>During my time at school, I participate in research. I have been doing this since freshman year, and have been co-author on a few papers, but have never been lead author. Well, that is now changing.</p>
<p><span id="more-256"></span></p>
<p>Yesterday, I submitted a paper to the 2010 ACM DIM (Digital Identity Management) workshop. My paper was  about a project I have been working on the last semester. I used several different things in my projects, some of which I have written about before. Rather than try to explain the project now, I will show you the abstract. I&#8217;ll post the full paper once it is either officially accepted or rejected.</p>
<blockquote>
<p style="text-align: center;"><span style="font-style: normal;">PEAR: A Hardware Based Protocol Authentication System</span></p>
<p style="text-align: center;">
<div id="_mcePaste" style="text-align: center;">
<div id="_mcePaste" style="text-align: center;"><span style="font-style: normal;">Abstract</span></div>
<div id="_mcePaste" style="text-align: center;">As users have to manage an increasing number of ac-</div>
<div id="_mcePaste" style="text-align: center;">counts, they have to balance password security and pass-</div>
<div id="_mcePaste" style="text-align: center;">word usability. As such, many users use insecure pass-</div>
<div id="_mcePaste" style="text-align: center;">words resulting in their accounts and data being vulnerable</div>
<div id="_mcePaste" style="text-align: center;">to unauthorized accesses. In this paper, we present Phys-</div>
<div id="_mcePaste" style="text-align: center;">ically Enhanced Authentication Ring, or PEAR, a system</div>
<div id="_mcePaste" style="text-align: center;">that alleviates this problem. We leverage Physically Un-</div>
<div id="_mcePaste" style="text-align: center;">clonable Functions (PUF) to create unclonable hardware</div>
<div id="_mcePaste" style="text-align: center;">devices, which users use to authenticate. Using a hardware</div>
<div id="_mcePaste" style="text-align: center;">device, our system uses zero-knowledge proofs, which pro-</div>
<div id="_mcePaste" style="text-align: center;">vide better security than traditional passwords, yet users</div>
<div id="_mcePaste" style="text-align: center;">must only enter a simple PIN. As such, our system is very</div>
<div id="_mcePaste" style="text-align: center;">usable and imposes little to no burden on end users and</div>
<div id="_mcePaste" style="text-align: center;">service providers. We present transaction levels on top of</div>
<div id="_mcePaste" style="text-align: center;">PEAR of as an extension and then discuss some other work</div>
<div id="_mcePaste" style="text-align: center;">that could be done in the future.</div>
</div>
<p style="text-align: center;">
</blockquote>
<div style="text-align: left;">I got a ton of help and feedback from the other authors of the paper, <a href="http://www.cs.purdue.edu/homes/mkirkpat/" target="_blank">Michael Kirkpatrick</a> and <a href="http://homes.cerias.purdue.edu/~bertino/" target="_blank">Elisa Bertino</a>, which I greatly appreciate. We used the name PEAR since it provides a lot of opportunities for cool logos and graphics.</div>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&#038;p=256</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
