获取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;
}
0 0
原创粉丝点击