BUUCTF reverse wp 6 - 10

helloword

安卓逆向, 工具下载
https://github.com/Juude/droidReverse
打开就有flag
BUUCTF reverse wp 6 - 10_第1张图片

BUUCTF reverse wp 6 - 10_第2张图片

xor

BUUCTF reverse wp 6 - 10_第3张图片
当前位或异或前一位得到加密后的字符, 一共33位, 逐位异或, global数据是硬编码的, 所以简单解密即可.
查看16进制格式, 复制到脚本里, 正则处理数据成hex格式.
BUUCTF reverse wp 6 - 10_第4张图片在这里插入图片描述调整一下
在这里插入图片描述rev脚本

enc = [0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11, 0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 
       0x19, 0x46, 0x1F, 0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F, 0x47, 0x32, 0x4F, 0x00
]

flag = chr(enc[0])
for n in range(1, len(enc)):
    flag += chr(enc[n] ^ enc[n - 1])
print(flag)

flag{QianQiuWanDai_YiTongJiangHu}O 去掉最后一位
flag{QianQiuWanDai_YiTongJiangHu}

reverse3

BUUCTF reverse wp 6 - 10_第5张图片
在这里插入图片描述

经过sub_4110BE加密后做一个递增加处理, 然后和str2比较.
BUUCTF reverse wp 6 - 10_第6张图片在这里插入图片描述
应该就是base64编码了, 先从整体上猜测, 然后验证, 这样逆向分析速度会更快.
rev脚本

from base64 import *

str_enc = 'e3nifIH9b_C@n@dH'
flag = ''
for i in range(len(str_enc)):
    flag += chr(ord(str_enc[i]) - i)

print(b64decode(flag))

flag{i_l0ve_you}

不一样的flag

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  char v3[29]; // [esp+17h] [ebp-35h] BYREF
  int v4; // [esp+34h] [ebp-18h]
  int v5; // [esp+38h] [ebp-14h] BYREF
  int i; // [esp+3Ch] [ebp-10h]
  _BYTE v7[12]; // [esp+40h] [ebp-Ch] BYREF

  __main();
  v4 = 0;
  strcpy(v3, "*11110100001010000101111#");
  while ( 1 )
  {
    puts("you can choose one action to execute");
    puts("1 up");
    puts("2 down");
    puts("3 left");
    printf("4 right\n:");
    scanf("%d", &v5);
    if ( v5 == 2 )
    {
      ++*(_DWORD *)&v3[25];
    }
    else if ( v5 > 2 )
    {
      if ( v5 == 3 )
      {
        --v4;
      }
      else
      {
        if ( v5 != 4 )
LABEL_13:
          exit(1);
        ++v4;
      }
    }
    else
    {
      if ( v5 != 1 )
        goto LABEL_13;
      --*(_DWORD *)&v3[25];
    }
    for ( i = 0; i <= 1; ++i )
    {
      if ( *(int *)&v3[4 * i + 25] < 0 || *(int *)&v3[4 * i + 25] > 4 )
        exit(1);
    }
    if ( v7[5 * *(_DWORD *)&v3[25] - 41 + v4] == 49 )
      exit(1);
    if ( v7[5 * *(_DWORD *)&v3[25] - 41 + v4] == 35 )
    {
      puts("\nok, the order you enter is the flag!");
      exit(0);
    }
  }
}

可以分析出来是map类型的问题, 在一个地图上分四个方向移动, 设竖直位置为y, 水平位置为x, 一开始都是0, 执行以flag为输入的一串操作后得到v7[5 * y - 41 + x] == 35即可通过验证.
BUUCTF reverse wp 6 - 10_第7张图片

转换成字符, 发现是碰到1就结束, 而最后要碰到"#"就能通过. 而计算的系数是5, 所以是5 * 5的map

s = '*11110100001010000101111#'
for i in range(0, 5):
    print(s[i * 5: i * 5 + 5])
*1111
01000
01010
00010
1111#

1 ↑
2 ↓
3 ←
4 →
所以flag就是
222441144222, 注意加flag{}

SimpleRev

BUUCTF reverse wp 6 - 10_第8张图片
在这里插入图片描述
找到交叉引用位置

unsigned __int64 Decry()
{
  char v1; // [rsp+Fh] [rbp-51h]
  int v2; // [rsp+10h] [rbp-50h]
  int v3; // [rsp+14h] [rbp-4Ch]
  int i; // [rsp+18h] [rbp-48h]
  int v5; // [rsp+1Ch] [rbp-44h]
  char src[8]; // [rsp+20h] [rbp-40h] BYREF
  __int64 v7; // [rsp+28h] [rbp-38h]
  int v8; // [rsp+30h] [rbp-30h]
  __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
  int v10; // [rsp+50h] [rbp-10h]
  unsigned __int64 v11; // [rsp+58h] [rbp-8h]

  v11 = __readfsqword(0x28u);
  *src = 0x534C43444ELL;
  v7 = 0LL;
  v8 = 0;
  v9[0] = 0x776F646168LL;
  v9[1] = 0LL;
  v10 = 0;
  text = join(key3, v9);
  strcpy(key, key1);
  strcat(key, src);
  v2 = 0;
  v3 = 0;
  getchar();
  v5 = strlen(key);
  for ( i = 0; i < v5; ++i )
  {
    if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
      key[i] = key[v3 % v5] + 32;
    ++v3;
  }
  printf("Please input your flag:");
  while ( 1 )
  {
    v1 = getchar();
    if ( v1 == 10 )
      break;
    if ( v1 == 32 )
    {
      ++v2;
    }
    else
    {
      if ( v1 <= 96 || v1 > 122 )
      {
        if ( v1 > 64 && v1 <= 90 )
        {
          str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
          ++v3;
        }
      }
      else
      {
        str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
        ++v3;
      }
      if ( !(v3 % v5) )
        putchar(32);
      ++v2;
    }
  }
  if ( !strcmp(text, str2) )
    puts("Congratulation!\n");
  else
    puts("Try again!\n");
  return __readfsqword(0x28u) ^ v11;
}

在这里插入图片描述
在这里插入图片描述
将数字转化为字符串分析一通, 得到更易读的代码

unsigned __int64 Decry()
{
  char in_ch; // [rsp+Fh] [rbp-51h]
  int len; // [rsp+10h] [rbp-50h]
  int j; // [rsp+14h] [rbp-4Ch]
  int i; // [rsp+18h] [rbp-48h]
  int key_len; // [rsp+1Ch] [rbp-44h]
  char src[8]; // [rsp+20h] [rbp-40h] BYREF
  __int64 v7; // [rsp+28h] [rbp-38h]
  int v8; // [rsp+30h] [rbp-30h]
  __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF
  int v10; // [rsp+50h] [rbp-10h]
  unsigned __int64 v11; // [rsp+58h] [rbp-8h]

  v11 = __readfsqword(0x28u);
  *src = 'SLCDN';
  v7 = 0LL;
  v8 = 0;
  v9[0] = 'wodah';
  v9[1] = 0LL;
  v10 = 0;
  text = join(key3, v9);                        // killshadow 注意v9是小端序所以要反过来接
  strcpy(key, key1);                            // ADSFK 只有从16进制窗口看的才是小端序正序
  strcat(key, src);                             // SLCDN 注意src是小端序所以要翻过来
                                                // key = ADSFKNDCLS
  len = 0;
  j = 0;
  getchar();
  key_len = strlen(key);
  for ( i = 0; i < key_len; ++i )
  {
    if ( key[j % key_len] > '@' && key[j % key_len] <= 'Z' )
      key[i] = key[j % key_len] + 32;
    ++j;
  }
  printf("Please input your flag:");
  while ( 1 )
  {
    in_ch = getchar();
    if ( in_ch == '\n' )
      break;
    if ( in_ch == ' ' )
    {
      ++len;
    }
    else
    {
      if ( in_ch <= '`' || in_ch > 'z' )
      {
        if ( in_ch > '@' && in_ch <= 'Z' )      // 大写字母和符号
        {
          str[len] = (in_ch - 39 - key[j % key_len] + 'a') % 26 + 'a';
          ++j;
        }
      }
      else                                      // 小写字母
      {
        str[len] = (in_ch - 39 - key[j % key_len] + 'a') % 26 + 'a';
        ++j;
      }
      if ( !(j % key_len) )
        putchar(32);
      ++len;
    }
  }
  if ( !strcmp(text, str) )
    puts("Congratulation!\n");
  else
    puts("Try again!\n");
  return __readfsqword(0x28u) ^ v11;
}

先处理key[]数组+32相当于小写化, 然后输入10个字符处理后再和text[]数组比较.

diction = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Key = "ADSFKNDCLS".lower()
text = "killshadow"
key_len = len(Key)

flag = ""
for i in range(10):
    for ch in diction:
        if (ord(ch) - 39 - ord(Key[i % key_len]) + ord('a')) % 26 + ord('a') == ord(text[i]):
            flag += ch
            break
print(flag)

KLDQCUDFZO



总结

记住看数据时, IDA从数字转字符串的时候是按正序显示, 所以如果表示成hex格式, 要注意小端序, 需要翻过来.

你可能感兴趣的:(逆向工程)