【逆向分析】静态分析_Navtive_小计

news2024/11/19 4:40:53

静态分析so小计

源APK

https://github.com/eternalsakura/ctf_pwn/blob/master/android%E9%80%86%E5%90%91/mobicrackNDK.apk

jadx

[外链图片转存失败,源站可能有防盗在这里插入!链机制,建描述]议将图片上https://传(imbog.csdnimg.cnUOIFq178e04c873d54461beea41f2c2f80d31.png)http指向s://img-blog.csdnimg.cn/178e04c873d54461beea41f2c2f80d31.png)]
通过源码发现关键函数在

public native boolean testFlag(String str);

    static {
        System.loadLibrary("mobicrackNDK");
    }

所以要看native 也就是so的代码进行分析
在这里插入图片描述
可惜ida实在是难搞,所以浅尝下hopper,下载:https://www.hopperapp.com/download.html?
把so丢进去即可。
在这里插入图片描述
点左上角的转换
在这里插入图片描述
搜索testFlag
在这里插入图片描述
这一块地址有点奇怪,无法转化为c,但是肉眼可见的可读性还行。
双击后面的代码可以跳转到指定的基地址,估计就是函数
在这里插入图片描述
点上面的可以返回
在这里插入图片描述
因此照着这个思路可以看到主要的代码逻辑在
abcdefghijklmn
这个里面
在这里插入图片描述

直接看汇编

str        r0, [sp, #0xc8 + var_C0] (把r0的字数据转移到sp+200+var_C0这个地址上)
blx        strlen@PLT   ; strlen(blx是跳转到strlen函数地址)
movs       r4, #0x0 (赋值,r4现在的值是0)
cmp        r0, #0x10 (比较r0和16的大小,这里没太懂为啥是r0的长度)
beq        loc_102e(b是跳转,eq是=0的意思,就是以上面如果条件是等于则跳转)

loc_102e

adds       r6, r4, #0x0 (r6 = r4 + 0 = 0 + 0 = 0

然后线性往下走loc_1030

loc_1030:
ldr        r2, [sp, #0xc8 + var_C0](sp+200+var_C0这个地址上的数据读出来放到r2上,也就是上面的r0的数据,r0是长度为10的字符串,这里应该是r2现在是r0的首位)
add        r1, sp, #0x14(r1 = sp + 20)
ldrb       r3, [r2, r6] (将地址为r2+r6的数据读出来放到r3上,由于r6后面在+1所以r3就是r2的每一位,也就是input[i])
subs       r3, r3, r6 (r3 = r3 - r6)(那就是input[i] = input[i]-i)
strb       r3, [r6, r1] (将r3的数据转移到r6+r1的地址上,首先我们看r1是不变的,r6在递增,所以也就是input[i]-i会逐位的放到r3上)
adds       r6, #0x1 (r6 = r6 + 1)
cmp        r6, #0x8 (r6 和 8 的数据进行比较)
bne        loc_1030 (b是跳转,ne是不等于0时跳转,这里我们注意到loc_1030依旧是这个代码块逻辑,所以这是一个循环)

也就是

for (int i = 0; i < 8; i++)
{
	r3[i] = input[i] - i;
}

当跳出循环之后再线性往下走就行

ldr        r3, =0x2f3e  ; 0x113c (伪指令,相当于mov r3,0x2f3e)
movs       r4, #0x0 (这里r4 = 0 )
strb       r4, [r1, #0x8] (把r4的数据放到r1+8上面)
add        r3, pc       ; dword_3f88 (r3 = r3 + pc)
ldr        r3, [r3]     ; dword_3f88,seed (r3 = 读r3这个地址上的值)
ldr        r0, [r3]     ; argument "__s1" for method strcmp@PLT, "QflMn`fH",seed (r0 = 读r3这个地址上的值)
blx        strcmp@PLT   ; strcmp (strcmp)
cmp        r0, r4 (比较r0 = r4的值,这里注意r3是上一个循环处理过的字符串,r0是seed)
bne        loc_111e(如果不等于0 则跳转loc_111e,相等则往下线性走)

看上去是找java层的Calc

ldr        r0, [r5]
ldr        r1, =0x1756  ; 0x1140,0x1756
ldr        r3, [r0]
add        r1, pc       ; "com/example/mobicrackndk/Calc"
ldr        r3, [r3, #0x18]
blx        r3
str        r0, [sp, #0xc8 + var_C4]
cmp        r0, r4
bne        loc_1070
package com.example.mobicrackndk;
/* loaded from: classes.dex */
public class Calc {
    public static String key;

    public static void calcKey() {
        StringBuffer sb = new StringBuffer("c7^WVHZ,");
        key = sb.reverse().toString();
    }
}

找到了calcKey这个函数

loc_1070:
ldr        r0, [r5]     ; CODE XREF=abcdefghijklmn+128
ldr        r2, =0x1763  ; 0x114c,0x1763
ldr        r3, =0x1767  ; 0x1150,0x1767
ldr        r4, [r0]
movs       r1, #0xe2
lsls       r1, r1, #0x1
add        r2, pc       ; "calcKey"
ldr        r4, [r4, r1]
add        r3, pc       ; "()V"
ldr        r1, [sp, #0xc8 + var_C4]
blx        r4
subs       r2, r0, #0x0
bne        loc_109e

取calcKey这个函数的methodid,定位到key

loc_109e:
ldr        r0, [r5]     ; argument #1 for method _ZN7_JNIEnv20CallStaticVoidMethodEP7_jclassP10_jmethodIDz, CODE XREF=abcdefghijklmn+164
ldr        r1, [sp, #0xc8 + var_C4] ; argument #2 for method _ZN7_JNIEnv20CallStaticVoidMethodEP7_jclassP10_jmethodIDz
bl         _ZN7_JNIEnv20CallStaticVoidMethodEP7_jclassP10_jmethodIDz ; _JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)
ldr        r0, [r7]
ldr        r2, =0x1747  ; 0x115c,0x1747
ldr        r3, =0x1749  ; 0x1160,0x1749
movs       r1, #0x90
lsls       r1, r1, #0x2
ldr        r4, [r0, r1]
add        r2, pc       ; "key"
add        r3, pc       ; "Ljava/lang/String;"
adds       r0, r7, #0x0
ldr        r1, [sp, #0xc8 + var_C4]
blx        r4
subs       r4, r0, #0x0
bne        loc_10ce
loc_10ce:
ldr        r2, [r7]     ; CODE XREF=abcdefghijklmn+218
movs       r3, #0x91
lsls       r3, r3, #0x2
ldr        r3, [r2, r3]
ldr        r1, [sp, #0xc8 + var_C4]
adds       r2, r4, #0x0
adds       r0, r7, #0x0
blx        r3
adds       r1, r0, #0x0
ldr        r0, [r5]
movs       r2, #0xa9
lsls       r2, r2, #0x2
ldr        r3, [r0]
add        r4, sp, #0x20
ldr        r3, [r3, r2]
movs       r2, #0x0
blx        r3
adds       r5, r0, #0x0
b          loc_1102

注意这块的位置loc_1102 -> loc_10f4 往下走又是loc_1102


             loc_10f4:
000010f4         ldr        r1, [sp, #0xc8 + var_C0]  (r1现在又是我们输入的字符串的首位)                          ; CODE XREF=abcdefghijklmn+296
000010f6         adds       r3, r4, r6 ( r3 = r4 + r6 由于r6上面到8 所以是从8 开始) 
000010f8         subs       r3, #0x8 (r3 = r3 - 8)
000010fa         ldrb       r2, [r1, r6] (r1 + r6 的值也就是input[i] 给 r2)
000010fc         subs       r2, r2, r6 (r2 = r2-r6 也就是input[i] - i)
000010fe         strb       r2, [r3] 将r2的值存到r3
00001100         adds       r6, #0x1 (r6 = r6 + 1 )

             loc_1102:
00001102         adds       r0, r5, #0x0  这里r0 = r5 +0                                       ; argument "__s" for method strlen@PLT, CODE XREF=abcdefghijklmn+270
00001104         blx        strlen@PLT                                          ; strlen
00001108         adds       r0, #0x8 (这里r0 = len(r0) + 8)
0000110a         cmp        r6, r0  
0000110c         blo        loc_10f4 (如果r6< len(r0) + 8 则跳转到loc_10f4,这里的r0应该就是上面calc函数返回的key的值)

所以这里转换出来就是

for (int i = 8; i < 16; i++)
{
	s3[i - 8] = input[i] - i;
}

所以输入
所以输入就可以变成

input_str = "QflMn`fH,ZHVW^7c"
output_str = ""
num = 0
for i in input_str:
    output_str += i + num
    num += 1

然后就是init初始话的时候对seed进行了操作
在这里插入图片描述

             loc_117e:
0000117e         ldrb       r3, [r4, r7]                (seed从第0位开始)                        ; CODE XREF=__init_my+36
00001180         subs       r3, #0x3 (绕r3 = r3 -3 = seed[i] - 3)
00001182         strb       r3, [r6, r7] 把r3存起来
00001184         adds       r7, #0x1 (+1递增)

             loc_1186:
00001186         ldr        r4, [r5]        (r4就是seed)                                    ; CODE XREF=__init_my+16
00001188         adds       r0, r4, #0x0                                        ; argument "__s" for method strlen@PLT
0000118a         blx        strlen@PLT                                          ; strlen
0000118e         cmp        r7, r0 ( r7从0开始)
00001190         blo        loc_117e

seed先做一层-3处理,所以前8位再-3即可,然后适配下python脚本

input_str = "QflMn`fH,ZHVW^7c"
output_str = ""
num = 0
for i in input_str:
    if num < 8:
        output_str += chr(ord(i) + num - 3)
    else:
        output_str += chr(ord(i) + num)
    num += 1

print(output_str)

后话

静态分析native原生程序,初步了解汇编,后续还需要多读代码。印象比较深刻的有如下:

  • ldr是读
  • strb是存
  • mov是赋值
  • 循环大概是什么样子

参考链接

https://ctf-wiki.org/android/basic_reverse/static/so-example/
https://github.com/wnagzihxa1n/CTF-Mobile-Tutorial/blob/master/2015%E6%B5%B7%E5%B3%A1%E4%B8%A4%E5%B2%B8CTF/%E4%B8%80%E4%B8%AAAPK%EF%BC%8C%E9%80%86%E5%90%91%E8%AF%95%E8%AF%95%E5%90%A7ndk/WriteUp.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/191786.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】入门(上)

本期博客给大家带来的全是干货&#xff0c;慢慢享用吧~C入门主要是一些对C语言不足的语法补充&#xff0c;废话不多说直接上干货&#xff1a;一、C的输出和输入1.1 输出在C上我们要想在屏幕&#xff08;控制台&#xff09;上进行一些内容的输出可以使用关键字&#xff1a;cout具…

MoCo解读

MoCo方法由何凯明团队提出&#xff0c;是无监督对比学习的代表作。经过MoCo预训练的视觉表征迁移到各种下游任务时&#xff0c;其效果超过了有监督预训练模型。 两点创新 对比学习的思想是将相似的样本距离拉近&#xff0c;不相似的样本距离拉远。对比学习主要在两方面进行设计…

JavaEE13-MyBatis查询数据库

前言&#xff1a;前面已经学习了Spring,Spring Boot,Spring MVC这3个框架&#xff0c;接下来学习第4个框架MyBatis(国内)&#xff1a;将前端传递的数据存储起来(前身IBatis)或者查询数据库里面的数据。PS&#xff1a;不同版本号区别3.5.1 -> 3.5的第一个版本3.5.10 -> 3.…

命令执行利用

数据来源 01 命令执行漏洞 命令执行漏洞- 例子1&#xff08;无防御&#xff09; 示例&#xff1a;&#xff08;我这里使用dvwa靶场做演示&#xff09; 解决靶场响应结果的中文乱码 charsetutf-8&#xff0c;修改为charsetgb2312 把安全等级调到&#xff1a;low&#xff0…

concat函数在mySQL和Oracle中的不同

在mysql中的使用1>.在该函数中传入两个值&#xff1a;22和33,得到结果为两个值的拼接效果如图所示2>.在该函数中传入两个及以上的值&#xff1a;22和33和44,得到结果为多个值的拼接效果如图所示3>.在该函数中传入两个及以上的值&#xff1a;null和22和33&#xff0c;得…

GitHub 上有哪些优秀的项目?

前言 各个领域模块的都整理了一下&#xff0c;包含游戏、一些沙雕的工具、实用正经的工具以及一些相关的电商项目&#xff0c;希望他们可以给你学习的路上增加几分的乐趣&#xff0c;我们直接进入正题~ 游戏 1.吃豆人 一款经典的游戏开发案例&#xff0c;包括地图绘制、玩家控…

车载网络 - BootLoader - CAN/CANFD刷写过程

话接上回,我们继续分享刷写流程。 刷写Boot到RAM(如果ECU中有独立的boot代码,无需执行此段) 9、获取单次刷写的最大长度(参考https://mp.csdn.net/mp_blog/creation/editor/127720716) Request:34 00 44 + 地址 + 长度 Response:74 00 44 + Maxlength 10、进行刷写传…

Netty之DefaultAttributeMap与AttributeKey的机制和原理

为什么要分析DefaultAttributeMap和AttributeKey呢&#xff1f;我自己对Netty也是一个不断的学习过程&#xff0c;从前面几篇Netty分析的博客中&#xff0c;可以看出&#xff0c;Netty是比较博大精深的&#xff0c;很像java.util.concurrent.*包中的源码&#xff0c;如果只是看…

【微电网】微电网的分布式电源优化配置研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

企业工程管理系统源码-专注项目数字化管理

高效的工程项目管理软件不仅能够提高效率还应可以帮你节省成本提升利润 在工程行业中&#xff0c;管理不畅以及不良的项目执行&#xff0c;往往会导致项目延期、成本上升、回款拖后&#xff0c;最终导致项目整体盈利下降。企企管理云业财一体化的项目管理系统&#xff0c;确保项…

关于卷积过程中通道数如何变化问题

以RGB图像为例。 一个12*12的像素图&#xff0c;对其进行5*5的卷积&#xff0c;最后得到一个8*8【计算过程&#xff1a;(12-5)/118】的像素图。 RGB图像有3个通道&#xff08;12*12*3&#xff09;&#xff0c;所以卷积核也要有3个通道&#xff08;5*5*3&#xff09;&am…

第一章 隐私计算科普与解读

前言 提醒&#xff1a;全文10千字&#xff0c;预计阅读时长15分钟&#xff1b;读者&#xff1a;对隐私计算感兴趣的小伙伴&#xff1b;目的&#xff1a;读者利用15~30 分钟对本文沉浸式阅读理解&#xff0c;能够掌握隐私计算 80% 的概念&#xff1b;关键词 &#xff1a;隐私计算…

好用的搜索工具listary

发现一个好工具记录一下。以后好好用起来。 这个工具我安装后&#xff0c;跟着引导教程&#xff0c;学做了一些操作立马就爱上了。 Listary&#xff1a;大幅度提高本地文件浏览与搜索速度效率的「超级神器」 百度安全验证https://baijiahao.baidu.com/s?id17127561426219890…

【Python】基于you-get下载网页视频

文章目录1 前言2 you-get2.1 安装2.2 简单使用2.3 扩展3 下载网页视频3.1 概述3.2 下载网页4 代码1 前言 过年了&#xff0c;想给家里长辈下几首戏曲&#xff0c;于是找到一个发布戏曲的网站&#xff0c;虽然可以通过IDM插件的资源嗅探来一一下载&#xff0c;但是内容太多&…

【JavaScript】数据劫持详解

&#x1f4bb; 【JavaScript】数据劫持 &#x1f3e0;专栏&#xff1a;JavaScript &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向&#xff1a;目前主攻前端&#…

这就是传说中超难的N皇后?——详细图解!

✔️本文主题&#xff1a;回溯算法之N皇后 算法 ✔️题目链接&#xff1a;N皇后 详解N皇后一、前言二、题目信息三、解题思路四、参考代码五、结语一、前言 大家好久不见&#xff0c;今天我们一起来学习一道很经典、也很有难度的一道题目——N皇后 二、题目信息 按照国际象棋…

Spring-基础知识二

Spring9.Spring JdbcTemplate的使用9.1 JdbcTemplate入门9.1.1 需要的包9.1.2 代码测试9.2 将数据源和jdbcTemplate交给Spring来管理9.2.1 druid连接池9.2.2 使用外部文件配置数据连接信息9.3 基于JdbcTemplate实现DAO9.Spring的事务管理机制9.1 PlatformTransactionManager 事…

第十章 面向对象编程(高级)

一、类变量和类方法&#xff08;P374&#xff09; 1. 类变量 定义语法&#xff1a; 访问修饰符 static 数据类型 变量名&#xff1b; 类变量也叫静态变量/静态属性&#xff0c;是该类的所有对象共享的变量&#xff0c;任何一个该类的对象去访问它时&…

微服务 热点流控 规则-授权 系统规则 自定义返回

微服务 热点流控 规则-授权 系统规则 自定义返回Sentinel-热点流控操作示例Sentinel规则-授权操作示例Sentinel规则-系统规则Sentinel自定义异常返回Sentinel-热点流控 拿商品举例&#xff0c;当一个商品的查询请求量异常火爆的时候&#xff0c;应该对该商品的查询请求进行限流…

FineReport使用

目录报表命名规范数据集命名规则参数命名规则条件属性命名规则超链接命名规范决策报表组件命名规则普通报表悬浮元素命名规则用户权限模版版本管理FineDB内置数据库外置数据库配置外接数据库新建数据库外接数据库配置入口配置外接数据库数据表权限控制&#xff1a;用户-部门职位…