获取DLL程序详解
来源:互联网 发布:淘宝买手机靓号可靠吗 编辑:程序博客网 时间:2024/05/16 05:08
/*
函数功能:(C语言版)
计算指定长度数据的Crc32b Hash
输入参数:
1.(内存指针):需要Hash的内存启示点
2.(长度):需要Hash的内存长度
3.(初始化Hash值):用于在已有的Hash值后面增加,默认请填写0
返回数据:
Crc32b Hash值
*/
DWORD HashCrc32(char *lpChar, int iLen, DWORD dwCrc)
{
if (0 == iLen) return dwCrc;
dwCrc = ~dwCrc;
while (iLen-- != 0)
{
DWORD dwTmp = *lpChar++;
for (int iLoop = 0; iLoop < 8; iLoop++)
{
if (((dwCrc ^ dwTmp) & 1)!= 0)
{
dwCrc = (dwCrc >> 1);
dwCrc = dwCrc ^ 0xEDB80000; // 此处为变形数值
dwCrc = dwCrc ^ 0x00008320; // 原数值: dwCrc ^ 0xEDB88320
}
else dwCrc >>= 1;
dwTmp >>= 1;
}
}
return ~dwCrc;
}
/*
函数功能:
通过API函数的字符串名称的Hash值,搜索出API的地址
输入参数:
1.(句柄型):模块载入的基址
2.(无符号长整形):Hash值
返回数据:
函数地址,如果获取失败返回NULL
*/
PVOID WINAPI xGetProcAddress(HMODULE hModule, const DWORD dwApiCrc)
{
PVOID lpResult = NULL;
PIMAGE_NT_HEADERS lpNtHeaders;
PIMAGE_EXPORT_DIRECTORY lpExport;
DWORD dwNameCrc;
char *lpcProcName;
WORD wProcOrd;
PDWORD lpProcNameEx;
PWORD lpProcOrdEx;
PDWORD lpProcPointerEx;
// 判断是否是DOS Stub
if (((PIMAGE_DOS_HEADER)hModule)->e_magic != IMAGE_DOS_SIGNATURE) return lpResult;
// 获取PE_Header基址
lpNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)hModule + ((PIMAGE_DOS_HEADER)hModule)->e_lfanew);
// 判断是否是PE Header
if (lpNtHeaders->Signature != IMAGE_NT_SIGNATURE) return lpResult;
// 获取导出表结构地址
lpExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)lpNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (DWORD)hModule);
// 判断导出函数如果数量如果为0退出
if (NULL == lpExport->NumberOfNames) return lpResult;
lpProcNameEx = (DWORD *)(lpExport->AddressOfNames + (DWORD)hModule);
lpProcOrdEx = (WORD *)(lpExport->AddressOfNameOrdinals + (DWORD)hModule);
lpProcPointerEx = (DWORD *)(lpExport->AddressOfFunctions + (DWORD)hModule);
// 搜索函数名称
for (DWORD dwLoop = 0; dwLoop < lpExport->NumberOfNames - 1; dwLoop++)
{
__try
{
// 获得函数地址
lpcProcName = (PCHAR)(((DWORD)lpProcNameEx[dwLoop]));
lpcProcName = (PCHAR)((DWORD)hModule + (DWORD)lpcProcName);
// 计算函数名称的Hash
dwNameCrc = HashCrc32(lpcProcName, StrLenEx(lpcProcName), 0);
}
__except(1)
{
return lpResult;
}
// Crc32b Hash相同
if (dwNameCrc == dwApiCrc)
{
// 得到函数序号
wProcOrd = (WORD)(((DWORD)lpProcOrdEx[dwLoop]) + lpExport->Base);
// 通过函数序号获取函数地址
lpResult = (PVOID)((DWORD)hModule + lpProcPointerEx[wProcOrd - lpExport->Base]);
}
}
return lpResult;
}
函数功能:(C语言版)
计算指定长度数据的Crc32b Hash
输入参数:
1.(内存指针):需要Hash的内存启示点
2.(长度):需要Hash的内存长度
3.(初始化Hash值):用于在已有的Hash值后面增加,默认请填写0
返回数据:
Crc32b Hash值
*/
DWORD HashCrc32(char *lpChar, int iLen, DWORD dwCrc)
{
if (0 == iLen) return dwCrc;
dwCrc = ~dwCrc;
while (iLen-- != 0)
{
DWORD dwTmp = *lpChar++;
for (int iLoop = 0; iLoop < 8; iLoop++)
{
if (((dwCrc ^ dwTmp) & 1)!= 0)
{
dwCrc = (dwCrc >> 1);
dwCrc = dwCrc ^ 0xEDB80000; // 此处为变形数值
dwCrc = dwCrc ^ 0x00008320; // 原数值: dwCrc ^ 0xEDB88320
}
else dwCrc >>= 1;
dwTmp >>= 1;
}
}
return ~dwCrc;
}
/*
函数功能:
通过API函数的字符串名称的Hash值,搜索出API的地址
输入参数:
1.(句柄型):模块载入的基址
2.(无符号长整形):Hash值
返回数据:
函数地址,如果获取失败返回NULL
*/
PVOID WINAPI xGetProcAddress(HMODULE hModule, const DWORD dwApiCrc)
{
PVOID lpResult = NULL;
PIMAGE_NT_HEADERS lpNtHeaders;
PIMAGE_EXPORT_DIRECTORY lpExport;
DWORD dwNameCrc;
char *lpcProcName;
WORD wProcOrd;
PDWORD lpProcNameEx;
PWORD lpProcOrdEx;
PDWORD lpProcPointerEx;
// 判断是否是DOS Stub
if (((PIMAGE_DOS_HEADER)hModule)->e_magic != IMAGE_DOS_SIGNATURE) return lpResult;
// 获取PE_Header基址
lpNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)hModule + ((PIMAGE_DOS_HEADER)hModule)->e_lfanew);
// 判断是否是PE Header
if (lpNtHeaders->Signature != IMAGE_NT_SIGNATURE) return lpResult;
// 获取导出表结构地址
lpExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)lpNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (DWORD)hModule);
// 判断导出函数如果数量如果为0退出
if (NULL == lpExport->NumberOfNames) return lpResult;
lpProcNameEx = (DWORD *)(lpExport->AddressOfNames + (DWORD)hModule);
lpProcOrdEx = (WORD *)(lpExport->AddressOfNameOrdinals + (DWORD)hModule);
lpProcPointerEx = (DWORD *)(lpExport->AddressOfFunctions + (DWORD)hModule);
// 搜索函数名称
for (DWORD dwLoop = 0; dwLoop < lpExport->NumberOfNames - 1; dwLoop++)
{
__try
{
// 获得函数地址
lpcProcName = (PCHAR)(((DWORD)lpProcNameEx[dwLoop]));
lpcProcName = (PCHAR)((DWORD)hModule + (DWORD)lpcProcName);
// 计算函数名称的Hash
dwNameCrc = HashCrc32(lpcProcName, StrLenEx(lpcProcName), 0);
}
__except(1)
{
return lpResult;
}
// Crc32b Hash相同
if (dwNameCrc == dwApiCrc)
{
// 得到函数序号
wProcOrd = (WORD)(((DWORD)lpProcOrdEx[dwLoop]) + lpExport->Base);
// 通过函数序号获取函数地址
lpResult = (PVOID)((DWORD)hModule + lpProcPointerEx[wProcOrd - lpExport->Base]);
}
}
return lpResult;
}
0 0
- 获取DLL程序详解
- DLL程序入口DllMain详解
- 【Windows】当程序调用dll时,获取dll路径
- 获取程序(EXE文件,dll文件)的主图标
- 续《从DLL中获取VCLSkin皮肤的演示程序》谈DLL制作方法
- 【CUDA】利用NVIDIA SDK生成dll程序详解
- 微信小程序获取textarea的值详解
- 详解微信小程序 登录获取unionid
- 微信小程序获取用户手机号详解
- 微信小程序获取用户手机号详解
- dll详解
- dll详解
- DLL 详解
- DLL详解
- DLL详解
- DLL详解
- DLL详解
- DLL详解
- hadoop 2.0版本后mapre-site的配置
- 求sn=a+aa+aaa+aaaa+……
- 《swift 2.1基础部分 》在playground上练习
- IOS应用程序的生命周期
- liferay 学习网站 作者为 胡启稳
- 获取DLL程序详解
- IOS动画学习
- XAMPP: Access forbidden!
- UIViewController生命周期
- Search in Rotated Sorted Array -- Leetcode
- Linux 查看用户执行过的命令,运行特定历史命令
- 黑马程序员-TCP上传图片-多线程并发上传图片-客户端并发登陆-自定义服务器
- 第17周项目6学生成绩统计(1)-(3)
- 豆瓣电台api