我可以阻止 C++ dll 在 Python Ctypes 中加载吗?

Posted

技术标签:

【中文标题】我可以阻止 C++ dll 在 Python Ctypes 中加载吗?【英文标题】:Can I prevent a C++ dll from loading in Python Ctypes? 【发布时间】:2016-09-02 11:38:01 【问题描述】:

我想知道是否有可能阻止或允许 python ctypes 加载 dll,具体取决于条件是否为真来自 dll。

一些背景:

我的应用程序使用各种计算算法,我在 Python 中进行了原型设计,然后在 C++ 中重新实现以提高速度。我仍然将 Python 用于应用程序“胶水”和 GUI。我正在使用 ctypes 包装器访问 dll 中的函数。

我现在需要保护该软件,以便它只有在存在安全加密狗的情况下才能运行。 Python 的开放性使这变得困难,所以我希望能够停止加载 dll 的 python 脚本,除非检查加密狗的函数是否存在返回 True。

示例 Python 包装器:

from ctypes import cdll, c_int , c_float, c_bool

lib = cdll.LoadLibrary('my.dll')

cpp_sum = lib.sum
cpp_sum.argtypes = [c_int,c_int]
cpp_sum.restype = c_int

def wrapped_sum(value_1,value_2):
    return cpp_sum(value_1,value_2)

还有 my.dll 的代码:

#include "stdafx.h"
#include <cmath>

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int sum(int a, int b) 
    return a + b;

//pseudo dongle code:
bool is_dongle_present()
    if dongle present return true
    else return false

理想情况下,如果 dongle_is_present 返回 false,则 dll 将无法加载。任何人都可以帮忙吗? 如果这个问题不清楚,请告诉我!

非常感谢

【问题讨论】:

【参考方案1】:

DllMain 函数添加到您的库中。

动态链接库 (DLL) 的可选入口点。当。。。的时候 系统启动或终止一个进程或线程,它调用 使用第一个线程的每个加载的 DLL 的入口点函数 过程。系统还调用 DLL 的入口点函数 它使用 LoadLibrary 和 FreeLibrary 加载或卸载 职能。

您可以通过在 DLL_PROCESS_ATTACH 上返回 FALSE 来阻止 dll 加载:

当系统调用 DllMain 函数时 DLL_PROCESS_ATTACH 值,如果成功,函数返回 TRUE 如果初始化失败,则为 FALSE。如果返回值为 FALSE 时 调用 DllMain 是因为进程使用了​​ LoadLibrary 函数, LoadLibrary 返回 NULL。 (系统会立即调用您的 带有 DLL_PROCESS_DETACH 的入口点函数并卸载 DLL。)如果 在进程中调用 DllMain 时返回值为 FALSE 初始化,进程以错误终止

更多信息请参见DllMain MSDN entry。

【讨论】:

请注意,从 DllMain 执行几乎所有操作(包括操作系统调用)都是不安全的,因为它是在内核加载程序锁定期间调用的。 谢谢 Ari0nhh 。我已经尝试过了,并且遇到了我正在努力解决的链接器错误(DllMain 已经定义)。根据您的警告 Richard,我倾向于定义一个全局“启用”变量,我可以从我的应用程序中设置该变量(假设加密狗的存在允许这样做),并在每个函数允许返回值之前对其进行检查。听起来更安全!

以上是关于我可以阻止 C++ dll 在 Python Ctypes 中加载吗?的主要内容,如果未能解决你的问题,请参考以下文章

怎样用python调用dll

无法在 python 中加载 c++ DLL

Python在主机程序初始化后连接到C++ dll?

在 Python 中使用 C++ DLL

防止来自Dll C ++的Dll注入

python 调用 C++的DLL,函数参数是数组怎么处理?