攻防世界安卓逆向练习
文章目录
- 一.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 语言深度解剖》,还没读到十分之一就感觉收获颇多。其中印象比较深刻的是其中的变量的命名规则。 里面提到的不允许使用拼音正是我有时候会犯的错。 因为在以往的工作中,偶尔会遇到时间紧迫的情况。 而对于新增加的变量不知…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
