草庐IT

第一次尝试反编译绕过 apk 简单的 jni 签名校验

maiiiiii 2023-03-28 原文

第一次尝试反向操作绕过 apk 简单的 jni 签名校验


1. 现象

修改了应用的内容之后,搜索 smali 没发现有做应用的签名校验,但重打包之后应用打开直接出现闪退。查看日志,确定是 jni 方法做了签名校验。

Caused by: java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad in "/data/app/pkgpath/lib/arm64/libencryption.so"

错误出现在JniUtils去 load libencryption.so 的过程中,查看 java 代码,发现这个库是用来做 aes 加密的,每一个网络请求都会用到这个方法,把签名校验放到这里的JNI_Onload可以防止直接从java层去掉LoadLibrary

打开(下载安装) IDA 看代码。

2. 定位

由于第一次下载 IDA ,最开始下的 IDA Free 不支持 arm,又重新去搞 IDA Pro。

第一次用了 ida64 去加载 armeabi-v7a 的文件,才直到需要区分64位,用不同的 exe。

终于成功加载了,直接搜索Signature,找到了一个checkSignature方法,然后在右边看不懂的界面里看到了熟悉的字符串,这个应该就是用来比较的本地签名缓存了。

因为是简单的签名校验,只要把这个值改成我们重签名之后的 MD5 值,应该就可以了。最简单粗暴的方法,直接改数据。。。

在 Hex View 中找到字符串,按 F2 编辑,可以看到直接改16进制的值,就可以生效了。把这一段替换好后,保存重打包,就可以正常运行了。

但这样改实在是太Low了,也没有学到任何知识。还是需要找到错误的出处,尝试去绕过校验,不是简单的修改签名

第一次用 IDA,边查教程边操作。先用Ctrl+F5让 IDA 反编译一个 C 的伪代码出来,IDA-View 里面全是指令,完全看不懂。

200KB 的 lib 直接导出了一个三万多行的 C 文件,看的让人头大。不过总算是能理一理逻辑了,先看出现错误的 JNI_OnLoad 方法。可以看到在判断签名非空和checkSignature的结果的地方,return -1或版本号。

定位到问题,接下来就要解决怎么改了。

3. 修改

作为只能看得懂一点点 smali 的菜鸡,对于 IDA 里面显示的内容没有一处能看得懂。

找到了对应的方法位置,要是 smali 代码,真的是随便就改掉了。这个第一次搞,完全无从下手。

迫于人菜瘾还大,不会改if(!checkSignature()),也不会直接改return 65542,最终决定从checkSignature方法的返回值下手,让他无论如何都return true就好了。依靠Copy to assembly,把反编译后的代码放到天书里面,至少让我看到了哪是哪。

可以看到这里调用了strcmp方法,比较 s1 与 s2 ,直接把这里改成 s1 比较 s1 就好了。

想法是美好的,改这个参数花了好久,最后用key-patch实现了,直接改这里的调用

修改后重新看反编译的代码,实现了绕过签名校验的功能。

4. 测试

64和32位的库都对应修改好之后,重新打包签名,运行正常。

5. 总结

比较笨方法直接改存储的签名信息,后面更多的是尝试修改 lib 库的代码。

理代码逻辑,修改内容可比绕过签名校验本身有意思多了,后面还是要多学习。

6. PS

我自己写的第一个 jni 的代码,就是从网上扒来的签名校验,实现几乎和这个一模一样,在Application:onCreate中调用 JNI 方法,然后方法内和写死的签名比较,错误的话直接killProcess。从安全性上还不如这个放在必须调用的加密库里面,我当时写的直接不去调用就可以绕过。

做这个尝试的时候好几次完全看不懂想放弃,想着直接用笨方法也能实现需求就算了。

但总想看看,如何能彻底把自己以前写过的垃圾代码干掉,就一点点的查和改。

后面可以通过这个去学习别的应用更好的签名校验做法。之前遇到过一个有意思的设计,签名校验成功之后去初始化一个静态的单例,然后在其它地方直接调用这个单例的方法。如果签名校验失败,这里的调用只会抛出空指针错误导致应用 crash,一开始不会联想到是因为重签名导致的应用错误。。。

当然一看 traces 就找到了问题,也可能只是设计的时候没考虑到这里会导致空指针,毕竟没什么人会无聊到闲着没事去重签名别人 apk。

有关第一次尝试反编译绕过 apk 简单的 jni 签名校验的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  5. ruby - rbenv 安装 ruby​​ 校验和不匹配 osx - 2

    我已经在mountainlion上成功安装了rbenv和ruby​​build。运行rbenvinstall1.9.3-p392结束于:校验和不匹配:ruby-1.9.3-p392.tar.gz(文件已损坏)预期f689a7b61379f83cbbed3c7077d83859,得到1cfc2ff433dbe80f8ff1a9dba2fd5636它正在下载的文件看起来没问题,如果我使用curl手动下载文件,我会得到同样不正确的校验和。有没有人遇到过这个?他们是如何解决的? 最佳答案 tl:博士;使用浏览器从http://ftp.rub

  6. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  7. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  8. ruby - 我怎样才能只写一次 "Text"并同时检查 path_info 是否包含 'A' ? - 2

    -if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc

  9. ruby-on-rails - CarrierWave - PDF - 只选择第一页 - 2

    我的Rails应用程序中安装了carrierwave。但是,当用户上传多页pdf时,我只希望应用程序获取文档中的第一页并将其转换为jpeg。这可能吗?用什么命令?这是我的uploader。#encoding:utf-8classImageUploader[200,300]##defscale(width,height)##dosomething#end#Createdifferentversionsofyouruploadedfiles:version:thumbdoprocess:resize_to_fill=>[150,210]process:convert=>:jpgdefful

  10. ruby - 如何跳过 CSV 文件的第一行并将第二行作为标题 - 2

    有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|

随机推荐