PE查壳,发现有壳
利用UPX静态脱壳机脱壳
打开exe文件,得到关键语句
ida打开,shift+F12找到关键语句,F5反编译
有随机数组产生,而且是二维的
编写代码得的随机数列
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i, j;
srand(0xCu);
for (i = 1; i <= 20; i++)
{
for (j = 1; j <= i; j++)
{
printf("%7d ", rand() % 100000);
}
printf("\n");
}
return 0;
}
下面就是走迷宫
if ( j_strlen(Str) == 19 )
{
sub_41114F(Str);
v4 = 0;
j = 1;
i = 1;
dword_423D78 += dword_41A138[101];
while ( v4 < 19 )
{
if ( Str[v4] == 'L' )
{
dword_423D78 += dword_41A138[100 * ++i + j];
}
else
{
if ( Str[v4] != 'R' )
{
((void (__cdecl *)(const char *, char))sub_41134D)("error\n", v3);
system("pause");
goto LABEL_18;
}
dword_423D78 += dword_41A138[100 * ++i + ++j];
}
++v4;
}
sub_41134D("your operation can get %d points\n", dword_423D78);
'L'是向下走一步,'R'是向右下走一步,可以走19步,从77开始选择走'L'或者是走'R',选择最大值走。手动扒去的步法为:RRRRRLLRRRLRLRRRLRL
输入发现是错误的,证明是对步法进行了改变。对我们输入的str进行跟踪,看到了sub_41114F函数,选择OD动态调试。
在函数sub_41114F上下断点,让程序运行到这里
对EAX寄存器进行数据窗口下跟随,看我们的值进行了怎么的变化,F8单步步过,看到我们的值发送了变化
重新执行程序,看看我的值具体的变化
F7单步步入,F4运行到00411949 E8 57F7FFFF call ConsoleA.004110A5 然后再F7步入,来到改变函数。
F4运行到0041181B,F7跳转到0041194E,F8单步执行,期间注意窗口值的变化,执行到00411992,发现我们的第二个值R变成了V
查看发现,原来是对值进行与4的异或,还是偶数项进行异或。重新异或得到flag:RVRVRHLVRVLVLVRVLVL