BUUCTF-REVERCE-[WUSTCTF2020]level1
[WUSTCTF2020]level1
定期刷re
有一些位上面的操作,学到了一点
无壳,加密函数为main,直接反编译
大概意思就是,原程序从flag文件里面读取了flag,然后逐个字符进行加密并输出。
输出文本就在output.txt里面
关键的加密算法基本都是位运算,这边一个个进行解析
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) == 0
是true
,这意味着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]
这个不是位运算了……
解密脚本
#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}
总结
其实是个很简单的题目。单独拿出来讲是因为头一次接触位运算加密,所以补充了一点相关知识。总之还是有所收获的。