飘云 发表于 2015-1-14 15:43:00

抛砖引玉2-PE64简单解析DLL导出表

方便你们写劫持工具。。。自己去整吧~~

/*
        解析PE64 DLL 导出表
        By 飘云/P.Y.G
        www.chinapyg.com
*/
#include "windows.h"
#include "stdio.h"


DWORD RVA2Offset(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA)
{
        PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pNTHeader + sizeof(IMAGE_NT_HEADERS));

        for(int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
        {
                if(dwRVA >= pSection.VirtualAddress && dwRVA < (pSection.VirtualAddress + pSection.SizeOfRawData))
                {
                        return pSection.PointerToRawData + (dwRVA - pSection.VirtualAddress);
                }
        }

        return 0;
}

void PE64_DLL(PCHAR lpFileName)
{
        HANDLE hfile = CreateFileA(lpFileName,
                GENERIC_READ|GENERIC_WRITE,
                FILE_SHARE_READ,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);

        if(hfile == INVALID_HANDLE_VALUE)
        {
                printf("创建文件失败.\n");
                return ;
        }
        HANDLE hFileMapping = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (hFileMapping == NULL || hFileMapping == INVALID_HANDLE_VALUE)
        {
                printf("创建共享内存失败 (%d).\n", GetLastError());
                return ;
        }

        LPBYTE lpBaseAddress = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
        if (lpBaseAddress == NULL)
        {
                printf("内存映射失败 (%d).\n", GetLastError());
                return ;
        }
        PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;

        // 验证PE合法性
        if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        {
                printf("--非PE文件!\n");       
                // 自行清理现场。。。
                return;
        }

        PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(lpBaseAddress + pDosHeader->e_lfanew);

        // 继续验证PE合法性
        if(pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
        {
                printf("--非PE文件!\n");
                // 自行清理现场。。。
                return;
        }

        int dwExportOffset = RVA2Offset(pNtHeaders, pNtHeaders->OptionalHeader.DataDirectory.VirtualAddress);
        PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)lpBaseAddress + dwExportOffset);
        DWORD dwFunctionNameOffset = (DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->Name);
        DWORD* pdwNamesAddress = (DWORD*)((DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->AddressOfNames));
        DWORD* pdwFunctionAddress = (DWORD*)((DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->AddressOfFunctions));
        WORD* pwOrdinals = (WORD*)((DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pExport->AddressOfNameOrdinals));

        DWORD dwNumberOfNames = pExport->NumberOfNames;

        if(dwNumberOfNames > 0)
        {
                printf("文件名: %s\n", dwFunctionNameOffset);
                printf("导出函数总数: %X\n", pExport->NumberOfFunctions);
                printf("名称函数总数: %X\n\n", pExport->NumberOfNames);

                printf("名称导出:\n\n");

                for(int i = 0; i < dwNumberOfNames; i++)
                {
                        DWORD dwFunctionAddress = pdwFunctionAddress];
                        DWORD pdwFunNameOffset = (DWORD)lpBaseAddress + RVA2Offset(pNtHeaders, pdwNamesAddress);

                        printf("[序号]: %-4X[名称]: %-30s: 0x%08X\n", pExport->Base + i/* + 1*/, pdwFunNameOffset, dwFunctionAddress);
                }

                printf("\n序号导出:\n\n");

                for(int i = 0; i < pExport->NumberOfFunctions - dwNumberOfNames; i++)
                {
                        printf("[序号]: %-4d: 0x%08X\n", pExport->Base + i/* + 1*/, pdwFunctionAddress);
                }
        }else
                printf("\n\t---------- 未找到导出表! ----------\n");


        UnmapViewOfFile(lpBaseAddress);
        CloseHandle(hFileMapping);
        CloseHandle(hfile);

}

void main()
{
        char szFileName;
        printf("请输入文件路径:\n");
        scanf("%s", szFileName);
        PE64_DLL(szFileName);
        system("pause");
}


开心啦 发表于 2015-1-14 16:30:15

此贴必火!感谢飘大,抢座留名.....{:soso_e113:}

Dxer 发表于 2015-1-14 17:14:38

藤椅是我的。多谢飘哥抽空来分享技术

lucky_789 发表于 2015-1-14 22:19:59

良码善用之

small-q 发表于 2015-1-15 08:59:01

爽啊。。。。又是福利

wanap571 发表于 2015-1-15 12:24:19

多谢飘哥抽空来分享技术

649117060 发表于 2015-1-16 11:30:12

谢谢分享谢谢分享谢谢分享

fzx118 发表于 2015-1-16 11:34:55

多谢分享大大技术
页: [1]
查看完整版本: 抛砖引玉2-PE64简单解析DLL导出表