【Android逆向】某python环境app回编译后的This copy of software is corrupted and is not safe to use问题分析

本文主要是介绍【Android逆向】某python环境app回编译后的This copy of software is corrupted and is not safe to use问题分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前言

一、分析思路

1、谁在做校验

2、用来校验的是什么

3、发送错误信息的方式

4、修改思路

二、修改后的效果

1.pip已经能正常使用

2.个别库安装还是有些问题,个别sample脚本运行还有问题

总结



前言

前一篇博文【五一创作】【Android逆向】某python环境app的PREMIUM内容展示分析_疑燃的博客-CSDN博客讲到,界面按钮虽然修改成功了,但实际上是运行不起来的,apk做了包校验,库不能安装成功,提示This copy of software is corrupted and is not safe to use.
To fix this error, uninstall your copy and do a clean install of this app from an official source (e.g. Google Play)

最近花了一些时间分析和验证这件事,主要是寻找这个是被谁校验了,校验的什么,怎样发出的这种错误信息,以及怎样解决。


一、分析思路

1、谁在做校验

在logcat日志里搜一下这个报错信息,发现日志除了打印这个信息,前面还有pip:out:的关键字:

 在反编译的代码里面找一下这个关键字,找到对应代码位置:

 继续分析代码,发现python脚本是通过java的Runtime.getRuntime().exec来调用的:

 所以构造日志,把拼接的命令打印出来,方法是去修改smali,这个在上一篇博文提到过,这里就不再多说了:

public void m51b(String str) {ProgressBar progressBar = new ProgressBar(m14462f(), null, 16842874);progressBar.setTag("progress_bar_tag");this.f14851Z.addView(progressBar);this.f14856e0 = new StringBuilder();PowerManager.WakeLock newWakeLock = ((PowerManager) m14462f().getSystemService("power")).newWakeLock(536870918, "pip:wakelock");newWakeLock.acquire();this.f14862k0 = true;this.f14851Z.setOnTouchListener(new View.OnTouchListener() { // from class: .pipactivity.f@Override // android.view.View.OnTouchListenerpublic final boolean onTouch(View view, MotionEvent motionEvent) {return C4866r.this.m59a(view, motionEvent);}});this.f14852a0.post(new RunnableC4868b());try {Process exec = Runtime.getRuntime().exec(C4821a.m165f((Activity) m14462f()) + " sh ", (String[]) null, new File(C4821a.m149o(m14462f())));try {BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(exec.getOutputStream()));String str2 = C4821a.m152l(m14462f()) + " ; /data/user/0/XXXX/files/busybox sh /storage/emulated/0/pd_before_act/pd_before_act.sh && /data/user/0/XXXX/files/aarch64-linux-android/bin/python " + str + " ; exit\n";Log.d("===", str2);bufferedWriter.write(str2);bufferedWriter.flush();Log.d("execBench", "writed");} catch (Exception e) {this.f14857f0 = false;e.printStackTrace();}Handler handler = new Handler();new Thread(new RunnableC4869c(exec)).start();new Thread(new RunnableC4870d(exec, handler, newWakeLock)).start();new Thread(new RunnableC4872e(exec)).start();} catch (Exception e2) {e2.printStackTrace();}}

这里需要说明的是:

a.日志以===开头,是便于查找,大家也可以根据自己的喜好,使用其他的关键字;

b.修改命令拼接串,加入的 /data/user/0/XXXX/files/busybox sh /storage/emulated/0/pd_before_act/pd_before_act.sh 是为了方便调试,添加的一个外接脚本,好处是可以不重新回编译,就可以通过在脚本里面加shell命令,来达到调试的目的,只要功能一运行到这里,就会执行脚本里面的语句。

c.busybox和python路径是怎么找到的:也是通过日志插桩确定的,但如果使用的是模拟器,而且root了,就方便多了,可以看得到文件路径。

 加日志是一个好方法,工作量小,比动态调试的动静小多了,这个的效果如下,拼接的命令打印出来就很清楚了:

 

在调试中发现,其他的shell命令都能正常执行,但只要一碰到运行python,就会报错,那问题应该就出在这里,apk的作者应该是对python做了一些修改。但是改的哪里,是python主文件还是so文件,需要确定。apk自带的python3.8,依赖libpython3.8.so.1.0这个库文件,为了确定是哪个被修改了,我另外找了一个python3.8,把LD_LIBRARY_PATH改成apk的python的lib路径,运行就会报错,这就确定了是libpython3.8.so.1.0被改了。

 走到这一步,就基本已经确定了方向,为此耗费了大量的时间。

2、用来校验的是什么

这个需要从分析libpython3.8.so.1.0这个so文件入手,但这个使用IDA反编译出来,搜索不到报错信息,需要用动态调试来做了,但是这个是python的so,并不是apk的so,apk的动态调试方法可能并不适用,而且汇编,哎。。。太过枯燥,就放弃了。大家如果有兴趣,可以自行研究一下。

回到问题本身,如果没办法从代码找到证据确定校验内容,也可以猜测一下。一般这种校验会校验些什么。我能想到的最明显的一个就是签名和原来的包不一致,可能会用来做校验;另外,反编译出来之后,会和原来包里的同一文件出现不一致的情况,暂时还想不到。

3、发送错误信息的方式

确定了修改点之后,发送方式基本也就确定了,那就是so文件回复的内容。

4、修改思路

如果对so文件反编译,而且有兴趣去研究汇编和动态调试,那可以尝试修改so文件,这样的副作用是最小的,至少包的依赖不会出现问题;

另一种方法,把libpython3.8.so.1.0替换掉,可以另外找一个,甚至可以自己编译一个,但是因为不能确定apk中的so的编译参数,所以用别的so文件来替换,可能会出现一些未知的问题。我暂时先用这种方法,替换了libpython3.8.so.1.0和_posixsubprocess.cpython-38.so。对这件事,做到这一步,就可以告一段落了,再去编译一个python,再去调apk本身的功能,这明显已经超纲了,之后有时间再尝试吧。

二、修改后的效果

1.pip已经能正常使用

2.个别库安装还是有些问题,个别sample脚本运行还有问题

这些问题就没有一个一个的去试了,按照具体错误提示,分析修改就行了。


总结

花了很多时间,终于把报错的原因分析出来了,作者的校验思路和校验点真是出乎意料。虽然距离真正解决这个错误,还有一小段路要走,但对于apk的逆向来说,该做的都已经做了。在这个过程中,通过填坑,也积累了不少经验教训,这个apk在包校验上也算得上一个逆向分析教科书式的存在了。

修改后的apk暂时还没有打包上传,这个事情近期应该会完成,如果有需要,可以联系我获取。

这篇关于【Android逆向】某python环境app回编译后的This copy of software is corrupted and is not safe to use问题分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/221099

相关文章

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

element-ui下拉输入框+resetFields无法回显的问题解决

《element-ui下拉输入框+resetFields无法回显的问题解决》本文主要介绍了在使用ElementUI的下拉输入框时,点击重置按钮后输入框无法回显数据的问题,具有一定的参考价值,感兴趣的... 目录描述原因问题重现解决方案方法一方法二总结描述第一次进入页面,不做任何操作,点击重置按钮,再进行下

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题

《解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题》本文主要讲述了在使用MyBatis和MyBatis-Plus时遇到的绑定异常... 目录myBATis-plus-boot-starpythonter与mybatis-spring-b