猿人学app内部第二题-app逆向-so初体验

声明:本文只作学习研究,禁止用于非法用途,否则后果自负。如果侵权到了您的权益,请立即联系我删除!


前言

案例为猿人学学员app第二题,主要学习各种逆向方法,最终目标脱机执行


一、准备

环境准备

  • frida 12.11.18
  • frida-tools 8.2.0
  • pixel 1 手机
  • ida 7.5
  • jadx
  • python 3.8.10
  • c++ 14
  • 010Editor

二、java

直接抓包,无抓包检测,charles设置wifi代理即可

在这里插入图片描述

只有一个data参数
使用jadx 打开apk,全局搜索url特征,/api/app2找到唯一一段可疑的代码

在这里插入图片描述
在这里插入图片描述
右键OooOOo查找用例,发现2处,一处为第一页的加载,另外就是其他页码的加载

在这里插入图片描述
分析出,f8535OooO0o0为页码,currentTimeMillis为13位时间戳,通过拼接,传入1NativeLib.encrypt1方法,并将结果转化base64 既是请求参数的data
使用frida hook NativeLib.encrypt验证分析

function hook_java() {
    Java.perform(function () {
        var nav = Java.use('com.yuanrenxue.challenge.two.NativeLib')
        nav.encrypt.implementation = function (v, j) {
            console.log("byte:", JSON.stringify(v))
            console.log("str:", j)
            var es = this.encrypt(v, j)
            console.log("加密返回:", JSON.stringify(es))
            return es
        }

    })
}
function main() {
    hook_java()
}

setImmediate(main)

frida -U com.yuanrenxue.challenge -l t2.js 注入app,
手动进入第二题,触发hook,入参为第一个是拼接而来转字节的1:1693660604784,第二个是时间戳,返回的结果通过base64 对的上抓包的结果

在这里插入图片描述
接下来找NativeLib.encrypt方法,发现是调用libtwo.so里面的方法

在这里插入图片描述

三、so

使用apktool 解压apk,在lib文件夹中,找到libtwo.so文件,然后使用ida打开,搜索encrypt 关键字,只有一个结果,按f5 解析为伪代码,方便分析

在这里插入图片描述
方法前2个参数为ida给的,后面a3,a4是我们传入的参数,选中按y把a1的类型改为JNIEnv*,把所有用到a1的函数,进入函数更改其类型为JNIEnv*,方便分析
进入函数sub_1c74,只有一个GetByteArrayElements,获取第一个参数的信息,不是加密的算法
在这里插入图片描述
进入函数sub_1CB0,只有一个GetArrayLength,提取长度,不是加密的算法

在这里插入图片描述
malloc 是开辟寄存器空间的方法,不用看
进入函数sub_C70,凭感觉是很有可能的,继续看最后2个函数
在这里插入图片描述
sub_1CE4 新建一个字节数组
sub_1D18 把v7的赋值给新建的数组,流程就比较明朗了,v7通过sub_C70执行之后,是最后加密完毕的值
在这里插入图片描述

在这里插入图片描述

使用frida hook 验证一下分析结果

function hook_so() {
    Java.perform(function () {
        // var twoadd = Module.getExportByName('libtwo.so', "malloc") // 拿到地址,名字要重新搜索进入汇编解密拿取名字
        var libtwoadd = Module.findBaseAddress("libtwo.so")
        Interceptor.attach(libtwoadd.add(0xc70), { // hook 地址
            onEnter: function (args) {  // 进入时  hook
                this.args0 = args[0]
                this.args1 = args[1]
                this.args2 = args[2]
                this.args3 = args[3]
                console.log("args1:", ptr(args[0]).readCString()) //1:1693456457984
                console.log("args2:", args[1]) //
                console.log("args3:", args[2]) // 47  长度
                console.log("args4:", args[3]) // 1693456457984
            },
            onLeave: function (retval) { // 返回时  可以修改返回值
                console.log(hexdump(this.args1))
                return retval
            }
        })
    })
}

在这里插入图片描述
结果证明分析是正确的,sub_c70,传入4个参数

  • 页码和时间戳的拼接
  • 开辟的空间指针地址
  • 第一个参数的长度
  • 时间戳

最后的结果 将16进制数据转10进制,会发现是对应上的,会有负数是因为使用的js 的JSON.stringify转化打印的结果

四、ida-trace

由于基础太差了,就算f5了很清晰,看的懂一点了,但是还是还原不了,所以就使用了ida trace的方法来还原

将ida dbgsrv文件夹中的,android_server文件 (64就是android_server64) 传入设备,然后开启端口,巴拉巴拉的操作

adb forward tcp:11678 tcp:11678
然后 adb shell  su模式  启动端口
chmod 777 android_server64
./android_server64 -p11678
frida 启动app  
新开一个ida
ida --- debugger --- attach --- android debugger --- 设置刚刚的端口 11678  第一次保存打勾,然后等待加载 搜索需要trace 的包名,
file --- script file  导入trace脚本  (根据要hook的so文件,和函数地址 填入相关的信息, 脚本自动设置断点)
trace脚本是抄其他大佬的,这里就不方便贴了

然后可能会出现一些问题,提示这个,我是随便点的,有概率进入debug,也不知道怎么回事

在这里插入图片描述
导入trace脚本之后,先挂起其他线程,然后设置

stop_thread()   // 挂起其他的线程  trace脚本的方法  用来处理上面的弹框
start_hook()		//trace脚本的方法

关掉hook 的自动注入  // 就是frida hook 文件里的setImmediate(main) 这一句
start_thread()  //  恢复执行线程  然后frida 主动调用 sub_c70方法

function call_c70() {
    var jidizhi = Module.findBaseAddress("libtwo.so")
    if (jidizhi) {
        var addr_c70 = jidizhi.add(0xc70)
        var func_c70 = new NativeFunction(addr_c70, "void", ["pointer", "pointer", "int", "long"])
        var time_page = Memory.allocUtf8String("1:1693650922914")
        var a2 = Memory.alloc(47)
        console.log(a2)
        var size = 47
        func_c70(time_page, a2, size, 1693650922914)
        console.log(hexdump(a2, {length: 47}))
    }
}

ida 进行下一个断点,一直到trace脚本设置的断点中,即 sub_c70的开始和结束的地址(c70,1130),可通过ida 查看到,然后加上基地址就是设置断点的地址
在这里插入图片描述
在这里插入图片描述
断点在函数开始断住之后, 设置ida
debugger --- tracing --- tracing options 根据 下图做完之后
debugger --- tracing --- insturction tracing

在这里插入图片描述
设置完毕解开断点,执行过trace的代码背景就会变成黄色,一直等待到断点断在函数结束的位置,即可关闭ida

五、算法还原

使用010Editor 打开trace日志文件,长这样,大概9w+行

在这里插入图片描述
画起来的是我写的注释,第一行对应x0,x1,x2,x3就是对应的传入参数的地址,已知第二个参数就是加密结果的地址,直接找00000071AD1FC280 对应的操作

在这里插入图片描述最前面的操作感觉是不太可能,直接看最后面的操作,也就是libtwo.so:sub_71ABA5CC70+460这里

在这里插入图片描述
发现下一个操作就是赋值操作,翻译理解一下就是STRB是汇编操作中一个赋值的操作码,
W9, [X10,X11] 就是将w9 赋值给 x10x11,代码表示就大约是

x10[x11] = w9

也就是0x7c赋值过去了,搜索该地址的所有操作,也就是w9的结果那一个地址 libtwo.so:sub_71ABA5CC70+45C
在这里插入图片描述

frida 主动调用该函数,验证一下,是不是这样的结果,固定好时间戳,发现是最后的15位的结果,先把这15位的结果尝试还原
在这里插入图片描述

那么我们的思路就是一个一个往上找,直到赋值的变量是我们传入的参数或者为固定值
所以,上图的w9的来源翻译过来就是

w9 = w9 ^ w10

常见的操作码如下

  • STRB 赋值
  • ADD &
  • AND +
  • LDRB 拿取 例:x10[x10]
  • MOV =
  • EOR ^
  • SUBS -
  • CSEL 三目表达式

大概是这些了,ok,你已经获取了分析trace文件的的大部分知识,只需要一点点时间,可以分析出,这一块的内容为
在这里插入图片描述
发现第一行的w91libtwo.so:sub_71ABA5CC70+428的w9的值是直接拿出来的 没有实际计算出来,那么就需要去找对应的地址也就是00000071A948B040的地方,看看有那些赋值操作给到了它

然后就是搞了俩三天,才把所有的逻辑追到了入参的地方,至此,分析完毕

接下来就是使用c来还原这些操作,为什么用c呢,因为不同语言的一些计算的差别,懒的去弄了,索性就用c来写,写完就是这样
在这里插入图片描述
然后直接打包,给python调用,开始请求
在这里插入图片描述
ok,莫得问题,下机


总结

学习了frida的各种api的使用,ida的操作,trace的操作,以及一定的trace文件分析能力

对于您提到的错误TypeError: list indices must be integers or slices, not str,这是因为您在访问列表中的元素时使用了字符串作为索引,而列表的索引必须是整数或切片类型。解决这个错误的方法是使用整数或切片来访问列表中的元素。 关于您提到的猿人js逆向的问,我需要更多的信息才能为您提供具体的答案。对于爬虫编写,您可以使用Python的各种库(如Requests、BeautifulSoup、Scrapy等)来获取网页的内容,并进一步解析和处理。您可以使用这些库发送HTTP请求获取网页内容,然后使用解析库来提取您需要的数据。 爬虫编写的一般步骤如下: 1. 导入所需的库 2. 发送HTTP请求获取网页内容 3. 使用解析库解析网页内容 4. 提取所需的数据 5. 进行数据的进一步处理和存储 您可以根据具体的需求和网站的结构进行相应的编写和调试。如果您需要更具体的帮助,请提供更多的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Python:TypeError: list indices must be integers or slices, not str报错解决及原理](https://blog.csdn.net/hhd1988/article/details/128031602)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Python BeautifulSoup [解决方法] TypeError: list indices must be integers or slices, not str](https://download.csdn.net/download/weixin_38590567/14871394)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值