SUCTF2019 - Akira Homework
main
分析 main 函数。创建一个新线程,它的参数是主线程的句柄。主线程检查输入是否正确,如果错误执行 if 里面的内容,如果正确执行 sub_1400093B0()。

把字符串串算出来,方便理解程序。顺便把其他函数重命名一下

StartAddress
StartAddress 里面前两个函数很明显是反调试(分别重命名为 anti_debug_1 和 anti_debug_2)
anti_debug_1 通过遍历进程快照查看有无可疑进程的 md5,最后还调用了一个函数,暂时看不出来什么意思。

anti_debug_2 通过某些 api 直接判断是否被调试。其中参数 a1 指向某些函数。回到 StartAddress 查找 qword_140016188 的交叉引用。

找到 sub_140009c20(重命名为 init_main),qword_140016188 指向一个结构

再看下面的函数 sub_140008850(重命名为 get_ntdll_api),GetProcAddress 的字符串是乱的。找找哪里修改了这些字符串,找到 TlsCallback_0

依旧重命名字符串

这样就比较清楚了,StartAddress 线程一直执行 anti_debug_1 和 anti_debug_2,并向主线程插入一个 Apc。

chech_input
sub_140009710(重命名为 chech_input)逻辑比较简单,就是输入字符串,然后验证,返回结果。最后也会执行 ??? 框起来的内容。

sub_140009200(重命名为 chech_password)的加密也很简单,直接解出 "Akira_aut0_ch3ss_!"

check_sign
sub_1400093B0(重命名为 check_sign)从一个签名文件中读取内容,并验证 md5。这个签名文件的是 exe文件名 + L":Signature"

验证成功后会执行 ??? 的内容

ApcRoutine
ApcRoutine 首先 WaitForMultipleObjects 等待 Handles。X 查找 Handles 的交叉引用

init_main 里面是 CreateEvent, 真正修改 Handles 的是上面三个函数。
这三个函数修改了 view_data,然后通过 SetEvent 通知 WaitForMultipleObjects



然后创建一个共享内存,写入 16 个字节

最后是一个 PE 加载器,加载的就是 view_data

静态分析差不多了,接下来用动态调试 (静态分析不下去了)
前面反调试的地方都 patch 掉(check_sign 也可以直接绕过,执行 ??? 的内容),然后在 WaitForMultipleObjects 把 r9d 改成 0xffffffff,防止超时。

执行完 WaitForMultipleObjects 说明三个修改 view_data 的函数都已执行,导出 view_data

得到这个 DLL,用 ida 打开。剩下就是一个简单的 AES 解密

密文是共享内存里写入的 16 给字节,密钥是 "Ak1i3aS3cre7K3y\0",解密得到 flag


浙公网安备 33010602011771号