reverse-for-the-holy-grail-350逆向寒假生涯(23/100)

拖进ida

在这里插入图片描述

大概看了一下,一眼看上去,有嫌疑的就是两个函数

  v4 = (unsigned int)validChars((__int64)&v9);

  v5 = stringMod((__int64)&v11);

validChars

在这里插入图片描述

这玩意主要是判断作用,实质性的改变这些不起作用。直接忽了

stringMod

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

分析

仔细看了一下代码,主要分三部分来进行加密的

第一部分

 do
    {
    
    
      v12 = *(_BYTE *)(v2 + v3);
      v14[v3] = v12;
      if ( 3 * ((unsigned int)v3 / 3) == (_DWORD)v3 && v12 != firstchar[(unsigned __int64)((unsigned int)v3 / 3)] )
        v4 = -1;
      ++v3;
    }
    while ( v3 != v1 );

( 3 * ((unsigned int)v3 / 3) == (_DWORD)v3这行代码也就是序数判断是否是3的倍数,不是三的倍数就没有必要继续判断后面的。
v12 != firstchar[(unsigned __int64)也就是用来判断序号0,3,6,9,12,15这六个是否等于firstchar数组中的元素
在这里插入图片描述

第二部分

 v7 = 666;
  do
  {
    
    
    *v6 = v7 ^ *(_BYTE *)v6;
    v7 += v7 % 5;
    ++v6;
  }
if ( v11 == 2 )
    {
    
    
      if ( *v5 != thirdchar[v9] )
        v4 = -1;
      if ( v10 % *v5 != masterArray[v9] )
        v4 = -1;
      ++v9;
      v10 = 1;
      v11 = 0;
    }

这里需要结合两处代码来查看,当等于2时,才能进入循环判断*v5 != thirdchar[v9],进去一次之后又被置位0,即+3。举个例子,第一次进去判断v5数组是下标2的位置,但是第二次进去的话,那就是下标5的位置。
即判断2,5,8,11,14,17下标值是否等于thirdchar数组元素
在这里插入图片描述

第三部分

 do
  {
    
    
    if ( v11 == 2 )
    {
    
    
      if ( *v5 != thirdchar[v9] )
        v4 = -1;
      if ( v10 % *v5 != masterArray[v9] )
        v4 = -1;
      ++v9;
      v10 = 1;
      v11 = 0;
    }
    else
    {
    
    
      v10 *= *v5;
      if ( ++v11 == 3 )
        v11 = 0;
    }
    ++v8;
    ++v5;
  }

这里v11 == 2的意思,主要是为了构成3个为一组,因为当0,和1时,都在else里面执行,即

执行后v10是第0号和第1号的乘积值,v10 *= *v5;

v5经过一番变换,

	v10 *= *v5;
      if ( ++v11 == 3 )
        v11 = 0;
    }
    ++v8;
    ++v5;

这里最主要的是v10 *= *v5,即执行了两次, v10初始值是1,执行完两次后,v10=*v5(第0号) X *v5(第1号),那么如何得到v5数组呢?
在这里插入图片描述

 v7 = 666;
  do
  {
    
    
    *v6 = v7 ^ *(_BYTE *)v6;
    v7 += v7 % 5;
    ++v6;
  }
  while ( &v14[18] != v6 );

从这里就可以看出v5数组了,已经把flag的值分别对应异或了一个数组,下面用代码求出数组:

	int v[18];
	v[0] = 666;
	for (int i = 1; i < 18; i++) {
    
    
		v[i] = v[i-1]+(v[i-1] % 5);
	}

然后用flag分别对应异或它之后就得到了v5数组,v5数组再用来3个一组爆破求出flag 的下标为1,4,7,11,14,17元素值,这里可以利用爆破。

 v10 % *v5 != masterArray[v9]

这行代码也就是v5[0]*v5[1]%v5[2] != masterArray[v9]
而v5数组中也就v5[1]未知,把v5[1]异或v[1]就等于flag[1]喽。

代码

#include <iostream>
using namespace std;
int main()
{
    
    
	char  unsigned firstchar[] = {
    
     0x41,0x69,0x6e,0x45,0x6f,0x61 };

	int thirdchar[] = {
    
     0x2EF,0x2C4,0x2DC,0x2C7,0x2DE,0x2FC };

	int masterArray[] = {
    
     0x1D7,0x0c,0x244,0x25E,0x93,0x6C };

	char  unsigned flag[18];
	int v[18];
	v[0] = 666;

	for (int i = 1; i < 18; i++) {
    
    
		v[i] = v[i-1]+(v[i-1] % 5);
	}

	int j = 0;
	for (int i = 0;i<18; i=i+3) {
    
    
		flag[i] = firstchar[j];
		j++;
	}

	j = 0;
	for (int i = 2;i<18 ; i = i + 3) {
    
    
		flag[i]=  thirdchar[j] ^ v[i];
		j++;
	}
	
	int z = 0;
	for (int j = 1; j < 18; j=j+3) {
    
    
		for (char i = 32; i <= 126; i++) {
    
    
			if (((flag[j-1] ^ v[j-1]) * (i ^ v[j ]) % (flag[j + 1] ^ v[j + 1])) == masterArray[z]) {
    
    
				flag[j ] = i;
				z++;
				break;
			}
		}
	}
	for (int i = 0; i < 18; i++) {
    
    
		std::cout << char(flag[i]);
	}
	
}

在这里插入图片描述

AfricanOrEuropean?

猜你喜欢

转载自blog.csdn.net/CSNN2019/article/details/113888015
今日推荐