分析一下程序,其实逻辑很简单,输入的字符串先进行乱序排列,再与值异或,最后与目标进行对比
其中有一个LOBYTE()有些显眼,搜一下
我们再看tmp的值
tmp的单位为db(double bits)的时候提取出的值,我们要不到那么多0啊,所以我们大胆猜测,其单位为dd(double word)
已知,LOBYTE()应用与32bit(dd)时,取后16bit,且tmp的存储方式为小端序,所以程序中LOBYTE(tmp[i])实际就为tmp在db提取时不为0的数据
其实你仔细看tmp中不为0的数据,其实是从1到32的乱序排列,所以说第一个for循环里面的第一句其实就是将输入的字符串打乱顺序
知道全程后脚本就很好写了
#include<iostream>
using namespace std;
int main()
{
char flag[]={0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53,0x79,0x57,0x5E,0x5D,0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E, 0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E,0x65,0x3C,0x5C,0x45, 0x6F, 0x62, 0x4D};
int tmp[]={ 0x9, 0x0A, 0x0F, 0x17, 0x7, 0x18, 0x0C, 0x6, 0x1, 0x10, 0x3, 0x11, 0x20, 0x1D, 0x0B, 0x1E, 0x1B, 0x16, 0x4, 0x0D, 0x13, 0x14, 0x15, 0x2, 0x19, 0x5, 0x1F, 0x8, 0x12, 0x1A, 0x1C, 0x0E, 0};
char tar[] = {0};
for (int i=0;i<=32;i++)
{
flag[i]^=tmp[i];
}
int h=0;
for(int i=0;i<=32;i++) //恢复顺序
{
for(int j=0;j<=32;j++)
if(i==tmp[j])
{cout<<flag[j];}
}
cout<<endl;
return 0;
}
得到flag{Tr4nsp0sltiON_Clph3r_1s_3z}
PS:以后看到有数组有规律地出现0的时候,可以凭借规律找到素组每一个元素的单位