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 @   古明地核  阅读(138)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示