简单逆向20(z3使用,算法逆向)

35 篇文章 5 订阅

诺莫20

知识点:
z3使用,算法逆向

开始:

放入IDA:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // esi
  unsigned int v4; // kr00_4
  char v5; // bl
  unsigned int v6; // eax
  char *v7; // edx
  char v8; // cl
  int v9; // eax
  char v11[80]; // [esp+8h] [ebp-A4h]
  char v12[80]; // [esp+58h] [ebp-54h]

  sub_401020((int)"Please input your flag: ");
  sub_401050("%40s", v12);
  memset(v11, 0, 0x50u);
  v3 = 0;
  v4 = strlen(v12);
  if ( v4 )
  {
    do
    {
      v5 = v12[v3];
      v6 = 0;
      do
      {
        v7 = &v11[v6 + v3];
        v8 = v5 ^ byte_41C658[v6++];
        *v7 += v8;                              // V11[V6 + V3] += V5 ^ BYTE_41C658[V6++];
                                                // V6++;


      }
      while ( v6 < 0x20 );
      ++v3;
    }
    while ( v3 < v4 );
  }
  v9 = strcmp(v11, (const char *)&unk_41E8B0);
  if ( v9 )
    v9 = -(v9 < 0) | 1;
  if ( v9 )
    puts("No, it isn't.");
  else
    puts("Yes, it is.");
  return 0;
}

逻辑很清晰,只是逆向有迭代,很难,直接使用z3模块

逆向:

from z3 import*
data1 = [0x72, 0xE9, 0x4D, 0xAC, 0xC1, 0xD0, 0x24, 0x6B, 0xB2, 0xF5, 0xFD, 0x45, 0x49, 0x94, 0xDC, 0x10, 0x10, 0x6B, 0xA3, 0xFB, 0x5C, 0x13, 0x17, 0xE4, 0x67, 0xFE, 0x72, 0xA1, 0xC7, 0x04, 0x2B, 0xC2, 0x9D, 0x3F, 0xA7, 0x6C, 0xE7, 0xD0, 0x90, 0x71, 0x36, 0xB3, 0xAB, 0x67, 0xBF, 0x60, 0x30, 0x3E, 0x78, 0xCD, 0x6D, 0x35, 0xC8, 0x55, 0xFF, 0xC0, 0x95, 0x62, 0xE6, 0xBB, 0x57, 0x34, 0x29, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
data2 = [0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x3A, 0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x7B,0x7C,0x7D,0x7E]  #"!\"#$%&',27h,'()*+,-./:;<=>?@[\]^_`{|}~"
flag = ""
m = Solver()
B = [BitVec("x%s"%i,8) for i in range(0x22)] 
v6 = 0
v11 = [0] * 65
for i in range(0x22):
    for j in range(0x20):
        v11[j + i] += B[i] ^ data2[j]
for i in range(0x41):
    m.add(v11[i] == data1[i])
print(m.check())
c = m.model()
print(c)
flag = ""
for i in range(0x22):
    print(c[B[i]],end = ",")
print()
n = [83,89,67,123,52,43,109,105,108,101,43,98,51,103,105,110,43,119,105,116,104,43,115,105,110,103,49,101,43,115,116,101,112,125]
for i in n:
    flag += chr(i)
print(flag)

'''
do
{
  v5 = v12[i];
  v6 = 0;
  do
  {
     v11[V6 + i] = v5 ^ BYTE_41C658[v6];  
     v6++;                         
  }
  while ( v6 < 32 );
  ++i;
}
while ( i < len(v12) );
'''


解释:
1.BitVec(“x%s”%i,8):

Int #整型
Bool #布尔型
Array #数组
BitVec(‘a’,8) #char型 不一定是8,更具当时环境定制
Real #实型
具体参考

2.为什么是0x22和0x20:

在这里插入图片描述
v11中,我们找到的有效数据(到0)一共65个(0x41),byte_41C658中有31(0x20-1)个。使用输入字符的长度为: 65 - 31 = 34(0x22)个

3.z3中python代码中可以将未知数赋值为表达式:

这里v11中元素的类型为:
在这里插入图片描述
输出:

<class 'z3.z3.BitVecRef'>
sat
[x9 = 101,
 x8 = 108,
 x14 = 105,
 x28 = 43,
 x31 = 101,
 x15 = 110,
 x27 = 101,
 x29 = 115,
 x18 = 105,
 x22 = 115,
 x0 = 83,
 x3 = 123,
 x7 = 105,
 x13 = 103,
 x23 = 105,
 x11 = 98,
 x30 = 116,
 x20 = 104,
 x1 = 89,
 x10 = 43,
 x16 = 43,
 x25 = 103,
 x21 = 43,
 x26 = 49,
 x32 = 112,
 x33 = 125,
 x6 = 109,
 x2 = 67,
 x19 = 116,
 x12 = 51,
 x24 = 110,
 x17 = 119,
 x4 = 52,
 x5 = 43]
83,89,67,123,52,43,109,105,108,101,43,98,51,103,105,110,43,119,105,116,104,43,115,105,110,103,49,101,43,115,116,101,112,125,
SYC{4+mile+b3gin+with+sing1e+step}

但有个疑问我还没搞懂,如果把data2换成字符串转ascii,就会报错
在这里插入图片描述

简单逆向10中,我们使用了z3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I Am Rex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值