mobile
level 4
本题考查的是RegisterNatives方法进行动态注册,将注册结果存在RegisterNatives函数中
先将apk文件加包成压缩包,再提取出里面的so文件,放进ida反编译
将目标锁定在关键信息点JNI_OnLoad 函数
然后找到unk_DFD8,里面藏有密文的数据
再返回反编译界面来看加密关系,可以看出就是个取反
直接一把逆
level 5
本题考查的是对unity游戏的安卓逆向
先将apk文件进行压缩成压缩包,然后提取出里面的assemblyCS.dll文件
将此文件放入dnSpy进行反编译
查看到里面的gamewindow函数,即可找到flag
(也可以修改里面游戏难度,直接进到最后一关拿到flag,但是在本题apk文件好像修改不了)
reverse
find_bomb
本题是扫雷题,做法多样(可以硬扫、动态调试找雷位置然后扫、找到输出flag以及动态调试跳到输出部分让他输出flag),但是由于打印flag后没有暂停,程序会直接退出,所以动调到拿flag的方法好像不是很管用。
直接对直接对puts交叉引用,找到如下函数
进到函数界面即可
rc4_sp
本题考查的是rc4加密的基本理解和掌握,主要是对rc4进行一个小小的修改
放入ida反编译
乍一看很标准的rc4,进到key那边
发现有个k3y数组索引循环+1的部分作了异或,直接在原有rc4解密上进行一个修改就可以了
key和密文都给了
flag{JusT_@_S1mpl3_RC4_w1tH_4_lITt1e_cH4nG3s}
exp
//程序开始
#include<stdio.h>
#include<string.h>
typedef unsigned longULONG;
/*初始化函数*/
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
char key1[]="iM_4_kEY";
for (i = 0; i<256; i++)
{
s[i] = i;
k[i] = key1[(i+1)%Len]^key[i%Len];
}
for (i = 0; i<256; i++)
{
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[i]和s[j]
s[j] = tmp;
}
}
/*加解密*/
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k<Len; k++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
int main()
{
unsigned char flag[]=
{
0x4A, 0x08, 0xD5, 0xF4, 0xF9, 0xD0, 0x3E, 0x1B, 0xEA, 0x46,
0xCC, 0x17, 0x35, 0x26, 0x1D, 0x7C, 0x61, 0xBB, 0xF1, 0xF6,
0x23, 0x41, 0xAB, 0x35, 0xDB, 0x0B, 0x43, 0x45, 0x8C, 0x35,
0x98, 0xC5, 0xCA, 0x59, 0xFE, 0xB1, 0xAD, 0xB5, 0x12, 0x7D,
0xDC, 0x82, 0x30, 0x02, 0x4A
};
unsigned char key[]=
"1m_@_K3y"
;
unsigned char s[256]={0};
rc4_init(s,key,8);
rc4_crypt(s,flag,46);
int i;
for(i=0;i<=44;i++){
printf("%c",flag[i]);
}
}
//程序完
base64-sp
本题考查的是对base64加密的理解和掌握
也是在原来加密基础上进行了一个小小的改动
如果直接一把梭拿到的是一个错误的flag
提示有些函数在main之前运行,对密文按x查找引用找到该函数
可以看到表和密文都进行更换了
密文是对数组进行异或,密码表则是进行加密后随机生成的新表,通过动调可直接拿,也可以写个脚本解密一下即可拿到flag
exp
对表
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i, v1;
char v0;
srand(191980);
// 打印原始的 base64 字符集
printf("Original base64 characters: %s\n", base64_chars);
// 进行乱序操作
for (i = 0; i < 64; ++i) {
v1 = rand() % 64;
v0 = base64_chars[i];
base64_chars[i] = base64_chars[v1];
base64_chars[v1] = v0;
}
// 打印乱序后的 base64 字符集
printf("Shuffled base64 characters: %s\n", base64_chars);
return 0;
}
base解密
import base64
import string
str1 = "egsieO6YnVbwLyQfnOXxJAFCJV57nVe7bBSiaCTianV~
" #待解秘字符串
string1 = " U5rcTj21azMWJ3okHXCdyYBnbeIhSLDlKiZvf8gNxP4976/Gwsp0VAmOtQ+qEFRu" #新表
string2 = " U5rcTj21azMWJ3okHXCdyYBnbeIhSLDlKiZvf8gNxP4976/Gwsp0VAmOtQ+qEFRu"
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
ezmaze
本题考查的是三维迷宫题,主要是对DFS算法的掌握
看到主函数部分
找到迷宫路线应该就能拿到flag
地图在这(10*10*10)
迷宫操作
用DFS算法脚本求解即可
exp
char maze[10][10][10]; // 这里要改成题目中的迷宫字符串。
char path[1000];
void findpath(int x, int y, int z, int len) {
if (x == 9 && y == 9 && z == 9) {
path[len] = 0;
printf("%s\n", path);
return;
}
maze[x][y][z] = 'X';
int dirs[6][3] = {
{0, 0, 1}, {0, 0, -1},
{0, 1, 0}, {0, -1, 0},
{1, 0, 0}, {-1, 0, 0}
};
for (int i = 0; i < 6; i++) {
int nx = x + dirs[i][0];
int ny = y + dirs[i][1];
int nz = z + dirs[i][2];
if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10 || nz < 0 || nz >= 10) continue;
if (maze[nx][ny][nz] == '.') {
path[len] = "FBLRUD"[i];
findpath(nx, ny, nz, len + 1);
}
}
maze[x][y][z] = '.';
}