hacking

You are currently browsing the archive for the hacking category.

DSx86

Every now and then I come across something that I can’t believe someone has taken the time to write.

In this case, it’s a DOS emulator for the Nintendo DS, the DSx86.

As if there weren’t enough options for extending the DS (homebrew, NES emulation), one man has taken it upon himself to write a DOS emulator for the DS. It will run most games that run on a 286/386, with some caveats. Not all the opcodes have been written in yet, and sound blaster support requires a little bit of finesse. But it’s under active development, which is exciting.

You load a game the same way you did back in the day… from the command line. Since the DS doesn’t have a keyboard, DSx86 includes one for you on the touch screen. It’s hilariously adorable.

Once the game is loaded you can either continue to use the “keyboard” or swap screens so that your game is shown in the touchscreen and you can use the stylus as a mouse. Holding down left/right on the d-pad to click took a bit of getting used to. There’s also a tap-to-click mode, but I found it difficult to use for gaming. It was a good illustration of how programs not designed for a touchscreen can be infuriating to use on one. Because most DOS games run at a slightly larger resolution than the DS, you have the option of either panning or resizing the screen. I found panning to be the most useful, and all it really cut off was the title/menu bar at the top.

Seeing the old Sierra logo along with the MIDI-tastic intro music on the DS was ridiculous and awesome. I’m just about finished my 20th or so lifetime play through of The Island of Dr. Brain. If you’re dying to take some of your old DOS games with you (you did save them all, right?) , check the compatibility list and give DSx86 a try.

Now I know how all my doctor friends feel watching medical dramas. I don’t know which is better, the completely incomprehensible analogy used for IRC channels, or the notion that anyone over the age of 12 uses leetspeak. Either way, I can’t wait to get back to decoding backdoors. Like you do.

I had to double check to make sure it wasn’t Sandra Bullock.

Want to learn to create 3D models, but find the user interface for most 3D modeling programs too infuriating? OpenSCAD may be for you! And we're teaching a class on how to use it on Sunday, June 27!

OpenSCAD is "The Programmers Solid 3D CAD Modeler." Rather than learn tricky user interfaces and navigate seemingly endless obscure menus, OpenSCAD uses a simple scripting language to generate 3D models from either existing or new 2D drawings. We'll start in 2D (great for creating designs for the laser cutter) and move into 3D modeling (perfect for MakerBot!).

A basic understanding of computer programming is helpful but not required. Sign up at EventBrite today!

Mushroom Thingy

I've been doing more Lego building from models. This time I made sort of an abstract mushroom tree forest thing. More photos are available on Flickr.

Here's the original model (left) and the resulting cubeified model after running it through AddCells (right):

I realized of course that with everything grey, it was very difficult to determine which bricks of which color were needed where. So I un-joined the primitives in the original model and ran AddCells on each one individually. I used different colored "cell" blocks for each one, and the resulting models kept the color:

Each peice needed to be moved a little bit so that all the blocks lined up, but other than that it worked pretty well.

Because each piece is separate, I couldn't use the hide tool to "slice" each layer. But I did find out something interesting: each "cube" in the new models is actually a vertex. I honestly don't understand a ton about how that's pulled off, but basically instead of being a point on a line, each vertex represents another object, the source cube.

In order to slice up the model, I wrote a script to delete all but a given layer, with layer 1 being the bottom layer, up to however many layers of cubes are in the model.

 

import Blender, BPyMessages, BPyMesh
from Blender import Scene, Mesh, NMesh, Window, sys, Group, Object, Draw
from Blender.Mathutils import \
	Matrix, Vector, ProjectVecs, AngleBetweenVecs, TranslationMatrix
 
 
def trimToLayer(selected,layerNumber, blockHeight,offset):
        toDelete= []
 
        mesh = selected.getData(mesh=1)
        tmesh = NMesh.GetRawFromObject(selected.name)
        tmesh.transform(selected.matrix)
        #Delete verticies above the current layer
        for v in tmesh.verts:
            if v.co[2] > blockHeight*layer:
                toDelete.append(v.index)
        if layerNumber > 1:
                #Delete verticies below the current layer
                for v in tmesh.verts:
                    if v.co[2] < blockHeight*layer-1:
                        toDelete.append(v.index)        
        toDelete = list(set(toDelete))
 
        mesh.verts.delete(toDelete)
        Window.Redraw()
 
 
##################3
if __name__ == "__main__":
    selection = Object.GetSelected();
 
    layer = Draw.PupIntInput("Layer",1,0,100)
    Blender.SaveUndoState('Kill Everything')  
    print "\nTrimming First Layer"
    for s in selection:
	bbox = s.getBoundBox(1)
	print bbox[0][2]
	trimToLayer(s,layer,1.2,bbox[0][2])

 

There are a couple problems with the script: primarily, I couldn't find a way to get the software to save a screenshot (ctrl+F3 normally). Because of this, I couldn't loop through the whole thing at once, I had to go through one layer at a time, running the script, hitting ctrl+f3, saving the image, lather rinse repeat. It was tedious, though not as tedious as manually cutting up each layer. But almost.

The resulting MRI-like were used to build the model. The exact placement of which bricks and where is left as an excercise to the reader. A few layers (from the bottom, middle, and towards the top) are shown below.

This is my first attempt at a Blender script, and admittedly one of my first times using blender, so any feedback on how to streamline this process would be appreciated.

It was only after hours of searching that I finally came up with what I was looking for: a way to take a polygon mesh (OBJ or similar) and convert it into a blueprint for building LEGO sculptures.

Don't get me wrong, there are tons of tools out there for LEGO CAD. But strangely none of them mention being able to go from a mesh to a LEGO layout. It's surprising, since it seems like such a natural fit. The rise of 3D printers has rejuvinated interest in voxels, voulmetric pixels, and as evidenced by all the LEGO sculpture artists we seem to be in a golden age of LEGO. 

Armed with Blender and a giant LEGO collection, I set out to get the computer to do the hard work for me. I used Blender, graph paper, a pencil, and of course lots of LEGOs.

Step 1: Voxelizing a Utah teapot

Let me preface this by saying that the Blender UI is not for the faint of heart. I took classes on Rhino and 3DSMax in college, and thought to myself "how different could it be?" The answer: very. If you're new to blender, don't fear the manual. You're going to need it, particularly the parts on installing/using python scripts.

To voxelize the teapot I used a script called Add Cells which covers the surface of any object with any other object. First I imported the teapot, and scaled it up a bit. Then I created my "fundamental unit" of LEGO. LEGOs have an aspect ratio of 6:5, so I created a 1×1 LEGO, a 0.6×0.5×0.5 rectangular prism in Blender.

Selecting both the teapot and my 1×1 lego I ran the Add Cells script (go to the Scripts menu –> Add -> Cells). I chose the Teapot for my object to be voxelized and the 1×1 LEGO as my voxel model.

Tada! A blocky teapot!

Step 2: Graphing each layer on paper

In order to make the build process easier, I went through layer by layer and drew a map of each layer on graph paper. This way when building with LEGOs I could shade in with a pencil each voxel I'd built. It sounds redundant, but when things all start looking the same after a few minutes and something isn't lining up, it's very helpful.

To see one layer at a time in Blender I went into Sculpture Mode, side view, and used ctrl+shift+right mouse to select and hide all but the layer I wanted to see. Then I switched to Top view and copied the layer onto my graph paper. By the end I had a sheet of paper full of wobbly circular outlines.

Step 3: Building it with LEGOs!

The completed model uses 244 LEGOs, many of which are tiny 1×1 and 1×2 bricks. The model is hollow, but the walls need to be fairly thick to be able to support the top. As it is I probably should have made things a little thicker; putting the last two layers on was a delicate operation.

I built each layer sequentially. There were a few overhang pieces near the bottom which I had to append to the layer above them, since they couldn't anchor to anything below.

Overall the project took about 4 hours, with a break in the middle for breakfast, church, etc.

Total LEGO count for the project was 244 individual bricks, distributed thusly:

  • 44 2×3 Bricks
  • 46 2×2 Bricks
  • 58 2×4 Bricks
  • 27 1×2 Bricks
  • 17 1×3 Bricks
  • 8 1×4 Bricks
  • 8 2×2 L shaped Bricks
  • 33 1×1 Bricks
  • 1 2×8 Brick
  • 1 2×6 Brick
  • 1 1×8 Brick
     

Success!

Now that I have a few more runs worth of data, I was able to pick a little bit of information out of the miCoach binaries.

There are 40 EXRCS001.BIN files on the device (after the data has been unpacked), each one corresponding to an individual workout. This means you can store up to 40 workouts before you need to sync the device again. Knowing that, I had a bit of a better idea what I was looking at.

The miCoach pacer records various data points periodically – every few seconds as far as I can tell. The record length for these data points is 14 bytes. So far we have:
0x1E – row number, increments one each row
0×21 – distance
0×23 & 0×24 – Not sure exactly what the values are, but these dropped to 0 at a point where I paused the pacer and the miCoach graph shows a stride/pace of 0
0×25 – stride rate
0×26 – same situation as 0×23 and 0×24
0×27 – heart rate
0×28 – Not sure what this is, but it’s the same for each row
0×29 – time in. I think this is in seconds, but I’m not sure. It goes up by 5 each record.

At the start of the file, from 0×07 to 0×10, is a bunch of data that I suspect to be the date but haven’t figured out an obvious format. For my workout on 5/20/2010 9:58am, the hex values are 01 5A 4F B4 3C A7 53 B4 3C 24 8C

Yay progress!

In preparation to tinker with the miCoach data, I started with some better-travelled exercise bits: WiiFit body test data. Starting with Jansen Price’s excellent blog post on the subject, I slowly worked through the data and wrote a python script to interpret the binaries and save them to a CSV. By using the excellent flot javascript library, I was able to generate the nice graph above. There was a lot of trial and error, but here’s an overview of the process:

  1. Copy Wii save game data to the SD card. This is done from Wii Options > Data Management > Save Data > Wii
  2. Find the save game data on the card. It’s in something like ‘private/wii/title/RFPE’, although different regions may have slightly different codes. RFPE is the code for WiiFit Plus. Copy the WiiFit data.bin file from the SD card to your local machine.
  3. Decrypt data.bin. This is explained pretty well here. To create the keys I ended up creating text files with the hex string for each and then using “xxd -r -p sd_iv_hex sd_iv” et al to save a binary version. If you’re getting “MD5 mismatch” errors, you probably saved the keys incorrectly. If you aren’t sure, check the file size. They should be 16 bytes each.
  4. Run the decrypted RPHealth.dat through a parser (I wrote one in Python for this)
  5. Run the CSV through your favorite graph generation library. I use flot because Google Charts don’t handle dates very well.

Thanks to Jansen’s handy chart of which bits are where, writing the parser was pretty easy. This isn’t the most elegant code I’ve ever written, but it gets the job done:

import struct
import string
import csv
 
 
mii = 0
#we know that each record is 0x9271 bytes long
record_length = 0x9281
 
record_start = 0
 
#path to WiiFit data file
infile = 'RPHealth.dat'
 
FH = open(infile, 'rb');
 
 
## It loops through 7 profiles, because I happen to know I have 7.
## A better approach would be to go to the end of the file, of course.
while (mii < 7):
 
    #go to the start of the current record
    FH.seek(record_start)
 
    #read the first 30 bytes (header + name)
    line = FH.read(30)
 
    #for some reason names are stored as N a m e instead of Name.
    #Throw away the header any extranous spaces
    data = struct.unpack("<9xcxcxcxcxcxcxcxcxcxcxc",line)
 
    #Condense our unpacked characters into a string
    wf_name = string.join(data,'')
 
    #open a new CSV file for this person.
    #If the name is shorter than 4 characters or has whitespace, the script
    #will exit. This should probably be fixed.
    FW = open('WiiFit_'+wf_name[0:4]+'.csv', 'w')
    recordWriter = csv.writer(FW, delimiter=",", quotechar="'", quoting=csv.QUOTE_MINIMAL)
 
    #Weigh-in data starts 0x38a1 bytes into the record
    FH.seek(record_start + 0x38a1)
 
    #we'll loop through the record data until it starts coming up blank
    while(1):
        #4 byte date 
        line = FH.read(4)
        data = struct.unpack(">i",line)
        #bit shift to get the month, day, and year. Could also get time if you wanted.
        year = data[0] >> 20 & 0x7ff
        month = data[0] >> 16 & 0xf
        day = data[0] >> 11 & 0x1f
 
        #break the loop if the date comes back 0
        if(year == 0): break
 
        #format the date into something humans like to read
        date = str(int(year)) + '-' + str(int(month)+1) + '-' + str(int(day))
 
        #the next three sets of 2 byte data represent weight, BMI, and balance
        line = FH.read(17)
        data = struct.unpack(">3H",line[0:6])
 
        recordWriter.writerow([date] + [data[0]] + [data[1]] + [data[2]])
 
 
    #now that we're done with the record, advance to the start of the next one
    record_start = record_start + record_length
 
    mii = mii+1

You can download a copy of it here.

I have to give Adidas credit where credit is due. They’ve managed to tie a $140 upsell to a pair of shoes I bought for $55.

It’s no secret that I, like many nerds, suffer from gadget lust. When I see a new gadget, my thought process goes something like: “Oh that’s so neat… but it’s kind of expensive, and I could build something way better for less money… but I’m never going to actually get around to doing that so I’ll just buy it.”

So when I noticed a sticker that said “miCoach compatible” on the new pair of running shoes I got from the clearance rack at DSW, I was intrigued. “Compatible” is almost certainly a hardware term. Was miCoach some sort of Adidas version of the Nike+? Did this mean that my shoe had a secret cavity for storing circuit boards? And would that cavity also fit the Nike+ so I could log my workout data automatically?

The answers to all of the above was yes. Hooray!

I did some research on the miCoach. It’s similar to the Nike+ (widget you put in your shoe to track your workout) but is more of a comprehensive package (includes a heart rate monitor and pacing tool which tells you to slow down / speed up according to your HR). It’s also about $100 more expensive than the Nike+. The shoe sensor has a user replaceable battery, but still.

Then I did some research on the data export. Because what fun is collecting data if you can only get it via someone else’s bad UI? Nike+ hacking is well traversed ground, with easy access to the XML workout data. miCoach doesn’t seem to have much going on, and uses a proprietary binary format to store the workout data (which is then presumably decoded by their servers). Gross.

I was all set to buy a Nike+ when I found out that my 5th generation iPod was not compatible with it. In order to use the Nike+ I’d have to pick up a new Nano. The price of the Nike+ just got a lot more expensive.

After talking to some of the Resistor folks I decided tinkering with the miCoach could be fun. Between the raw data from the device and whatever software is used to transmit it to the the miCoach servers we should be able to get *something* interesting. It’s admittedly pretty far out of the realm of things I’ve done before, so it’ll either be a good learning experience or a huge road block / dead end.

We’ll see when it gets here next week!

During the last 12 hours of the hackathon I decided to write a TCP server for an old project I want to finally finish. I decided to write it in Python, mostly because my friend Adam likes Python and Adam would inevitably be the one answering my questions when I got stuck. I should mention that prior to yesterday evening I knew nothing about socket programing. And I only had a vague idea of what threading was.

Since not everyone has friends like Adam, I’m writing up my findings in a tutorial.

Note: A bug in my CSS is causing the code blocks to show up extra wide. I’ll fix it once I’m back home from the hackathon

Understanding Sockets

First, I’m going to assume you understand that this is not a tutorial about writing an HTTP server. Instead this server will take connections from clients and keep them open to pass data back and forth until one side decides to close the connection. By keeping the connection open we eliminate the need to constantly poll the server for updates.

Socket Programming HOWTO provides a broad overview of sockets and is a good starting place.

Python’s Socket Library

Luckily python has an easy to use library. Like other libraries, we import it with thusly:

from socket import *

Many of the socket methods you’ll use are pretty self explanatory:
socket.listen() – listens for incoming connections
socket.accept() – accepts an incoming connection
socket.recv() – returns incoming data as a string
socket.send() – sends data to client socket*
socket.close() – closes the socket

*in this context the ‘client socket’ can be on either the server or client side. When a client connects to a server, the server creates a new client socket on its end. The two clients, one on each end, communicate with each other while the server socket remains open for incoming connections. This becomes more clear as you work with socket connections.

Writing the server
First thing’s first, we need to establish our server socket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
##server.py
from socket import *      #import the socket library
 
##let's set up some constants
HOST = ''    #we are the host
PORT = 29876    #arbitrary port not currently in use
ADDR = (HOST,PORT)    #we need a tuple for the address
BUFSIZE = 4096    #reasonably sized buffer for data
 
## now we create a new socket object (serv)
## see the python docs for more information on the socket types/flags
serv = socket( AF_INET,SOCK_STREAM)    
 
##bind our socket to the address
serv.bind((ADDR))    #the double parens are to create a tuple with one element
serv.listen(5)    #5 is the maximum number of queued connections we'll allow

So now we have a server that’s listening for a connection. Or at least we did until the script reached the end and terminated, but we’ll get to that in a bit. Let’s leave our server hanging and jump to our client software.

Creating the client
Start a new python script for the client. We’ll need many of the same constants from the server, but our host will be ‘localhost’. For now we’ll be running both the server and the client on the same machine.

1
2
3
4
5
6
7
8
9
10
##client.py
from socket import *
 
HOST = 'localhost'
PORT = 29876    #our port from before
ADDR = (HOST,PORT)
BUFSIZE = 4096
 
cli = socket( AF_INET,SOCK_STREAM)
cli.connect((ADDR))

Notice that we’re creating another socket object on this end but instead of binding and listening, we’re using the connect() method to connect to our server.

So what happens if we run our server and then run our client? Well, not much. While our server starts to listen, it then hits the end of the script. We need it to instead wait until it accepts a connection and then do something with that connection.
socket.accept() does just that, and returns two things: a new client socket and the address bound to the socket on the other end. Once we have that, we can send data!

Continuing on server.py:

12
13
14
15
16
17
18
19
20
21
22
23
serv = socket( AF_INET,SOCK_STREAM)    
 
##bind our socket to the address
serv.bind((ADDR))    #the double parens are to create a tuple with one element
serv.listen(5)    #5 is the maximum number of queued connections we'll allow
print 'listening...'
 
conn,addr = serv.accept() #accept the connection
print '...connected!'
conn.send('TEST')
 
conn.close()

The last step is to jump back over to our client and tell our client to expect to receive data:

9
10
11
12
13
14
15
cli = socket( AF_INET,SOCK_STREAM)
cli.connect((ADDR))
 
data = cli.recv(BUFSIZE)
print data
 
cli.close()

Now when you run your server it will wait until a client connects. Once you run your client it will connect and receive a short message (the word “TEST” in this case) and print it to the screen. If you wanted to you could have the client send a response, using the same send() and recv() methods (but reversed).

Make sure you close() your connections when you’re done using them. If you don’t close things nicely they have a nasty habit of staying bound/connected until you forcibly kill the python process. This can be a real pain when you’re debugging.

By itself this isn’t particularly useful, especially considering we can only handle one connection at a time and exit once it’s closed. By adding a few while loops and some threading we can make this into something much more valuable. As it is, I’m pretty wiped from the hackathon, so the threading tutorial will have to wait until another day.

Exploding Capacitors

When I went to boot up an old computer which had sat dormant since I moved in April, nothing happened. No lights, no whirring, nothing. I assumed it was a bad power supply, and left it for another day. Over the weekend my boyfriend got sick of seeing it out, guts exposed to the world, and threw a new power supply in it. Still no life. Then he pulled out everything but the motherboard, and it booted! Or at least, as much as a computer with just a motherboard can.

As he added each component in one by one, the culprit became clear without even having to power up the machine:

exploded capacitors

Not seeing it? Here, let me get a little closer:

This is, or was, my video card. A reasonably nice (at the time) 7600 GT. The most remarkable thing is that this is not the first time I've seen this happen to this particular card. In fact, it's the third. Two other friends of mine have had theirs blow capacitors as well. And a google search for "exploding capacitors 7600" brings up tons of results.

Goodbye, video card. We have these in a number of the computers in the house, including my main machine. I wonder how long it will be until the next one goes.

« Older entries