前言
这是笔者近期做的比较难的一道题,学到很多东西,写下wp模拟一下当时的思路。
正文
先运行一下
直接退出了,不知道是不是我的环境问题
64位无壳,拖入ida看看
主函数长这样。先搜索一下字符串,发现找不到。。
beginthreadex是创建一个线程的函数
但是找到了比较可疑的字符串,跟进
是一段反调试,下面有几个加密。patch掉反调试后动调分析一下
从主函数头开始分析,f8看看哪里有字符串显示
进入sub_7FF61D089710
走到第十六行出现字符串,下面是输入
奇怪的是再走就自己退出了,再找找有没有其他反调试
看看刚刚主函数创建的进程函数StartAddress
进入第一个函数
gpt就是好(笑)
总的来说,这段代码对当前函数的进程进行遍历,并将进程名都存储并加密,与特定的字符串(调试进程的进程名的密文)比对,如果相同就退出。总之还是一个反调试
简单粗暴 直接干掉exit
继续往下看下一个函数
一眼反调试,patch掉exit
继续往下看看,进入sub_7FF61D089850
万恶的出题人把所有字符串都异或了一遍,真是可恶
手动分析一下发现是超时检测,直接干掉exit
再往下看看
一段很像密文的东西,下面有一个MZ(文件头?!)的检查
看看v10
这段东西就是一个文件了。现在还不知道干什么的。不过好像反调试已经没了,从头开始动调分析
f8到输入的地方,手动逆向一下密文(不难)Akira_aut0_ch3ss_!
进入下面的函数
给v3赋值0x100003
传入的密文和参数进入了sub_7FF743AF5DF0里,返回值赋给v4
查看v4里面的值,发现是个地址,g跳转几次跟踪一下
指向这个函数
查看sub_7FF743AF8450,里面没啥东西
查看sub_7FF743AF8910
进行了一个加密,发现byte_7FF743B011A0就是那个很像文件的东西
大概猜测是输入的密文作为参数对文件进行了解密,查看是什么调用了这个函数
一模一样的三兄弟,挨个看看
一共三个加密,交叉引用看看是哪里引用了这些加密、
发现是第一个函数里的东西(初始化)大概是三个加密函数附上三个参数,0x100001,0x100003,0x100002,靠这些标志数找加密函数
回头找找刚才的函数,在sub_7FF743AF8B20发现第一次加密,这个没有输入部分,自动完成。
现在是使用输入密文进行第二次加密
第三次加密是sub_7FF743AF93B0里的
将上面的md5密文当作参数进行加密
至此三个加密都清楚,写脚本解密(可以动调过第一个解密之后再dump数据)
脚本
#include <iostream>
#include <Windows.h>
#include <io.h>
#define DLLSIZE 19456
#include <stdio.h>
unsigned __int8 aa[] =
{
0x0C, 0x5A, 0x09, 0x6B, 0x03, 0x00, 0x69, 0x00, 0x40, 0x72,
//略;
0x41, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x69, 0x00, 0x00, 0x72,
0x00, 0x00, 0x61, 0x00, 0x00, 0x5F
};
int main(){
for (size_t i = 0; i < 19456; i++)
{
if (i % 3 == 2)
{
aa[i] = ((int)(unsigned __int8)aa[i] >> 4) | (16 * aa[i]);//函数解密
}
}
//解密1003
PCHAR pKey1003 = (PCHAR)"Akira_aut0_ch3ss_!";
DWORD dwKey1Len = strlen(pKey1003);
for (size_t i = 0; i < 19456; i++)
{
if (!(i % 3))
{
aa[i] ^= pKey1003[i / 3 % dwKey1Len];//函数解密
}
}
FILE* pFileNew = fopen("Test.DLL", "wb+");
fwrite(aa, 1, DLLSIZE, pFileNew);
fclose(pFileNew);
return 0;
}
得到dump的文件,拖入ida
简单的aes解密,密文在文件创建处这里
简单解密得到flag
flag{Ak1rAWin!}