Cracking by example: MIPS native library
A little background on this one: I have a MIPS native library that checks a license file that is unique per CPU ID. The license number itself is a 128-bit hexadecimal number represented as a string which is most likely generated taking the CPU ID seed. I have access to the native library .so and I decompiled it at Retargetable Decompiler site.
Fortunately whoever compiled the library did it with GCC and -g switch on, so we have a lot of debug symbols.
|Reduced capture of decompiled functions prototypes|
I decided to start with testLock function, mainly because it actually wrapped testLicense and looked simpler than testLicense, especially in the number of parameters it takes.
|First lines of testLock decompilation|
|First lines of testLock disassembly|
testLock only had a couple of callers all around the library code.
|One of testLock callers|
We can easily see the caller checks if the return value is lesser than 1. I'm going to assume a value < 1 means error because in a lot of C APIs a negative value is an error (why 0 is error in this API really baffles me). Next step is to modify testLock() so it always returns 1.
|testLock() function in Bless hexadecimal editor|
First instruction jr ra jumps to the address specified in RA register, which in MIPS is equivalent of returning to function caller (similar to x86's RET instruction). Second instruction li v0,1 sets V0 register to 1. V0 is used to store the return value of a function. So replacing the current code with these 2 functions should be equivalent of return 1 (li v0,1 is actually executed before the jump due to MIPS' delay slot). More detailed information about MIPS function calling conventions here.
But we need to keep the function size to not mess up offset references and relocation information contained on the library. Fortunately, MIPS, like other architectures, has a NOP instruction, and also forunately, all instructions in MIPS are the same size: 4 bytes. And not only that, NOP instruction is all zeroes.
|Modified testLock() function|
And that's all, folks!