计算可移植可执行文件导出RVA

问题描述

im试图将dll传递到此exe,并将字符串移至其首次导出。 这个dll仅有一个空的main和char [200]导出

Test.dll

extern "C" __declspec(dllexport) char encoded[200];
char encoded[200];

Export.exe


std::uint64_t* GetPtrFromRVA(std::uint64_t m_dwRVA,IMAGE_NT_HEADERS* m_pNtHeaders,uint8_t* m_aImage)
{

    auto GetSectionHeader = [m_dwRVA,m_pNtHeaders]() -> IMAGE_SECTION_HEADER*
    {
        IMAGE_SECTION_HEADER* m_pSection = IMAGE_FIRST_SECTION64(m_pNtHeaders);
        for (int i = 0; i < m_pNtHeaders->FileHeader.NumberOfSections; i++,m_pSection++)
        {
            std::uint64_t m_dwSize = m_pSection->Misc.VirtualSize;
            if (!m_dwSize)
                m_dwSize = m_pSection->SizeOfRawData;

            if ((m_dwRVA >= m_pSection->VirtualAddress) && (m_dwRVA < (m_pSection->VirtualAddress + m_dwSize)))
                return m_pSection;
        }

        return nullptr;
    };

    IMAGE_SECTION_HEADER* m_pSectionHeader = GetSectionHeader();
    if (!m_pSectionHeader)
        return nullptr;

    auto m_dwDelta = (std::uint64_t)(m_pSectionHeader->VirtualAddress - m_pSectionHeader->PointerToRawData);
    return (std::uint64_t*)(m_aImage + m_dwRVA - m_dwDelta);
}

int main(int argc,char* argv[])
{

    std::string file_path = std::string(argv[1]);
    std::vector<std::uint8_t> file_data;
    std::ifstream file_stream(file_path,std::ios::binary);

    file_stream.unsetf(std::ios::skipws);
    file_stream.seekg(0,std::ios::end);

    const auto file_size = file_stream.tellg();

    file_stream.seekg(0,std::ios::beg);
    file_data.reserve(static_cast<uint32_t>(file_size));
    file_data.insert(file_data.begin(),std::istream_iterator< std::uint8_t >(file_stream),std::istream_iterator< std::uint8_t >());

    auto dos_header = reinterpret_cast<IMAGE_DOS_HEADER*>(file_data.data());
    if (!dos_header || dos_header->e_magic != IMAGE_DOS_SIGNATURE)
        return 0;

    auto nt_headers = reinterpret_cast<IMAGE_NT_HEADERS*>(file_data.data() + dos_header->e_lfanew);
    if (!nt_headers || nt_headers->Signature != IMAGE_NT_SIGNATURE)
        return 0;

    IMAGE_EXPORT_DIRECTORY* export_directory = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(GetPtrFromRVA
    (
        nt_headers->OptionalHeader64.DataDirectory[DIR_EXPORT].VirtualAddress,nt_headers,file_data.data()
    ));

    std::uint32_t* name_address = reinterpret_cast<std::uint32_t*>(GetPtrFromRVA(

        export_directory->AddressOfNames,file_data.data()
        )); //correctly resolved

    std::uint16_t* ordinal_address = reinterpret_cast<std::uint16_t*>(GetPtrFromRVA(

        export_directory->AddressOfNameOrdinals,file_data.data()
    )); //correctly resolved

    std::uint32_t* functions_address = reinterpret_cast<std::uint32_t*>(GetPtrFromRVA(

        export_directory->AddressOfFunctions,file_data.data()
    )); //correctly resolved

    std::uint64_t* function_offset = reinterpret_cast<std::uint64_t*>(GetPtrFromRVA(
        functions_address[0],file_data.data()
    ));//wrong address to first export !

    const char* test_data = "string";
    memcpy((char*)function_offset,test_data,strlen(test_data ));
    memcpy((char*)function_offset + 100,strlen(test_data ));


    return 1;

}

我遇到的问题是我无法正确解析rva函数,尽管所有rvas都无法解析

std::uint64_t* function_offset = reinterpret_cast<std::uint64_t*>(GetPtrFromRVA(
        functions_address[0],file_data.data()
    )); 

是完全正确的。此导出应该在数据部分中,但是似乎“ function_offset”最终指向了dll清单的中间吗?任何提示或出口知识大受赞赏

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...