BUUCTF-REVERCE-[WUSTCTF2020]level1

[WUSTCTF2020]level1

定期刷re

有一些位上面的操作,学到了一点

无壳,加密函数为main,直接反编译

image-20230313213904928

大概意思就是,原程序从flag文件里面读取了flag,然后逐个字符进行加密并输出。

输出文本就在output.txt里面

image-20230313214121230

关键的加密算法基本都是位运算,这边一个个进行解析

1.(i & 1) != 0

两个整数之间的&其实就是按位AND运算

让我们假设number == 6,那么:

6 -> 00000000000000000000000000000110 (even)

     &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

1 -> 00000000000000000000000000000001

-------------------------------------

0 -> 00000000000000000000000000000000

以及当number == 7

7 -> 00000000000000000000000000000111 (odd)

     &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

1 -> 00000000000000000000000000000001

-------------------------------------

1 -> 00000000000000000000000000000001

其实说白了,如果(number & 1) == 0true,这意味着number是偶数

所以((i & 1) != 0),当i为偶数的时候为false

2.(ptr[i] << i)

字面意思,<<就是整体的为移动,单位是bit

#include <iostream>
#include <bitset>

using namespace std;

int main() {
    unsigned short short1 = 4;
    bitset<16> bitset1{short1};   // the bitset representation of 4
    cout << bitset1 << endl;  // 0b00000000'00000100

    unsigned short short2 = short1 << 1;     // 4 left-shifted by 1 = 8
    bitset<16> bitset2{short2};
    cout << bitset2 << endl;  // 0b00000000'00001000
    
    unsigned short short3 = short1 << 2;     // 4 left-shifted by 2 = 16
    bitset<16> bitset3{short3};
    cout << bitset3 << endl;  // 0b00000000'00010000

}

解法其实就是把 << 换成 >> 就可以了

3.i * ptr[i]

这个不是位运算了……

解密脚本

image-20230313220335872

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<unistd.h>
#include<fstream>
using namespace std;
int main(){
    ifstream file;
    file.open("output.txt", ios::in);
    for (short i = 1; i <= 19; ++i ){
        long a;
        file >> a;
        if ( (i & 1) != 0 )
            cout << char(a >> i);
        else
            cout << char(a / i);
    }
}

ctf2020{d9-dE6-20c}

总结

​ 其实是个很简单的题目。单独拿出来讲是因为头一次接触位运算加密,所以补充了一点相关知识。总之还是有所收获的。

posted @ 2023-03-13 22:09  古明地核  阅读(119)  评论(0编辑  收藏  举报