一,luck_guy
先查壳,没有特殊情况,进入ida
分析猜测是输入v4,让后对v4进行修改(查了一下单词,patch_me相当于加密等操作吧)我们跟进让后进入get_flag函数
发现有一个生成随机数的函数,并且只有特定的数才可以得到flag,与标题:luck_guy相吻合,所以我们直接分析代码就可以,随机数啥的都不用管;
可知当case1时输出正确的flag,其中,我们需要f1和f2;
可知f1是GXY{do_not_
可知我们要求的f2的运算,其中
是16进制数字字符串"我们对其按"r"转换成字符串
记住大端序和小段序,其中/x7F是一个不可打印字符,所以表示成这样.具体如下
`\x7F` 是一个十六进制的转义字符,它在ASCII编码中代表一个特定的字符。在ASCII码表中,`\x7F` 对应的十进制数值是127,这个字符被称为删除(DEL)控制字符。在C语言和类似的编程语言中,转义字符以反斜线 `\` 开头,后跟一个或两个十六进制数字,用来表示特定的控制字符或特殊字符。`\x7F` 就是以 `\x` 开头,后跟十六进制数字 `7F`,用来表示ASCII码中的第127个字符,即删除字符。
所以f2是icug`of\x7F
之后有一个加密操作,猜测应该会进行操作才和一开始所需要的f2相同(要不然就相当于没有了)
写代码实现
可知GXY{do_not_hate_me}
二,Java逆向解密
看题目猜测就和java有关,总之先查壳
我们学习一下.class
在编程和计算机科学中,.class
文件通常指的是 Java 程序中的类文件。这些文件包含了 Java 源代码(.java
文件)编译后的字节码。字节码是一种中间表示形式,它是由 Java 虚拟机(JVM)执行的。
总之进行java反编译;这里我选择的是jd-gui,打开所要反编译的程序;
清晰明了,但是得到的好像是java语言,所以我找了一个在线网站把java转换成c语言之后拷贝到devc++中分析;
我们输入str即为flag,之后str进入Encrypt函数,在函数中,
可知需要match是1;
即需要Resultlist[j] == KEY[j])都成立
KEY存在,而Resultlist和我们输入的str即arr有关,写c语言反推;
三,JustRE1
进去看,但是找了半天也不见关键
之后用字符串索引shift+f12
看到了有一个和flag{}相似的字符串,点进去
点"x"查看引用他的函数,跟进,反编译
可以看到
之后将19999和0代替其中的%d,可知flag;
本题中强调了字符串的使用;寻找关键之处;
四,刮开有奖
进入ida,自己分析代码或shitf+f12,找到了进入函数
GetDlgItemTextA,有一个Get,猜测和输入有关,查查
GetDlgItemTextA
函数用于从对话框中的控件获取文本。这个函数特别适用于当你需要读取用户在文本框(Edit Control)中输入的内容。
所以string是flag且长度是8;
if语句全部满足,则正确,v4==ak1w,v5==V1Ax,所以可以求string的一些值,string[1],string[2],string[3]直接带入,是 C a @现在要找v7[0];
这里有一个函数,点进去但是不知道在干什么,放着先不管
相似的结构,点进函数
分析好难,所以先看整体,有一个函数,点进去
发现是base64加密,但是少了一个A,注意到这一串上面有一个41h,对它点"a"
这样就合并了在 IDA Pro 中.
键盘上的 "A" 键用于将数据转换为字符串。具体来说,当你在反汇编窗口中选择一个地址或一段数据,并按下 "A" 键,IDA 会尝试将该地址或数据解释为一个 ASCII 字符串。这个功能对于识别和提取程序中的字符串非常有用,比如字符串常量或者格式化输出的参数等。
所以对两个字符串进行base64解密,
得到也知道对应v4是string的[5][6][7]位是jMp
v5对应的string[2][3][4]是WP1
但是结果和我们一开始求的string[1],string[2],string[3] C a @不一样,所以我们要分析冲突点,我们发现有一个函数
一开始点进去没看懂,但是只有这里没有发掘了
发现了有许多*(a1+)的运算,一定和地址有关,但是我们的v7只有两个数,
点击查看sub_4010F0,发现这是对v7的前11个元素的加密,且加密方式比较难以分析。但由于v7[0]到v7[11]都已给出(根据IDA的变量命名规则,v8就是v7[2],v9就是v7[3],依此类推),我们可以直接在本地复现这个函数,得到加密后的v7。这里要注意两点:
1.IDA对函数形参的类型判断有误,通过分析比较容易发现sub_4010F0的参数a1应该是int*类型。
2.IDA中*(a1+i)是指从a1开始偏移i个字节,所以IDA中的(a1 + 4i)实际上相当于a1[i],在本地复现时需要去掉函数中所有的“ 4 * ”
( 引用于BUUCTF Reverse题解:第一部分(已完结) - C12AK - 博客园)
我们要知道数组和指针的地址关系,,数组定义的时候地址都是连续的,所以在ida中v8就是v7[2];所以在函数中,我们写代码猜测
因为str一共有三个数,我们把地址存入指针数组,让后找到p[2]+1即为&str[2]+1是str的下一个变量的地址,虽然没定义但是地址是连着的,所以str[3]是1086;如果不给*p[3]赋值,那么也可以输出,但是是随机数,
理解了这个之后,我们进入函数就可以猜测,这是v7[0]到v7[10]进入函数中进行加密,(函数中有明显的地址偏移)之后我们用数组进行运算得出加密后的v7数组
#include<stdio.h>
int sub_4010F0(int* a1, int a2, int a3);
int main()
{
int v7[] ={90,74,83,69,67,97,78,72,51,110,103};
sub_4010F0(v7, 0, 10);
for(int i=0;i<11;i++){
printf("%c",v7[i]);
}
return 0;
}
int sub_4010F0(int *a1, int a2, int a3)
{
int result;
int i;
int v5;
int v6;
result = a3;
for ( i = a2; i <= a3; a2 = i )
{
v5 = i;
v6 = a1[i];
if ( a2 < result && i < result )
{
do
{
if ( v6 > a1[result] )
{
if ( i >= result )
break;
++i;
a1[v5] = a1[result];
if ( i >= result )
break;
while ( a1[i] <= v6 )
{
if ( ++i >= result )
goto LABEL_13;
}
if ( i >= result )
break;
v5 = i;
a1[result] = a1[i];
}
--result;
}
while ( i < result );
}
LABEL_13:
a1[result] = v6;
sub_4010F0(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
得到结果是
3CEHJNSZagn(示例:v5 = 4 * i改成v5=i;因为不需要计算地址位数,直接进行数组移动
v6 = *(4 * i + a1);改成v6 = a1[i] )
之后找到string[0]和string[1]对应的if语句就可以了
小总结:
1.关键是理解数组和地址关系;
2.分析函数的时候先整体后仔细;
标签:总结,a1,reverse,int,函数,学习,result,v7,string From: https://blog.csdn.net/2403_87862296/article/details/143715943