52pj2025春节红包解题-安卓中级

news/2025/2/23 10:35:04/文章来源:https://www.cnblogs.com/WXjzc/p/18715432

先找到判断方法,显然是一个native

ida加载so,导出表中没有这个函数,所以是动态注册的,找到jni_onload

找到函数地址

修改3个参数的类型,便于分析

总得来看,最终要执行的不是a就是ao了

bool __fastcall sub_BE440(JNIEnv *env, jobject object, jstring inputKey)
{int v5; // r4const char *key; // r0const char *v7; // r9int v8; // r4int v9; // r6int v10; // r1unsigned int v11; // r6char *v12; // r4_BOOL4 v13; // r8int v14; // r0void (__fastcall *v15)(_BYTE *, const char *, int, void *); // r8void *v16; // r5int v17; // r4const std::nothrow_t *v18; // r1unsigned __int64 v20; // [sp+0h] [bp-58h]_BYTE v21[16]; // [sp+18h] [bp-40h] BYREF_QWORD v22[2]; // [sp+28h] [bp-30h] BYREFv5 = 0;key = (*env)->GetStringUTFChars(env, inputKey, 0);if ( key ){v7 = key;HIDWORD(v20) = inputKey;v8 = A();v9 = CNJAK();if ( !byte_134E49 ){afdm::decrypt_buffer((afdm *)byte_134D7E, &byte_4, 0xA8FC3415, v20);byte_134E49 = 1;}v10 = -1;if ( v8 )v10 = 1;v11 = v9 + v10;v12 = getenv(byte_134D7E);                  // 反调?v13 = v12 == 0 || v11 < 3;v14 = jgbjkb();                             // 反调?if ( v11 <= 2 && v12 ){v13 = 1;dword_134D90 = -559038669;}v22[0] = *(_QWORD *)&off_12FCE8;            // 下面的v15是为了获得一个函数,不是a就是aov22[1] = *(_QWORD *)&off_12FCF0;v15 = (void (__fastcall *)(_BYTE *, const char *, int, void *))nullsub_9(*(_DWORD *)((unsigned int)v22 | (4 * ((v14 | v13) ^ (unsigned int)sub_BE6CC & 1 ^ (((unsigned int)ao ^ (unsigned int)a) >> 24) & 1))));dword_134D90 = -559038669;memset(v21, 0, sizeof(v21));v16 = (void *)operator new[](0x13u);v15(v21, v7, 19, v16);                      // v15是一个函数,这边v7就是输入的keyv17 = memcmp(v16, &unk_3A0FC, 0x13u);       // 比较结果operator delete[](v16, v18);(*env)->ReleaseStringUTFChars(env, (jstring)HIDWORD(v20), v7);return v17 == 0;}return v5;
}

aao的差异很小,但总归是要执行其中的一个的,所以反调可以直接忽略掉,两个函数都看一下

改一下参数的类型,发现这两个函数唯一的差别就是ao没有去动态修改sub_BED58生成的值,因此解密函数应该是a

int __fastcall a(_BYTE *a1, char *key, int a3, void *a4)
{__int64 v5; // d17int i; // r6int v9; // r5char v10; // r0_QWORD v12[2]; // [sp+0h] [bp-30h] BYREFint v13; // [sp+14h] [bp-1Ch]v5 = *((_QWORD *)a1 + 1);v12[0] = *(_QWORD *)a1;v12[1] = v5;if ( a3 )                                     // a3=19{for ( i = 0; i != a3; ++i ){v9 = i & 0xF;if ( (i & 0xF) == 0 )sub_BED58((unsigned __int8 *)v12);      // 初始化v12的值,需要注意v12的长度是16,但一共有19次循环,第17次时这个函数又会被调用一次v10 = key[i] ^ *((_BYTE *)v12 + v9);      // 异或*((_BYTE *)a4 + i) = v10;*((_BYTE *)v12 + v9) = v10;}}return v13;
}
int __fastcall ao(_BYTE *a1, char *key, int a3, void *a4)
{__int64 v5; // d17int i; // r4_QWORD v10[2]; // [sp+0h] [bp-30h] BYREFint v11; // [sp+14h] [bp-1Ch]v5 = *((_QWORD *)a1 + 1);v10[0] = *(_QWORD *)a1;v10[1] = v5;if ( a3 ){for ( i = 0; i != a3; ++i ){if ( (i & 0xF) == 0 )sub_BED58((unsigned __int8 *)v10);*((_BYTE *)a4 + i) = key[i] ^ *((_BYTE *)v10 + (i & 0xF));}}return v11;
}

最后比较结果,比较的值是0x48,0x27,0x8f,0xaf,0x9b,0xf8,0xec,0x72,0x98,0x07,0x72,0x0c,0x6b,0xe2,0x3a,0xb6,0x42,0x59,0xf7

最后根据手机的实际情况选择对应架构的so进行hook或者调试,分析时用的是armeabi-v7a,我的手机是arm64,应该用arm64-v8a(重打包apk,把其他架构的删掉也可以)

Java.perform(function(){var soAddr = Process.getModuleByName("libwuaipojie2025_game.so");var func_addr = soAddr.base.add(0xE9954);Interceptor.attach(func_addr, {onEnter: function(args){console.log("hook到函数");},onLeave: function(retval){console.log(retval.readByteArray(16));}});
});

得到该函数两次执行的结果,第二次是要依据第一次的输入来做的,所以要先解一下前16位

0x2e,0x4b,0xee,0xc8,0xe0,0x95,0x88,0x47,0xb0,0x72,0x1b,0x68,0x40,0xd0,0x0a,0x84

target = [0x48,0x27,0x8f,0xaf,0x9b,0xf8,0xec,0x72,0x98,0x07,0x72,0x0c,0x6b,0xe2,0x3a,0xb6,0x42,0x59,0xf7]
result = [0x2e,0x4b,0xee,0xc8,0xe0,0x95,0x88,0x47,0xb0,0x72,0x1b,0x68,0x40,0xd0,0x0a,0x84]for i in range(0,len(result)):print(chr(target[i]^result[i]),end='')
#flag{md5(uid+202

再次输入密钥时输入flag{md5(uid+202(发现反调试时需要getenv返回非0,hook了一下),得到后3位0x77,0x70,0x8a

Java.perform(function(){var soAddr = Process.getModuleByName("libwuaipojie2025_game.so");var jgbjkb_addr = Module.findExportByName("libwuaipojie2025_game.so","_Z6jgbjkbv");Interceptor.attach(jgbjkb_addr, {onEnter: function(args){console.log("hook到jgbjkb");},onLeave: function(retval){console.log("jgbjkb返回值为"+retval);}});    var getenv_addr = Module.findExportByName("libc.so","getenv");Interceptor.attach(getenv_addr, {onEnter: function(args){console.log("hook到getenv");},onLeave: function(retval){console.log("修改getenv返回值为1");retval.replace(1);}});    var func_addr = soAddr.base.add(0xE9954);Interceptor.attach(func_addr, {onEnter: function(args){console.log("hook到函数");},onLeave: function(retval){console.log(retval.readByteArray(16));}});
});

target = [0x48,0x27,0x8f,0xaf,0x9b,0xf8,0xec,0x72,0x98,0x07,0x72,0x0c,0x6b,0xe2,0x3a,0xb6,0x42,0x59,0xf7]
result = [0x2e,0x4b,0xee,0xc8,0xe0,0x95,0x88,0x47,0xb0,0x72,0x1b,0x68,0x40,0xd0,0x0a,0x84,0x77,0x70,0x8a]for i in range(0,len(result)):print(chr(target[i]^result[i]),end='')
#flag{md5(uid+2025)}

得到flagflag{md5(uid+2025)}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

留言版

<link rel="stylesheet" href="https://blog-static.cnblogs.com/files/elkyo/OwO.min.css" /><script src="https://blog-static.cnblogs.com/files/elkyo/OwO.min.js"></script><script>/*文章评论*/var le = $("…

ToDesk远程打印详细设置步骤教学

很多小伙伴常有打印、远程打印的需求,特别是对于电商人、跨境电商、教师、产品经理、实验人员等群体来说掌握这项技能可谓是能够在很多场景下带来便捷,大幅提升做事效率!那么是否有方法可以随时随地实现这样需求呐? 答案是肯定的,通过ToDesk远程控制软件即可轻松设置成功~…

SaaS 已死:微软 CEO 如何看待商业软件的未来

(作者使用 Canva AI Image Generator 生成的图片)Brad Gerstner 和 Bill Gurley 在他们的播客 BG2 Pod 中采访了微软 CEO Satya Nadella。Nadella 声称 SaaS 时代已经结束,未来将由 AI 作为主导力量的集成平台引领。 几十年来,SaaS 应用一直驱动着商业运营——从客户关系管理…

011 Axios网络请求封装

在日常应用过程中,一个项目中的网络请求会很多,此时一般采取的方案是将网络请求封装起来在src目录下创建文件夹utils,并创建文件request,用来存储网络请求对象axios 所有安装包都在这个package.json里面可以查看。 在src文件中创建utils文件夹(网络请求的方法),在utils文…

CTFShow-Web168:免杀脚本

CTFShow-Web168:免杀脚本 对eval,system还有$_POST和$_GET进行过滤,$_REQUEST还可以用 🛠️ Web167 WriteUp 提供一个免杀脚本: <?php $bFIY=create_function(chr(25380/705).chr(92115/801).base64_decode(bw==).base64_decode(bQ==).base64_decode(ZQ==),chr(0x16964…

搭建gitlab runner

1、搭建runner 镜像:gitlab/gitlab-runner:latest 2、注册runner,输入gitlab-runner register命令 root@runner-6f49c57c49-5889v:/# gitlab-runner register Runtime platform arch=amd64 os=linux pid=1054 revision=81ab07f6 version=1…

前端开发过程小知识点记录(开发过程实时更新)

1.#main div 距离页面顶部和左边有间距,但是并没有人为设置 出现现象图: 原因:大多数浏览器会为 body 和 html 元素添加默认的外边距。可以通过重置这些样式来解决此问题。 解决办法:在css中清除浏览器的默认样式 html, body { margin: 0; /* 清除默认外边距 */ padding: 0…

Idea自动生成注释

原文链接 使用IDEA配置自动生成注释。 1 创建类时自动加注释 点击左上角菜单栏的 file -> Setting -> Editor -> File and Code Templates -> Includes -> File Header输入如下内容: /***@Author: 代码的路*@Date: ${DATE} ${TIME}*@Param: *@Return: *@Descri…

JavaIO流(三)

6.转换流 不同编码读取出现乱码的问题:如果代码编码和被读取的文本文件编码是一致的,使用字符流读取文本时不会出现乱码 如果代码编码和被读取的文本文件编码是不一致的,使用字符流读取文本时就会出现乱码InputStreamReader(字符输入转换流) 是Reader抽象类下的实现类解决…

pycharm上传github问题:rejected

我从pycharm上传项目时,遇到的问题:以下是一些解决思路: 这个错误提示表明,你在尝试将本地代码推送到远程仓库时,远程仓库中已经包含了你本地尚未获取的更改。换句话说,远程仓库的代码比你的本地代码更新。Git 为了防止冲突,拒绝了你的推送操作。 错误原因 这种情况通常…

EDR简介

一、什么是edr 终端检测与响应(EDR)是一种安全解决方案,可检测并响应勒索软件和恶意软件等威胁。它通过持续监控端点可疑活动来工作,方法是收集有关事件的数据,如系统日志、网络流量、进程间通信 (IPC)、RPC 调用、身份验证尝试和用户活动。 安装在端点上的 EDR 将收集数据…

KUKA库卡KR210机器人维修解决方案概览

库卡KR210机器人,作为一款集高性能与广泛适用性于一体的工业机器人,在众多生产线上发挥着举足轻重的作用。在其高效运转的过程中,难免会遇到一些故障,及时的维修与保养就显得尤为重要。以下,将详细阐述一些常见的维修方法及其注意事项,以期为使用者提供更为全面的指导。常…