阻止调用dll
发布网友
发布时间:2022-05-07 06:53
我来回答
共3个回答
热心网友
时间:2023-10-19 22:59
几种方法供参考:
1、存储注册码的加密版本到注册表,而后在DLL成员函数的一开始读取加密的注册码,解密后验证,不正确就退出,错误超过一定次数直接卸载DLL并删除。
2、在DLL的内部定义一个标志变量,没有鉴权时为0;而后添加一个鉴权的函数,每次使用DLL的方法前调用这个函数,验证成功注册码后把变量执1,在所有其他函数中检查这个变量的值,为1继续,0退出。
上面这两个方法都必须导出所有的函数,下面这个方法可以隐藏关键功能的函数,实现复杂度稍大,但是也不难,就是实现一个简单的工厂:
3、DLL对外只保留一个“工厂”接口,比如
//全局变量,用来存储每个接口的鉴权密码
std::string g_strPassword[16];
//不需要导出的功能函数1
int func1(...)
{
//第一句
if (false==fbCheckPassword(g_bPasswordOK[0].c_str()))
return ;
//做一些工作
...
// 清除鉴权,防止其他程序偷偷使用
g_bPasswordOK[0] = "";
return 1;
}
//不需要导出的功能函数2
void func2(...)
{
//第一句
if (false==fbCheckPassword(g_bPasswordOK[1].c_str()))
return ;
//做一些工作
...
// 清除鉴权,防止其他程序偷偷使用
g_bPasswordOK[1] = "";
return ;
}
...
extern "C" void * QueryFuncByName(int nFuncID,const char * pstrPwd) ;
//工厂
void * QueryFuncByName(int nFuncID,const char * pstrPwd)
{
if (false==fbCheckPassword(pstrPwd))
return 0;
g_bPasswordOK[nFuncID]=std::string(pstrPwd);
switch (nFuncID)
{
case 0:
return (void *)func1;
break;
case 1:
...
};
}
在主程序里调用
extern "C" void * QueryFuncByName(int nFuncID,const char * pstrPwd) ;
typedef int (*ftFunc1)(...);
void * pvfunc = QueryFuncByName(0,"password");
if (pvfunc )
{
ftFunc1 pfunc1 = (ftFunc1)pvfunc ;
pfunc1 (12);// 真正调用
}
这种方法好处是DLL中的关键函数都无法轻易被别人使用,即使使用结构查看工具确定了内部函数的入口,每次鉴权也都够呛。而且每次调用后状态重置,使得其它进程想在鉴权后偷偷使用加密的函数变得很难。
希望对LZ有所帮助!
热心网友
时间:2023-10-19 22:59
楼上这位仁兄,说的很好。不过,他的有些方法,是比较容易被破解的。
因为用户完全可以监视注册表,使用同样的方法往注册表写数据就可以破解。
我也提供2中方法:
1、自己写一个加壳程序,对目标DLL进行加壳。要想使用DLL,首先要在调用进程中进行脱壳,脱壳的方法只有你自己知道,因此,这中方法是最安全的,也很难破解。但是编写难度也相对较高。另外,这种方法,使得目标DLL看上去不像一个DLL,用DLL查看工具也无法查看其导出函数的名字等。。。
2、使用内核对象,比如一个内存映射对象,其内容为注册码。然后在DLL的 DLLMAIN函数中,首先试图打开该内核对象,如果失败,或者验证错误,就返回 0,这样,调用进程就会崩溃,从而无法使用DLL。内存映射对象的名字,还有注册码只有你自己知道,而且其注册码的验证算法只有在DLL被破解的情况下才能破解,而没有注册码的前提下很难破解,这是一个死锁。。安全系数也很高。
热心网友
时间:2023-10-19 22:59
几种方法供参考:
1、存储注册码的加密版本到注册表,而后在DLL成员函数的一开始读取加密的注册码,解密后验证,不正确就退出,错误超过一定次数直接卸载DLL并删除。
2、在DLL的内部定义一个标志变量,没有鉴权时为0;而后添加一个鉴权的函数,每次使用DLL的方法前调用这个函数,验证成功注册码后把变量执1,在所有其他函数中检查这个变量的值,为1继续,0退出。
上面这两个方法都必须导出所有的函数,下面这个方法可以隐藏关键功能的函数,实现复杂度稍大,但是也不难,就是实现一个简单的工厂:
3、DLL对外只保留一个“工厂”接口,比如
//全局变量,用来存储每个接口的鉴权密码
std::string g_strPassword[16];
//不需要导出的功能函数1
int func1(...)
{
//第一句
if (false==fbCheckPassword(g_bPasswordOK[0].c_str()))
return ;
//做一些工作
...
// 清除鉴权,防止其他程序偷偷使用
g_bPasswordOK[0] = "";
return 1;
}
//不需要导出的功能函数2
void func2(...)
{
//第一句
if (false==fbCheckPassword(g_bPasswordOK[1].c_str()))
return ;
//做一些工作
...
// 清除鉴权,防止其他程序偷偷使用
g_bPasswordOK[1] = "";
return ;
}
...
extern "C" void * QueryFuncByName(int nFuncID,const char * pstrPwd) ;
//工厂
void * QueryFuncByName(int nFuncID,const char * pstrPwd)
{
if (false==fbCheckPassword(pstrPwd))
return 0;
g_bPasswordOK[nFuncID]=std::string(pstrPwd);
switch (nFuncID)
{
case 0:
return (void *)func1;
break;
case 1:
...
};
}
在主程序里调用
extern "C" void * QueryFuncByName(int nFuncID,const char * pstrPwd) ;
typedef int (*ftFunc1)(...);
void * pvfunc = QueryFuncByName(0,"password");
if (pvfunc )
{
ftFunc1 pfunc1 = (ftFunc1)pvfunc ;
pfunc1 (12);// 真正调用
}
这种方法好处是DLL中的关键函数都无法轻易被别人使用,即使使用结构查看工具确定了内部函数的入口,每次鉴权也都够呛。而且每次调用后状态重置,使得其它进程想在鉴权后偷偷使用加密的函数变得很难。
希望对LZ有所帮助!
热心网友
时间:2023-10-19 22:59
楼上这位仁兄,说的很好。不过,他的有些方法,是比较容易被破解的。
因为用户完全可以监视注册表,使用同样的方法往注册表写数据就可以破解。
我也提供2中方法:
1、自己写一个加壳程序,对目标DLL进行加壳。要想使用DLL,首先要在调用进程中进行脱壳,脱壳的方法只有你自己知道,因此,这中方法是最安全的,也很难破解。但是编写难度也相对较高。另外,这种方法,使得目标DLL看上去不像一个DLL,用DLL查看工具也无法查看其导出函数的名字等。。。
2、使用内核对象,比如一个内存映射对象,其内容为注册码。然后在DLL的 DLLMAIN函数中,首先试图打开该内核对象,如果失败,或者验证错误,就返回 0,这样,调用进程就会崩溃,从而无法使用DLL。内存映射对象的名字,还有注册码只有你自己知道,而且其注册码的验证算法只有在DLL被破解的情况下才能破解,而没有注册码的前提下很难破解,这是一个死锁。。安全系数也很高。
热心网友
时间:2023-10-19 22:59
现在的程序,注册码都比较容易破。除非加个厉害的壳。
一般的壳,学过1段时间破解的就能破。
至于内存映射,ollydbg一调试注册码就出来了。
建议楼主学编程就专心学编程,想把自己的成果安全化,那就再去学加密解密。
热心网友
时间:2023-10-19 23:00
现在的程序,注册码都比较容易破。除非加个厉害的壳。
一般的壳,学过1段时间破解的就能破。
至于内存映射,ollydbg一调试注册码就出来了。
建议楼主学编程就专心学编程,想把自己的成果安全化,那就再去学加密解密。