标签:BUUCTF int sp v1 v2 bp key 刷题
BUUCTF刷题
1.不一样的flag
IDA32打开文件,并找到main函数,F5进入伪代码界面,从头分析
void main()
{
char v0; // [sp+17h] [bp-35h]@1
int v1; // [sp+30h] [bp-1Ch]@1
int v2; // [sp+34h] [bp-18h]@1
signed int v3; // [sp+38h] [bp-14h]@2
signed int i; // [sp+3Ch] [bp-10h]@14
int v5; // [sp+40h] [bp-Ch]@20
__main();
v1 = 0;
v2 = 0;
qmemcpy(&v0, _data_start__, 0x19u); // _data_start__为*11110100001010000101111#
while ( 1 )
{
puts("you can choose one action to execute");//开始输入flag
puts("1 up");
puts("2 down");
puts("3 left");
printf("4 right\n:");
scanf("%d", &v3);
if ( v3 == 2 )
{
++v1;
}
else if ( v3 > 2 )
{
if ( v3 == 3 )
{
--v2;
}
else
{
if ( v3 != 4 )
LABEL_13:
exit(1);
++v2;
}
}
else
{
if ( v3 != 1 )
goto LABEL_13;
--v1;
}
/这部分都是一些指令,上下左右然后对V1,v2进行相关的加减修改
//输入1--- v1-1 up
//输入2--- v1+1 down
//输入3--- v2-1 left
//输入4--- v2+1 right
for ( i = 0; i <= 1; ++i )
{
if ( *(&v1 + i) < 0 || *(&v1 + i) > 4 )
exit(1);
}
if ( *((_BYTE *)&v5 + 5 * v1 + v2 - 41) == '1' )// 如果最后结果是字符‘1’就退出
exit(1);
if ( *((_BYTE *)&v5 + 5 * v1 + v2 - 41) == '#' )// 如果最后是‘#’则输出puts
{
puts("\nok, the order you enter is the flag!");
exit(0);
}
}
}
里出来了,但是感觉缺点啥,看看大佬的wp,发现这是一道迷宫题,最后的flag就是你输入的”上下左右“,只要根据地图走就行
地图就是一开始的_data_start__。将其3个为一组,得到地图:
*1111
01000
01010
00010
1111#
'*'就是起点,'#'就是出口,只能走0,遇到'1'程序就停止,遇到'#'程序输出一句话
// puts("\nok, the order you enter is the flag!");
当”走出迷宫“后,输入的字符就包括222441144222
最后flag就是flag{222441144222}
2.simpleRev
常规操作一波,查壳,看环境,IDA打开 F5伪代码分析
分析,可以看出主要函数就是Dercy();跟进分析----》
__int64 Decry()
{
char v1; // [sp+Fh] [bp-51h]@19
int v2; // [sp+10h] [bp-50h]@1
signed int v3; // [sp+14h] [bp-4Ch]@1
signed int i; // [sp+18h] [bp-48h]@1
signed int v5; // [sp+1Ch] [bp-44h]@1
char src[8]; // [sp+20h] [bp-40h]@1
__int64 v7; // [sp+28h] [bp-38h]@1
int v8; // [sp+30h] [bp-30h]@1
__int64 v9; // [sp+40h] [bp-20h]@1
__int64 v10; // [sp+48h] [bp-18h]@1
int v11; // [sp+50h] [bp-10h]@1
__int64 v12; // [sp+58h] [bp-8h]@1
v12 = *MK_FP(__FS__, 40LL);
*(_QWORD *)src = 'SLCDN'; //注意小端存储,真正的src=NDCLS
v7 = 0LL;
v8 = 0;
v9 = 'wodah'; //这也是小端存储,V9=hadow
v10 = 0LL;
v11 = 0;
text = join(key3, (const char *)&v9); // join--将两个字符串接起来,key3="kills";v9="hadow"
strcpy(key, key1); // key=key1;key1为”ADSFK“
strcat(key, src); // 将key和src字符串连接起来,key就为ADSFKNDCLS
v2 = 0;
v3 = 0;
getchar();
v5 = strlen(key);
for ( i = 0; i < v5; ++i )
{
if ( key[v3 % v5] > '@' && key[v3 % v5] <= 'Z' )
key[i] = key[v3 % v5] + 32;
++v3;
} // 对key进行加密操作,即大小写转化
printf("Please input your flag:", src);
while ( 1 )
{
v1 = getchar();
if ( v1 == '\n' )
break;
if ( v1 == 32 )
{
++v2;
}
else
{
if ( v1 <= 96 || v1 > 122 )
{
if ( v1 > 64 && v1 <= 90 ) // v1在A~Z之间
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
}
else
{
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
}
if ( !(v3 % v5) )
putchar(32);
++v2;
}
}
if ( !strcmp(text, str2) ) //最后经过处理得到的str2和text文本一样即通过,所以text就是最终加密文本,脚本需对text处理得出flag
puts("Congratulation!\n");
else
puts("Try again!\n");
return *MK_FP(__FS__, 40LL) ^ v12;
}
整理:
加密后flag---text = killshadows
加密中使用的字符串(经大小写转换)---key = adsfkndcls
输入的字符---v1
最终得到的处理过的flag---Str2
脚本如下:
#include<stdio.h>
#include<windows.h>
#include<string.h>
/*
加密后flag---text = killshadows
加密中使用的字符串(经大小写转换)---key = adsfkndcls
输入的字符---v1
最终得到的处理过的flag---Str2
*/
int main(){
char text[]={"killshadows"};
char key[]="adsfkndcls";
char str[50];
int i;
char a;
int v3=strlen(text);
int v2;
int v5=strlen(key);
int j;
for(i=0;i<v3-1;i++){
//这里用来试26取余的乘数
for(j=0;;j++){
str[i] = text[i] - 97 + 26*j + 39 -97 + key[i];
if(str[i]>64 && str[i]<91)
break;
}
}
printf("%s",str);
system("pause");
return 0;
}
flag{KLDQCUDFZO}!!!!
标签:BUUCTF,int,sp,v1,v2,bp,key,刷题 来源: https://blog.csdn.net/qq_51521220/article/details/120460353
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。