观察程序
用PE 探查一下
是32位程序 无壳 用IDA 打开
这里如果你IDA版本较高 可以直接F5生成伪代码
此时版本为 IDA Pro 7.7
但是有些较低的不行 所以我讲一下 无法直接F5的情况
这里无法生成伪代码是因为 栈不平衡
勾选上 栈指针 Options->Generral->Stack pointer
就可以看到栈指针的情况了
有两处栈不平衡情况
tips:在call函数最后 retn指令会使得栈指针恢复被调用前的数值
使用快捷键 Alt + k 修改新旧sp指针的差值为0
修改第一处:
修改第二处:
F5查看伪代码
看到一个VirtualProtect函数 没有遇到过 查一下
是一个加密函数 加密encrypt函数 暂时还用不到 跳过
有两个函数 wrong 和 omg 使用了 str
wrong:
1 | char *__cdecl wrong(char *a1) |
omg:
1 | int __cdecl omg(char *a1) |
写一下脚本
错的flag 题目没有那么简单
再往后看
有个for循环 循环了187次 有点像在还原程序
encrypt函数打不开 报错 查看汇编代码 大多还是数据 基本上确定了for循环在进行解密
动态调试 去壳
这里用x32debug 动态调试
一步一步调试 找到主函数下的for循环
按下F4 运行到for循环的下一步
按下F7进入encrypt函数内部
有正确的汇编代码
将解密完的程序dump 出来
将dump出的新程序拖进IDA
入口变成了 start 这是dump程序默认更改的 点击start函数名 按X查看调用 易找到原来的main函数
还原的encrypt函数
1 | int __cdecl start(int a1) |
还原的finally函数
1 | int __cdecl sub_40159A(int a1) |
encrypt函数加密思路
将a1的前19为与“hahahaha_do_you_find_me?”异或 其中a1就是我们的输入字符串
finally函数的加密思路
函数逻辑 看了很久不是很懂 再加上 还有随机数的干扰 这里就无法猜出它的解密方法
只能退一步 猜还是利用了encrypt函数的异或
因为 flag{…..} 最后一个必定是** }** 可以知道是 71 与 ”:” 异或
进一步猜 前四字符都是 和 71异或
解密脚本
1 | store = [0x0E, 0x0D, 0x09, |
参考WP:[(60条消息) 网鼎杯 2020 青龙组]jocker(详解)_ST4RBOY的博客-CSDN博客_网鼎杯jocker
- 本文标题:网鼎杯-2020-青龙组-jocker
- 本文作者:萧禾财
- 创建时间:2022-07-13 16:02:21
- 本文链接:https://ipartmentxhc.github.io/2022/07/13/青龙组-jocker/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!