逆向2

学习记录!
peid查看下发现加壳了的。不是很难的一个壳。双击运行下如下图:


OD载入查找字符串,发现并没有效果。先脱壳再说吧。
00401220 > $  B8 DC0F4500   mov eax,crackme4.00450FDC
00401225   ?  50            push eax
00401226   .  64:FF35 00000>push dword ptr fs:[0]
0040122D   .  64:8925 00000>mov dword ptr fs:[0],esp ;在这里对esp下硬件断点,再运行
00401234   ?  33C0          xor eax,eax
00401236   ?  8908          mov dword ptr ds:[eax],ecx

接下来来到:
0045100B    83C4 04         add esp,0x4
0045100E    55              push ebp
0045100F    53              push ebx
00451010    51              push ecx
00451011    57              push edi
00451012    56              push esi
00451013    52              push edx
00451014    8D98 57121600   lea ebx,dword ptr ds:[eax+0x161257]
0045101A    8B53 18         mov edx,dword ptr ds:[ebx+0x18]
0045101D    52              push edx
0045101E    8BE8            mov ebp,eax
00451020    6A 40           push 0x40
00451022    68 00100000     push 0x1000
00451027    FF73 04         push dword ptr ds:[ebx+0x4]
0045102A    6A 00           push 0x0
0045102C    8B4B 10         mov ecx,dword ptr ds:[ebx+0x10]
0045102F    03CA            add ecx,edx
00451031    8B01            mov eax,dword ptr ds:[ecx]
00451033    FFD0            call eax  ;调用VirtualAlloc 继续运行
00451035    5A              pop edx

然后会在这里断下:
0045109D    5D              pop ebp                                  ; 0028FF94
0045109E    FFE0            jmp eax
运行完后就会跳转到oep处,dump下来即可,这个壳网上的例子很多。
用IDA分析会直接来到main处,查看整个函数,很容易发现gets函数,控制台的程序用gets获取字符串也很正常。
.text:0040144C                 movzx   eax, byte_440035
.text:00401453                 mov     [ebp+var_60], al
.text:00401456                 lea     eax, [ebp+var_28]
.text:00401459                 mov     [esp], eax      ; char *
.text:0040145C                  call    sub_401756
.text:00401461                 lea     eax, [ebp+var_38]
.text:00401464                 mov     [esp], eax      ; char *
.text:00401467                  call    sub_401756
.text:0040146C                 lea     eax, [ebp+var_88]
.text:00401472                 mov     [esp], eax
.text:00401475                 call    sub_40152E
.text:0040147A                 lea     eax, [ebp+var_48]
.text:0040147D                 mov     [esp], eax      ; char *
.text:00401480                  call    sub_401756
.text:00401485                 lea     eax, [ebp+var_B8]
.text:0040148B                 mov     [esp], eax      ; char *
.text:0040148E                 call    gets
.text:00401493                 lea     eax, [ebp+var_C8]
同样用OD载入在40148E处断,如下图 在输入password时才断,说明前面还有一个gets 先不管,注意已经写到内存28FE90处了。

下面一个函数4016F2用IDA跟进参数为地址28FE80处
int __cdecl sub_4016F2(int a1)
{
  int result; // eax@1

  *(_BYTE *)a1 = 118;
  *(_BYTE *)(a1 + 7) = 91;
  *(_BYTE *)(a1 + 1) = 3;
  *(_BYTE *)(a1 + 5) = 85;
  *(_BYTE *)(a1 + 2) = 64;
  *(_BYTE *)(a1 + 9) = 100;
  *(_BYTE *)(a1 + 3) = 112;
  *(_BYTE *)(a1 + 4) = 2;
  *(_BYTE *)(a1 + 6) = 91;
  *(_BYTE *)(a1 + 8) = 5;
  result = a1 + 10;
  *(_BYTE *)(a1 + 10) = 0;
  return result;
}
就是将这些值写进去10个字节
0028FE80  76 03 40 70 02 55 5B 5B 05 64 00 00 F8 FE 28 00  v@pU[[d..(.
0028FE90  31 32 33 34 35 00 80 02 FE FF FF FF AA 38 DE 77  12345.€??辸
0028FEA0  A2 34 DE 77 00 00 00 00 98 2F 7E 00 98 2F 7E 00  ?辸....?~.?~.
0028FEB0  00 00 00 00 00 00 00 00 90 2F 7E 00 08 FF 28 00  ........?~.(.
0028FEC0  37 33 38 38 37 38 36 35 00 00 00 00 DA 98 F9 76  73887865....跇鵹

上一行为写进去的值每次不变,下一行是自己输入的password。这里应该输入10个字符的。接着向下运行

004014AB  |> /83BD 34FFFFFF>/cmp [local.51],0x9                      ;  循环10次
004014B2  |. |7F 58         |jg Xduan. 0040150C
004014B4  |. |8D45 F8       |lea eax,[local.2]
004014B7  |. |0385 34FFFFFF |add eax,[local.51]
004014BD  |. |2D C0000000   |sub eax,0xC0                            ;  0028FE80 自动生成的那个字符串
004014C2  |. |0FBE10        |movsx edx,byte ptr ds:[eax]             ;  取一个字符给edx
004014C5  |. |8D45 F8       |lea eax,[local.2]
004014C8  |. |0385 34FFFFFF |add eax,[local.51]
004014CE  |. |2D B0000000   |sub eax,0xB0                            ;  0028FE90 输入的password
004014D3  |. |0FBE00        |movsx eax,byte ptr ds:[eax]             ;  取一个字符给eax
004014D6  |. |31C2          |xor edx,eax                             ;  将取的两个字符异或
004014D8  |. |8D45 F8       |lea eax,[local.2]
004014DB  |. |0385 34FFFFFF |add eax,[local.51]
004014E1  |. |83C0 80       |add eax,-0x80                           ;  0028FEC0  另外的字符串
004014E4  |. |0FBE00        |movsx eax,byte ptr ds:[eax]             ;  取一个给eax
004014E7  |. |39C2          |cmp edx,eax
004014E9  |. |74 17         |je Xduan. 00401502                       ;  相等循环下一次 否则失败
004014EB  |. |8D45 A8       |lea eax,[local.22]
004014EE  |. |890424        |mov dword ptr ss:[esp],eax
004014F1  |. |E8 60020000    |call duan.00401756  ;失败
004014F6  |. |C785 30FFFFFF>|mov [local.52],0x0
00401500  |. |EB 24         |jmp Xduan.00401526
00401502  |> |8D85 34FFFFFF |lea eax,[local.51]
00401508  |. |FF00          |inc dword ptr ds:[eax]    ;加1
0040150A  |.^\EB 9F         \jmp Xduan. 004014AB
0040150C  |>  8D45 98       lea eax,[local.26]
0040150F  |.  890424        mov dword ptr ss:[esp],eax
00401512  |.  E8 3F020000   call duan.00401756
00401517  |.  E8 44D20000   call <jmp.&msvcrt._getch>                ; [_getch
0040151C  |.  C785 30FFFFFF>mov [local.52],0x0
00401526  |>  8B85 30FFFFFF mov eax,[local.52]
0040152C  |.  C9            leave
0040152D  \.  C3            retn
说明10次异或成功应该能成功,重新运行输入xdsec,1234567890.发现28FEC0处的变了,说明这个字符串与输入的name有关,不过这里并不需要了解是怎么转变的,新的字符串为
0028FEC0  38 33 37 33 37 34 38 30 36 36 00 00 DA 98 F9     8373748066..跇鵹
将这个字符串与28FE80处的异或即可得到password为4E3077433561636B3352(十六进制)字符串为N0wC5ack3R。
接下来看看name字符串是怎么变形的,在gets函数上有两个函数调用,分别断即可找到。
signed int __cdecl sub_40152E(int a1)
{
  signed int result; // eax@11
  signed int i; // [sp+28h] [bp-30h]@1
  signed int j; // [sp+28h] [bp-30h]@10
  size_t v4; // [sp+2Ch] [bp-2Ch]@1
  char v5; // [sp+30h] [bp-28h]@1
  char v6[8]; // [sp+50h] [bp-8h]@3

  gets(&v5);
  v4 = strlen(&v5);
  for ( i = 0; i < (signed int)v4; ++i )
  {
    if ( v6[i - 32] <= 96 || v6[i - 32] > 122 )
    {
      if ( v6[i - 32] > 64 )
      {
        if ( v6[i - 32] <= 90 )
          v6[i - 32] = (7 * (v6[i - 32] - 65) + 13) % 26 + 65;
      }
    }
    else
    {
      v6[i - 32] = (7 * (v6[i - 32] - 97) + 13) % 26 + 65;
    }
  }
  for ( j = 0; ; ++j )
  {
    result = j;
    if ( j >= (signed int)v4 )
      break;
    *(_BYTE *)(a1 + 2 * j) = v6[j - 32] / 10 + 48;
    *(_BYTE *)(a1 + 2 * j + 1) = v6[j - 32] % 10 + 48;
    *(_BYTE *)(a1 + 2 * j + 2) = 0;
  }
  return result;
}
分析得y=7*(x+13)mod26+65,是一个放射密码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值