<?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>TrueJournals &#187; programming</title>
	<atom:link href="http://truejournals.com/tags/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://truejournals.com</link>
	<description>College student; Engineer; Programmer; Nerd.</description>
	<lastBuildDate>Mon, 18 Jul 2011 04:24:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>How I Wrote My First Software Crack</title>
		<link>http://truejournals.com/2011/06/22/how-i-wrote-my-first-software-crack/</link>
		<comments>http://truejournals.com/2011/06/22/how-i-wrote-my-first-software-crack/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 01:03:59 +0000</pubDate>
		<dc:creator>TrueJournals</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[cracking]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://truejournals.com/?p=221</guid>
		<description><![CDATA[Before I really get into this article, I need to place a couple notes here: This is a semi-technical post.  It assumes some knowledge of programming and how software works, but I&#8217;ll try to keep it as simple as possible. I&#8217;ve done my best to not give away what application I&#8217;m writing about.  This is [...]]]></description>
			<content:encoded><![CDATA[<p>Before I really get into this article, I need to place a couple notes here:</p>
<ol>
<li>This is a semi-technical post.  It assumes some knowledge of programming and how software works, but I&#8217;ll try to keep it as simple as possible.</li>
<li>I&#8217;ve done my best to not give away what application I&#8217;m writing about.  This is on purpose.  While this is an interesting look into hacking software, getting around DRM is, to the best of my knowledge, illegal.  This article is actually about reverse-engineering, not cracking software.</li>
<li>If the author of this application finds this blog post and thinks I&#8217;ve given away too much, they should <strong>please</strong> e-mail me and I&#8217;ll take it down.  If you think this article is about your application and it is not, however, I will not remove the article.</li>
<li>If you like software, buy it!  Seriously&#8230; software developers need to eat, too!</li>
</ol>
<p>Now, let&#8217;s get into the bread and butter of this article!</p>
<p><span id="more-221"></span>There&#8217;s a certain piece of software that I&#8217;ve used once or twice, each time with wonderful results.  It really is well-written, it&#8217;s just a bit expensive for how often I use it.  Luckily, it has a free 15-day trial, so I&#8217;ve been able to use that occasionally.  However, I wanted to see if I could do more than that.  I wondered if I could break open the licensing for this software, figure out how it works, and bypass it.  As it turns out, it was easier to just give myself a license, but that doesn&#8217;t come until the end.</p>
<p>The download page for this particular software notes that it requires Java to run.  Since I know of a <a title="jd-gui java decompiler" href="http://java.decompiler.free.fr/?q=jdgui" target="_blank">java decompiler</a>, and I&#8217;m familiar with Java, I figured I&#8217;d be able to decompile the source code and get to hacking.  However, the software installs to an exe.  So, my first question is this: where are the class files?  Those familiar with Java should know that one writes a .java file, then uses javac to compile that to a .class file, which is executed by the java interpreter.   Luckily, the class files I was looking for were hidden right inside the exe.  Even more, <a title="7zip archiver" href="http://7-zip.org/" target="_blank">7-zip</a> had no problem opening the exe as an archive and exposing those class files.</p>
<p>So, now I&#8217;ve got the class files and a Java decompiler.  Let&#8217;s get to reading source code!  This part gets a bit tricky.  I discovered very quickly that the source code was run through an obfuscator before being compiled.  An obfuscator is an application that takes easy-to-read code, and makes it close to impossible to read.  There&#8217;s a couple tricks obfuscators generally use to do this.  Whatever obfuscator was used on the application I&#8217;m decompiling, however, only seemed to do one thing: it took all variables, class names, method names, etc., and renamed them.  It started with A and went to Z.  This makes code very difficult to follow, because classes and variables are usually named to describe what they contain.  For example, if there was a method to verify a license, it would be called&#8230; verifyLicense.  This would be an easy method for me to search for and change.  Now, instead of looking for something to do with licensing, I have to figure out what code executes, and go through it line-by-line.</p>
<p>So, I start looking through classes, thinking perhaps I&#8217;ll find something useful.  Lo-and-behold&#8230; I did!  There was a class staring right at me named &#8220;Startup&#8221;.  Looking inside that class, it had a &#8220;main&#8221; method.  Perfect!  So, I start looking through code.  Luckily, jd-gui is able to link to other classes where necessary.  So, instead of attempting to figure out which &#8220;A&#8221; a certain line of code is referring to, I just click on the &#8220;A&#8221; and I&#8217;m taken right to the relevant code.  This made my job a lot easier.</p>
<p>As I&#8217;m going through the code, I notice a lot of it is just initializing the program.  A couple threads created, variables populated, etc.  Then, I notice an if statement.  This if statement takes me to another class which I notice contains the code for creating the licensing dialog.  Perfect!  Essentially, this if statement checks for a valid license, and if false, displays the licensing dialog.  So&#8230; all I need to do is remove this if statement, compile the code, replace the class in the exe and I&#8217;m done right?</p>
<p>As it turns out, not so right.  I was able to change the code, but compilation was another problem in and of itself.  First off, since a package already existed with the name of the package this class belonged to, I had to leave out the &#8220;package&#8221; line.  I figured this wouldn&#8217;t be a big issue and moved on.  Next, I realized that the java compiler I was using had much stricter class-package name standards.  It wouldn&#8217;t let me have a class which shared a name with a package.  So, if I had package com.truejournals.D.E, containing classes A, B and C, I couldn&#8217;t have a class named com.truejournals.D.E.  This is a huge problem, as the entire obfuscation process seemed to ignore this.  In order to get around this, I would have to refractor almost all of the code.</p>
<p>I&#8217;m not sure how&#8230; but by removing an import or two, I was able to get the code to compile.  Replacing it, however, proved to be another challenge.  Using a resource editor, I found a jar file inside the exe.  I was able to extract that jar file, and was greeted with all the class files I found when opening the exe with 7-zip.  So, this is where I needed to replace the file.  After finding how to do this (7-zip won&#8217;t do it&#8230; jar uf will!), I was able to put my class file inside the jar.  Now, all I had to do was place the jar file back inside the exe.  However, the resource editor I was using wouldn&#8217;t let me do this.  So, I found another that would and was able to replace the jar file.</p>
<p>Now&#8230; the moment of truth&#8230; I open the exe and&#8230; <em>nothing</em>.  Nothing pops up on my screen, so I open task manager.  Turns out, the process is just sitting there idling.  Perhaps there&#8217;s another check somewhere, or perhaps the exe is just rejecting my self-compiled class.  Either way, it looks like I need to find a better way to do this.  What if I could, instead, create my own valid license?</p>
<p>By following the methods in jd-gui, I was able to actually find the code that checks the license.  Here&#8217;s an outline of how this process works:</p>
<ol>
<li>When you open the application for the first time, it creates a file in your application data folder.  The name of this file is the md5 of your computer name with a couple more characters tacked on the end.  The content of this file is a bunch of random uppercase letters with a couple dashes thrown in.</li>
<li>When you enter a serial number, a string is created with a couple pieces of information, separated by ||| (three bars).  The information contained is: the serial from an older version of the program, the serial number you entered, the contents of the file from step #1, your computer&#8217;s host name, and the version of the application.</li>
<li>This string is encrypted by DES-ECB with the first eight characters of the md5 of a key stored in the program&#8217;s code, and sent to &#8220;license2.php&#8221; on the website the application is hosted on.</li>
<li>license2.php generates a response, which is read by the application.</li>
<li>The response is first decrypted using DES-ECB with the first eight characters of the md5 of the contents of the file from step #1 as the key.</li>
<li>This decrypted string is then decrypted again using the same key used in step 3.</li>
<li>The fully decrypted string is checked.  The first character is a key validity checker: 0, 1, 2, 3 or 5 seem to represent a valid license, perhaps some of these with restrictions.  0 seems to be a fully valid license.  The rest of the decrypted string must be the serial number sent to the server.  Although, this only seems to matter if the first character is a 0.</li>
<li>The encrypted response received from the server is stored in the settings file of the application for future offline license verification.</li>
</ol>
<p>Since I now knew that a valid license string is stored in the settings file, all I have to do is generate my own in the right format with the right encryption.  At this point, I have two options.  Either I can run all the encryption once and generate a perfectly valid license for my computer, or I can create an application that will read the special file from part #1 above and generate a valid license.  I chose to go with option 2.</p>
<p>So I opened Visual Studio and went to work, coding in C# because it&#8217;s what I&#8217;m most familiar with from Visual Studio.  After a lot of coding, and a lot of debugging, I was able to create an application that writes the settings file with a valid serial number of 1234.  To be honest, I have no idea what a valid serial number for this application actually looks like, but that doesn&#8217;t matter &#8212; the program doesn&#8217;t care.  If the stored license works, it&#8217;s happy.</p>
<p>I&#8217;ve run this application on two computers now, with stunning results: it works!  A click of a button and a little waiting gives a valid license for this application.  Overall, I&#8217;m very happy with how this came out.  Normally, application cracks either patch an exe or generate a valid serial number, then disable online checking.  However, neither of these options seemed to work for me, so I came up with the next best thing: generate a valid license.  This was an intriguing look into a licensing method for a piece of software, and a great way for me to explore some code.  It&#8217;s unlikely that I&#8217;d ever be able to use this same methodology to crack another program, but I&#8217;m still glad I went through all the trouble to figure this out.</p>
]]></content:encoded>
			<wfw:commentRss>http://truejournals.com/2011/06/22/how-i-wrote-my-first-software-crack/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Why Did Wave Die so Quickly?</title>
		<link>http://truejournals.com/2010/02/15/why-did-wave-die-so-quickly/</link>
		<comments>http://truejournals.com/2010/02/15/why-did-wave-die-so-quickly/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 00:52:45 +0000</pubDate>
		<dc:creator>TrueJournals</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[thoughts]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://truejournals.com/?p=175</guid>
		<description><![CDATA[A while ago, I was super excited to finally get a Google Wave invite.  Today, I barely ever used the service.  I just open it every now and then to see if anything&#8217;s happened.  Generally, it hasn&#8217;t.  But&#8230; Google Wave had so much potential!  It was touted as a killer web application!  What happened?  Wave [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago, I was super excited to finally get a Google Wave invite.  Today, I barely ever used the service.  I just open it every now and then to see if anything&#8217;s happened.  Generally, it hasn&#8217;t.  But&#8230; Google Wave had so much potential!  It was touted as a killer web application!  What happened?  Wave had so much momentum, but it seems to have crashed, and gone into one of those experiments that Google toyed around with, but no one really cares about anymore.</p>
<p>First off, let me say that whether Wave succeeds or not makes little difference for Google.  Google is a company with enough resources to work on a major product, even if that product is a failure.  Google wanted Wave to replace e-mail.  This is where the whole &#8220;Federated Wave Servers&#8221; idea came from.  In order for Wave to be the new standard, companies had to be able to run their own Wave servers &#8212; Google couldn&#8217;t control it.  Besides that, Google already controls a good chunk of the e-mail market with GMail, so this was mostly a fun experiment for them.</p>
<p>But, still, it seems like something that should have succeed&#8230; or, at least, lasted a good amount of time.  But, Wave has quickly lost momentum and died in everyone&#8217;s mind.  The problem is that Google stopped innovating, and the Wave server never became very popular.  I don&#8217;t believe there have been any feature additions to Wave since it launched, and I&#8217;m not sure there&#8217;s any good source other than Google Wave to get a Wave account.</p>
<p>Wave died because Google seems to have abandoned it.  They released a product, and they appeared to have stopped working on it.  Wave is something Google needed to not only push to corporations, but also continue innovating, and releasing new features, and this never happened.  Google was unable to explain to potential customers why they <strong>need</strong> Wave, and this is where it failed.  I think this is slightly unfortunate, but I&#8217;m not very surprised.  While e-mail is antiquated, it still works, and it&#8217;s going to take <strong>a lot</strong> of push in order to move away from it.  Google didn&#8217;t seem to have any major corporations backing Wave, which also contributed to the failure.</p>
<p>Who knows&#8230; maybe we&#8217;ll see Google attempt to revive Wave with some new features.  Maybe it will come back for a couple months&#8230; But Google will have to work really hard to get the momentum and excitement about Wave going again.</p>
<p>I do, by the way, have 12 Wave invites.  I suppose you can comment here or contact me if you want one.  That&#8217;s a dangerous statement to say on the Internet.  Although Wave has died, I have a feeling there are people who never got in on the game, and are still looking for invites, only to find a product that no one uses.</p>
]]></content:encoded>
			<wfw:commentRss>http://truejournals.com/2010/02/15/why-did-wave-die-so-quickly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding n810 NJoy Programming</title>
		<link>http://truejournals.com/2009/06/14/understanding-n810-njoy-programming/</link>
		<comments>http://truejournals.com/2009/06/14/understanding-n810-njoy-programming/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 03:42:59 +0000</pubDate>
		<dc:creator>TrueJournals</dc:creator>
				<category><![CDATA[maemo]]></category>
		<category><![CDATA[mce.ini]]></category>
		<category><![CDATA[mcedit]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[talk.maemo.org]]></category>

		<guid isPermaLink="false">http://truejournals.com/?p=107</guid>
		<description><![CDATA[I think this would be a good place to archive my explanation of NJoy programming.  I was asked about how the patterns in mce.ini for the n810 work, with PatternError given as an example.  This was my reply: The different sections of the line are separated by semicolons. So, priority is the first part, then [...]]]></description>
			<content:encoded><![CDATA[<p>I think this would be a good place to archive <a href="http://talk.maemo.org/showpost.php?p=296703&amp;postcount=23">my explanation of NJoy programming</a>.  I was asked about how the patterns in mce.ini for the n810 work, with PatternError given as an example.  This was my reply:</p>
<p>The different sections of the line are separated by semicolons. So, priority is the first part, then a semicolon, then the &#8220;ScreenOn&#8221; value, then a semicolon, etc. So, I&#8217;ll use your example and point out each section of the programming.</p>
<p>0;1;0;40002000200040ff200020000000;0000;0000</p>
<p>To make this easier, I&#8217;m going to assign an index to each section of the command. I&#8217;ll split the string up by the semicolons. We&#8217;ll say the first character (a zero, in this case) has an index of 1. The second part of the split (a one), has an index of 2, etc, etc.</p>
<p><strong>0</strong>;1;0;40002000200040ff200020000000;0000;0000<br />
Index 1 defines the priority. If two patterns trigger at once, items with a higher priority (lower number for this section), take precedence, because only one pattern can be going at once. Since the priority is 1 (0 being the highest priority, 255 being the lowest), this pattern will display instead of almost any other pattern (the exception is patterns that have a priority of 0)</p>
<p>0;<strong>1</strong>;0;40002000200040ff200020000000;0000;0000<br />
Index 2 defines whether or not the pattern should fire based on what state the display is in. In this case, it&#8217;s a 1, which mce.ini tells us means &#8220;show pattern even when the display is on&#8221;. So, this pattern will display no matter what.</p>
<p>0;1;<strong>0</strong>;40002000200040ff200020000000;0000;0000<br />
Index three gives the timeout. This can tell the pattern to stop firing after a certain amount of time. In this case, it&#8217;s a zero, which means that the pattern will never stop firing (unless it&#8217;s told to).</p>
<p>0;1;0;<strong>40002000200040ff200020000000</strong>;0000;0000<br />
Index four starts the actual programming of the LED. Index four gives the programming of the RED LED. It also gets a bit more complicated here. We have to split this section up into strings of four characters each in order to understand the programming. This is what the pattern looks like, split into four-character strings, with each string separated by a pipe (|):<br />
4000|2000|2000|40ff|2000|2000|0000<br />
So, there are seven different commands given to the red LED.  Let&#8217;s take a look at them one by one:</p>
<ol style="list-style-type: decimal;">
<li><strong>4000</strong> &#8212; This sets the brightness of the LED (anything starting with a 40 will change the brightness). I believe this tells the LED to turn off (0 brightness). I believe that ff would be 100% brightness.</li>
<li><strong>2000</strong> &#8212; This bumps the brightness up over a certain amount of time. This gets REALLY confusing. The first two characters, 20, tell how long it should take to change the brightness. 20 is in the 01 &#8211; 3f range, so we get &#8220;short&#8221; steps. If I understand this, we get 19 &#8220;short&#8221; steps of time ~0.49ms, so this should take about 9.31 milliseconds. The next two characters, 00, defines how many steps in brightness the LED should take. 00 is no change, so the pattern will pause for about 9.31 milliseconds.</li>
<li><strong>2000</strong> &#8212; Because this is the same command as above, this will also create a 9.31 millisecond pause.</li>
<li><strong>40ff</strong> &#8212; Again we see a 40. This says to change the channel brightness. This time, we&#8217;re changing it to ff, which should be 100% brightness. So, this command turns the LED on.</li>
<li><strong>2000</strong> &#8212; This creates another 9.31 ms pause.</li>
<li><strong>2000</strong> &#8212; This creates another 9.31 ms pause.</li>
<li><strong>0000</strong> &#8212; This tells the pattern to loop (&#8220;jump to the start of the pattern&#8221;).</li>
</ol>
<p>So, the red LED will turn off, pause for (2*9.31 ms =) 18.62 milliseconds, turn on, pause for another 18.62 milliseconds, then loop.</p>
<p>0;1;0;40002000200040ff200020000000;<strong>0000</strong>;0000<br />
Index five gives the pattern for the GREEN LED. This is a very exciting pattern. It simply tells the pattern to repeat again and again and again. So&#8230; nothing happens with the green LED.</p>
<p>0;1;0;40002000200040ff200020000000;0000;<strong>0000</strong><br />
Index six gives the pattern for the BLUE LED.  Again, very exciting.  The blue LED does&#8230; nothing.</p>
<p>I hope this helps you understand how the programming works.</p>
]]></content:encoded>
			<wfw:commentRss>http://truejournals.com/2009/06/14/understanding-n810-njoy-programming/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Danger of &#8220;Incorrect Password&#8221;</title>
		<link>http://truejournals.com/2009/05/11/the-danger-of-incorrect-password/</link>
		<comments>http://truejournals.com/2009/05/11/the-danger-of-incorrect-password/#comments</comments>
		<pubDate>Tue, 12 May 2009 03:21:39 +0000</pubDate>
		<dc:creator>TrueJournals</dc:creator>
				<category><![CDATA[thoughts]]></category>
		<category><![CDATA[website]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://truejournals.com/?p=77</guid>
		<description><![CDATA[I&#8217;m sure you&#8217;ve seen the message before.  You try to log into a website you go to every now and then, and forget which password you used for it, or type something in wrong.  &#8221;Sorry, this password is incorrect,&#8221; says the website.  You grumble to yourself and try again, paying little attention to the harmless [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure you&#8217;ve seen the message before.  You try to log into a website you go to every now and then, and forget which password you used for it, or type something in wrong.  &#8221;Sorry, this password is incorrect,&#8221; says the website.  You grumble to yourself and try again, paying little attention to the harmless message.  From a programmer&#8217;s perspective, it&#8217;s a bit more interesting than that.</p>
<p>With a SQL database backend, it&#8217;s quite easy to figure out a login problem.  It&#8217;s a simple matter of searching the databse for a username that is equal to the one the user entered.  If the password of that row matches the password the user entered (generally md5 encoded), then the user can login.  If it doesn&#8217;t, they get the &#8220;incorrect password&#8221; message, and if the username search returns zero rows, they get an &#8220;incorrect username&#8221; message.  Simple and secure, right?</p>
<p>Wrong.  The problem with telling the user that the password was the incorrect data entered is that it lets them know that the username is correct.  For someone legitimately logging into the website, this is great.  They know exactly what to fix, they fix it and move on.  For someone who doesn&#8217;t actually own the account, however, this message is a lot more interesting.</p>
<p>Potentially, a script could be written to try thousands, even millions of usernames all with the same password.  Once an &#8220;incorrect password&#8221; message is reached, the script can then try another list of thousands to millions of passwords, until it gets an account.  All automated, and very simple.</p>
<p>So, the solution is to not let the user know what&#8217;s wrong.  Just say &#8220;incorrect login details.&#8221;  Something is wrong, but we&#8217;re not gonna tell you what.  Good luck!  This will stop any username-guessing script.  Now, you can&#8217;t tell a valid username from an invalid username.  However, some websites like to have lists of their members, or the hacker may already know a username for some reason.  So, how do we combat this?</p>
<p>Login try limits.  After 5 failed attempts, lock out the IP address in question.  Any user who just typed something wrong should be able to get it right within five tries, and blocking the IP will stop from additional attacks.  However, some robots are more complex than this.</p>
<p>When it comes down to it, if someone <strong>really</strong> wants to get into your website, they will.  A botnet will millions of different IP addresses could foil the above scheme.  Additionally, proxies could get around this block.  It would seem that there is no way to keep a website secure.</p>
<p>The responsibility falls on the user, really.  Most websites say somewhere that if someone breaks into your account, they aren&#8217;t responsible.  Website admins should have really long annoying to type passwords, because they can easily save the password somewhere, and normal users should have passwords that are strong enough.  If you&#8217;re really worried that someone will break into your account, choose a better, longer password.</p>
<p>Or, do we need to go above and beyond passwords?  Is there a level of security past passwords that we have yet to reach.  A lot of computers now have fingerprint readers.  Could we have websites that require your fingerprint as your password?  How about an image?  A website could issue you a completely random image for your password.  You save this image, and have to upload it any time you want to login.  The image would have to be small enough to let dial up users be able to upload the image, but it could be big enough to be very, very random.</p>
<p>So, security isn&#8217;t perfect.  I doubt it ever will be.  If someone really, really wants to break into something, they will.  This is why we have jails.</p>
]]></content:encoded>
			<wfw:commentRss>http://truejournals.com/2009/05/11/the-danger-of-incorrect-password/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Programming Brainstorm</title>
		<link>http://truejournals.com/2009/04/23/programming-brainstorm/</link>
		<comments>http://truejournals.com/2009/04/23/programming-brainstorm/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 14:28:23 +0000</pubDate>
		<dc:creator>TrueJournals</dc:creator>
				<category><![CDATA[life]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[thoughts]]></category>
		<category><![CDATA[brainstorm]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tearbookmarks]]></category>

		<guid isPermaLink="false">http://truejournals.com/?p=55</guid>
		<description><![CDATA[Every now and then when working on a program, I like to have a brainstorming session.  Usually I&#8217;m just lying comfortably in my bed, thinking of how I can expand a program more, remove bugs, or make it quicker or more stable.  Last night, I had a brainstorming session for tear bookmarks, and I thought [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then when working on a program, I like to have a brainstorming session.  Usually I&#8217;m just lying comfortably in my bed, thinking of how I can expand a program more, remove bugs, or make it quicker or more stable.  Last night, I had a brainstorming session for tear bookmarks, and I thought I&#8217;d share my notes with everyone who reads this.</p>
<p>My brainstorming session basically consists of my tablet running xournal.  I get nice lined notebook paper, where I can write down any ideas that pop into my head.  I can then look at that later and go &#8220;No&#8230; that won&#8217;t work&#8221; or &#8220;Hmm&#8230; I might be on to something,&#8221; and try to implement it.</p>
<p>So, if you&#8217;d like to see what I&#8217;ve been thinking about for tear bookmarks, look at the following PDF: <a href="http://truejournals.com/wp-content/uploads/2009/04/2009-04-22-tearbookmarksbrainstorm.pdf">2009-04-22-tearbookmarksbrainstorm</a>.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://truejournals.com/2009/04/23/programming-brainstorm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

