DigitalCircuits
该文件为python打包成的exe文件,可以用如下方法判断:
1、python打包成的文件通常的图标都是python模样
2、用ExeinfoPe查看文件
3、ida载入文件,shift+f12查看字符串
判断出这一点,接下来我们的任务就是将.exe文件反编译出python源码了
参考这篇文章:(别再问我exe反编译成Python脚本了! - 云+社区 - 腾讯云 (tencent.com))
首先通过pyinstxtractor.py脚本提取pyc文件,引用参考文章中的方法
执行命令
1 | python pyinstxtractor.py DigitalCircuits.exe |
运行结果如下
生成了一个名为DigitalCircuits.exe_extracted的文件夹
在文件夹内可以找到与可执行文件同名的.pyc文件,不过需要手动补后缀
下一步是还原文件头
将pyc文件与同目录下的struct文件用十六进制编辑器打开对比
发现缺少第一行的16个字节
先插入16个字节,再将struct中的第一行复制到pyc文件中
保存,然后通过uncompyle6将pyc文件反编译为py文件
1 | uncompyle6 -o DigitalCircuits.py DigitalCircuits.pyc |
代码如下,注释为个人分析
1 | # uncompyle6 version 3.7.4 |
解题脚本如下
1 | def f1(a, b):#与运算 |
更新:
看了大佬们的wp才发现这是个tea加密算法,只不过是二进制的而已,套用tea解密的脚本即可求得flag
这里贴的是Dest0g3 Team的脚本
1 | def tea_decode(enc, k): |
Hell_world
这道题比赛的时候没有思路,刚刚照着大佬们的wp复现了一下,虽然只是懂了个大概,但还是记录一下
引用SU战队的话,“跟西湖论剑题目gghdl差不多 就是改了下case结构和数据可以根据链接来解题”
拿到程序,ida打开后首先shift+f12搜索字符串,search含有flag
的字符串
之后就是解析每个case函数的作用
然后我们通过动态调试的方法找到读取输入的函数
再分析case3
如果输入长度是44位的话就执行case4,进而执行case9,所以推测case9是加密函数
在分析case9之前,先查看输出正确的条件
正确条件为*(_DWORD )(a1 + 376) == 44,因此我们需要查看修改(_DWORD *)(a1 + 376) 值的位置,发现只在case11中出现
追踪传入sub_7FF629329CC0函数的v74, v71,可以追踪到图中标出的关键函数,此函数在程序中共调用了3次,另外两次分别在case10和case9中,其中case9的该函数传入的为我们输入的数据(存在a1中)
因此我们可以动态调试分析该函数的功能,传入字符串0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUI
常用字符0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM{}_-
运行case9中的sub_7FF629350180函数,查看对应的汇编代码
查看函数返回值(存在rax寄存器中)
其中22332222即为传入字符串中0对应的二进制码00110000每位加二,所以函数的功能其实就是字符串转换为对应的二进制
再查看sub_7FF629329CC0函数的汇编代码,发现就是异或运算
所以flag就是将dword_7FF629415B80和dword_7FF629415C50中的数据异或即可