吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4223|回复: 19
收起左侧

[原创] 10月安恒逆向第一题详细分析

[复制链接]
52lxw 发表于 2018-10-29 13:24
首先用PEiD查一下编译器和壳,发现有UPX壳,直接用吾爱的upx脱壳机脱壳

IDA反编译,得到如下:
[C] 纯文本查看 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  const char *v3; // eax
  int v5; // [esp+14h] [ebp-2Ch]
  char result; // [esp+1Ah] [ebp-26h]
  char input; // [esp+29h] [ebp-17h]
  int tree; // [esp+38h] [ebp-8h]
  int *start; // [esp+3Ch] [ebp-4h]

  sub_402400();
  v5 = 0;
  start = &v5;
  welcome();
  gets(&input);
  if ( strlen(&input) != 15 )
  {
    printf("Nah... ur a fake reverser!");
    exit(0);
  }
  tree = init(&input, 15);
  pre(tree, start, (int)&result);
  v3 = base64(&result);                         // base64加密
  if ( !strncmp(v3, "aWNuZXJyc2VhZXRydmVl", 0x14u) )
  {
    puts("well done bro!");
    printf("ur really know something about tree!");
  }
  else
  {
    printf("Nah.. ur an idiot!");
  }
  return 0;
}

题目给出提示是tree
进入init函数发现是用用户的输入初始化二叉树
[C] 纯文本查看 复制代码
v13 = 1;
  i_1 = 0;
  v11 = 0;
  p = (int *)malloc(4 * len);
  while ( i_1 < len ) //初始化用户的输入数据
  {
    sub_402B70(2.0, (long double)(v13 - 1));
    v6 = (signed int)(double)2.0;
    v10 = 0;
    for ( i = 0; i < v6; ++i )
    {
      v5 = i_1 + i;
      if ( i_1 + i >= len )
        break;
      v8 = 0;
      if ( input[v5] != '#' )
      {
        v8 = malloc(12u);
        *(_BYTE *)v8 = input[v5];
        v8[1] = 0;
        v8[2] = 0;
        p[v5] = (int)v8;
      }
      if ( i_1 > 0 )
      {
        v4 = p[v11 + v10];
        if ( i & 1 )
        {
          *(_DWORD *)(v4 + 8) = v8;//右子树
          ++v10;
        }
        else
        {
          *(_DWORD *)(v4 + 4) = v8; //左子树
        }
      }
    }
    v11 = i_1;
    i_1 += v6;
    ++v13;
  }

然后pre函数进行前序遍历,将遍历的结果保存在result_1这个数组里面
[C] 纯文本查看 复制代码
int __cdecl pre(int a, _DWORD *cnt, int *result_1)
{
int i; // eax
int result; // eax

if ( a )
{
i = (*cnt)++;
*((_BYTE *)result_1 + i) = *(_BYTE *)a;
pre(*(_DWORD *)(a + 4), cnt, result_1);
result = pre(*(_DWORD *)(a + 8), cnt, result_1);
}
return result;
}
//------------------------
对应的C前序遍历的源码
void print_preorder(node * tree) {
if(tree) {
printf("%d\n",tree->data);
print_preorder(tree->left);
print_preorder(tree->right);
}
}

最后用base64加密前序遍历的结果:
[C] 纯文本查看 复制代码
_BYTE *__cdecl sub_401794(char *a1)
{
  _BYTE *v2; // [esp+18h] [ebp-20h]
  signed int v3; // [esp+1Ch] [ebp-1Ch]
  int v4; // [esp+24h] [ebp-14h]
  int v5; // [esp+28h] [ebp-10h]
  int v6; // [esp+2Ch] [ebp-Ch]

  v3 = strlen(a1);
  if ( v3 % 3 )
    v6 = 4 * (v3 / 3 + 1);
  else
    v6 = 4 * (v3 / 3);
  v2 = malloc(v6 + 1);
  v2[v6] = 0;
  v5 = 0;
  v4 = 0;
  while ( v6 - 2 > v5 )
  {
    v2[v5] = aAbcdefghijklmn[(unsigned __int8)a1[v4] >> 2];
    v2[v5 + 1] = aAbcdefghijklmn[16 * (a1[v4] & 3) | ((unsigned __int8)a1[v4 + 1] >> 4)];
    v2[v5 + 2] = aAbcdefghijklmn[4 * (a1[v4 + 1] & 0xF) | ((unsigned __int8)a1[v4 + 2] >> 6)];
    v2[v5 + 3] = aAbcdefghijklmn[a1[v4 + 2] & 0x3F];
    v4 += 3;
    v5 += 4;
  }
  if ( v3 % 3 == 1 )
  {
    v2[v5 - 2] = '=';
    v2[v5 - 1] = '=';
  }
  else if ( v3 % 3 == 2 )
  {
    v2[v5 - 1] = '=';
  }
  return v2;
}
与网上的base64源码比较:
[color=#0000ff]const[/color] [color=#0000ff]char[/color] * base64char = [color=#800000]"[/color][color=#800000]ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/[/color][color=#800000]"[/color][color=#000000];[/color][color=#0000ff]char[/color] * base64_encode( [color=#0000ff]const[/color] unsigned [color=#0000ff]char[/color] * bindata, [color=#0000ff]char[/color] * base64, [color=#0000ff]int[/color][color=#000000] binlength ){    [/color][color=#0000ff]int[/color][color=#000000] i, j;    unsigned [/color][color=#0000ff]char[/color][color=#000000] current;    [/color][color=#0000ff]for[/color] ( i = [color=#800080]0[/color], j = [color=#800080]0[/color] ; i < binlength ; i += [color=#800080]3[/color][color=#000000] )    {        current [/color]= (bindata[i] >> [color=#800080]2[/color][color=#000000]) ;        current [/color]&= (unsigned [color=#0000ff]char[/color])[color=#800080]0x3F[/color][color=#000000];        base64[j[/color]++] = base64char[([color=#0000ff]int[/color][color=#000000])current];        current [/color]= ( (unsigned [color=#0000ff]char[/color])(bindata[i] << [color=#800080]4[/color] ) ) & ( (unsigned [color=#0000ff]char[/color])[color=#800080]0x30[/color][color=#000000] ) ;        [/color][color=#0000ff]if[/color] ( i + [color=#800080]1[/color] >=[color=#000000] binlength )        {            base64[j[/color]++] = base64char[([color=#0000ff]int[/color][color=#000000])current];            base64[j[/color]++] = [color=#800000]'[/color][color=#800000]=[/color][color=#800000]'[/color][color=#000000];            base64[j[/color]++] = [color=#800000]'[/color][color=#800000]=[/color][color=#800000]'[/color][color=#000000];            [/color][color=#0000ff]break[/color][color=#000000];        }[/color]
[color=#000000]        current [/color]|= ( (unsigned [color=#0000ff]char[/color])(bindata[i+[color=#800080]1[/color]] >> [color=#800080]4[/color]) ) & ( (unsigned [color=#0000ff]char[/color]) [color=#800080]0x0F[/color][color=#000000] );        base64[j[/color]++] = base64char[([color=#0000ff]int[/color][color=#000000])current];        current [/color]= ( (unsigned [color=#0000ff]char[/color])(bindata[i+[color=#800080]1[/color]] << [color=#800080]2[/color]) ) & ( (unsigned [color=#0000ff]char[/color])[color=#800080]0x3C[/color][color=#000000] ) ;        [/color][color=#0000ff]if[/color] ( i + [color=#800080]2[/color] >=[color=#000000] binlength )        {            base64[j[/color]++] = base64char[([color=#0000ff]int[/color][color=#000000])current];            base64[j[/color]++] = [color=#800000]'[/color][color=#800000]=[/color][color=#800000]'[/color][color=#000000];            [/color][color=#0000ff]break[/color][color=#000000];        }        current [/color]|= ( (unsigned [color=#0000ff]char[/color])(bindata[i+[color=#800080]2[/color]] >> [color=#800080]6[/color]) ) & ( (unsigned [color=#0000ff]char[/color]) [color=#800080]0x03[/color][color=#000000] );        base64[j[/color]++] = base64char[([color=#0000ff]int[/color][color=#000000])current];        current [/color]= ( (unsigned [color=#0000ff]char[/color])bindata[i+[color=#800080]2[/color]] ) & ( (unsigned [color=#0000ff]char[/color])[color=#800080]0x3F[/color][color=#000000] ) ;        base64[j[/color]++] = base64char[([color=#0000ff]int[/color][color=#000000])current];    }    base64[j] [/color]= [color=#800000]'[/color][color=#800000]\0[/color][color=#800000]'[/color][color=#000000];    [/color][color=#0000ff]return[/color][color=#000000] base64;}[/color]

这里识别是base64可以用PEiD的密码学插件Krypto ANALyzer,也可以通过代码里的0x3f,>>2,>>4等特征来识别
if ( !strncmp(v3, "aWNuZXJyc2VhZXRydmVl", 0x14u) )
  {
    puts("well done bro!");
    printf("ur really know something about tree!");
  }
  else
  {
    printf("Nah.. ur an idiot!");
  }
最后比较base64之后的结果

那flag就是base64解码,然后模仿一下前序遍历就行了
In [2]: base64.b64decode("aWNuZXJyc2VhZXRydmVl")
Out[2]: b'icnerrseaetrvee'

免费评分

参与人数 5吾爱币 +11 热心值 +5 收起 理由
Hmily + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
JMCSec + 1 + 1 我很赞同!
xinkui + 1 + 1 谢谢@Thanks!
spll6 + 1 + 1 用心讨论,共获提升!
姚小宝 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yssun 发表于 2018-10-29 16:55
学习中,不错不错,高手
spll6 发表于 2018-10-29 17:16
emmet_mayi 发表于 2018-10-29 17:26
0232 发表于 2018-10-29 17:33
谢谢了!!!!!!!!!
河北网友 发表于 2018-10-29 17:41
谢谢分享
 楼主| 52lxw 发表于 2018-10-29 17:55
题目文件下载链接: https://pan.baidu.com/s/1vptBYyCO4Woyjk4mEvVu8A 提取码: eqmt
wisoft 发表于 2018-10-29 18:33
都考数据结构了,哎,越来越偏专业了
zhangyu19546 发表于 2018-10-29 21:48
感谢分享
kenxue0721 发表于 2018-10-29 22:50
10月安恒逆向第一题详细分析,用PEID查一下编译器和壳,用IDA反编译。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 00:53

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表