171226 逆向-JarvisOJ(APK_500)

本文记录了JarvisOJ-APK_500的逆向分析过程,包括解决AndroidManifest.xml解码失败的问题、动态调试反调试机制以及通过静态分析找到核心native函数并成功获取flag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1625-5 王子昂 总结《2017年12月26日》 【连续第452天总结】
A. JarvisOJ-APK_500
B.
跟之前的APK300-DebugMe如出一辙
一大堆反调试,字符串都进行了加密,通过异或动态解密来操作

DebugMe主要的坑点在于IDA把函数的返回值识别错误了,ARM并没看懂,其他还好

这个500的坑点就比较多了..
首先用Apktool和改之理都报AndroidManifest.xml解码失败,于是整个文件都反编译不出来
拖入安卓系统安装是正常的,因此可以直接解压缩出classes.dex,用dex2jar得到jar文件,然后用jd-gui之类的工具看到java

不过为了学习,还是研究了一波
直接解压出来的xml是二进制数据,不能直接查看
但是可以通过010Editor的模板来识别
首先可以发现MagicNumber错误,修改为00030800即可
解包发现还是错误,继续对比正常的xml分析
在这里https://justanapplication.wordpress.com/category/android/android-binary-xml/
有对二进制AndroidManifest.xml的格式解析
可以看到0x20处的StylePoolOffset应该为0,此处为一个巨大的值,试着将其修改
解包就正常了

(修改完了通过压缩软件添加入apk即可)

然而动态调试还是不行,估计是反调试在作祟
直接附加会显示权限不够,通过adb start时Waitting for the debugger不会消失,于是就一直卡着无法进展

继续静态分析
lib中只有libeasy.so一个库,java代码中显示核心方法为native函数:helloword
查看函数列表,没有发现相关的内容

找了一圈,最后在JNI Onload函数中发现了东西
这里写图片描述
这个熟悉的解密字符串函数没有变,还是它们
下面第二个字符串是函数类型的声明,继续往下看
这里写图片描述
调用了JNI的RegisterNatives这个方法就很明显了,在动态注册native函数
那么函数名、函数类型都有了,函数体在哪儿?
肯定就是上面那个sub_1198咯

点进去看,果然是
这里写图片描述
抛开前面的反调试不管,这里进行了一次bytes转码,连接到一个变量中
继续往下读,发现一共有4次变换

  • 第一次
    input[i] ^= i
  • 第二次
    input[i] += 1, i<4
  • 第三次
    前7个字符移到最后,其余字符顺序向前移动
  • 第四次
    异或硬编码数组

最后转16进制与一个结果字符串比较
结果字符串解出来是

ddedd4ea2e7bef168491a6cae2bc660
脚本调用bytes.fromhex的时候发现它长度不对,只有31位
转十六进制的时候是sprintf(buff, “%x”, input),注意格式化不是%02x
因此有一个0被消掉了,需要爆破

写出脚本进行逆解,还是不对
偶然看硬编码数组的时候发现有一个坑
这里写图片描述
这里进行了标识,说明有地方调用了它
查看交叉引用,发现果然有重写
这里写图片描述
写了两次,观察发现第二次和原值相同,那说明真正正确的应该是前一个值

修改硬编码脚本后即可得到flag

s = "ddedd4ea2e7bef168491a6cae2bc660"
n = []
for i in range(32):
    p = s[:i] + "0" + s[i:]
    n.append(bytes.fromhex(p))

b = [133, 139, 236, 131, 236, 20, 131, 141, 12, 1, 117, 95, 198, 69, 243, 80]
b[3] = 0x83
b[4] = 0x6c
b[5] = 0x9c
b[6] = 0x83


for a in n:
    flag = []
    flag1 = ""
    for i in range(16):
        p = a[i]^b[i]
        flag.append(bytes((p, )))
    flag = flag[-7:] + flag[:-7]
    for i in range(4):
        flag[i] = bytes((flag[i][0] - 1, ))
    for i in range(16):
        p = flag[i][0] ^ i
        if(p<=32 or p>=127):
            break
        flag1 += chr(p)
    else:
        print(flag1)

得到两个全为可见字符串的flag,很明显发现其中一个为有意义的词组,提交完成

C. 明日计划
JarvisOJ Shell

### JarvisOJ FM 功能概述 JarvisOJ 是一个在线编程练习平台,旨在帮助用户提升其逆向工程技能。其中的 FM(File Management)模块主要用于文件管理操作,涉及二进制文件分析、调试以及反汇编等内容[^1]。 FM 的核心功能包括但不限于以下几个方面: - **文件上传与解析** 用户可以通过该模块上传目标文件并对其进行初步解析,提取基本信息以便后续处理。 - **动态调试支持** 提供了一个集成环境用于运行和调试程序,允许设置断点、查看寄存器状态及内存数据等操作。 - **静态反汇编展示** 对于上传的目标可执行文件,能够生成对应的汇编代码视图,便于理解程序逻辑结构。 以下是实现简单文件读取的一个 Python 示例代码片段: ```python def read_binary_file(file_path): try: with open(file_path, 'rb') as file: content = file.read() return content except Exception as e: print(f"Error reading the binary file: {e}") ``` 此代码展示了如何打开并读取一个二进制文件的内容到内存中,这是许多基于文件的操作的第一步,在 JarvisOJ FM 中可能被用来加载待分析样本。 ### 常见问题解答 当使用 JarvisOJ FM 进行学习时可能会遇到一些典型疑问如下: #### 文件无法成功上传? 这可能是由于服务器端配置限制或者客户端网络连接不稳定引起的问题。建议检查所选文件大小是否超出规定上限,并确认当前互联网状况良好再尝试重新提交作业。 #### 调试过程中崩溃怎么办? 如果在利用内置工具对项目进行单步跟踪期间发生异常终止现象,则需仔细核查输入参数合法性;另外也要留意是否存在未初始化变量引用等情况造成非法访问错误。 #### 如何更高效地阅读大量汇编码? 除了依赖自动化插件辅助外,培养扎实的基础理论知识同样重要。平时应多加实践各类算法转换过程中的机器指令表达形式,逐渐形成快速定位关键路径的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值