反编译时遇到一点问题……所以复现也不完全
无壳32位
寻找加密主函数
先静态分析往下跟
注意12行sub_44E753第一个参数是0,第二个参数是疑似输入内容IpAddress,跟进去
这里只会触发case 0
这里上文a1是IpAddress,涉及到它的函数是sub_44FCC5
出现了IpAddress的大量引用,不知道哪个有用,动调尝试
会发现只有19行sub_44ED5C运行后会有字符串输出的变化
仔细调试会发现应该是在14行位置跳转至真·主函数
下个断点继续动调
F7进入,然后F8到这里停了,打个断点重启
再来一次
跑进主函数了
往上翻,在主函数开头部分按P形成函数,然后F5分析
通过len error的字样,我们可以猜测第一个if判断的是字符串长度,猜一下长度为41(紧接着41被改成48,根据答案格式可以猜测,增加的7个字符应当是 D0g3{}和'\0',输入的仅仅是括号内的部分)
我们也可以进17行确认一下
显然是在计算flag长度
然后找一下加密函数
这里22行应该是字符串比较,unk_1013C008点进去就是密文(注意密文对比用了48个字符,从4D往下48个都是密文)
(1013C008)16+(48)10 =(1013 C038)16
整理一下可得密文:
0x4D,0xB8,0x76,0x29,0xF5,0xA9,0x9E,0x59,
0x55,0x56,0xB1,0xC4,0x2F,0x21,0x2C,0x30,
0xB3,0x79,0x78,0x17,0xA8,0xED,0xF7,0xDB,
0xE1,0x53,0xF0,0xDB,0xE9,0x03,0x51,0x5E,
0x09,0xC1,0x00,0xDF,0xF0,0x96,0xFC,0xC1,
0xB5,0xE6,0x62,0x95,0x01,0x00,0x00,0x00,
F8到21行F7进去
照例P然后F5反编译(和官方跑出来不一样!红温了!8.3我也试过了,也不一样)
qword_1013C000是一个被异或的部分,应该是某种密钥
其值为54AA4A9
我这个伪代码和答案有出入,编不出来……拿官方的函数写脚本吧
抄一下官方的脚本进行分析
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
void fdec()
{
__int64 dq_key = 88777897; //用于异或的key(54AA4A9)
BYTE flag[] = {
0x4D,0xB8,0x76,0x29,0xF5,0xA9,0x9E,0x59,
0x55,0x56,0xB1,0xC4,0x2F,0x21,0x2C,0x30,
0xB3,0x79,0x78,0x17,0xA8,0xED,0xF7,0xDB,
0xE1,0x53,0xF0,0xDB,0xE9,0x03,0x51,0x5E,
0x09,0xC1,0x00,0xDF,0xF0,0x96,0xFC,0xC1,
0xB5,0xE6,0x62,0x95,0x01,0x00,0x00,0x00,
}; //密文
__int64 p;
int j, i;
for (i = 0; i < 6; i++) //48/8=6轮
{
p = *((__int64*)&flag[i * 8]); //每次取8位,形成一个块构成整数
for (j = 0; j < 64; j++) //64次加密
{
if (p & 1) //就是判断是否>0
{
p = ((unsigned __int64)p ^ dq_key) >> 1; //异或之后右移一位
p |= 0x8000000000000000;//还原符号位1
}
else
{
p = (unsigned __int64)p >> 1; //直接右移一位
}
}
*((__int64*)&flag[i * 8]) = p; //加密之后赋值回去
}
for (i = 0; i < 48; i++) //全部打印出来
printf("%c", flag[i]);
printf("\n");
return;
}
int main(int argc, BYTE* argv[])
{
fdec();
return 0;
}