攻防世界安卓逆向练习
文章目录
- 一.easy-so
- 1. jadx分析程序逻辑
- 2. ida查看so文件
- 3. 解题脚本:
- 二.ezjni
- 1. 程序逻辑分析
- 2. 解题脚本:
- 三.easyjava
- 1. 主函数逻辑
- 2. getIndex函数
- 3. getChar函数
- 4.解题脚本
- 四.APK逆向
- 1.程序逻辑分析
- 2.解题脚本
- 3.动态调试
- Android2.0
- app3
一.easy-so
1. jadx分析程序逻辑
可以看到关键在于cyberpeace.CheckString()函数
双击跟进之后可以发现是native层函数
2. ida查看so文件
程序逻辑:
1. 将字符串保存到新的空间buffer中
2. 第一个判断是将buffer的前16个字符和后16个字符进行交换
3. 第二个判断是将buffer的2个相邻的字符互换位置
_BOOL8 __fastcall Java_com_testjava_jack_pingan2_cyberpeace_CheckString(__int64 a1, __int64 a2, __int64 a3)
{const char *str; // r14size_t len; // raxint len2; // r15dunsigned __int64 v6; // r12char *newMem; // raxchar *buffer; // r13bool v9; // ccsize_t v10; // r12size_t i; // rbxchar tmp; // alchar tmp1; // alsize_t j; // rbxchar tmp2; // alstr = (*(*a1 + 1352LL))(a1, a3, 0LL);len = strlen(str);len2 = len;v6 = ((len << 32) + 0x100000000LL) >> 32;newMem = malloc(v6);buffer = newMem;v9 = v6 <= len2;v10 = v6 - len2;if ( v9 )v10 = 0LL;memset(&newMem[len2], 0, v10);memcpy(buffer, str, len2);if ( strlen(buffer) >= 2 ){i = 0LL;do{tmp = buffer[i];buffer[i] = buffer[i + 16];buffer[i++ + 16] = tmp;}while ( strlen(buffer) >> 1 > i );//32>>1 = 16 也就是说i<16时执行循环}tmp1 = *buffer;if ( *buffer ){*buffer = buffer[1];buffer[1] = tmp1;if ( strlen(buffer) >= 3 ){j = 2LL;do{tmp2 = buffer[j];buffer[j] = buffer[j + 1];buffer[j + 1] = tmp2;j += 2LL;}while ( strlen(buffer) > j );}}return strcmp(buffer, "f72c5a36569418a20907b55be5bf95ad") == 0;
}
注意,不同的so文件得到的反汇编结果不一样
一开始我使用arm64-v8a文件夹中的so文件得到的是这个结果,显然是错误的,这个循环最后会丢失一些数据
后来打开x86_64文件夹的so文件就正常了
3. 解题脚本:
#include <stdio.h>
int main()
{char flag[33] = "f72c5a36569418a20907b55be5bf95ad";char tmp;for (int i = 0; i < 32; i += 2) // 两两交换{tmp = flag[i];flag[i] = flag[i + 1];flag[i + 1] = tmp;}int i = 0;do{tmp = flag[i];flag[i] = flag[i + 16];flag[i++ + 16] = tmp;} while (i<16);printf("flag{%s}",flag);//flag{90705bb55efb59da7fc2a5636549812a}return 0;
}
二.ezjni
1. 程序逻辑分析
可以看到也是获取字符串然后加密
1. 获取字符串
2. 进行base64加密(base表有更换)
3. 调用ncheck这个native函数判断结果
base64encode函数,换表base64加密:
ncheck函数,这里应该和上一题easyso是一样的操作,只是由于反编译错误
1. 先将前16和后16个字符进行交换
2. 然后从头遍历,每两个字符一组互换位置
2. 解题脚本:
先输出ncheck处理前的base串
#include <stdio.h>
int main()
{char flag[33] = "MbT3sQgX039i3g==AQOoMQFPskB1Bsc7";char tmp;for (int i = 0; i < 32; i += 2) // 两两交换{tmp = flag[i];flag[i] = flag[i + 1];flag[i + 1] = tmp;}int i = 0;do{tmp = flag[i];flag[i] = flag[i + 16];flag[i++ + 16] = tmp;} while (i<16);printf("%s",flag);//QAoOQMPFks1BsB7cbM3TQsXg30i9g3==return 0;
}
先输出base64表
public class test1{private static final char[] table = {'i', '5', 'j', 'L', 'W', '7', 'S', '0', 'G', 'X', '6', 'u', 'f', '1', 'c', 'v', '3', 'n', 'y', '4', 'q', '8', 'e', 's', '2', 'Q', '+', 'b', 'd', 'k', 'Y', 'g', 'K', 'O', 'I', 'T', '/', 't', 'A', 'x', 'U', 'r', 'F', 'l', 'V', 'P', 'z', 'h', 'm', 'o', 'w', '9', 'B', 'H', 'C', 'M', 'D', 'p', 'E', 'a', 'J', 'R', 'Z', 'N'};public static void main(String[] args) {System.out.println("hello");String s="hellk";System.out.println(s);for (int i=0;i<table.length;i++){System.out.print(table[i]);//i5jLW7S0GX6uf1cv3ny4q8es2Q+bdkYgKOIT/tAxUrFlVPzhmow9BHCMDpEaJRZN}}
}
然后用CyberChef嗦一下
三.easyjava
1. 主函数逻辑
这题基本和安卓没什么关系,主要是分析java代码逻辑
主函数这里调用了一个check方法判断输入的flag
再看看check方法
先判断头尾flag{}格式,然后获取花括号内的字符
创建两个类用于后续的一些处理
然后使用stringBuilder和func函数创建一个新的字符串
注意func函数每次传进去的是单字符的字符串,所以每次append添加的是单个字符
func函数
用了两个函数来套娃操作
2. getIndex函数
先看看index函数(注意这里的函数名和变量名都是根据分析手动修改的)
这里的函数逻辑已经分析出来了,首先判断字符是否为字母,然后获取该字符在str中的下标
再用下标在array中查找对应位置,然后将array中的下标返回
最后使用change函数改变表(change是个循环左移一位的操作)
- array初始化
- change函数
3. getChar函数
这个逻辑就比较简单了,也是表中查值然后记录index,根据index在table表中查找字符
-
list和上一个函数有类似的操作
-
judgeCount,由于字符根本没有25那么长,这个函数纯纯干扰让人多分析一下,没什么实际作用
4.解题脚本
import java.util.ArrayList;
public class glass0{static String str = "abcdefghijklmnopqrstuvwxyz";static ArrayList<Integer> array = new ArrayList<>();static void change() {int value = array.get(0).intValue(); // 首个元素的int值array.remove(0); // 移除array.add(Integer.valueOf(value)); // 又加回去?str += "" + str.charAt(0);str = str.substring(1, 27); // 切割字符串并调整,左移一位的效果}public static void main(String[] args) {char[] flag="wigwrkaugala".toCharArray();String table = "abcdefghijklmnopqrstuvwxyz";int[] Table={7, 14, 16, 21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8};int[] intergerArr = {8, 25, 17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13};ArrayList<Integer> list = new ArrayList<>();//初始化listfor(int i=3;i<Table.length;i++){list.add(Table[i]);}for(int i=0;i<3;i++){list.add(Table[i]);}//初始化arrayfor (int i = 2; i < intergerArr.length; i++) {array.add(intergerArr[i]); // 截取num~length后半段字符串}for (int j = 0; j < 2; j++) {array.add(intergerArr[j]); // 截取0~num-1前半段字符串}//开始解密for(int i=0;i<flag.length;i++){//获取下标值int index=table.indexOf(flag[i]);//获取num值int num=list.get(index);//这个num是getIndex函数的返回值int value=array.get(num);char chr=str.charAt(value);flag[i]=chr;change();}System.out.println(flag);//venividivkcr}
}
flag{venividivkcr}
四.APK逆向
1.程序逻辑分析
对用户名和输入的SN码进行检测,用户名这里已经给出,所以查看checkSN即可
checkSN
可以看到sn码有22位,然后是对userName进行md5处理,md5之后的十六进制字符串每隔2位取一个,然后用flag{}包裹住就是需要的sn码
2.解题脚本
- 对userNamemd5
- 对md5结果每2位取一个
import hashlib
text = "Tenshine"
hash_obj = hashlib.md5()
hash_obj.update(text.encode())
encrypted_text = hash_obj.hexdigest()
for i in range(0,len(encrypted_text),2):print(encrypted_text[i],end='')
#bc72f242a6af3857
flag:bc72f242a6af3857
3.动态调试
使用jeb动态调试
下断点后运行程序输入22个字符即可成功断下并看到字符串的值
jadx也可以调试,但是感觉没有jeb那么丝滑
而且这红色的是变量值,第一眼看过去还以为是报错…
Android2.0
主要是调用了JNI.getResult这个native函数
Init的功能是将str分为三段,分别存储在三个数组中,然后就是一些异或和比较操作了
解题脚本(注意循环是0-3,不包括第五个字符)
#include<stdio.h>
int main()
{unsigned char one[5] = "LN^dl";unsigned char two[5] = " 5-0a";two[3] = 0x16;unsigned char three[5] = "AFBo}";unsigned char flag[16] = { 0 };for (int i = 0; i < 4; i++){three[i] ^= two[i];two[i] ^= one[i];one[i] = (one[i] ^ 0x80) / 2;flag[i * 3] = one[i];flag[i * 3 + 1] = two[i];flag[i * 3 + 2] = three[i];}flag[12] = one[4];flag[13] = two[4];flag[14] = three[4];printf("%s",flag);return 0;
}
flag{sosorryla}
app3
.ab文件,chatgpt是这么解释:
通常情况下,.ab后缀的文件是Android应用程序备份文件,也称为“应用程序包文件”(.apk文件)的备份文件。
当您使用Android设备上的备份和重置功能时,系统将应用程序的数据和设置打包成一个.ab文件,以便稍后可以还原到设备上。
这些备份文件可以保存在本地存储设备或云存储中,以防意外数据丢失或设备更换。
.ab有加密和未加密两种,这里未加密就显示none
下载解包工具:android-backup-extractor
注意:该工具使用需要java11及以上环境
使用命令
java -jar abe.jar unpack 399649a0e89b46309dd5ae78ff96917a.ab app3.tar
然后就会输出app3.tar压缩包,解压即可在文件夹里面找到apk文件
jadx打开分析逻辑
相关文章:

攻防世界安卓逆向练习
文章目录 一.easy-so1. jadx分析程序逻辑2. ida查看so文件3. 解题脚本: 二.ezjni1. 程序逻辑分析2. 解题脚本: 三.easyjava1. 主函数逻辑2. getIndex函数3. getChar函数4.解题脚本 四.APK逆向1.程序逻辑分析2.解题脚本3.动态调试 Android2.0app3 一.easy-so 1. jadx分析程序逻…...
自然语言处理从入门到应用——自然语言处理的语言模型(Language Model,LM)
分类目录:《自然语言处理从入门到应用》总目录 语言模型(Language Model,LM)(也称统计语言模型)是描述自然语言概率分布的模型,是一个非常基础和重要的自然语言处理任务。利用语言模型ÿ…...

【MySql】InnoDB一棵B+树可以存放多少行数据?
文章目录 背景一、怎么得到InnoDB主键索引B树的高度?二、小结三、最后回顾一道面试题总结参考资料 背景 InnoDB一棵B树可以存放多少行数据?这个问题的简单回答是:约2千万。为什么是这么多呢?因为这是可以算出来的,要搞…...

【综述】视频无监督域自适应(VUDA)的小综述
【综述】视频无监督域自适应(VUDA)的小综述 一篇小综述,大家看个乐子就好,参考文献来自于一篇综述性论文 完整PPT已经上传资源:https://download.csdn.net/download/weixin_46570668/87848901?spm1001.2014.3001.550…...

《深入理解计算机系统(CSAPP)》第9章虚拟内存 - 学习笔记
写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理…...

信息论与编码 SCUEC DDDD 期末复习
1.证明熵的可加性 2.假设一帧视频图像可以认为是由3*10的五次方个像素组成(每像素均独立变化),如果每个像素可取128个不同的等概率亮度表示。请计算出每帧图像含多少信息量?若有一口述者在约12000个汉字的字汇中选400个字来口述此…...

windows安装python开发环境
最近因工作需要,要学习一下python,所以先安装一下python的开发环境,比较简单 下载和安装Python 首先,在浏览器中打开Python的官方网站(https://www.python.org/downloads/) 然后,从该网站下载与你的操…...

java idea常用的快捷方式
文章目录 java idea常用的快捷方式快速复制选多行改变代码格式化 快速代码编辑psvmsout5.forarr.for快速死循环快速补全代码当方法还没创建的时候抽取具有一定功能的代码变成方法 java idea常用的快捷方式 快速复制 c t r l d \color{red}{ctrld} ctrld 选多行改变 A l t 鼠…...

lwIP 开发指南
目录 lwIP 初探TCP/IP 协议栈是什么TCP/IP 协议栈架构TCP/IP 协议栈的封包和拆包 lwIP 简介lwIP 源码下载lwIP 文件说明 MAC 内核简介PHY 芯片介绍YT8512C 简介LAN8720A 简介 以太网接入MCU 方案软件TCP/IP 协议栈以太网接入方案硬件TCP/IP 协议栈以太网接入方案 lwIP 无操作系…...

RabbitMQ消息属性详解
content-type属性 如同各种标准化的HTTP规范,content-type传输消息体的MIME类型。例如,如果你的应用程序正在发送JSON序列化的数据值,那么将content-type属性设置为application/json将允许尚待开发的消费者应用程序在收到消息时检查消息类型…...
shader 混合模式
在所有着色器执行完毕,所有纹理都被应用,所有像素准备被呈现到屏幕之后,使用Blend命令来操作这些像素进行混合。 3.2 blend的语法 BlendOff:关闭blend混合(默认值) BlendSrcFactor DstFactor :配置并启动混…...
【大数据工具】Hive 安装
Hive 环境搭建与基本使用 Hive 安装包下载地址:https://dlcdn.apache.org/hive/ 注:安装 Hive 前要先安装好 MySQL 1. MySQL 安装 MySQL 安装包下载地址:https://dev.mysql.com/downloads/mysql/archives/community/MySQL%20::%20Downloa…...
Android9.0 iptables用INetd实现app某个时间段禁止上网的功能实现
1.前言 在9.0的系统rom定制化开发中,在system中netd网络这块的产品需要中,会要求设置app某个时间段禁止上网的功能,liunx中iptables命令也是比较重要的,接下来就来在INetd这块实现app某个时间段禁止上网的的相关功能,就是在系统中只能允许某个app某个时间段禁止上网,就是…...

webpack.config.js基础配置(五大核心属性)
在上一节webpack零基础入门中我们在安装完webpack 和 webpack-cli依赖之后,直接通过npx webpack ./src/main.js --modedevelopment的方式对src下的js文件进行了打包。 其中的 ./src/main.js: 指定 Webpack 从 main.js 文件开始打包,不但会打包 main.js&a…...
【华为OD机试】阿里巴巴找黄金宝箱(IV)【2023 B卷|200分】
【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地, 藏宝地有编号从0-N的箱子,每个箱子上面有一个数字,箱子排列成一个环, 编号最大的箱子的下一个是编号为0的箱…...
Qt6 C++基础入门2 文件结构与信号和槽
目录 标准文件结构widget.hwidget.cppmain.cpppro 文件 信号与槽自定义信号connect 的两种方式 标准文件结构 widget.h widget 对象的头文件 一般会直接在头文件导入所有后续在 cpp 文件内用到的类,所以 include 基本都会写在这里 // 头文件标志起始 #ifndef WID…...

常用模拟低通滤波器的设计——契比雪夫II型滤波器
常用模拟低通滤波器的设计——契比雪夫II型滤波器 切比雪夫 II 型滤波器的振幅平方函数为: 式中,为有效带通截止频率, 是与通带波纹有关的参量, 大,波纹大,; 为 N 阶契比雪夫多项式。 在 Matl…...

SSM 如何使用 Redis 实现缓存?
SSM 如何使用 Redis 实现缓存? Redis 是一个高性能的非关系型数据库,它支持多种数据结构和多种操作,可以用于缓存、队列、计数器等场景。在 SSM(Spring Spring MVC MyBatis)开发中,Redis 可以用来实现数…...
uin-app如何获取微信昵称和头像的博客
在很多应用中都会使用到微信登录功能,这样可以方便用户快速地完成注册、登录等操作。本文将介绍如何通过uin-app获取微信用户的昵称和头像信息。 第一步:准备开发环境 首先,需要下载并安装QQ精简版开发工具(uin-app)…...

第六十七天学习记录:对陈正冲编著《C 语言深度解剖》中关于变量命名规则的学习
最近开始在阅读陈正冲编著的《C 语言深度解剖》,还没读到十分之一就感觉收获颇多。其中印象比较深刻的是其中的变量的命名规则。 里面提到的不允许使用拼音正是我有时候会犯的错。 因为在以往的工作中,偶尔会遇到时间紧迫的情况。 而对于新增加的变量不知…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...