NSSCTF_RE_[WUSTCTF 2020]level1
64位无壳
main函数:
int __cdecl main(int argc, const char **argv, const char **envp) { FILE *stream; // ST08_8 signed int i; // [rsp+4h] [rbp-2Ch] char ptr[24]; // [rsp+10h] [rbp-20h] unsigned __int64 v7; // [rsp+28h] [rbp-8h] v7 = __readfsqword(0x28u); stream = fopen("flag", "r"); fread(ptr, 1uLL, 0x14uLL, stream); fclose(stream); for ( i = 1; i <= 19; ++i ) { if ( i & 1 ) printf("%ld\n", (unsigned int)(ptr[i] << i)); else printf("%ld\n", (unsigned int)(i * ptr[i])); } return 0; }
输出:198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000
逻辑很简单,如果i和1按位与运算为1则将ptr[i]与i进行移位运算
否则就相乘
先上脚本:
C语言版:
#include<stdio.h> int main(){ int nums[]={198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000}; for(int i=0; i<19; i++){ if((i+1)&1){ printf("%c",nums[i]>>(i+1)); } else{ printf("%c",nums[i]/(i+1)); } } return 0; }
Python版:
nums=[198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000] for i in range(19): if (i+1)&1: print(chr(nums[i]>>(i+1)),end='') else: print(chr(int(nums[i]//(i+1))),end='')
补充:
C语言中&符号为---按位与运算
i&1 -- 按位与运算,取 2进制整数 i 的最低位,如果最低位是1 则得1,如果最低位是0 则得0。 奇数 i 的最低位 是1,偶数i 的最低位 是0。
另外,python中'/'和'//'的区别:
'/' 除法会保留小数
'//' 除法只保留整数
解决了为啥之前使用/会报错的问题