首页 > 其他 > 详细

IDA 静态调试和动态调试

时间:2021-01-22 17:03:40      阅读:160      评论:0      收藏:0      [点我收藏+]

Fn+f5转成c语言伪代码

shift+f12 查看文件中所有常量字符串的值

ctrl+s查看so文件字段信息  

JNI函数方法名还原 选中v3 按y建 作用(类型还原)


v3 + 676 前面是一个指针 比如 *(_DWORD *)v3 + 676 表示 v3 是JNIEnv *类型
形如 *(_DWORD *)vX + YYY 皆是
可选中v3 按y键进行类型替换,替换为JNIEnv *
为伪代码添加注释 : /

g跳转到指定地址

IDA动态调试

目的:找到自毁程序的内置密码

IDA下载配置 mac需要在10.15以下版本才可以使用

首先,需要准备安卓真机,最好是pxiel 6.0的系统,

将ida文件夹里面的dbgsrv下的android_server放入真机的/data/local/tmp/下 添加777权限 chmod 777 xxx

技术分享图片

 

 ./android_server运行服务并且监听端口23946 adb forward tcp:23946 tcp:23946

技术分享图片

 

 后面再运行ida 32 点go打开ida new是静态调试

技术分享图片

 

 

我们选择 debugger-->attach -remote ARMLinux/Android debugger技术分享图片

 

 技术分享图片

 

输入127.0.0.1点ok。会出来如下界面,如果说链接拒绝,请检查前面启动服务和监听端口是否正常

技术分享图片

 

 

我们找到需要调试的进程com.yaotong.crackme点ok

技术分享图片

 

稍等一会儿之后会出来如下界面

技术分享图片

 

 由于我们之前说过,这个函数的验证密码的函数叫securityCheck

我们现在需要跳到这个函数的内存地址,去调试这个函数,如何找到这个函数的内存地址呢

函数运行实际内存地址=头so文件的基地址(根据实际运行情况,此基基地值app每次执行的值都不一样)  + 该函数的偏移量(固定不变.so文件可查看)

我们现在另外打开一个ida 以静态方法打开此apk的libcrackme.so文件找到securityCheck函数的偏移量为11A8

技术分享图片

 

 

 再打开以动态方法调试的ida 按control+s(显示app中的so文件)

我们找到libcrackme.so 找到第一个标有x权限的so文件

技术分享图片

 

 

打开

技术分享图片

 

 

 显示的内存地址为F4395000

 我们打开电脑上的科学计算器,计算方法以16进制进行计算

用F4395000+11A8得到的就是实际的securityCheck运行的的内存地址 F43961A8

我们在动态的ida里面按下G 输入刚才得到的内存地址,跳到此内存地址

技术分享图片

 

 跳转后的界面如下

技术分享图片

 

 现在我们对此函数进行调试,我们需要在Java_com_yaotong_crackme_MainActivity_securityCheck函数这里进行打断点调试,右键addbreakpoint

技术分享图片

 

 

断点后的样子

技术分享图片

 

 调试有两个快捷键,F7 和F8   

F7单步调试,要进入函数
F8单步调试,不进入函数

一般都是F8。进入函数步骤太多了。看不出来。我们F8尝试调试

技术分享图片

 

 

发现报错,没关系 我们再次尝试

再次报错,一直都报错,此时 我们想到,可能是此app用了反调试

IDA调试原理 是利用Linux系统 ptrace 来实现
当应用被调试时,应用内存里的TracerPid 字段就不为0

进入设备查看ptrace字段:
//进入设备
adb shell
//获得APP的进程ID

ps | grep 包名
//打印该APP里内存状态信息
cat /proc/pid(进程ID)/status

TracerPid为 0代表 没有被调试,不为0代表在被调试。
反调试的原理,检测TracerPid是否被占用,如果被调用。阻止app继续运行

反反调试
    动态调试,找到检测TracerPid的代码,不执行此代码
方法:
  此检查代码一般在.init_arra 和 JNI_OnLoad两处。此函数都是在程序最开始运行的时候执行
  在JNI_OnLoad函数出打断点调试,找到检测TracerPid的代码,修改so文件的执行函数,不执行此代码

IDA调试反调试小经验 如何找到反调试代码:
  结合IDA静态时的代码,观察程序逻辑
  指令一般会整过执行完,直到函数末尾。
so文件在加载阶段会执行JNI_ONLoad函数。此后便不再执行。要在so文件加载阶段才能给JNI_ONLoad打断点。

分下面几个步骤:

    1.修改APP的AndroidManifest.xml文件的application字段,再后面加上一段代码android:debuggable=‘‘ture".然后重新打包签名安装

技术分享图片

 

 

 

 

    2.运行的时候检查是否允许debuggable项

adb shell dumpsys package com.yaotong.crackme
技术分享图片

 

 

 3.以调试模式启动APP,APP此时会挂住

  adb shell am start -D -n 包名/.类名

  adb shell am start -D -n com.yaotong.crackme/.MainActivity(MainActivity是application 下的第一个activity.此activity为初始启动界面)

技术分享图片

 

 

 

技术分享图片

 

 

 挂起 的程序就像上图这样。一直等待调试,

4.我们打开ida动态调试,对此app再次进行调试

打开好找到 Debugger-->Debugger options 勾选下图红色选框内容

技术分享图片

 

 

 再点击一下左上角对运行按钮技术分享图片

技术分享图片

 

 

 5.再进入设备查看进程对PId ps |grep 包名  或者frida-ps -Ua也可以

技术分享图片

 

   

6.使JDB命令使程序恢复运行

adb forward tcp:8700 jdwp:18776(APP的PID)
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

技术分享图片

 

7.so文件在被加载时。ida会停住此文件对加载,我们用control+s来一步步查看libcrackme.so文件是否被加载。并且加载对so文件需要有x权限

如果未加载。我们再点击左上角对运行按钮,来一步步对尝试,如此反复,直到出现带有x权限对libcrackme.so文件

技术分享图片

 点进去,我们得到libcrackme.so文件本次运行的基地址,我们现在需要跳转到JNIONLOAD函数里 对此函数进行调试 G ,然后和JNI_onload内存值相加

技术分享图片

 

 

 得到这样的图

技术分享图片

 

 

 

现在我们对JNI_onload进行打断点 点左上角的运行三角形,让程序进行运行。F8进行调试

(对JNI_inload进行调试是找出此段代码中检测tracepid的代码,对检测tracepid的代码进行定位,找到 pthread_create() 的位置。后修改so文件的十六进制内容,从而让此段代码不执行)

每一步的F8调试,我们都一一都找,鼠标放上去,看到里面运行的代码,找寻 pthread_create这个函数,由于这个函数是一直不停的去检测,应该是个while循环,我们可以按照里面的箭头,线路图,是否有往回走的,来判断pthread_create大致在哪里

技术分享图片

 

 如图 ,找到了 位置在BLX R7位置。现在我们到静态so文件里面 找到blx r7的执行命令

鼠标点在blx R7 在点hexview1   阴影的地方就是该函数的运行指令的16进制技术分享图片

 

 我们现在把37 FF 2E E1复制一下,用文本方式打开so文件,在里面搜索37 FF 2E E1 将搜到的37 FF 2E E1全部改为 00 00 00 00,

让指令变为空指令

改完以后报错,再重新打包,签名 安装

安装完成后,我们就可以重新对securityCheck进行动态调试了

 

继续接之前的

现在继续调试就不会报错了

我们一步步的F8向下走。看看程序执行,(在此之前在app上随便输入个密码)

我们试想这个密码肯定是错的。程序会判断密码是对是错,如果错了,肯定会走错的流程,对了肯定走对的流程,我们一步步的F8,发现

技术分享图片

 

 发现红红色圈子的箭头一直闪,正常应该走短的哪个箭头,结果却绕过短的执行了长的,我们把鼠标放在R0上

技术分享图片

 

 

 

发现寄存器里面的值正好是我们输入的1111 由此可判断这部分函数应该是判断密码和输入的是否正却,我们F5转化为伪代码进行查看

技术分享图片

 

 

 

仔细看这段代码 判断v7不等于v5 break ,v7是v6赋值的。我们把鼠标放在v6上。发现v6的值为aiyou,bucuoo 前面的unsigned __int8可以上网上查下含义,大致的意识是定义类型,

我们把得到的密码输入进入尝试,发现密码正确,完成

学自猿人学

IDA 静态调试和动态调试

原文:https://www.cnblogs.com/wuxianyu/p/14276369.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!