签到

一题验证题目 找一下

能发现到比较点 再往上看

int __cdecl sub_4017F0(int a1)
{
  char Str1[28]; // [esp+D8h] [ebp-24h] BYREF
  int v3; // [esp+F4h] [ebp-8h]
  int v4; // [esp+F8h] [ebp-4h]

  v4 = 0;
  v3 = 0;
  while ( *(_DWORD *)(a1 + 4 * v4) <= 0x3Du )
  {
    Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)];
    ++v4;
  }
  Str1[v4] = 0;
  if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") )
    return sub_401770();
  else
    return sub_4017B0();
}

sub_401890函数

int __thiscall sub_401890(CWnd *this)
{
  CWnd *DlgItem; // eax
  int v2; // eax
  struct CString *v4; // [esp-4h] [ebp-C4h]
  int v5[26]; // [esp+4Ch] [ebp-74h] BYREF
  int i; // [esp+B4h] [ebp-Ch]
  char *Str; // [esp+B8h] [ebp-8h]
  CWnd *v8; // [esp+BCh] [ebp-4h]

  v8 = this;
  v4 = (CWnd *)((char *)this + 100);
  DlgItem = CWnd::GetDlgItem(this, 1002);
  CWnd::GetWindowTextA(DlgItem, v4);
  v2 = sub_401A30((char *)v8 + 100);
  Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v2);
  if ( !strlen(Str) )
    return CWnd::MessageBoxA(v8, "请输入pass!", 0, 0);
  for ( i = 0; Str[i]; ++i )
  {
    if ( Str[i] > 57 || Str[i] < 48 )
    {
      if ( Str[i] > 122 || Str[i] < 97 )
      {
        if ( Str[i] > 90 || Str[i] < 65 )
          sub_4017B0();
        else
          v5[i] = Str[i] - 29;
      }
      else
      {
        v5[i] = Str[i] - 87;
      }
    }
    else
    {
      v5[i] = Str[i] - 48;
    }
  }
  return sub_4017F0((int)v5);
}

也就是

第一层 用户输入字符转数字

'0' ~ '9'  -> ch - 48      // 0 ~ 9
'a' ~ 'z'  -> ch - 87      // 10 ~ 35
'A' ~ 'Z'  -> ch - 29      // 36 ~ 61

第二层 用这个数字去查表

Str1[i] = table[v5[i]]

最后要求

Str1 == "KanXueCTF2019JustForhappy"

所以

exp

table = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
target = "KanXueCTF2019JustForhappy"

def encode_index(x):
    if x <= 9:
        return chr(x + 48)
    if x <= 35:
        return chr(x + 87)
    return chr(x + 29)

ans = ""

for c in target:
    idx = table.index(c)
    ans += encode_index(idx)

print(ans)

flag

flag{j0rXI4bTeustBiIGHeCF70DDM}