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中'/'和'//'的区别:

'/'  除法会保留小数

'//'  除法只保留整数

解决了为啥之前使用/会报错的问题

 

posted @ 2022-03-28 20:36  Luccky  阅读(34)  评论(0编辑  收藏  举报