XCTF_reverse logmin

  • 知识点:
    1,基本算法;
    2,ida 的使用;

0x01

下载题目,一个没有后缀的文件,直接拖入 exeinfoPE查壳:

在这里插入图片描述ELF linux文件, 64位;

0x02

拖入 ida, 静态分析,shift + F12,查看字符串 ,找到主函数 main, F5反编译一波:

在这里插入图片描述在这里插入图片描述
主要代码段以及分析:

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
    
    
  size_t v3; // rsi@1
  int i; // [sp+3Ch] [bp-54h]@3
  char s[36]; // [sp+40h] [bp-50h]@1	定义一个长度36数组
  int v6; // [sp+64h] [bp-2Ch]@1		整型变量 v6
  __int64 v7; // [sp+68h] [bp-28h]@1	定义一个长整型变量
  char v8[8]; // [sp+70h] [bp-20h]@1	定义一个长度8数组,这里存在反编译错误;
  int v9; // [sp+8Ch] [bp-4h]@1			定义一个整型变量

  v9 = 0;
  strcpy(v8, ":\"AL_RT^L*.?+6/46"); //strcpy()复制 16 位字符串给 v8,v8长度位 8,显然放不下的,所以是反编译错误了;

  v6 = 7;
  v7 = 'ebmarah';		//小端存储,需要逆序字符串

  printf("Welcome to the RC3 secure password guesser.\n", a2, a3);
  printf("To continue, you must enter the correct password.\n");
  printf("Enter your guess: ");
  __isoc99_scanf("%32s", s);	//输入入口
  v3 = strlen(s);
  if ( v3 < strlen(v8) )	//strlen() v8与输入的字符串做对比
    sub_4007C0();		//输出 incrrect password!
  for ( i = 0; i < strlen(s); ++i )
  {
    
    
    if ( i >= strlen(v8) )
      sub_4007C0();		// 输出:incrrect password!
    if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) ) // (char)强制类型转换 ; __BYTE unsigned char类型
      sub_4007C0();
  }
  sub_4007F0(); //输出 password
}

/*代码逻辑:
	第一个 if, 检测用户输入长度 ,如果长度 < strlen(v8) ,直接 exit;
	for, 做 strlen(s) 次循环;
	第二个 if, 检测 i 的值,如果 i > strlen(v8) ,实际上还是检测输入的 s 长度;
	第三个 if, (char) 强制类型转换 *(__BYTE *)&v7 --> 一个指向 v7[0] 的指针,*(__BYTE *)&v7 + i % v6 --> 做指针加运算,指针向后移动,
		实际上就相当于顺序读取 v7 数组里的元素; s[i] != (...) --> 将用户输入与 v7数组元素分别与 v8数组元素做 ^ 运算的字符比较,相等则跳到 sub_400ef0() ,跳出 password;
	*/

0x03

明白代码逻辑,直接 py:

v7 = "harambe";
v8 = ":\"AL_RT^L*.?+6/46";
flag = "";

for i in range(len(v8)):
    flag += chr(ord(v7[i%7]) ^ ord(v8[i]));


print(flag)

#RC3-2016-XORISGUD

猜你喜欢

转载自blog.csdn.net/qq_46635165/article/details/109267704
今日推荐