0

我正在制作一个自解压程序,它本质上获取一个指向要提取的数据(硬编码)的指针并将其添加到缓冲区中,我将从中执行操作,

但是,我遇到了一个问题,我的 memcpy 函数似乎出现了缓冲区溢出错误,我尝试了 memcpy_s,但出现了同样的问题:

我真的不明白为什么该功能不起作用,因为我正在将数据移动到内存中具有正确大小的分配区域,

LPVOID ExtractPayload(HINSTANCE _hInstance)
{
DWORD m_ptr = NULL;
PIMAGE_NT_HEADERS m_pntHeader;
PIMAGE_DOS_HEADER m_pdosHeader;
PIMAGE_SECTION_HEADER m_psectionHeader;
m_pdosHeader = (PIMAGE_DOS_HEADER)_hInstance;   // we don't need to make checks
m_pntHeader = (PIMAGE_NT_HEADERS)((DWORD)m_pdosHeader + m_pdosHeader->e_lfanew);
m_psectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)m_pntHeader + sizeof(IMAGE_NT_HEADERS) + (40 * 4)); // pointing to desired section header

LPVOID m_pvFileBuffer = NULL; 

SYSTEM_INFO si;
GetSystemInfo(&si);
printf("Virtual size %d\n",m_psectionHeader->Misc.VirtualSize);
int m_pageNumber = (m_psectionHeader->Misc.VirtualSize / si.dwPageSize);
if ((m_psectionHeader->Misc.VirtualSize % si.dwPageSize) > 0)
{
    m_pageNumber++;
    printf("pages : %i\n",m_pageNumber);
    printf("page size: %i\n", si.dwPageSize);
}

m_pvFileBuffer = VirtualAlloc(NULL, (si.dwPageSize*m_pageNumber), MEM_RESERVE, PAGE_NOACCESS);

for (unsigned int i = 0; i < m_pageNumber*si.dwPageSize; i += si.dwPageSize)
    {
        // we need a char* to pointer arithmetic with
        char* p = reinterpret_cast<char*>(m_pvFileBuffer);

        // reserve the ith page
        VirtualAlloc(p + i, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE);
    }
printf("lpvoid : %d",m_pvFileBuffer);
m_ptr = Rva2Offset(m_psectionHeader->VirtualAddress,m_psectionHeader,m_pntHeader->FileHeader.NumberOfSections);

memcpy(m_pvFileBuffer,(DWORD*)m_ptr,m_psectionHeader->Misc.VirtualSize);
//memcpy(&m_pvFileBuffer,&m_ptr,m_psectionHeader->Misc.VirtualSize); // buffer over-run here
//VirtualFree(m_pvFileBuffer,m_psectionHeader->Misc.VirtualSize,MEM_RELEASE);
cin.get();
return m_pvFileBuffer;
 }

这是错误:

First-chance exception at 0x002f16f3 in Stub.exe: 0xC0000005: Access violation reading location 0x00002a00. A buffer overrun has occurred in Stub.exe which has corrupted the program's internal state. Press Break to debug the program or Continue to terminate the program. For more details please see Help topic 'How to debug Buffer Overrun Issues'.

此外,代码中断并转到此处:

密码破解

我怀疑我正在尝试读取不可读的内存(部分的数据),但是我不确定,

感谢您的时间。

4

1 回答 1

0
int m_pageNumber = (m_psectionHeader->Misc.VirtualSize / si.dwPageSize);

This rounds the size down to the number of pages possibly minus one. Are you sure that VirtualSize is a multiple of dwPageSize? because later you do:

memcpy(m_pvFileBuffer,(DWORD*)m_ptr,m_psectionHeader->Misc.VirtualSize);

and if VirtualSize is not a multiple of dwPageSize then you are going to far in the memcpy().

I do not know the API well enough to know whether the VirtualAlloc() properly allocates all the pages, but the other problem could be that the function does not do what you're thinking so writing in those pages creates a memory violation.

Just in case, the division should be like this if VirtualSize may not be a multiple of dwPageSize():

int m_pageNumber = ((m_psectionHeader->Misc.VirtualSize + si.dwPageSize - 1) / si.dwPageSize);
于 2013-05-26T02:54:26.813 回答