拖进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?