[WUSTCTF2020]level1

给了两个文件。

查壳是64位无壳,直接拖进IDA看主函数。

for循环的上几行大概意思是从文件里读取flag,然后逐位进行加密并输出到output.txt。 for循环里进行加密操作。这里涉及到了位运算,与1进行&运算结果如果不是0就进行左移位操作并输出无符号整数。结果如果是0就进行*运算然后输出。

写个脚本逆回去即可。

总结一下常见的位运算:

& 与 运算规则: 第一个操作数的第n位与第二个操作数的第n位对比,如果都是1,那么第n位的结果为1,否则为0;同真为真,一假为假。

5转换为二进制:00000000 00000000 00000000 00000101
3转换为二进制:00000000 00000000 00000000 00000011
5 & 3 结果:00000000 00000000 00000000 00000001

和1进行&运算可以判断奇偶,结果为0是偶,为1是奇。

|或 运算规则: 第一个操作数的第n位与第二个操作数的第n位对比,只要有一个是1,那么第n位的结果为1,否则为0;一真为真,同假为假。

5转换为二进制:00000000 00000000 00000000 00000101
3转换为二进制:00000000 00000000 00000000 00000011
5 | 3 结果:00000000 00000000 00000000 00000111

^异或 运算规则: 第一个操作数的第n位与第二个操作数的第n位对比,如果相反那么第n位结果的为1,否则为0;同为假,异为真。

5转换为二进制:00000000 00000000 00000000 00000101
3转换为二进制:00000000 00000000 00000000 00000011
5 ^ 3结果:00000000 00000000 00000000 00000110

还有特性:a ^ b ^ a = b; a ^ b ^ b = a(满足交换律)

移位 左移即转为二进制后整体向左移动,溢出的位数抹去,再在右边补0。如1111左移2位结果是1100。 带符号右移正数与不带符号右移结果相同。如1111右移2位结果是0011。 对于负数来说,带符号右移需要求补码后再移动,且左边补的不是0而是1,最后还要求原码才是最终结果。

以上内容计组课应该有讲,原理和CTF似乎关系不大,碰到题只需写反向的代码解密即可。