逆向学习(二)

目录 不对的地方还请大佬多多指出–

文章目录

  • 目录
  • xor
  • reverse3
  • 不一样的flag
  • SimpleRev

xor 首先用exeinfope查看为64位 用IDA打开 f5得到源码
printf("Input your flag:\n", 0LL); get_line(v6, 256LL); if ( strlen(v6) != 33 )//这里也就是flag的长度了 goto LABEL_12; for ( i = 1; i < 33; ++i ) v6[i] ^= v6[i - 1]; v3 = global; if ( !strncmp(v6, global, 0x21uLL) )//这里是关键点与比较上述运算后的global比较,一致则成功 printf("Success", v3); else LABEL_12: printf("Failed", v3); result = __stack_chk_guard; if ( __stack_chk_guard == v7 ) result = 0; return result;

追踪global(点击它)后可以得到一串字符,那么这里逆推回去得到原v6
也就是flag
逆向学习(二)
文章图片

选个字母右键选择16进制然后复制出来这样容易写代码
逆向学习(二)
文章图片

这里涉及一个知识点:两次异或操作得到的是本身
源码这里是:v6[i] ^= v6[i - 1]; 我们复原的话只需要前面那个和后面那个字符异或就行 举个例子: 以变量来说(0 1 1’相当于是变量这里举个例子说明) 其中1’和2’等等是题目得到的变量
0^1=>1'1'^2=>2' 2'^3=>3' 我们再求 1 2 3 的时候只需要 1= 1'^02= 2'^1'

所以我们的脚本如下
glo=[0x66,0x0a,0x6b,0x0c,0x77,0x26,0x4F,0x2E,0x40,0x11,0x78,0x0D,0x5A,0x3B,0x55,1,0x70,0x19,0x46,0x1F,0x76,0x22,0x4D,0x23,0x44,0x0E,0x67,0x6,0x68,0x0f,0x47,0x32,0x4f]s='' for i in range(1,len(glo)): a=glo[i]^glo[i-1]s+=chr(a)print(s)

得到flag=>flag{QianQiuWanTqi_YiTongJiangHu}

reverse3 老套路 还是用exeinfope得出 无壳 32位 用IDA打开
F5直接进入主函数
sub_41132F("please enter the flag:"); sub_411375("%20s", &Str); v0 = j_strlen(&Str); v1 = (const char *)sub_4110BE(&Str, v0, &v11); strncpy(Dest, v1, 0x28u); v8 = j_strlen(Dest); for ( j = 0; j < v8; ++j ) Dest[j] += j; v2 = j_strlen(Dest); if ( !strncmp(Dest, Str2, v2) ) sub_41132F("rigth flag!\n"); else sub_41132F("wrong flag!\n");

逻辑很简单的逻辑与shr2比较 点开逆向学习(二)
文章图片

按题目可以得到脚本
s='' str1= 'e3nifIH9b_C@n@dH' for i in range(len(str1)): s+=chr(ord(str1[i])-i)print(s)

得到e2lfbDB2ZV95b3V9
【逆向学习(二)】然后以为是flag 一直不对 参考了大佬的博客 原来是还有个base64
sub_4110BE(&Str, v0, &v11); 点进去 一大串看不懂的代码 还是太菜了继续加油!
用base64解得flag逆向学习(二)
文章图片

不一样的flag 走迷宫题 进入main 追随start 得到 10字符串
*11110100001010000101111#
分成5行
*1111
01000
01010
00010
1111#
逆向学习(二)
文章图片

1就退出 # 就成功 走的数就是flag 得到flag
SimpleRev 老办法exeinfope一波逆向学习(二)
文章图片

用64位 IDA打开进入主函数 得到代码
int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { int v3; // eax char v4; // [rsp+Fh] [rbp-1h]while ( 1 ) { while ( 1 ) { printf("Welcome to CTF game!\nPlease input d/D to start or input q/Q to quit this program: ", argv, envp); v4 = getchar(); if ( v4 != 100 && v4 != 68 ) break; Decry(); } if ( v4 == 113 || v4 == 81 ) Exit(); puts("Input fault format!"); v3 = getchar(); putchar(v3); } }

老套如用IDA64位打开跟进main 函数进入Decry()函数
代码如下
v7 = 0LL; v8 = 0; v9 = 512969957736LL; v10 = 0LL; v11 = 0; text = (char *)join(key3, &v9); strcpy(key, key1); strcat(key, src); v2 = 0; v3 = 0; getchar(); v5 = strlen(key); for ( i = 0; i < v5; ++i ) { if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 ) key[i] = key[v3 % v5] + 32; ++v3; } printf("Please input your flag:", src); while ( 1 ) { v1 = getchar(); if ( v1 == 10 ) break; if ( v1 == 32 ) { ++v2; } else { if ( v1 <= 96 || v1 > 122 ) { if ( v1 > 64 && v1 <= 90 ) 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) ) puts("Congratulation!\n"); else puts("Try again!\n"); return __readfsqword(0x28u) ^ v12; }

v9 = 512969957736LL;
text = (char *)join(key3, &v9);
strcat(key, src);
很容易找到key src
需要注意的是,x86系列的CPU都是以小端序储存数据的,即低位字节存入低地址,高位字节存入高地址,所以正确的字符串应该反过来即
v9 = ‘hadow’;
将其反过来连接得到 text= killshadow
2. *src = https://www.it610.com/article/NDCLS
3. 连接起来得到 :key= ‘ADSFKNDCLS’逆向学习(二)
文章图片

然后逆向学习(二)
文章图片

用脚本得到新的key
key= 'ADSFKSLCDN' v3=0 v5=len(key) for i in range(v5): if (ord(key[v3%v5])> 64 and ord(key[v3%v5])<=90):print(chr(ord(key[v3 % v5])+32),end='')v3+=1

key= adsfkndcls
以下就是主函数分析 :
如果满足再大小写之中并且满足
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;

我们可以通过遍历的方法得到想要的字符串
代码如下
import string dict=string.ascii_letters key='adsfkndcls' text='killshadow' v5=len(text) for i in range(len(text)): for j in dict: if((ord(text[i]) == (ord(j)-39-ord(key[i%v5])+97)%26+97)): print(j)

这里发现不对 不知道为什么是只有大写,没有过滤了小写 。。希望能得到大师傅的解答
得到flag
如果有错误的话请多多指正

    推荐阅读