[转]Android逆向之动态调试总结 神乎(共五篇)

时间:2019-05-13 19:14:24下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《[转]Android逆向之动态调试总结 神乎》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《[转]Android逆向之动态调试总结 神乎》。

第一篇:[转]Android逆向之动态调试总结 神乎

[转]Android逆向之动态调试总结

神乎

一、在SO中关键函数上下断点

刚学逆向调试时。大多都满足于在SO中某关键函数上下断点。然后通过操作应用程序,去触发这个断点,然后进行调试

详细的步骤可以参见非虫大大的《Android软件安全与逆向分析》

简单说:在libsyclover.so文件中有一个函数jnicall1。每次单击按钮的时候,便会调用此函数。

1.静态载入此so文件,找到函数的偏移地址为:0x132C2.执行android_server3.端口转发 adb forward tcp:23946 tcp:23946 4.运行程序 5.IDA附加

然后会弹出

点击OK之后,在弹出的列表框中选择需要附加的进程即可 6.下断点

附加完成之后,会停在libc.so这个模块中。此时按下Ctrl + S,弹出模块列表框,搜索so文件名。

记录下基地址:0×76072000(RX权限)

和静态分析时得到的偏移地址0x132C相加得到0x7607332C

G跳转到此位置

F2下好断点!7.触发断点

下好断点,便F9执行,此时状态是runing

此时,去应用中单击按钮,程序便会断在刚刚下好的断点处~

ok~ 这种调试方法局限性很大,适合于比较初级的调试。这种调试手法在现在已经满足不了需求了。

二、在JNI_OnLoad函数上下断点

JNI_OnLoad函数大概功能就是在程序加载so的时候,会执行JNI_OnLoad函数,做一系列的准备工作。

很多时候,程序猿们会将一些重要信息放在此函数中,而不是通过某种事件来重复触发。包括说将反调试函数放置在此函数中。因此,调试手段发生了改变,上述调试方法基本上被淘汰。

1.静态分析,找到JNI_OnLoad函数的偏移:0×1504

2.执行android_server3.端口转发 adb forward tcp:23946 tcp:23946 4.以调试模式启动程序 adb shell am start-D-n com.example.mytestcm/.MainActivity

此时,手机界面会出现Waiting For Debugger页面 5.打开ddms或者Eclipse(必要,为了使用jdb命令)6.IDA附加 7.设置调试选项

Debugger — Debugger Options

8.F9运行程序

IDA中,F9运行程序,此时是runing状态。

在命令行中执行:jdb-connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700其中port=8700是从ddms中看到的。

此时程序会断下来 9.下断点

Ctrl + S 然后搜索到so文件名

记录下基地址是:0×76118000

加上JNI_OnLoad函数的偏移地址0×1504为0×76119504

G跳转到0×76119504,下断点

A.触发断点

下好断点之后,直接F9运行吧,就能断在JNI_OnLoad函数处~

当这种调试手法出现之后,将特殊函数,或者反调试函数放在JNI_OnLoad中也不是那么的安全了。此时,程序猿们通过分析系统对SO文件的加载链接过程发现,JNI_OnLoad函数并不是最开始执行的。在JNI_OnLoad函数执行之前,还会执行init段和init_array中的一系列函数。

因此,现在的调试方法,都是将断点下在init_array中~

至于下断点的方法,可以类比于在JNI_OnLoad中下断点的方法,在init_array的函数中下断点。还有一种方法便是通过在linker模块中,通过对其中函数下断点,然后也能单步到init_array中下面便详细介绍下如何给任意系统函数下断点

三、给任意系统函数下断点 1.需要准备的有:

与你调试环境一致的系统源码,这个也可以在http://androidxref.com/网站上在线查阅。

root之后的手机,方便将系统的一些so文件dump至本地,静态获取到系统函数的偏移地址 2.流程

执行android_server

端口转发 adb forward tcp:23946 tcp:23946 调试模式启动程序 adb shell am start-D-n 包名/类名

IDA附加

静态找到目标函数对应所在模块的偏移地址

Ctrl+S找到对应模块的基地址,两个地址相加得到最终地址

G跳转至地址,然后下断

F9运行

执行jdb-connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

断下,进行调试

四、在dvmDexFileOpenPartial函数下断点,dump出明文dex 发展至今,从去年到现在,apk的加解密发展非常迅速。国内出现了很多针对apk的加壳保护方案。主要也体现在对dex的保护和对so的保护!针对dex的保护,很长一段时间,都能通过对dvmDexFileOpenPartial函数下断点,从而dump出明文dex文件。

以这次alictf的第三题为例子,展示下如何对dvmDexFileOpenPartial函数下断点!

其他步骤都是一样的,这儿主要说下如何找到dvmDexFileOpenPartial函数位置

1.查看源码

dvmDexFileOpenPartial函数在rewriteDex这个函数中被调用。

可以看到关键字符串信息是:Unable to create DexFile

此时,从手机的/system/lib目录下得到libdvm.so 2.载入IDA,搜索字符串:Unable to create DexFile

得到偏移地址是:0x0005AE8A 3.下断点

搜索模块libdvm.so

基地址是0×41492000

加上偏移地址为0x414ECE8A

G跳转至此位置,下好断点,即可 4.dump明文dex文件

下好断点之后,F9运行,执行jdb-connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

程序断下

此时,看到寄存器窗口中的值为:

R0保存dex的起始地址,R1便是dex的长度

直接dump即可!5.后续

dump出来的dex就可以进行反编。

效果如下:

五、写在最后

随着现在技术的发展,对apk的保护是越来越好!大大增加了逆向分析人员的分析难度。同时,在整个攻防的过程中,对攻防两端的人都带来了非常棒体验。双方都取得了长足的进步!

也促使了整个加固方向水平的提升!

其中,动态调试手法在整个过程中是必不可少的。

第二篇:Android之activity总结——转自论坛

Android之activity总结——转自论坛

一、什么是activity Activity 是用户接口程序,原则上它会提供给用户一个交互式的接口功能。它是 android 应用程序的基本功能单元。Activity 本身是没有界面的。所以activity类创建了一个窗口,开发人员可以通过setContentView(View)接口把UI放到activity创建的窗口上,当activity指向全屏窗口时,也可以用其他方式实现:作为漂浮窗口(通过windowIsFloating的主题集合),或者嵌入到其他的activity(使用ActivityGroup)。activity是单独的,用于处理用户操作。几乎所有的activity都要和用户打交道,二、activity生命周期

2011-11-20 20:23:32 上传 下载附件(64.6 KB)由图可知:

在一个Activity正常启动过程中,这些方法调用的顺序是onCreate-> onStart-> onResume;在Activity被kill掉的时候方法顺序是onPause-> onStop-> onDestroy,此为一个完整的Lifecycle。那么对于中断处理(比如电话来了),则是onPause-> onStop,恢复时onStart-> onResume;如果当前应用程序的是一个Theme为Translucent(半透明)或者Dialog 的Activity那么中断就是onPause ,恢复的时候onResume。

那么对于”Other app need memory”,就是我们手机在运行一个应用程序的时候,有可能打进来电话发进来短信,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能,另外系统也不允许你占用太多资源,至少要保证一些功能(比如电话),所以资源不足的时候也就有可能被kill掉。方法在系统中的作用及我们应该做什么:

onCreate:在这里创建界面,做一些数据的初始化工作;

onStart: 到这一步变成“用户可见不可交互”的状态;

onResume:变成和用户可交互的,(在Activity栈系统通过栈的方式管理这些Activity,即当前Activity在栈的最上端,运行完弹出栈,则回到上一个Activity);

onPause:到这一步是可见但不可交互的,系统会停止动画等消耗CPU的事情。从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候你的程序的优先级降

低,有可能被系统收回。在这里保存的数据,应该在onResume里读出来。

onStop:变得不可见,被下一个activity覆盖了

onDestroy:这是Activity被kill前最后一个被调用方法了,可能是其他类调用finish方法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有

一个Progress Dialog在线程中运行,请在onDestroy里把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛异常。

onPause,onstop,onDestroy,三种状态下 activity都有可能被系统kill 掉。

三、Activity之间的通信

在 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。

Intent负责对操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。

在应用中,我们可以以两种形式来使用Intent:

直接Intent:指定了component属性的Intent(调用setComponent(ComponentName)或者setClass(Context, Class)来指定)。通过指定具体的组件类,通知应用启动对应的组件。

间接Intent:没有指定comonent属性的Intent。这些Intent需要包含足够的信息,这样系统才能根据这些信息,在在所有的可用组件中,确定满足此Intent的组件。对于直接Intent,Android不需要去做解析,因为目标组件已经很明确。

Android需要解析的是那些间接Intent,通过解析,将 Intent映射给可以处理此Intent的Activity、IntentReceiver或Service。Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。

四、Activity 的 Intent Filter

Intent Filter 描述了一个组件愿意接收什么样的 Intent 对象,Android 将其抽象为 android.content.IntentFilter 类。在 Android 的 AndroidManifest.xml 配置文件中可以通过 节点为一个 Activity 指定其 Intent Filter,以便告诉系统该 Activity 可以响应什么类型的 Intent。

当使用 startActivity(intent)来启动另外一个 Activity 时,如果直接指定 intent 对象的 Component 属性,那么 Activity Manager 将试图启动其 Component 属性指定的 Activity。否则 Android 将通过 Intent 的其它属性从安装在系统中的所有 Activity 中查找与之最匹配的一个启动,如果没有找到合适的 Activity,应用程序会得到一个系统抛出的异常。这个匹配的过程如下:

2011-11-20 20:23:59 上传 下载附件(16.72 KB)

五、Activity的栈式管理

Android针对Activity的管理使用的是栈,就是说某一个时刻只有一个Activity处在栈顶,当这个Activity被销毁后,下面的Activity才有可能浮到栈顶,或者有一个新的Activity被创建出来,则旧的Activity就被压栈沉下去了。Activity是Android程序的表现层。程序的每一个显示屏幕就是一个Activity。正在运行的Activity处在栈的最顶端,它是运行状态的。

2011-11-20 20:26:09 上传 下载附件(23.43 KB)

当在程序中调用 Activity.finish()方法时,结果和用户按下 BACK 键一样:它告诉

Activity Manager该Activity实例可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity,把原 Activity 压入到栈的第二层,从 Running 状态转到 Paused 状态。

六、Activity的加载模式standard、singleTop、singleTask、singleInstance(其中前两个是一组、后两个是一组),默认为standard standard:就是intent将发送给新的实例,所以每次跳转都会生成新的activity。singleTop:也是发送新的实例,但不同standard的一点是,在请求的Activity正好位于栈顶时(配置成singleTop的Activity),不会构造新的实例singleTask:和后面的singleInstance都只创建一个实例,当intent到来,需要创建设置为singleTask的Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。singleInstance:首先说明一下task这个概念,Task可以认为是一个栈,可放入多个Activity。比如启动一个应用,那么Android就创建了一个Task,然后启动这个应用的入口Activity,那在它的界面上调用其他的Activity也只是在这个task里面。那如果在多个task中共享一个Activity的话怎么办呢。举个例来说,如果开启一个导游服务类的应用程序,里面有个Activity是开启GOOGLE地图的,当按下home键退回到主菜单又启动GOOGLE地图的应用时,显示的就是刚才的地图,实际上是同一个Activity,实际上这就引入了singleInstance。singleInstance模式就是将该Activity单独放入一个栈中,这样这个栈中只有这一个Activity,不同应用的intent都由这个Activity接收和展示,这样就做到了共享。当然前提是这些应用都没有被销毁,所以刚才是按下的HOME键,如果按下了返回键,则无效。

七、Activity的跳转Activity跳转,无返回结果 这是最简单的Activity跳转方式。从一个Activity启动另一个Activity,直接startActivity(new Intent(当前Activity.this, 下一Activity.class))。

Activity跳转,返回数据/结果 需要返回数据或结果的,则使用startActivityForResult(Intent intent, int requestCode),requestCode的值是自定义的,用于识别跳转的目标Activity。跳转的目标Activity所要做的就是返回数据/结果,setResult(int resultCode)只返回结果不带数据,或者setResult(int resultCode, Intent data)两者都返回!而接收返回的数据/结果的处理函数是onActivityResult(int requestCode, int resultCode, Intent data),这里的requestCode就是startActivityForResult的requestCode,resultCode就是setResult里面的resultCode,返回的数据在data里面。

** 注意,在setResult后,要调用finish()销毁当前的Activity,否则无法返回到原来的Activity,就无法执行原来Activity的onActivityResult函数,看到当前的Activity没反应。

下载[转]Android逆向之动态调试总结 神乎(共五篇)word格式文档
下载[转]Android逆向之动态调试总结 神乎(共五篇).doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐