#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>

uint32_t* DAT_00404068;
uint64_t* DAT_00404090;


void FUN_00401380(undefined4 param_1,undefined8 param_2,undefined8 param_3)

{
  ulong uVar1;

  _DT_INIT();
  uVar1 = 0;
  do {
    (*(code *)(&__DT_INIT_ARRAY)[uVar1])(param_1,param_2,param_3);
    uVar1 = uVar1 + 1;
  } while (uVar1 < 2);
  return;
}


void _FINI_1(void)

{
  char local_48 [32];
  ulong local_28;
  undefined8 uStack_20;
  undefined8 local_18;
  undefined1 local_10;

  if (DAT_00404068 == 0) {
    if (DAT_00404098 == 0) {
      local_10 = 0;
      builtin_strncpy(local_48,"\nCongratulations ! The right pas",0x20);
      local_18 = 0xa0a292d3a207325;
      local_28 = 0x73692064726f7773;
      uStack_20 = 0x20646565646e6920;
      fprintf(stderr,local_48,DAT_00404090);
    }
    else {
      local_28 = local_28 & 0xffffffffffffff00;
      builtin_strncpy(local_48,"\nWrong password ! Try again...\n\n",0x20);
      fputs(local_48,stderr);
    }
    return;
  }
  return;
}


int check_password(char* password) {
  return (int)(char)( // Have to be equal to 0 for a good password
      password[0]  ^ 0x58 | // X
      password[1]  ^ 0x67 | // g
      password[2]  ^ 0x6e | // n
      password[3]  ^ 0x73 | // s
      password[4]  ^ 0x57 | // W
      password[5]  ^ 0x45 | // E
      password[6]  ^ 0x7a | // u
      password[7]  ^ 0x41 | // A
      password[8]  ^ 0x74 | // t
      password[9]  ^ 0x66 | // f
      password[10] ^ 0x42 | // B
      password[11] ^ 0x6f   // o
      // XgnsWEuAtfBo
  );
}



int8_t main(int param_1,char* *param_2) {
  char *password;
  int ret;
  size_t pw_length;
  code *__addr;
  long lVar3;

  if (param_1 == 2) {
    password = (char *)param_2[1];
    pw_length = strlen(password);
    if (pw_length == 12) {
      DAT_00404068 = 0; //4 bytes
      DAT_00404090 = password; //8 bytes

      // Allocate memory aligned to page boundary
      __addr = (code *)valloc(1024);

      // protect this memory
      ret = mprotect(__addr,1024,7); // 0 if successful

      if ((__addr != (code *)0x0) && (ret == 0)) { // If memory right allocated and protected correctly

        for(uint32_t i = 0; i < 169; i++) {

          __addr[i] = (code)((&DAT_004020c0)[i] ^ 0x17); // 1 byte

        }

        DAT_00404098 = (*__addr)(password); // Have to be equal to 0 for a good password
        return 1;
      }
                    /* WARNING: Subroutine does not return */
      return(-1);
    }
    fwrite("\nWrong password ! Try again...\n\n",1,0x20,stderr);
  }
  else {
    fwrite("\nMSE-SRE Challenge D1 --- Enjoy !\n",1,0x22,stderr);
    fwrite("\nWhat I need is the right password!\n",1,0x24,stderr);
    fprintf(stderr,"\nUsage: %s <password>\n\n",*param_2);
  }
  return 1;
}
