(Whale 蓝鲸)Rev2

(Whale 蓝鲸)Rev2

四月 20, 2019 (Updated: )

打开程序运行一下:

发现三个按钮选择选哪一个都会导致程序直接关闭,果断ida调试

第一层代码挺简单,就是建一个堆栈,然后把一些数据放堆栈里,最后用消息框输出flag
去数据源的地址看一下是什么:

发现是一堆十六进制数符,一开始以为就是十六进制转字符串,结果发现不对,这些十六进制数值太大了,不是任何一种常用字符,属于乱码类型
猜测经过了一些算法的转码,一开始以为是if判断里左边的那个函数,右边是反调试函数
结果进去后发现什么也没有,然后傻眼了好久,就去看了程序的模块结构

发现输出flag的消息窗函数在该程序里面有两个,推断之前运行程序弹出的乱码是其中一个,猜测另一个是对的,拉进od调试一下看看

发现运行完这个函数便会出现弹窗,而在此之前什么关键信息都没找到,关键函数应该就在这里,步入查看

发现这个跳转会跳过第一个调用消息框的模块,运行第二个,这和刚刚在ida内的分析吻合,第一个消息框函数前面确实有一些其他东西,修改这个跳转使其不能实现,走一下上面这个消息框

这个int3会反调试,一旦运行该行命令会卡死程序,将其nop掉后调试

这个jmp跳转会导致程序直接跳过所有弹窗,nop掉他

这里不知道为什么我在另一台电脑上是可以直接在消息弹唱中看到flag的,但我这个正常输出后只有弹窗内容不显示,所以直接走到txet这里停下,查看内存地址,因为消息框正文是储存在相应内存空间的

果然是flag
然后突然想到,刚刚那个跳掉该消息框的je跳转不是对应的ida反汇编里面的if判断么,也就是if判断生效后执行的函数里面是转码函数,因为if条件实现后运行程序终止的函数,我一直都没看中间那个函数,血亏啊,浪费好多时间

查看if条件实现后运行的这个函数的内部结构

果然是解码算法,a2就是堆栈空间地址,v2的值为0xDDCCAABB, 该算法将堆栈内的数据每八个为一组v2做异或运算后以字符串输出
写出脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using namespace std;
int main()
{
int a[9]={0xBCA0CCBB,0xB8BED1DC,0xAEBECFCD,0x82ABC4D2,0xB393D9D2,0xA993DED4,0x82B8CBD3,0xB9BECBD3,0xDDCCD79A},b=0xDDCCAABB;
int c;
char d;
for(int n=0;n<9;n++)
{
c=a[n]^b;
do
{
d=(char)(c%256);
cout<<d;
}
while(c/=256);
}
cout<<endl;
return 0;
}
隐藏