转自:http://forum.xda-developers.com/showpost.php?p=12853986&postcount=19
Well... I have attached a debugger to native code, set breakpoints,
analyzed registers, memory, etc. It wasn‘t that easy though. It took me several
days to start debugging and get first key, but I got second one in about 1
hour.
Actually I don‘t really need that key, I can‘t even
play Angry Birds Rio on my old G1, but it was challenging and I love challenges
;) Plus I have learnt a LOT about gdb, assembler, ARM architecture,
etc.
So I want to thank you, Goddchen, for giving me an
opportunity to learn & play :)
Ok, let‘s move
on...
First, I have disassembled libangrybirds.so using IDA
Pro 5.5 . I was able to examine code and attach IDA to gdbserver on a device,
but unfortunately it wasn‘t working properly. IDA was thinking that
libangrybirds.so is a main binary of a process it attached to, but it should
look into loaded shared libs instead. Weird, but I didn‘t find a way to attach
it properly. And this is pity, because IDA is a great tool and it would make
debugging a pleasure, but I had to use gdb instead.
Second,
Android has problems with debugging multi-threaded native code. MT support was
added in NDK r5 and because of some bug it‘s not possible on a system older than
Gingerbread.
Third, you could attach gdb manually, but
ndk-gdb script does great work for you. You will have to do some tricks to use
it with 3rd party app though.
Fourth, it seems
libangrybirds.so is a Java code compiled to native or something like that. There
are objects like FileInputStream, ByteOutputStream, etc., but there are also
some API differencies. We‘ll see String and Array<uchar> objects, but it‘s
usually easy to find a pointer to simple uchar[].
Steps to
start native code debugging:
Ok, let‘s find a key for levels lua files:
(gdb) br _ZN7GameLua9loadLevelEN4lang6StringE Breakpoint 1 at 0x80468e4c
(gdb) c Continuing. [New Thread 5857] [Switching to Thread 5857] Breakpoint 1, 0x80468e4c in GameLua::loadLevel () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so
(gdb) x/4x $r1 0x4395e66c: 0x00a405f0 0x00153b28 0x804ec778 0x00000000 (gdb) x/s 0x00a405f0 0xa405f0: "levels/warehouse/Level190"
(gdb) advance _ZN4lang7AESUtil7decryptERKNS_5ArrayIhEES4_RS2_ 0x80539894 in lang::AESUtil::decrypt () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so
(gdb) x/4x $r1 0x1592b0: 0x00159528 0x00000020 0x00000020 0x7b206e65
(gdb) x/s 0x00159528 0x159528: "USCaPQpA4TSNVxMI1v9SK9UC0yZuAnb2a"
(gdb) x/4x $r2 0x4395d6f4: 0x009ca248 0x000004a0 0x000004a0 0x00000378 (gdb) x/4x 0x009ca248 0x9ca248: 0x3347b5dc 0x26048446 0x1a0c1231 0x35d3f99c
As you can see there is AES::BlockMode passed to AES:ecrypt(). It would be quite hard to interpret it without
headers, so I was trying various block modes and I found that CBC with empty
initial vector decodes to string starting with ‘7z‘. For me that meant: mission
successfull :)
Ok, highscores.lua and settings.lua files
now. Technique is very similar, but there are some differences:
Maybe there is a better solution to last problem, but I‘ve decided
to add some Thread.sleep() call just after System.loadLibrary(), so gdb will
attach before highscores.lua loading.
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V const-wide/16 v0, 5000 invoke-static {v0, v1}, Ljava/lang/Thread;->sleep(J)V
(gdb) br _ZN7GameLua18loadPersistentFileERKN4lang6StringE Breakpoint 1 at 0x80457030 (gdb) c Continuing. [New Thread 6735] [Switching to Thread 6735] Breakpoint 1, 0x80457030 in GameLua::loadPersistentFile () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so (gdb) x/s $r2 0x4395e3b8: "highscores.lua"
(gdb) advance _ZN4lang7AESUtil7decryptERKNS_5ArrayIhEES4_RS2_ 0x80539894 in lang::AESUtil::decrypt () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so (gdb) x/4x $r1 0x159294: 0x00159620 0x00000020 0x00000020 0x00159518 (gdb) x/s 0x00159620 0x159620: "44iUY5aTrlaYoet9lapRlaK1Ehlec5i0"
(gdb) x/4x $r2 0x4395ddc4: 0x0015bc00 0x00000040 0x00000040 0x00000001 (gdb) x/16x 0x0015bc00 0x15bc00: 0x2271b777 0xe6f19f4c 0x2489a316 0xfae1aee2 0x15bc10: 0x82e0ef38 0xe84fc25d 0xb196adac 0xbf030439 0x15bc20: 0xb6b9bade 0x3046af12 0xe8eeeb0d 0x20e8037c 0x15bc30: 0x1a405edf 0xc218f7f6 0xc29209e2 0x9ad03e8c
Now we have got everything we want :)
Ahh, not
exactly everything... I would be really happy to know, how to properly attach
IDA for debugging - it would be much easier, even if gdb interface is also very
good.
原文:http://www.cnblogs.com/Blessing/p/3537178.html