攻防世界高手进阶区——dice_game
攻防世界高手进阶区——dice_game
题目里面啥都没有。
一.分析文件
- checksec
只有栈溢出保护关闭了,其他都是开着的。
- 运行
可以看出是要猜数字,猜对50次。
- ida逆向
1 | __int64 __fastcall main(int a1, char **a2, char **a3) |
跟进一下sub_A20()
1 | __int64 sub_A20() |
可以看出是要答对50次数字。
1 | int __fastcall sub_B28(const char *a1) |
答对后就可以开启flag文件。
二,解题思路
- 文件输入名字处存在栈溢出漏洞。
只需要覆盖0x40个字节就可以将seed覆盖。
覆盖seed后就可以将伪随机数生成器的种子给替换,
伪随机数生成器的种子一样生成的随机数是相同的。
(不同的动态链接库的rand函数算法可能不同,需要将文件给的so文件给用上)
再用python的ctypes模块实现即可。
三,exp
1 | #coding=utf8 |
.dll,动态链接库英文为DLL,是Dynamic Link Library的缩写。DLL是一个包含可由多个程序,同时使用的代码数据的库
模块ctypes是Python内建的用于调用动态链接库函数的功能模块,一定程度上可以用于Python与其他语言的混合编程。由于编写动态链接库,使用C/C++是最常见的方式,故ctypes最常用于Python与C/C++混合编程之中。
ctypes 是 Python 的外部函数库。它提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。
ctypes导出了
cdll
对象,在Windows系统中还导出了windll
和oledll
对象用于载入动态连接库。通过操作这些对象的属性,你可以载入外部的动态链接库。cdll
载入按标准的cdecl
调用协议导出的函数,而windll
导入的库按stdcall
调用协议调用其中的函数。oledll
也按stdcall
调用协议调用其中的函数,并假定该函数返回的是Windows HRESULT
错误 代码,并当函数调用失败时,自动根据该代码甩出一个OSError
异常。
PS:关于ctypes引用一下大佬的解释
1 C函数的调用规定
C函数在调用过程中关于参数传递和压栈由多种规定,作为dll提供给其他程序调用时,必须明确并统一为同一种调用规定,否则会导致栈破坏,编译器负责具体实现调用规定,主要有以下几种调用规定
调用规定 | 声明 | 编译符号修饰 | 调用规则 | 说明 |
---|---|---|---|---|
_stdcall | __declspec(dllexport) int __stdcall fun(int a, int b) |
_fun@number | 参数从右向左入栈,调用者压栈,被调者负责弹栈 | win32 API默认调用规则 |
_cdecl | __declspec(dllexport)int __cdecl fun(int a, int b) |
_fun | 参数从右向左入栈,调用者负责压栈和弹栈 | C/C++默认调用规则 |
_fastcall | __declspec(dllexport)int __fastcall fun(int a, int b) |
@fun@number | 寄存器和栈共同参数与参数传递 | 寄存器传参提高性能,难以跨平台 |
2 ctypes加载dll库接口
python下调用C库有多种方式,ctypes是其中一种比较方便的,调用时首先需要加载dll文件,根据C dll的调用规定不同需要使用不同接口,使用ctypes需要import ctypes
库
- 对于stdcall的C dll
1 | import ctypes |
以上两种接口都是可用的
- 对于cdecl的C dll
1 | import ctypes |
对于简单的C函数,例如int add(int a, int b)
, 此时就可以直接调用了,如
1 | import ctypes |
上两种接口都是可用的
- 对于cdecl的C dll
1 | import ctypes |
对于简单的C函数,例如int add(int a, int b)
, 此时就可以直接调用了,如
1 | import ctypes |
作者:cheng3100
链接:https://www.jianshu.com/p/b338e55c3b71
来源:简书