吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1237|回复: 7
收起左侧

[新手问题] IDA解CTF reverse题时关于字符数组下标的一个问题

[复制链接]
deoplljj 发表于 2020-4-30 11:40
本帖最后由 deoplljj 于 2020-4-30 11:41 编辑

这是BUUCTF re的“刮开有奖”一题。下面是IDA解开的一段关键的字符数组运算代码。

a1是一个字符数组的头指针

int __cdecl sub_CD10F0(int a1, int a2, int a3)
{
  int result; // eax
  int i; // esi
  int v5; // ecx
  int v6; // edx

  result = a3;
  for ( i = a2; i <= a3; a2 = i )
  {
    v5 = 4 * i;     //这里乘了4
    v6 = *(_DWORD *)(4 * i + a1);    //a1[4*i]里面也乘了4
    if ( a2 < result && i < result )
    {
      do
      {
        if ( v6 > *(_DWORD *)(a1 + 4 * result) )       //a1[4*result]
        {
          if ( i >= result )
            break;
          ++i;
          *(_DWORD *)(v5 + a1) = *(_DWORD *)(a1 + 4 * result);      //a1[v5]=4*result
          if ( i >= result )
            break;
          while ( *(_DWORD *)(a1 + 4 * i) <= v6 )
          {
            if ( ++i >= result )
              goto LABEL_13;
          }
          if ( i >= result )
            break;
          v5 = 4 * i;    //乘了4
          *(_DWORD *)(a1 + 4 * result) = *(_DWORD *)(4 * i + a1);     //a1[4*result]=a1[4*i]
        }
        --result;
      }
      while ( i < result );
    }
LABEL_13:
    *(_DWORD *)(a1 + 4 * result) = v6;     //a1[4*result]=v6
    sub_CD10F0(a1, a2, i - 1);
    result = a3;
    ++i;
  }
  return result;
}

但是根据网上师傅们的wp(https://zhuanlan.zhihu.com/p/100934324 ),自己重新在IDE里面复现代码的时候,这些地方的乘4全部都不要了?

for(i=a2;i<=a3;a2=i)
        {
                v5 = i;     //原来是4*i
                v6 = a1[i];        //4*i也改成i了
                if( a2 < result && i < result )
                {
                 do{
                         if(v6>(a1[result]))
                         {
                                 if(i>=result)
                                         break;
                                 ++i;
                                 a1[v5] = a1[result];
                                 if(i>=result)
                                         break;
                                 while(a1[i]<=v6)
                                 {
                                         if(++i>=result)
                                         goto LABEL_13;
                                 }
                                 if(i>=result)
                                         break;
                                 v5 = i;     //4*i也改掉了
                                 a1[result] = a1[i];
                         }
                         --result;
                 }while(i<result);
                 }
                 LABEL_13:
                         a1[result] = v6;
                         a(a1,a2,i-1);
                         result = a3;
                         ++i;

        }

我自己一开始是直接把IDA里的代码复现过来,但是最终出来的答案是错的。把全部4*都去掉以后就可以算出正确答案。想问下各位大佬们,这里的4*i为啥要去掉?

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

头像被屏蔽
Deuez 发表于 2020-4-30 13:16
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| deoplljj 发表于 2020-4-30 13:28
Deuez 发表于 2020-4-30 13:16
上网课中,,没仔细看代码,看了下描述,觉得说的可能是int类型占的是4字节吧,然后指针找地址时候偏移就要 ...

感谢,你这么一说恍然大悟,应该是这个问题了。
 楼主| deoplljj 发表于 2020-4-30 13:40
Deuez 发表于 2020-4-30 13:16
上网课中,,没仔细看代码,看了下描述,觉得说的可能是int类型占的是4字节吧,然后指针找地址时候偏移就要 ...

但是我自己实验了一下,似乎还是有点不太明白

int a[]={100,200};
printf("%d",(*(a+1)));

这样会输出200,但是把a+1改成a+4会直接溢出。
是因为这样直接用指针运算和IDA中的(_DWORD )的效果是不一样的原因还是..?

头像被屏蔽
Deuez 发表于 2020-4-30 13:43
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽
Deuez 发表于 2020-4-30 13:46
提示: 作者被禁止或删除 内容自动屏蔽
头像被屏蔽
Deuez 发表于 2020-4-30 13:47
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| deoplljj 发表于 2020-4-30 13:47
Deuez 发表于 2020-4-30 13:43
指针也是有类型的,你指针类型是int,,,,,有vs的话可以去内存窗口看看,或者安装一个vc++6.0,调试去 ...

了解了,感谢大佬
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-25 10:11

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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