IDA解CTF reverse题时关于字符数组下标的一个问题
本帖最后由 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
if ( a2 < result && i < result )
{
do
{
if ( v6 > *(_DWORD *)(a1 + 4 * result) ) //a1
{
if ( i >= result )
break;
++i;
*(_DWORD *)(v5 + a1) = *(_DWORD *)(a1 + 4 * result); //a1=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=a1
}
--result;
}
while ( i < result );
}
LABEL_13:
*(_DWORD *)(a1 + 4 * result) = v6; //a1=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; //4*i也改成i了
if( a2 < result && i < result )
{
do{
if(v6>(a1))
{
if(i>=result)
break;
++i;
a1 = a1;
if(i>=result)
break;
while(a1<=v6)
{
if(++i>=result)
goto LABEL_13;
}
if(i>=result)
break;
v5 = i; //4*i也改掉了
a1 = a1;
}
--result;
}while(i<result);
}
LABEL_13:
a1 = v6;
a(a1,a2,i-1);
result = a3;
++i;
}
```
# 我自己一开始是直接把IDA里的代码复现过来,但是最终出来的答案是错的。把全部4\*都去掉以后就可以算出正确答案。想问下各位大佬们,这里的4*i为啥要去掉? Deuez 发表于 2020-4-30 13:16
上网课中,,没仔细看代码,看了下描述,觉得说的可能是int类型占的是4字节吧,然后指针找地址时候偏移就要 ...
感谢,你这么一说恍然大悟,应该是这个问题了。 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
指针也是有类型的,你指针类型是int,,,,,有vs的话可以去内存窗口看看,或者安装一个vc++6.0,调试去 ...
了解了,感谢大佬
页:
[1]