下载下来的是个elf文件,因为懒得上Linux,直接往IDA里扔,

切到字符串的那个窗口,发现Congratulation!,应该是程序成功执行的表示,

双击,按‘x’,回车跟入

找到主函数:

 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3)
2 {
3 signed int i; // [rsp+8h] [rbp-68h]
4 signed int j; // [rsp+Ch] [rbp-64h]
5 __int64 v6; // [rsp+10h] [rbp-60h]
6 __int64 v7; // [rsp+18h] [rbp-58h]
7 __int64 v8; // [rsp+20h] [rbp-50h]
8 __int64 v9; // [rsp+28h] [rbp-48h]
9 __int64 v10; // [rsp+30h] [rbp-40h]
10 __int64 v11; // [rsp+40h] [rbp-30h]
11 __int64 v12; // [rsp+48h] [rbp-28h]
12 __int64 v13; // [rsp+50h] [rbp-20h]
13 __int64 v14; // [rsp+58h] [rbp-18h]
14 __int64 v15; // [rsp+60h] [rbp-10h]
15 unsigned __int64 v16; // [rsp+68h] [rbp-8h]
16
17 v16 = __readfsqword(0x28u);
18 puts("Let us play a game?");
19 puts("you have six chances to input");
20 puts("Come on!");
21 v6 = 0LL;
22 v7 = 0LL;
23 v8 = 0LL;
24 v9 = 0LL;
25 v10 = 0LL;
26 for ( i = 0; i <= 5; ++i ) //以&v6为首地址,获取并写入6个32位的WORD型数据
27 {
28 printf("%s", "input: ", (unsigned int)i);
29 __isoc99_scanf("%d", (char *)&v6 + 4 * i);
30 }
31 v11 = 0LL;
32 v12 = 0LL;
33 v13 = 0LL;
34 v14 = 0LL;
35 v15 = 0LL;
36 for ( j = 0; j <= 4; j += 2 ) //以&v11为首地址,将之前获取的数据经sub_400686处理之后写入
37 {
38 dword_601078 = *((_DWORD *)&v6 + j); //每次取相邻的两个
39 dword_60107C = *((_DWORD *)&v6 + j + 1);
40 sub_400686((unsigned int *)&dword_601078, &unk_601060); //将其中更地位的数据的地址传入
41 *((_DWORD *)&v11 + j) = dword_601078; //将处理之后的值写回原地址
42 *((_DWORD *)&v11 + j + 1) = dword_60107C;
43 }
44 if ( (unsigned int)sub_400770(&v11) != 1 ) //检查函数,判断你的输入是否正确
45 {
46 puts("NO NO NO~ ");
47 exit(0);
48 }
49 puts("Congratulation!\n");
50 puts("You seccess half\n");
51 puts("Do not forget to change input to hex and combine~\n");
52 puts("ByeBye");
53 return 0LL;
54 }

函数很简单,执行的流程也可以说是一目了然。

我们先看sub_4006770:

总共6个值,已经给出来了3个,剩下三个组了一个很友善的三元一次方程组,贼良心。

结果已经有了,下面就是根据sub_400686逆推正确的输入:

这个算法有点把子意思,反正我是看的去有些晕。但这不重要,也不需要去做什么深入分析,强行逆转就好。

加法变减法,代码的执行顺序完全倒转,至于异或了的再来一次

核心部分也就是那个for循环处理之后也就是这样:

1 v5 = 0x458BCD42*64;
2 for ( i = 0; i <= 63; ++i )
3 {
4 v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
5
6 v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
7
8 v5 -= 0x458BCD42;
9 }

最终的脚本:

 1  unsigned int i = 0, j = 0, sum = 0;
2 unsigned int a[6] = { 0xDF48EF7E ,0x20CAACF4,0,0,0,0x84F30420 };
3 unsigned int temp[2] = { 0,0 }, date[4] = { 2,2,3,4 };
4 char* p = (char*)&a;
5 a[2] = 0x84A236FF / 2 + 0xFA6CB703 / 2 + 0x42D731A8 / 2 + 1;
6 a[3] = a[2] - 0x84A236FF;
7 a[4] = a[2] - 0x42D731A8;
8 for (i = 0; i < 6; i++) printf("a[%d] = 0x%x \n", i, a[i]);
9 for (i = 0; i < 5; i += 2) {
10 temp[0] = a[i]; temp[1] = a[i + 1];
11 sum = 0x458BCD42 * 64;
12
13 for (j = 0; j < 64; j++) {
14 temp[1] -= (temp[0] + sum + 20) ^ ((temp[0] << 6) + date[2]) ^ ((temp[0] >> 9) + date[3]) ^ 0x10;
15 temp[0] -= (temp[1] + sum + 11) ^ ((temp[1] << 6) + date[0]) ^ ((temp[1] >> 9) + date[1]) ^ 0x20;
16 sum -= 0x458BCD42;
17 }
18 a[i] = temp[0];
19 a[i + 1] = temp[1];
20 }
21 putchar(10);
22 for (i = 0; i < 24; i += 4) printf("%c%c%c", p[i + 2], p[i + 1], p[i]);
23
24 // putchar(10);
25 //for (i = 0; i < 24; i++) printf("%c", p[i]);
26   //最开始我是按逐字符输出的虽然看起来他应该是个flag,但顺序不对:“alf r{g i_e g_s aer }!t ”
27 //putchar(10);
28 //for (i = 0; i < 24; i += 4) printf("%c%c%c%c", p[i + 3], p[i + 2], p[i + 1], p[i]); //调换大小端之后,发现好要去掉空格:“ fla g{r e_i s_g rea t!}”
29

最后:

get flag: flag{re_is_great!}

BUU reverse xxor的更多相关文章

  1. [BUUCTF]REVERSE——[GWCTF 2019]xxor

    [GWCTF 2019]xxor 附件 步骤: 无壳,64位ida载入 程序很简单,首先让我们输入一个字符串,然后进行中间部分的操作,最后需要满足44行的if判断,看一下sub_400770函数 得到 ...

  2. LeetCode 7. Reverse Integer

    Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have you ...

  3. js sort() reverse()

    数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...

  4. [LeetCode] Reverse Vowels of a String 翻转字符串中的元音字母

    Write a function that takes a string as input and reverse only the vowels of a string. Example 1:Giv ...

  5. [LeetCode] Reverse String 翻转字符串

    Write a function that takes a string as input and returns the string reversed. Example: Given s = &q ...

  6. [LeetCode] Reverse Linked List 倒置链表

    Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed either i ...

  7. [LeetCode] Reverse Bits 翻转位

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  8. [LeetCode] Reverse Words in a String II 翻转字符串中的单词之二

    Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...

  9. [LeetCode] Reverse Words in a String 翻转字符串中的单词

    Given an input string, reverse the string word by word. For example, Given s = "the sky is blue ...

随机推荐

  1. python编程中的并发------多线程threading模块

    任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...

  2. 神舟zx6-ct5da装黑苹果Macos 10.15.6记录

    可能是一时脑子抽风,突然就想体验一把mac系统.以前就了解过,给非苹果电脑装macos叫黑苹果,emmmmm.好吧,给我的神船也整一个. 看了很多个视频,整理一下装黑苹果过程.本人电脑系统是win10 ...

  3. 03 父子组件sync&update

    父组件传给子组件是基本数据类型. 父组件 <template> <el-container class="consele-container"> <e ...

  4. 跟着兄弟连系统学习Linux-【day10】

    day11-20200610 p36.源码包安装过程 (1)安装前需要准备工作 安装gcc编译器(前两期已经安装) 源码保存位置/usr/local/src 软件安装位置:/usr/local/ (2 ...

  5. [LeetCode题解]79. 单词搜索

    题目描述 题目:79. 单词搜索 解题思路 遍历 首先找重复性,题目说给定单词是否存在于二维数组中,可以简化为从 (x, y) 走 n 步(n 表示单词长度),查看给定单词是否存在.然后再遍历二维数组 ...

  6. C:将算术表达式的符号和数分开

    程序: #include <stdio.h> #include <string.h> static int pos=; static char* line; void test ...

  7. leetcode刷题-59螺旋矩阵2

    题目 给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵. 思路 与螺旋矩阵题完全一致 实现 class Solution: def generateM ...

  8. 关于input框仿百度/google自动提示的方法

    引入jquery-autocomplete文件 链接:https://pan.baidu.com/s/1hW0XBYH8ZgJgMSY1Ce6Pig 密码:tv5b $(function() { $( ...

  9. Vue 侦听器 watch

    1. 侦听器 watch Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性 当属性发生改变时,自动触发属性对应的侦听器. 当需要在数据变化时执行异步或开销较大的操作时,这 ...

  10. Shader 001 - 函数造型能力

    0x00 从函数出发 Shader 中的很多效果都是由函数计算得出的,如何更好地理解二者的关系呢.不妨先看看函数是什么?函数的定义可以简单地描述为:给定一个集合 A,对于其中的元素施加法则 f,则可以 ...