Hacking devices can/will void your warranty and can turn your expensive consumer electronics into worthless trash if you don't know what you're doing. This blog is for information purposes only, and if you try to hack into your own consumer electronics, you do so at your own risk. The device I'm currently hacking is the Canon SX10 IS camera.

Monday, October 25, 2010

Canon SX10IS fix

My powershot SX10IS was doing something very weird. With the flip out screen in normal position facing the photographer, the LCD was off. If I moved it out just slightly, the LCD would come on, but the picture was upside down.

It actually worked ok if I flipped out the LCD, but it was annoying. So I tore it apart to fix it and decided to document it since I found nobody else having run into this issue.

Step 1, remove the two visible screws that show up when you flip out the screen. Once you've removed those, the black shield can be removed.

It snaps in and out so a little force was needed to slide it out. It slides away from the LCD.

Flip the LCD back to normal position. This is where you'll see the microswitch. In my case, there was a broken wire.

Resoldered the two broken wire pieces together and that took care of it. To test it, I had to make sure the microswitch was firmly in the correct position.

yeah, I know, bad solder job. The wires were super small, very thin. I had to strip back some of the insulation. Anyway, my point here isn't to demonstrate my superior soldering and electrical engineering capabilities, but to show others how to get to that part of the camera and fix it yourself if it is malfunctioning the same way.

The more exciting stuff comes from the safe software hacking. Since the canon can "boot up" from a properly formatted SD card, you don't have to do any kind of bios flashing, which makes the chdk hack one of the safest I've seen.

Tried out the "fast MD 080914" script to see if I could get some lightning from a storm. Now, I'm familiar with the long exposure time technique to capture lightning. I don't like it. Not only is the picture noisy, but any other lights in the area get over exposed and quite often the picture, taken at night, looks like a daytime picture.

But not with this script.

I could actually hold the camera, with ISO set at 80, late at night and catch some very crisp, clean lightning strikes.

That was a 1 second exposure. All I had to do was hold the camera while it watched for the lightning and snapped the picture on its own. Very nice hack. There's others stuff, like being able to see the exact battery % and watch as it drops while the flash is being powered up, and then goes back up. It reveals why the camera thinks it is low on battery and yet seems to go fine for a long time after. And the temperature sensors - I didn't even know there that many sensors for detecting temperature in the different parts of the camera.

Anyway, if you have a canon, consider looking into that hack. I'm glad I did.

Sunday, September 5, 2010

Canon SX10 IS initial hacking

This camera was actually very easy to hack. Indeed, most Canon cameras are. And the greatest thing about it is that it is almost perfectly safe. You don't flash anything into the firmware. Instead, you program an SD card to be bootable and to have the specific boot files you need on it.

All of that is available at CHDK. It is a site set up to specifically hack Canon cameras. The firmwares are adapted for new cameras all of the time, and the wiki page is pretty clear on how to do it.

I am no photo expert, but the hacks have helped add some fun to the camera. Ok, it's somewhat fun to play games on the camera while you're waiting for your kid's school play to start. But there are a few things that I have really enjoyed.

First, my SD card lost it's little plastic tab that determines whether it is read only or writable. So now the card is read only to every device, except my canon. In the read only mode, the canon hack is enabled and can write to the card. So i haven't lost the card's usefulness.

Second, the motion detection scripts. I set up the camera when a recent electrical storm passed through and caught pictures of lightning, all without having to do a 30 second exposure. in fact, the pictures are crisp, clean with no ISO noise and all taken while I was holding the camera. I had taken pictures of lightning before by doing long term exposures, but these pictures were so much better and I didn't have to use a tripod.

Time lapse, being able to see the temperature of the lens, and the exact battery power % available at all times, those are really great functions.

I did run into one hardware problem with this camera. The LCD screen had a little switch in it that allows it to detect when you've flipped the screen over. As a result, when I close flip LCD with it facing me, it thinks it is facing the camera and shuts off the LCD. In order to use the LCD, I have to swing it open and, since it can't detect which direction, I end up not being able to flip the screen so the person I'm taking a picture of can see themselves. It's annoying, but something I can actually live with.

Nonetheless, I took apart part of the camera and found that the cause was this really, really small wire that had broken. So I reattached it and the camera was working again.

Note the use the of the word "was". It's happened again, so I'm going to need to take it apart again. This time I'll take pictures with my other digital camera so I can document how to fix it.

Thursday, August 19, 2010

Why no progress?

Yes, I'm still alive but of little or no use at this point.

The sourceforge project was been taken down due to a DMCA order from two parties. After scrubbing the project of all files considered copyrighted, there isn't enough there to continue investigation. I could get the opensphd part hosted again (although one of the parties has not reviewed the code and accepted that it is open source) but it requires taking upon myself the liability and costs for any challenge issued after reinstating that code. I don't have bottomless pockets and can't take that liability upon myself.

There is another project called ketlaer that has taken a different approach and is adaptable to 1283/1073 devices. They tap into the Asus library, which is publicly available from Asus to work with those devices. MyMediaSystem has been ported and known to work on several compatible devices. Unfortunately, does not work with the 1262/1282 nor could I see any way to adapt it such that it would without adding code that would be considered in violation of the DMCA.

It is not the end of my blog, but looks like the end of my screenplay hacking for now.

Wednesday, April 14, 2010

MIPS disassembler / reverse engineering tool

I know I haven't posted for a long time, but I have been busy hacking.

I needed a decompiler with source code that I could modify to try to build something similar to what an acquaintance of mine once built, the MIPSX Sourcer. When I was into hacking a certain DVD player, I learned MIPSX which isn't too far different than MIPS but different enough to make the tools incompatible. Doing a disassembler is easy. In fact, objdump comes on the ScreenPlay Pro itself, so just objdump the DvdPlayer and presto, a gazillion lines of MIPS code with no chance of understanding it and not knowing where to start. I needed something that would take any new information I gave it and apply it across the whole file to give me more information back, and I had to start from scratch.

First, I needed an understanding of the binary format of the executable file.

I put together a basic program to open and do a raw dump of each section defined in that ELF_Format.

Once I had that, it was a small matter to make the disassembler, made even easier by the Reverse Engineering Compiler:
In fact REC looked very similar to what I wanted...but it was not able to handle the Iomega firmware and testing with other MIPS code I found it was difficult to get the information together that I wanted. However, the author published a small piece of his code:

This was a nice jewel. It had some stuff wrong but it was a nice start anyway. So I plugged in the functions into the code I wrote and send each instruction from the ELF segments that were listed as executable and poof, instant MIPS code. It didn't match exactly with what I was getting out of objdump, so I did some investigating.

You have to register (free) to get the documents, but this is the most accurate documentation on the language, of course. Not always the easiest to digest for a beginner, so here was a good primer I came across:


I didn't like the way dismips.c was representing a lot of the information, and some of it was just wrong. So I modified it to resemble the objdump disassembly a little closer. Then I have it analyze the code from top down. It assumes that any 0x3c1cXXXX followed by a 0x279cXXXX (where XXXX is any hexadecimal digit) is the beginning of a new function...and so far I haven't found any exceptions to the rule. Those two values equate to: LUI $gp,0xXXXX and ADDIU $gp,$gp,0xXXXX. These almost always followed a JR $RA instruction (with one instruction after that).

Those familiar with assembly but not familiar with MIPS need to understand that MIPS processors use a pipeline for processing the instructions and depending upon the pipeline, you can have multiple instructions in the pipe being processed at different stages. JR $RA (Jump to address specified by Register RA) changes the current execution address. But JR doesn't get the address loaded into the current instruction pointer (IP) before the next instruction is loaded into the pipeline. So the next instruction will also be executed even though it occurs AFTER the JR.

so you may see something like:

jr $ra
addiu $sp,$sp,0x20

lui $gp,0xfcc
addiu $gp,$gp,0xffffb9a4
addu $gp,$gp,$t9

the actual start of the function is on the LUI and the end of the other function will include adding 32 (hex value 0x20) into the $SP (stack pointer) register.

Ok, I'm getting sidetracked. The links up above contain better information about how MIPS works, but I wanted to explain that part so I could explain how the analysis engine works.

Now, I figured out that register $t9 always contains the address of the function being started. Whenever the code was calling a function it would do a JALR $ra,$t9 (objdump leaves off $ra since it is assumed, but I like having it there). What that does is jumps to register $t9 and stores the current IP in $ra (so that JA can then return to the next line after the JALR + one more line due to pipelining). So I make the assumption that $t9 will always contain the address of the beginning of the function at the beginning.

$a0 - $a3 are registers that are typically used for passing parameters. More can be passed by placing them onto the stack, but most times I only need to know what the first 4 parameters to any given function are anyway. Knowing this means a block of code like this:

lw $a0,0xffff802c($gp)
addiu $a0,$a0,0xffff9460
lw $t9,0x2cd8($gp)
jalr $ra,$t9

is a call to a function with one parameter. But objdump shows this and trying to make sense of it isn't all that helpful.

So I have the program analyze the registers as it decompiles them. If it knows the value, it prints it next to the instruction. LW $a0,0xffff802c($gp) means to take the value of the register $gp and add 0xffff802c and go to that address and fetch the word (LoadWord) at that address. Well, these addresses are all in the .GOT segment in the ELF file (Global Offsets Table) so I have it peek in there to get the address. I also added the opcode and address.

004002e0: 3c1c0fcc lui $gp,0xfcc; gp=0x0fcc0000
004002e4: 279cb920 addiu $gp,$gp,0xffffb920; gp=0xfcbb920
004002e8: 0399e021 addu $gp,$gp,$t9; gp=0x100bbc00
0040034c: 8f84802c lw $a0,0xffff802c($gp); a0=0x00af0000
00400350: 00000000 nop
00400354: 24849460 addiu $a0,$a0,0xffff9460; a0=00ae9460
00400358: 8f992cd8 lw $t9,0x2cd8($gp); t9=0x00ad2310
0040035c: 00000000 nop
00400360: 0320f809 jalr $ra,$t9
00400364: 00000000 nop

(the first hex number is the address where the instruction will be loaded, the second hex number is the instruction that is decoded) So now we know it's calling a function with one parameter, 0x00ae9460. That happens to be an address in the .rodata segment (Read Only data segment). So I looked there, found a string terminated with a zero and included this information in. This is what I get:

004002e0: 3c1c0fcc lui $gp,0xfcc; gp=0x0fcc0000
004002e4: 279cb920 addiu $gp,$gp,0xffffb920; gp=0xfcbb920
004002e8: 0399e021 addu $gp,$gp,$t9; gp=0x100bbc00
0040034c: 8f84802c lw $a0,0xffff802c($gp); a0=0x00af0000
00400350: 00000000 nop
00400354: 24849460 addiu $a0,$a0,0xffff9460; a0=00ae9460
00400358: 8f992cd8 lw $t9,0x2cd8($gp); t9=0x00ad2310
0040035c: 00000000 nop
00400360: 0320f809 jalr $ra,$t9; unknown("malloc failure\n")
00400364: 00000000 nop

and that unknown function at that address is scattered throughout the code with other strings that I commonly see when I execute DvdPlayer. So I know now that the function at address 0x00ad2310 is probably printf.

So I built a separate file to document the addresses and functions at those addresses. The disassembler can then use those to pull the function names when parsing apart functions, rather than saying "unknown".

From there, I used objdump on the Ellion firmware, compiled with symbols and objdumped it with symbols. Looked at the printf function and sure enough it matched the opcodes for the function I figured was printf in the Iomega firmware. The only exceptions were the addresses and offset values. Went forward and backward from those function and found the matching functions and was able to label those.

With many of the library functions identified, it makes it that much easier to read the source and find functions that match in the Iomega vs. Ellion firmware. Especially helpful was to find the assert command, because it lists what function name it was in as one of the parameters.

I'm using this utility to try to track down what is turning off the flashing light when the DvdPlayer boots. I've identified all of the calls in the main.cpp function, which is similar but not exactly the same as the Ellion's main.cpp. What I'm going to do from this point is knock out the function calls one at a time, searching the binary file and replacing the JALR calls with NOPs. I can more easily find the ones I'm looking for due to the disassembly and using HexEdit I can replace the opcode with 0s to turn it into a NOP.

I've added some other analysis to the utility, which I will blog about when I publish the utility.

Tuesday, March 9, 2010

Wifi mostly solved

For my purposes, it's solved. But if you use WEP or no wifi security, there would need to be changes.

I posted this at mini-modding, but I'm replicating it here as well:

In the /tmp/hddmedia/wpa.conf file I have the following (replaced 'thessid' with the SSID used, and 'thepassphrase' with the passphrase used:


proto=WPA RSN
pairwise=TKIP CCMP

since the interface is at /tmp/net I have to create the directory. And since the file is stored on the 4th partition, I also needed to mount that. Also, I wanted to make sure the wired LAN was also recognized if present. So here's what is at the beginning of my /usr/local/etc/rcS file:

mount /dev/ide/host0/bus0/target0/lun0/part4 /usr/local/etc/dvdplayer/hdd/volumes/HDD1
ln -s /usr/local/etc/dvdplayer/hdd/volumes/HDD1 /tmp/hddmedia
mkdir /tmp/net

echo 'nameserver' > /etc/resolv.conf
udhcpc -p /var/lock/udhcpc_eth0.pid -t 15 -b -s /etc/udhcpc.script -i eth0

modprobe ehci-hcd
modprobe ohci-hcd
sleep 2
ifconfig wlan0 up
iwconfig wlan0 essid "myssid"
wpa_supplicant -P/var/lock/wpa_supplicant.pid -D ipw -c /tmp/hddmedia/wpa.conf -i wlan0 -B
udhcpc -p /var/lock/udhcpc_wlan0.pid -t 15 -b -s /etc/udhcpc.script -i wlan0

The second udhcpc takes about 30 seconds to run, and then it still doesn't start responding to pings until after another minute has passed.

Now I'm sure there's going to be a better way to do what I've listed above. Like do we really need to have udhcpc staying as a running process after it has assigned the IP address? I don't know. But this is a starting point that works at least.

There is a script already on the ScreenPlay in the /etc directory called udhcpc.script. It's already there, but for reference here is the listing:

# udhcpc script edited by Jason Lee

[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"

case "$1" in
/sbin/ifconfig $interface

/sbin/ifconfig $interface $ip $BROADCAST $NETMASK

if [ -n "$router" ] ; then
echo "deleting routers"
while route del default gw dev $interface ; do

for i in $router ; do
route add default gw $i dev $interface

echo -n > $RESOLV_CONF
# [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
[ -n "$domain" ] && echo domain $domain >> $RESOLV_CONF
for i in $dns ; do
echo adding dns $i
echo nameserver $i >> $RESOLV_CONF
echo ok > $DHCP_OK
echo ok > $DHCP_OK2$interface

exit 0

Friday, March 5, 2010

RootApp and Wifi

Played around with the RootApp. Noticed that if you run RootApp with a -1 DvdPlayer then it will execute the specified program once, go to sleep after the program exits, then when you turn it back on it will resume and exit the RootApp watchdog program. Also, if you do RootApp -s then it won't execute any program, but will immediately put the player to sleep. When you power on, it wakes up and...reboots. But if you combine them doing -s -1 then when you power back on, it will resume and exit from RootApp.

I've also worked on trying to understand the wifi. When you disable the DvdPlayer from starting up, it doesn't mount the media partition or link the media drive to /tmp/hddmedia. It also doesn't configure the network/netmask and gateway for the wired or wireless connection.

At the beginning of the rcS file in the /usr/local/etc is the instructions for doing the network config, so I just adapted it for mine and added drive mounting and linking.

ifconfig eth0 netmask
route add default gw
mount /dev/ide/host0/bus0/target0/lun0/part4 /usr/local/etc/dvdplayer/hdd/volumes/HDD1
ln -s /usr/local/etc/dvdplayer/hdd/volumes/HDD1 /tmp/hddmedia

And of course I took out the RootApp DvdPlayer command so that it wouldn't activate the DvdPlayer. This has left two things for me to solve. #1) How to control the blue light. It continues to flash after booting, and the bootscreen stays up. Well, the HelloWorld can take care of the bootscreen, but figuring out what controls that power light has been more difficult. #2) Wifi does not get set up.

First run
which installs the ehci-hcd and ohci-hcd modules using modprobe.

I think it also needs:
/sbin/modprobe ieee80211-rtl
/sbin/modprobe ieee80211_crypt

I found this info in the Main DvdPlayer as well:
/bin/echo nameserver >> /etc/resolv.conf
ifconfig wlan0 up
wpa_supplicant -P/var/lock/wpa_supplicant.pid -D ipw -c /tmp/net/wpa.conf -i wlan0 -B
wpa_cli -p /tmp/net/wpa_supplicant status > /tmp/net/WPA.STATUS;touch /tmp/net/WPA.OK

The /tmp/net/wpa.conf file is added when DvdPlayer runs, but it looks something like this:


proto=WPA RSN
pairwise=TKIP CCMP
psk="your wifi passphrase"

I've extracted information and found a webpage about setting up which has helped.

But I'm actually stuck at ifconfig wlan0 up. wlan0 isn't there. The light doesn't come on in the wifi adapter so I think the port needs to activate power or recognize the device or something similar. NetworkSet.cpp (can be found in Conceptronic sources) gives some hints but I haven't understood it yet. Anyway, that's what I'm working on now.

Saturday, February 27, 2010

Cursor, Navigation, Free Memory w/o resetav

Tonight I figured out how to set the graphics of the cursor. According to a system .x file in the common directory, the cursor is 32 x 32 x 2 bit color. So while I was direct drawing on the screen, I told it to use the same memory for the cursor. And it sure did. Color still seems limited to shades of green. But who knows, it may come in handy somewhere.

Also figured out how to navigate through a movie. I found out that the very routine that gives you how much time has elapsed in the movie also gives you the amount of time in the movie. Was able to jump around to the menu, move the menu selection, and activate it. All done through commands, not via the remote. Should be pretty easy to hook up to the remote once I want to, since I've previously figured out how to interact with the remote.

I was very concerned about calling the resetav all of the time. It would take the video bios and audio bios and put the information back in flash memory. Well, that's a problem if you do it too often. yet, it was the only way I could figure out how to recover once I displayed information on the screen. Well, that's no longer a necessity. It is still required if another program has done it, but mine seems to be able to recover from my own now. Can get all of the layers freed up and shut off.

This has all been pushed out to the git repository.

Tuesday, February 23, 2010

MP3 and LED

I've pushed out the changes so that MP3s can now be played, and that recording light was being turned on by the "setAVModeSCART" function, which made it very easy to track down what GPIO was controlling that light. Especially after I noticed that the light came on after the shutdown VideoPlayback process happened. So I just backtracked from the endin gof the program, commenting stuff out and rebooting (to turn off the light) until the light didn't come on.

Monday, February 22, 2010

Direct screen control

I am now able to control every pixel on the screen. Apparently they chose the R5G6B5 bitmap format for a reason -- it's the native storage format for the screen.

DG_GetSurfaceDesc (m_hSurface, &surfDesc);
DG_Lock(m_hSurface, 0, 0, unitRect.width, unitRect.height, 0);
x = horizonal value from 0 - 1920 (for 1080I)
y = vertical value from 0 - 1080 (for 1080I)
*((uint16_t *)((uint8_t *)surfDesc.lpsurface + (y*surfDesc.lPitch)) + x) = 0xffff;
// format is r5, g6, b5

edit: It was quite easy to switch it to a higher color format by just changing it from Format_16 to Format_32 when the surface was being created. It does not affect the video, it only applies to the overlay surfaces. But the SDK has Format_16 as the default, possibly inserted there by Ellion.

Sunday, February 21, 2010

MPG, Dvd, ISO, and JPG now working

Latest adjustments to the HelloWorld-JC program now include the ability to playback MPG, Dvd files, and automatically mount ISOs. I was also able to extract some code for having the chip render JPG. I was concerned that the method used for decoding the JPG was to pass the information via RPC to the chip. I figured that would interfere with the playback. Turns out, it doesn't! Since all of the decoding is done on the chip, the processor continues to be free to read and unpackage the media it is streaming.

Sunday, February 14, 2010

After nearly a month of having to work until late night to finish my project at work until I finished it Friday, I finally got a chance last night and tonight to continue hacking on the ScreenPlay. And the verdict? Success!

It's pretty limited right now. I've added several files and I'm still very dependent upon the library...For simplification, I've got only the AVI file types working right now (with corresponding audio). I now have the Hello World start up with a hard coded AVI filename that it launches and then it overlays the video screen with a translucent "Hello World", along with the cursor that continues to display as a green block (and the graphic structure still mystifies me).

Right now, it plays the video for about 10 seconds and then kicks out. Look at the main2.cpp program for more info. As always, I have checked this into the git repository on opensphd.sourceforge.net.

Monday, January 25, 2010

Dvdplayer, additional progress

Most of what I have been working on lately has been trying to understand the DvdPlayer program from Ellion. I've posted the source so far at opensphd.sourceforge.net in the HelloWorld git repository. Presently, I have it able to display a PNG and BMP on NTSC, PAL, and HDMI 720p and 1080i on the Iomega ScreenPlay Pro. I'm attempting to understand the video streaming. A99 has successfully added audio streaming to his version of the Hello World program.

In the meantime, Iomega has released r1.96 of the firmware. I have not investigated it yet, and quite frankly I don't have an interest in doing that because once I get my own DvdPlayer program written, I won't need their new firmware.

Superberney has also run out of time for maintaining IomTools, so he has agreed to open source it. I placed it out on the SVN repository in the opensphd.sourceforge.net, along with the changes I made to get the VSFTP and BFTP stuff working. I have not compiled and done any testing on it yet.

So there is plenty of stuff to do, and plenty of stuff in progress, just no discoveries to report right now. It's very interesting to see how Realtek constructed this. What I have learned from this is that the DvdPlayer program has plugin modules for pulling the data from files, http internet, streaming, transcoding server, etc, all which it puts in line to choose where the data comes from. It then analyzes it to determine what type of package the information is in, AVI, MPG, MPV, RM, etc. Again, all of those are put in line to choose which format applies. Then it unpacks and I believe at that point it sends the corresponding audio and video streams to the 1282 chip. They also have a module for picking out the SPU stream (subpicture unit, the subtitles). Anyway, I'm not getting any hacking done by posting this, so I'll end this post for now and hopefully my next post will be about playing a video.