【Android 逆向】【攻防世界】android2.0
这是一道纯算法还原题
1. apk安装到手机,提示输入flag,看来输入就是flag
2. jadx 打开apk查看
this.button.setOnClickListener(new View.OnClickListener() { // from class: com.example.test.ctf03.MainActivity.1
@Override // android.view.View.OnClickListener
public void onClick(View v) {
String str = MainActivity.this.pwd.getText().toString();
int result = JNI.getResult(str);
MainActivity.this.Show(result);
}
});
JNI.java
public class JNI {
public static native int getResult(String str);
static {
System.loadLibrary("Native");
}
}
3. IDA打开 libNative.so 看看
bool __fastcall Java_com_example_test_ctf03_JNI_getResult(JNIEnv *env, jclass a2, jstring str)
{
int v3; // r4
const char *str_chars; // r8
char *v5; // r6
char *v6; // r4
char *v7; // r5
int i; // r0
int j; // r0
v3 = 0;
str_chars = (*env)->GetStringUTFChars(env, str, 0);
if ( strlen(str_chars) == 15 )
{
v5 = (char *)malloc(1u);
v6 = (char *)malloc(1u);
v7 = (char *)malloc(1u);
Init(v5, v6, v7, str_chars, 15);
if ( !First(v5) )
return 0;
for ( i = 0; i != 4; ++i )
v6[i] ^= v5[i];
if ( !strcmp(v6, a5) )
{
for ( j = 0; j != 4; ++j )
v7[j] ^= v6[j];
return strcmp(v7, "AFBo}") == 0;
}
else
{
return 0;
}
}
return v3;
}
先看一下Init函数在干什么
int __fastcall Init(int result, char *a2, char *a3, const char *str_chars, int len)
{
int v5; // r5
int v6; // r10
int v7; // r6
if ( len < 1 )
{
v6 = 0;
}
else
{
v5 = 0;
v6 = 0;
do
{
v7 = v5 % 3;
if ( v5 % 3 == 2 )
{
a3[v5 / 3u] = str_chars[v5];
}
else if ( v7 == 1 )
{
a2[v5 / 3u] = str_chars[v5];
}
else if ( !v7 )
{
++v6;
*(_BYTE *)(result + v5 / 3u) = str_chars[v5];
}
++v5;
}
while ( len != v5 );
}
*(_BYTE *)(result + v6) = 0;
a2[v6] = 0;
a3[v6] = 0;
return result;
}
通过分析可知,该函数将字符串分为了三分,第一个字符给a1,第二个给a2,第三个给a3,第四个给a1,这样循环下去
再看First函数
bool __fastcall First(char *a1)
{
int i; // r1
for ( i = 0; i != 4; ++i )
a1[i] = (2 * a1[i]) ^ 0x80;
return strcmp(a1, "LN^dl") == 0;
}
这里是 拿着a对应的字符做个计算然后取和一个常量比较,这里可以倒推出a1的值,对应python
def first():
b = "LN^dl"
a1 = ''
for i in range(0, 4):
print(i)
a1 += (chr(int((ord(b[i])^0x80)/2)))
a1 += 'l'
print(a1)
#得到 fgorl
注意这里得到了a1原来的值,但是这里a1已经被改了,值为"LN^dl"
, 我就在这里被坑到了
first函数过了之后,v6 做了一些计算,然后又和一个常量比较,那么又可以用上面的方法取干活
for ( i = 0; i != 4; ++i )
v6[i] ^= v5[i];
if ( !strcmp(v6, a5) ){
......
}
对应python
def second():
a5 = [ord(' '), ord('5'), ord('-'), 0x16, ord('a')]
# v5 = [ord('f'), ord('g'), ord('o'), ord('r'), ord('l')]
v5 = [ord('L'), ord('N'), ord('^'), ord('d'), ord('l')]
v6 = ""
for i in range(0, 4):
t = v5[i]^a5[i]
v6 += (chr(t))
v6 += 'a'
print(v6)
# 得到 l{sra
最后v7 也是一个套路,这里就直接给还原的代码了
def third():
a6 = [ord('A'), ord('F'), ord('B'), ord('o'), ord('}')]
v6 = [ord(' '), ord('5'), ord('-'), 0x16, ord('a')]
v7 = ''
for i in range(0, 4):
t = v6[i]^a6[i]
v7 += (chr(t))
v7 += '}'
print(v7)
# 得到 asoy}
最后把三个值拼起来,也就是最上面分析的那个循环赋值的逻辑,这里是还原算法
s1 = 'fgorl'
s2 = 'l{sra'
s3 = 'asoy}'
flag = ''
for i in range(5):
flag += s1[i] + s2[i] + s3[i]
print(flag)
# 得到 flag{sosorryla}
【Android 逆向】【攻防世界】android2.0的更多相关文章
- 逆向-攻防世界-crackme
查壳,nSpack壳,直接用软件脱壳,IDA载入程序. 很明显,就是将402130的数据和输入的数据进行异或,判断是否等于402150处的数据.dwrd占4字节. 这道题主要记录一下刚学到的,直接在I ...
- 逆向-攻防世界-maze
题目提示是走迷宫. IDA载入程序分析. 输入字符长度必须是24,开头必须是nctf{,结尾必须是}.在125处按R就可以变成字符. sub_400650和sub_400660是关键函数,分析sub_ ...
- 逆向-攻防世界-CSAW2013Reversing2
运行程序乱码,OD载入搜索字符串,断电到弹窗Flag附近. 发现跳过00B61000函数,弹窗乱码,我们试试调用00B61000函数.将00B61094的指令修改为JE SHORT 00B6109b. ...
- 逆向-攻防世界-logmein
iDA载入程序,shift+F12查看关键字符串,找到双击来到所在地址,进入函数 然后进入主函数, 经过分析,可以得出:输入的字符要等于 经过处理的v7和v8的异或.v8很明显,但是v7是怎么回事呢 ...
- 逆向-攻防世界-no-strings-attached
看题目就知道查找不到关键字符串,为防止踩坑,strings命令查看,没有找到有用的字符串.IDA载入程序查找入口函数, main函数中有4个函数,经过分析判断authenticate()为关键函数,跟 ...
- 攻防世界逆向——game
攻防世界逆向:game wp 攻防世界逆向新手区的一道题目. 是一道windows的creak,动态调试打开是这样的: 题目说明是让屏幕上所有的图像都亮之后,会出现flag,看来应该是可以玩出来的. ...
- [转]Android逆向之动态调试总结
一.在SO中关键函数上下断点 刚学逆向调试时.大多都满足于在SO中某关键函数上下断点.然后通过操作应用程序,去触发这个断点,然后进行调试 详细的步骤可以参见非虫大大的<Android软件安全与逆 ...
- 攻防世界 reverse evil
这是2017 ddctf的一道逆向题, 挑战:<恶意软件分析> 赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件.随后IT部门发现小A的电脑发出了异常网络访问请求,进 ...
- 攻防世界 reverse 进阶 APK-逆向2
APK-逆向2 Hack-you-2014 (看名以为是安卓逆向呢0.0,搞错了吧) 程序是.net写的,直接祭出神器dnSpy 1 using System; 2 using System.Diag ...
- Android trap攻防思路整理
Android trap攻防 图/文 h_one 0x01 反 ...
随机推荐
- [转帖]elasticsearch8.0以上版本修改内置用户密码
https://www.cnblogs.com/zhang-ding-1314/p/16199682.html 修改密码需要在es启动,并cd到es的bin目录下执行: 1.重置密码并在控制台显示新密 ...
- [转帖]Linux块层技术全面剖析-v0.1
Linux块层技术全面剖析-v0.1 perftrace@gmail.com 前言 网络上很多文章对块层的描述散乱在各个站点,而一些经典书籍由于更新不及时难免更不上最新的代码,例如关于块层的多队列.那 ...
- CCPC Finals 2021 H Harie Programming Contest (网络流&支配树的妙用)
Link 题意: 给一个二分图,求有多少种方案删去恰好两个点,使得最大匹配数不变.\(n,m\le 2\times 10^5\). 二话不说先跑一遍 Dinic 网络流,设残量网络形成的图为 \(G\ ...
- 【JS 逆向百例】有道翻译接口参数逆向
逆向目标 目标:有道翻译接口参数 主页:https://fanyi.youdao.com/ 接口:https://fanyi.youdao.com/translate_o?smartresult=di ...
- 每日一库:使用Viper处理Go应用程序的配置
在开发Go应用程序时,处理配置是一个常见的需求.配置可能来自于配置文件.环境变量.命令行参数等等.Viper是一个强大的库,可以帮助我们处理这些配置. 什么是Viper? Viper是一个应用程序配置 ...
- gRPC如何保障数据安全传输
什么是 gRPC? gRPC 是由 Google 开发的高性能.开源的 RPC(Remote Procedure Call)框架,用于在客户端和服务器之间进行通信.它基于 Protocol Buffe ...
- ABP无法使用异步操作,但要调用异步方法
使用 AsyncHelper.RunSync(() => _studentRepository.FirstOrDefaultAsync(x => x.Code == studentCode ...
- python2排序
python list cmp排序 对于list的排序一般使用cmp 示例: sorted(xxlist, cmp=self.sortFunc) def sortFunc(self, a, b): r ...
- C# WinForm 界面控件
C# WinForm是一种GUI应用程序框架,它允许开发人员使用各种控件来创建丰富的用户界面.以下是一些C# WinForm中常见的界面控件:这些界面控件在C# WinForm应用程序开发中非常常见, ...
- C# 字符与字符串操作
在C#中,字符和字符串是两个重要的数据类型,有许多内置的方法可以处理字符和字符串.这些方法是非常有用的,可以帮助开发人员更方便.更高效地处理文本数据. 格式化字符串: using System; us ...