1. 程式人生 > >Android漫遊記(4)---.so檔案動態除錯一例

Android漫遊記(4)---.so檔案動態除錯一例

    Android平臺的動態除錯一直以來是個困擾我等Coder的頭疼問題,特別是對於本地的動態除錯支援,可以說是“弱智”級別的,不知道Google的新版NDK和新出的Android Studio對這塊支援如何,讓我們拭目以待。

    言歸正傳,我這裡採用的是cygwin+ndk-gdb的除錯模式,靈感來自於XDA的一篇博文(點選開啟連結),平臺和原文作者不同:

    1、Win7 64

    2、NDK r9d x86_64

    3、Android 4.2.2

    4、cygwin 64

    5、IDA pro 6.1

    話不多話,開始正題,除錯步驟如下:

    1、環境搭建這類的各位可以自行Google之,這裡就不多說了。

    2、首先我們隨便找個網站,下載遊戲的APK包。Android的APK包的正式釋出版本是取消了debug屬性的,在除錯之前,我們還需要做些準備工作。

    3、用apktool解包apk檔案,然後修改AndroidManifest.xml,在重新打包,再用signapk簽名。

    4、為ndk-gdb除錯做準備工作,這個上面那篇博文已經寫得很詳細,這裡不再贅述。說明一點:我們除錯的目標是.\libs\armeabi\libgame.so,這個so是遊戲主庫檔案。

          準備好後的目錄結構大致如下:

          

    5、好了,準備工作完畢,開始我們的除錯之旅!

    首先,安裝我們重新打包的apk到手機,然後進入cygwin shell,進入本地的遊戲解包後的目錄。這裡要重點說明一點:由於一些相容性問題,我們不能直接使用google原來的ndk-gdb除錯指令碼,需要做一些修改:

    

我這裡直接給DATA_DIR賦值為app目錄:/data/data/com.umonistudio.tile。這步驟很重要,否則你會遇到run-as之類的錯誤,導致無法繼續除錯!

好了,終於準備完畢了,切換到cygwin shell,開始除錯,如果沒有問題的話,就會順利進入gdb提示符,我的輸出如下:

$ ndk-gdb --verbose --start --nowait
Android NDK installation path: /cygdrive/e/Tools/android-ndk-r9d-windows-x86_64/       android-ndk-r9d
Using default adb command: /cygdrive/e/Tools/adt-bundle-windows-x86_64-20131030/       adt-bundle-windows-x86_64-20131030/sdk/platform-tools/adb
ADB version found: Android Debug Bridge version 1.0.31
Using ADB flags:
Using JDB command: /cygdrive/e/Tools/Java/jdk1.7.0_15/bin/jdb
Using auto-detected project path: .
Found package name: com.umonistudio.tile
ABIs targetted by application: armeabi
Device API Level: 17
Device CPU ABIs: armeabi-v7a armeabi
Compatible device ABI: armeabi
Using gdb setup init: ./libs/armeabi/gdb.setup
Using toolchain prefix: /cygdrive/e/Tools/android-ndk-r9d-windows-x86_64/android-ndk-r9
Using app out directory: ./obj/local/armeabi
Found debuggable flag: true
Found data directory: '/data/data/com.umonistudio.tile'
Found device gdbserver: /data/data/com.umonistudio.tile/lib/gdbserver
Found first launchable activity: .tile
Launching activity: com.umonistudio.tile/.tile
## COMMAND: adb_cmd shell am start -n com.umonistudio.tile/.tile
Starting: Intent { cmp=com.umonistudio.tile/.tile }
## COMMAND: adb_cmd shell sleep 2
Found running PID: 8706
Launched gdbserver succesfully.
Setup network redirection
## COMMAND: adb_cmd shell run-as com.umonistudio.tile /data/data/com.umonistudio       .tile/lib/gdbserver +debug-socket --attach 8706
## COMMAND: adb_cmd forward tcp:5039 localfilesystem:/data/data/com.umonistudio.       tile/debug-socket
Attached; pid = 8706
Listening on Unix socket debug-socket
## COMMAND: adb_cmd pull /system/bin/app_process obj/local/armeabi/app_process
2384 KB/s (21980 bytes in 0.009s)
Pulled app_process from device/emulator.
## COMMAND: adb_cmd pull /system/bin/linker obj/local/armeabi/linker
3246 KB/s (63176 bytes in 0.019s)
Pulled linker from device/emulator.
## COMMAND: adb_cmd pull /system/lib/libc.so obj/local/armeabi/libc.so
4186 KB/s (424460 bytes in 0.099s)
Pulled libc.so from device/emulator.
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-mingw32msvc --target=arm-linux-android".
For bug reporting instructions, please see:
<http://source.android.com/source/report-bugs.html>.
Warning: E:\works\apktools\biecaibaikuaier_an_debug_sign/system/core/include/cutils: No such file or directory.
Remote debugging from host 0.0.0.0
0x400f44b8 in epoll_wait () from E:/works/apktools/biecaibaikuaier_an_debug_sign/obj/local/armeabi/libc.so
warning: Could not load shared library symbols for 108 libraries, e.g. libstdc++.so.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
warning: Breakpoint address adjusted from 0x400b4ab7 to 0x400b4ab6.
(gdb)

這裡需要說明一點,我輸入的除錯命令:ndk-gdb --verbose --start --nowait,加了一個nowait引數:如果不加nowait會在libgame.so這個目標so載入前,gdb就斷下來,導致我們無法除錯目標庫。

好了,我們在gdb命令號輸入:

(gdb) info shared
From        To          Syms Read   Shared Object Library
0x400b2280  0x400bb418  Yes (*)     E:/works/apktools/biecaibaikuaie                                                                                                                    r_an_debug_sign/obj/local/armeabi/linker
0x400df830  0x4012e294  Yes (*)     E:/works/apktools/biecaibaikuaie                                                                                                                    r_an_debug_sign/obj/local/armeabi/libc.so
                        No          libstdc++.so
                        No          libm.so
                        No          liblog.so
                        No          libcutils.so
                        No          libgccdemangle.so
                        No          libcorkscrew.so
                        No          libz.so
                        No          libutils.so
                        No          libbinder.so
                        No          libemoji.so
                        No          libjpeg.so
                        No          libexpat.so
                        No          libm4u.so
                        No          libstlport.so
                        No          libnetutils.so
                        No          libbwc.so
                        No          libhardware.so
                        No          libsync.so
                        No          libui.so
                        No          libGLES_trace.so
                        No          libEGL.so
                        No          libGLESv2.so
                        No          libion.so
                        No          libdpframework_os.so
                        No          libdpframework_plat.so
                        No          libdpframework.so
                        No          libgui.so
                        No          libcamera_client.so
                        No          libcam.utils.so
                        No          libaed.so
                        No          libcameracustom.so
                        No          libcam_camera_exif.so
                        No          libnativehelper.so
                        No          libmatv_cust.so
                        No          libcamdrv.so
                        No          libimageio.so
                        No          libcam.campipe.so
                        No          libGdmaScalerPipe.so
                        No          libSwJpgCodec.so
                        No          libvcodec_oal.so
                        No          libsched.so
                        No          libvcodec_utility.so
                        No          libmp4enc_xa.ca7.so
                        No          libvcodecdrv.so
                        No          libJpgDecPipe.so
                        No          libmhalImageCodec.so
                        No          libalmkdrv.so
                        No          libskia.so
                        No          libtinyxml.so
                        No          libandroidfw.so
                        No          libgabi++.so
                        No          libicuuc.so
                        No          libicui18n.so
                        No          libsqlite.so
                        No          libdvm.so
                        No          libGLESv1_CM.so
                        No          libETC1.so
                        No          libwpa_client.so
                        No          libhardware_legacy.so
                        No          libsonivox.so
                        No          libcrypto.so
                        No          libssl.so
                        No          libstagefright_foundation.so
                        No          libspeexresampler.so
                        No          libaudioutils.so
                        No          libmedia_native.so
                        No          libmedia.so
                        No          libusbhost.so
                        No          libharfbuzz.so
                        No          libhwui.so
                        No          libmtkbtextadpa2dp.so
                        No          libextjsr82.so
                        No          libandroid_runtime.so
                        No          libjavacore.so
                        No          libdrmframework.so
                        No          libdrmmtkwhitelist.so
                        No          libdrmmtkutil.so
                        No          libdrmframework_jni.so
                        No          libstagefright_memutil.so
                        No          libstagefright_omx.so
                        No          libstagefright_yuv.so
                        No          libvorbisidec.so
                        No          libstagefright_enc_common.so
                        No          libstagefright_avc_common.so
                        No          libstagefright.so
                        No          libmtp.so
                        No          libexif.so
                        No          libstagefright_amrnb_common.so
                        No          libmtk_drvb.so
                        No          libamr_wrap.so
                        No          libmedia_jni.so
                        No          libbcinfo.so
                        No          libbcc.so
                        No          libRS.so
                        No          librs_jni.so
                        No          libandroid.so
                        No          libchromium_net.so
                        No          libwebcore.so
0x5dd4a500  0x5dfb591c  Yes (*)     E:/works/apktools/biecaibaikuaie                                                                                                                    r_an_debug_sign/obj/local/armeabi/libgame.so
                        No          libsoundpool.so
                        No          libsrv_um.so
                        No          libIMGegl.so
                        No          libEGL_mtk.so
                        No          libusc.so
                        No          libGLESv1_CM_mtk.so
                        No          libGLESv2_mtk.so
                        No          libpvrANDROID_WSEGL.so
                        No          libpvr2d.so
                        No          gralloc.mt6589.so
(*): Shared library is missing debugging information.

可以看到我們的目標庫已經成功載入,地址0x5dd5a500---0x5dfb591c,終於可以開始愉快的玩耍了微笑

這裡我們開啟IDA,檢視libgame.so的反彙編,找到GameOver::initscore(int,bool)這個函式:


先說明下這個函式的作用:在遊戲結束後,顯示當前局的分數!我們看下其函式名匯出為:_ZN8GameOver9initScoreEib。好了,我們在GDB輸入:

(gdb) br _ZN8GameOver9initScoreEib
Breakpoint 1 at 0x5dd4c612
(gdb) info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x5dd4c612 <GameOver::initScore(int, bool)+26>
(gdb) disas 0x5dd4c612,+20
Dump of assembler code from 0x5dd4c612 to 0x5dd4c626:
   0x5dd4c612 <_ZN8GameOver9initScoreEib+26>:   cmp     r1, #0
   0x5dd4c614 <_ZN8GameOver9initScoreEib+28>:   beq.n   0x5dd4c61a <_ZN8GameOver9initScoreEib+34>
   0x5dd4c616 <_ZN8GameOver9initScoreEib+30>:   ldr     r3, [pc, #284]  ; (0x5dd4c734 <_ZN8GameOver9initScoreEib+316>)
   0x5dd4c618 <_ZN8GameOver9initScoreEib+32>:   str     r3, [sp, #4]
   0x5dd4c61a <_ZN8GameOver9initScoreEib+34>:   adds    r4, r5, #0
   0x5dd4c61c <_ZN8GameOver9initScoreEib+36>:   adds    r4, #252        ; 0xfc
   0x5dd4c61e <_ZN8GameOver9initScoreEib+38>:   bl      0x5dde73d4 <_ZN7cocos2d13CCUserDefault17sharedUserDefaultEv>
   0x5dd4c622 <_ZN8GameOver9initScoreEib+42>:   ldr     r2, [r4, #32]
   0x5dd4c624 <_ZN8GameOver9initScoreEib+44>:   ldr     r3, [pc, #272]  ; (0x5dd4c738 <_ZN8GameOver9initScoreEib+320>)
End of assembler dump.
(gdb)

對照IDA反彙編,可以看到是斷在了函式的內部,當然我們可以調整斷點到函式入口,這裡主要是為了演示,就不做調整。


好了,斷點下好了,我們開始遊戲,選擇“街機”模式開始遊戲,然後點幾下,再隨便點個白塊兒讓遊戲結束。

看看gdb的輸出視窗:

(gdb) c
Continuing.
[New Thread 8720]
[Switching to Thread 8720]


Breakpoint 1, 0x5dd4c612 in GameOver::initScore(int, bool) () from E:/works/apktools/biecaibaikuaier_an_debug_sign/obj/local/armeabi/libgame.so
(gdb) info registers
r0             0x65cf59f8       1708087800
r1             0x0      0
r2             0x6e0aeb37       1846209335
r3             0x4013d1f4       1075040756
r4             0x65cf5af4       1708088052
r5             0x65cf59f8       1708087800
r6             0x7      7
r7             0x5dde3b2d       1574845229
r8             0x5e1c2c70       1578904688
r9             0x5e0c2f3c       1577856828
r10            0x5cdd5a88       1558010504
r11            0x5e1c2c84       1578904708
r12            0x5e088afc       1577618172
sp             0x5e1c2af8       0x5e1c2af8
lr             0x5dd4ca0f       1574226447
pc             0x5dd4c612       0x5dd4c612 <GameOver::initScore(int, bool)+26>
cpsr           0x30     48
(gdb)set $r6=99999

YES,成功斷下!輸入info registers檢視當前暫存器狀態,注意檢視r6暫存器,值為0x7(我剛才點了7個黑塊兒)。我們開始個好玩的東西,gdb輸入:set $r6=99999,然後讓遊戲繼續,看看有什麼微笑!!!


總結一下:

這裡主要是演示了下Android平臺下,對於無原始碼的第三方動態庫的彙編級除錯過程(不針對任何遊戲,不用於任何商業目的),目前google官方的除錯工具對native除錯支援不好,希望後面google能對這塊給力些。上面所涉及的內容只用於技術交流之用處,不用於任何商業目的。

轉載請註明出處:生活秀            Enjoy IT!微笑