本帖最后由 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;
}
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为啥要去掉?
|