hgame ShinyShot!

就是mark一下里面smc

解法
做的时候可以直接锁定加密部分sub_4014FA函数

size_t __cdecl sub_4014FA(char *a1, char *a2)
{
  int v2; // eax@3
  int v3; // ebx@5
  int v4; // eax@5
  int v5; // ebx@7
  int v6; // eax@7
  size_t result; // eax@17
  signed int v8; // [sp+10h] [bp-18h]@1
  size_t v9; // [sp+10h] [bp-18h]@15
  int j; // [sp+14h] [bp-14h]@15
  signed int i; // [sp+18h] [bp-10h]@1
  int v12; // [sp+1Ch] [bp-Ch]@1

  v12 = 0;
  v8 = 4 * strlen(a1) / 3;
  for ( i = 0; i < v8; ++i )
  {
    if ( i & 3 )
    {
      if ( ((((i >> 32) >> 30) + i) & 3) - ((i >> 32) >> 30) == 1 )
      {
        v3 = 16 * a1[v12 - 1] & 0x30;
        v4 = v12++;
        a2[i] = byte_405020[v3 | (a1[v4] >> 4)];
      }
      else if ( ((((i >> 32) >> 30) + i) & 3) - ((i >> 32) >> 30) == 2 )
      {
        v5 = 4 * a1[v12 - 1] & 0x3C;
        v6 = v12++;
        a2[i] = byte_405020[v5 | (a1[v6] >> 6)];
      }
      else
      {
        a2[i] = byte_405020[a1[v12 - 1] & 0x3F];
      }
    }
    else
    {
      v2 = v12++;
      a2[i] = byte_405020[(a1[v2] >> 2)];
    }
  }
  if ( strlen(a1) % 3 == 1 )
  {
    a2[v8] = byte_405020[16 * a1[v12 - 1] & 0x30];
    a2[v8 + 1] = 61;
    a2[v8 + 2] = 61;
  }
  else if ( strlen(a1) % 3 == 2 )
  {
    a2[v8] = byte_405020[4 * a1[v12 - 1] & 0x3C];
    a2[v8 + 1] = 61;
  }
  a2[strlen(a2)] = 0;
  v9 = strlen(a2);
  for ( j = 0; ; ++j )
  {
    result = v9 - 1;
    if ( (v9 - 1) <= j )
      break;
    a2[j + 1] ^= a2[j];   //每个字符异或和前一位异或
  }
  return result;
}
图片.png

改表的base64

hgame ShinyShot!_第1张图片
图片.png

文件32位跟加密后数据对比


hgame ShinyShot!_第2张图片
图片.png

字符异或得到

DnY0m19iAgArMKjSP2Uvme8wOzb0iD==

从网上找个base64解码,套脚本就好

题目的解法很简单

关于smc可以看到

int __cdecl sub_4017AA(char a1)
{
  char *Str; // ST00_4@4
  char *MaxCount; // [sp+4h] [bp-200h]@3
  int DstBuf; // [sp+Eh] [bp-1F6h]@1
  __int16 v5; // [sp+12h] [bp-1F2h]@1
  int v6; // [sp+3Ch] [bp-1C8h]@1
  CHAR Filename; // [sp+40h] [bp-1C4h]@1
  char Str1; // [sp+144h] [bp-C0h]@1
  char Buf[60]; // [sp+1A8h] [bp-5Ch]@1
  unsigned int mum; // [sp+1E4h] [bp-20h]@1
  FILE *v11; // [sp+1E8h] [bp-1Ch]@4
  char *v12; // [sp+1FCh] [bp-8h]@1

  v12 = &a1;
  sub_401EE0();
  puts("Sorroundings...Weird..");
  mum = 0;
  memset(Buf, 0, sizeof(Buf));
  memset(&Str1, 0, 0x64u);
  memset(&Filename, 0, 0x104u);
  DstBuf = 0;
  v6 = 0;
  memset((&v5 & 0xFFFFFFFC), 0, 4 * (((&DstBuf + -(&v5 & 0xFFFFFFFC) + 50) & 0xFFFFFFFC) >> 2));
  puts("I see!It's not my fault!Wrong is the world!");
  puts("So..Now I should give a shot to fix it!");
************************************************************************
  scanf("%u", &mum);    //输入一个数字
  if ( mum > 0x20000 )  //判断输入数字大小
    sub_40178C();      
  getchar();                 //吃掉回车
  sub_401460(mum);   //关键
  puts("And then,a shiny explosion!");
  fgets(Buf, 59, iob);
  Buf[strlen(Buf) - 1] = 0;
  if ( strlen(Buf) != 22 )
    sub_40178C();
**************************************************************************
  puts("Seems I have passed a test.");
  sub_4014FA(Str, MaxCount);
  GetModuleFileNameA(0, &Filename, 0x104u);
  v11 = fopen(&Filename, "rb");
  fseek(v11, -32, 2);
  fread(&DstBuf, 0x20u, 1u, v11);
  fclose(v11);
  if ( !strcmp(&Str1, &DstBuf) )
  {
    puts("Congratulations!");
    puts("The flag is hgame{your input string + your input num}");
    puts("e.g:hgame{aaaaaaaaaa111}");
  }
  else
  {
    printf("But Failed..Finally");
  }
  return 0;
}

进入sub_401460函数

BOOL __cdecl sub_401460(unsigned int a1)
{
  DWORD flOldProtect; // [sp+14h] [bp-14h]@1
  unsigned int v3; // [sp+18h] [bp-10h]@1
  unsigned int v4; // [sp+1Ch] [bp-Ch]@1

  flOldProtect = 0;
  VirtualProtect(TopLevelExceptionFilter, 0x4000u, 0x40u, &flOldProtect);//更改页属性
  v4 = a1 >> 3;  
  v3 = a1 & 7;   
  *(TopLevelExceptionFilter + (a1 >> 3)) ^= 1 << (a1 & 7);
  return VirtualProtect(TopLevelExceptionFilter, 0x4000u, flOldProtect, &flOldProtect);  //基址是TopLevelExceptionFilter ,0x401000
}

做的时候并没有太注意,没有详细分析。当喵说了安卓的smc的时候才知道这个也是更改了某个地址。

*(TopLevelExceptionFilter + (a1 >> 3)) ^= 1 << (a1 & 7);
[地址基址 + (输入的数字右移三位)] 和输入数字的后三位异或]
7 bin 0111
后边3位可以与某个地址异或,剩下的几位作为地址偏移来改变某一地方。

hgame ShinyShot!_第3张图片
图片.png

查看反汇编发现了此处跳传导致sub_4014FA函数没有参数进栈。
这两个参数的作用是显示出


图片.png

怎么能保证正常跳转呢?这就需要使用上面分析的,将jmp short loc_4018F5改为jmp short loc_4018E5

jmp short loc_4018F5的机器码为 EB 15;JMP的机器码为EB,15为偏移。

0x15 = 0x4018F5 - 0x4018DE - jmp长度(2byte)

那么跳到 loc_4018E5就是

x4018E5-0x4018DE-0x2=0x5

所以输入数字最低三位应为100
要修改的字节的地址是0x4018DF ,所以输入的数字:
mum=(0x8df<<3) + 0x4 = 0x46FC=18172
(当然可以直接在文件中更改


图片.png

这样这个题目也算是完整了:
Byt3_H4cker_sho0O0o0t!


hgame ShinyShot!_第4张图片
图片.png

总结:和安卓的那个smc很像,基本可以归为一类但实现smc的方法明显安卓的要复杂不少。

你可能感兴趣的:(hgame ShinyShot!)