hangzhouw 发表于 2022-3-15 19:54

关于PE的基础练习

本人在学习了PE的基础知识后,用c++编写了有如下功能的代码:
1、查看PE头
2、RVA与FOA互相转换
3、往空白区域添加shellcode
4、扩大节区或添加新节区,并添加shellcode
5、将内存中的PE文件(不是PE映像)写入磁盘

现在只实现了这些功能,接下来会实现更多功能并优化代码。有机会的话会把当前的基于控制台的程序改为基于窗口的程序。

hangzhouw 发表于 2022-3-16 17:47

添加了新的功能
查看导出表,并根据函数名字或序号来显示函数地址

hangzhouw 发表于 2022-3-18 17:16

这个功能是先新增一个节区, 再把导出表移到新的节区
PIMAGE_SECTION_HEADER pNewSectionHeader = pSectionHeader + pFileHeader->NumberOfSections - 1;
        PDWORD pNewAddressOfFunctions = (PDWORD)((DWORD)pDosHeader + pNewSectionHeader->PointerToRawData);
        PDWORD pNewAddressOfNames = pNewAddressOfFunctions + pExportDirectory->NumberOfFunctions;
        PWORD pNewAddressOfNameOrdinals = (PWORD)(pNewAddressOfNames + pExportDirectory->NumberOfNames);
        LPSTR pNewAddressOfDllName = (LPSTR)(pNewAddressOfNameOrdinals + pExportDirectory->NumberOfNames);
        LPSTR pNewAddressOfNameString = NULL;
        PIMAGE_EXPORT_DIRECTORY pNewExport = NULL;
        PDWORD pOldAddressOfFunctions = (PDWORD)((DWORD)pDosHeader + RVA2FOA(pExportDirectory->AddressOfFunctions));
        PDWORD pOldAddressOfNames = (PDWORD)((DWORD)pDosHeader + RVA2FOA(pExportDirectory->AddressOfNames));
        PWORD pOldAddressOfNameOrdinals = (PWORD)((DWORD)pDosHeader + RVA2FOA(pExportDirectory->AddressOfNameOrdinals));
        DWORD StrLen = 0;

        memcpy(pNewAddressOfFunctions, pOldAddressOfFunctions, pExportDirectory->NumberOfFunctions * 4);
        memcpy(pNewAddressOfNames, pOldAddressOfNames, pExportDirectory->NumberOfNames * 4);
        memcpy(pNewAddressOfNameOrdinals, pOldAddressOfNameOrdinals, pExportDirectory->NumberOfNames * 2);

        strcpy(pNewAddressOfDllName, "Dll2.dll");
        pNewAddressOfNameString = (LPSTR)((DWORD)pNewAddressOfDllName + strlen(pNewAddressOfDllName) + 1);
        for (DWORD i = 1; i <= pExportDirectory->NumberOfNames; i++) {
                strcpy((char*)((DWORD)pNewAddressOfNameString + StrLen),(char*)((DWORD)pDosHeader+RVA2FOA(*(pOldAddressOfNames+(i-1)))));
                *(pNewAddressOfNames+i-1) = FOA2RVA((DWORD)pNewAddressOfNameString - (DWORD)pDosHeader + StrLen);
                StrLen += strlen((char*)((DWORD)pDosHeader + RVA2FOA(*(pOldAddressOfNames + (i - 1))))) + 1;
        }

        pNewExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pNewAddressOfNameString + StrLen);

        memcpy(pNewExport, pExportDirectory, sizeof(IMAGE_EXPORT_DIRECTORY));

        pNewExport->AddressOfFunctions = FOA2RVA((DWORD)pNewAddressOfFunctions - (DWORD)pDosHeader);
        pNewExport->AddressOfNames = FOA2RVA((DWORD)pNewAddressOfNames - (DWORD)pDosHeader);
        pNewExport->AddressOfNameOrdinals = FOA2RVA((DWORD)pNewAddressOfNameOrdinals - (DWORD)pDosHeader);
        pNewExport->Name = FOA2RVA((DWORD)pNewAddressOfDllName - (DWORD)pDosHeader);

        pOptionalHeader->DataDirectory.VirtualAddress = FOA2RVA((DWORD)pNewExport - (DWORD)pDosHeader);

        WriteFileBuffer2File(File,pFileBuffer,FileSize);
页: [1]
查看完整版本: 关于PE的基础练习