简单赋值语句的逆向

signed int __fastcall sub_401020(int a1)
{
  signed int v1; // edx@1
  signed int result; // eax@2

  v1 = 0;
  do
  {
    result = 0;
    do
    {
      *(_DWORD *)a1 = 0xFFEEFFEE;
      if ( !v1 )
      {
        *(_DWORD *)(a1 + 4) = 0xFEFEFEFE;
LABEL_5:
        *(_DWORD *)(a1 + 8) = 0xEFEFEFEF;
        goto LABEL_6;
      }
      *(_DWORD *)(a1 + 4) = 0xEFEFEFEF;
      if ( v1 != 9 )
        goto LABEL_5;
      *(_DWORD *)(a1 + 8) = 0xFEFEFEFE;
LABEL_6:
      if ( !result )
      {
        *(_DWORD *)(a1 + 12) = 0xFEFEFEFE;
LABEL_8:
        *(_DWORD *)(a1 + 16) = 0xEFEFEFEF;
        goto LABEL_9;
      }
      *(_DWORD *)(a1 + 12) = 0xEFEFEFEF;
      if ( result != 9 )
        goto LABEL_8;
      *(_DWORD *)(a1 + 16) = 0xFEFEFEFE;
LABEL_9:
      ++result;
      a1 += 20;
    }
    while ( result < 9 );
    ++v1;
  }
  while ( v1 < 9 );
  return result;
}


先贴出来IDA逆向之后的代码,然后一一来分析

题目来自于:百度杯十一月第三场Reverse03


两个do-while嵌套,然后范围都是0-9,可以看作两个for循环,即写成这样:

for(i=0;i<9;i++)
    for(j=0;j<9;j++){
    …………
    }

然后,省略号里面都是赋值语句,首先注意赋值的对象:

*(_DWORD *)(a1)
*(_DWORD *)(a1 + 4)
*(_DWORD *)(a1 + 8)
*(_DWORD *)(a1 + 12)
*(_DWORD *)(a1 + 16)
然后,LABEL_9的地方有:a1 += 20
所以这里的指针相当于是控制了5个数组,每次a1自增加之后,会要给5个数组的横坐标为v1,纵坐标为result的地方赋值(之后就用i,j了)
不妨设5个数组为a1,a2,a3,a4,a5
那么,a1数组都是同一个数:0xFFEEFFEE(代码中出现a1的地方只有一次)
a2和a4也比较好判断,因为相当于有个if-else代码:

      if ( !v1 )
      {
        *(_DWORD *)(a1 + 4) = 0xFEFEFEFE;
LABEL_5:
        *(_DWORD *)(a1 + 8) = 0xEFEFEFEF;
        goto LABEL_6;
      }
      *(_DWORD *)(a1 + 4) = 0xEFEFEFEF;

a2,也就是这里的(a1+4),可以看到,i为0的时候,赋值为0xFEFEFEFE,i不为0的时候,赋值为0xEFEFEFEF
a4同理不作分析
a3和a5是比较难判断的,自己一开始也判断错了,默认为跟a2和a4的格式相同
注意这样的if语句:
      if ( !v1 )
      {
        *(_DWORD *)(a1 + 4) = 0xFEFEFEFE;
LABEL_5:
        *(_DWORD *)(a1 + 8) = 0xEFEFEFEF;
        goto LABEL_6;
      }
      *(_DWORD *)(a1 + 4) = 0xEFEFEFEF;
      if ( v1 != 9 )
        goto LABEL_5;
      *(_DWORD *)(a1 + 8) = 0xFEFEFEFE;

goto语句:
当i不为0,会跳转到LABEL_5,执行(a1+8)的0xEFEFEFEF的赋值,然后跳转到LABEL_6
当i为0,也会执行(a1+8)的0xEFEFEFEF的赋值,然后跳转到LABEL_6
所以,*(_DWORD *)(a1 + 8) = 0xFEFEFEFE这个代码是执行不到的干扰代码
也即:a3中所有元素都是0xEFEFEFEF


下面把每个数组元素列出来:
设0xFFEEFFEE为0,0xFEFEFEFE为1,0xEFEFEFEF为2
那么各个数组分别为:


a1:
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

a2:
1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2

a3:
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2

a4:
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2

a5:
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2

然后继续~~~

完整版题解在这儿:

reverse

全部评论

相关推荐

11-29 11:21
门头沟学院 Java
点赞 评论 收藏
分享
专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-27 10:28
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务