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反汇编。能够看到是断在了函数的内部,当然我们能够调整断点到函数入口。这里主要是为了演示。就不做调整。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlmZXNob3c=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
好了,断点下好了,我们開始游戏。选择“街机”模式開始游戏,然后点几下,再随便点个白块儿让游戏结束。
看看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!
Android漫游记(4)---.so文件动态调试一例的更多相关文章
- Android(五)——dex文件动态调试
代码动态调试: 代码动态调试技术,一般是通过观察程序在运行过程中的状态,如寄存器内容,函数执行结果,内存使用情况等等,分析函数功能,明确代码逻辑,查找可能存在的漏洞 工具:IDA 条件:Android ...
- Android Studio 动态调试 apk 反编译出的 smali 代码
在信安大赛的准备过程中,主要通过 Android Studio 动态调试 apk 反编译出来的 smali 代码的方式来对我们分析的执行流程进行验证.该技巧的主要流程在此记录.以下过程使用 Andro ...
- 针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案
基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些局部变量的地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的起始地址等.在 Linux 环境下,可通过 gdb 对程序进行动态调 ...
- Android系统加载Apk文件的时机和流程分析(1)--Android 4.4.4 r1的源码
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80982869 Android系统在启动时安装应用程序的过程,这些应用程序安装好之 ...
- IDA动态调试Android的DEX文件
Android程序的dex文件的动态调试确实是个大问题,网上也有一些教程但是不是特别的详细,今天用到了IDA动态调试Android的DEX文件,特此记录一下. IDA 6.6新添加了对dex文件的调试 ...
- Android动态方式破解apk前奏篇(Eclipse动态调试smail源码)
一.前言 今天我们开始apk破解的另外一种方式:动态代码调试破解,之前其实已经在一篇文章中说到如何破解apk了: Android中使用静态方式破解Apk 主要采用的是静态方式,步骤也很简单,首先使用 ...
- [转]Android逆向之动态调试总结
一.在SO中关键函数上下断点 刚学逆向调试时.大多都满足于在SO中某关键函数上下断点.然后通过操作应用程序,去触发这个断点,然后进行调试 详细的步骤可以参见非虫大大的<Android软件安全与逆 ...
- android动态调试samli代码(转)
转载自看雪http://bbs.pediy.com/showthread.php?t=189610,非常感谢原作者分享! 跟踪apk一般的做法是在反编译的smali代码中插入log输出,然后重新编译运 ...
- Android Studio动态调试smali代码
工具: Android Studio版本: 3.0.1 smalidea插件: https://github.com/JesusFreke/smali/wiki/smalidea. 反编译工具:本节先 ...
随机推荐
- C++ ofstream和ifstream详细用法
转载地址:http://soft.chinabyte.com/database/460/11433960.shtml ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就 ...
- c++ 复制构造函数和赋值函数
c++ 自动提供了下面这些成员函数 1默认构造函数 2.复制构造函数 3.赋值操作符 4.默认析构函数 5.地址操作符 赋值构造函数copy construtor 用于将一个对象复制到新创建的对象中, ...
- boost库学习随记六:使用同步定时器、异步定时器、bind、成员函数回调处理、多线程的同步处理示例等
一.使用同步定时器 这个示例程序通过展示如何在一个定时器执行一个阻塞等待. //makefile #-------------------------------------------------- ...
- 一个简单的win32窗口
#include <windows.h>#include <stdio.h> LRESULT CALLBACK WinSunProc( HWND hwnd, // ...
- Android 开机动画源码分析
Android系统在启动SystemServer进程时,通过两个阶段来启动系统所有服务,在第一阶段启动本地服务,如SurfaceFlinger,SensorService等,在第二阶段则启动一系列的J ...
- mysql select简单用法
1.select语句可以用回车分隔 $sql="select * from article where id=1" 和 $sql="select * from artic ...
- BZOJ 1597: [Usaco2008 Mar]土地购买( dp + 斜率优化 )
既然每块都要买, 那么一块土地被另一块包含就可以不考虑. 先按长排序, 去掉不考虑的土地, 剩下的土地长x递增, 宽y递减 dp(v) = min{ dp(p)+xv*yp+1 } 假设dp(v)由i ...
- hdu2629Identity Card
Problem Description Do you own an ID card?You must have a identity card number in your family's Hous ...
- 将 Excel 数据导入 MySql
能承受上万数据量,速度快,并且使用了事务,不会出现某条数据错误而导致部分数据插入(要是全部成功要是一条都不成功,测试过程中没出现失败),需要的朋友可以参考下 1.NPOI 2.MySql.Data 这 ...
- python成长之路——第四天
内置函数: callable:查看对象是否能被调用(对象是函数的话能被调用) #callable def f1(): pass f2="a" print(callable(f1)) ...