[作者]
网名:猪头三
个人网站:http://www.x86asm.com
[序言]
很久不研究另类的编码技术了,不知怎么的这几天突然心血来潮,突然想分享一个有趣的技术给大家.
[技术作用]
我们知道dll的主要作用是提供接口别人使用,按照正规的方式需要把函数名导出出来,但这对于有安全瘾的人来说,但有时我们需要更加安全不想把函数名导出.下面我提供一个技术.
[声明]
为了避免不必要的争吵,我把这内容定位在编程技巧,而不是定位在技术讨论.
[原理]
DLL入口点的声明为:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
第2个参数按照MSDN文档解释只能接收他规定的数值比如:
DLL_PROCESS_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
DLL_PROCESS_DETACH
但有时想接受更多扩展定义,比如 100 101 102这些自定义数值怎么办呢?
如果接收更多扩展定义,那我们写接口的时候根本不用导出函数名了,只要让调用者知道这些扩展定义,并对DLL发送这些定义数值,DLL内部可以根据这些ID进行识别做对应的功能处理.
这样是不是相对更加安全呢?^_^
下面我们继续讨论原理.......
要让DLL能接收到这些扩展定义,只要让调用者找到DLL的入口点,并调用就OK了.下面我们开始实战.
[基础理论]
1> DLL模块的使用原理
2> PE结构的理解
3> C/C++语言
4> VS开发工具的使用
[DLL内部源码]
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
case 100: // 扩增定义
{
printf("自定义已经传递进来了ID: 100 \n") ;
}
break;
case 101: // 扩增定义
{
printf("自定义已经传递进来了ID: 101\n") ;
}
break;
case 102: // 扩增定义
{
printf("自定义已经传递进来了ID: 101\n") ;
}
break;
}
return TRUE;
}
[调用DLL源码]
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dword_Error ;
// PE文件头
PIMAGE_DOS_HEADER pstruct_ImageDOSHeaders = NULL ;
PIMAGE_NT_HEADERS pstruct_pImageNTHeaders = NULL ;
// 加载目标DLL
HINSTANCE handle_Dll = ::LoadLibrary("Test_Dll.dll") ;
if (handle_Dll == NULL)
{
return 0 ;
}
// 校验PE头是否合法
pstruct_ImageDOSHeaders = (PIMAGE_DOS_HEADER)handle_Dll;
if (pstruct_ImageDOSHeaders->e_magic != IMAGE_DOS_SIGNATURE)
return 0 ;
// 定位PE的NT头并校验
pstruct_pImageNTHeaders = (PIMAGE_NT_HEADERS)((PBYTE)pstruct_ImageDOSHeaders + pstruct_ImageDOSHeaders->e_lfanew);
if (pstruct_pImageNTHeaders->Signature != IMAGE_NT_SIGNATURE)
return 0 ;
// 定义DLLMAIN入口函数并获取入口地址
BOOL (APIENTRY *DllMain)( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved);
DllMain = (BOOL (APIENTRY *)( HMODULE, DWORD, LPVOID))(((PBYTE)handle_Dll) + pstruct_pImageNTHeaders->OptionalHeader.AddressOfEntryPoint);
// 开始发送扩展定义
DllMain(handle_Dll, 100, &dword_Error );
DllMain(handle_Dll, 101, &dword_Error );
DllMain(handle_Dll, 101, &dword_Error );
return 0;
}
[结束]
希望这个编程技巧对大家有用,感谢大家对这个技巧的支持
- 标 题:自定义DLL入口点dllmain()的第2个参数数值传递从而达到隐藏导出接口
- 作 者:猪头三
- 时 间:2011-11-24 18:14:27
- 链 接:http://bbs.pediy.com/showthread.php?t=143308