【发布时间】:2013-05-26 01:42:10
【问题描述】:
我正在制作一个自解压程序,它本质上是获取一个指向要提取(硬编码)的数据的指针,并将其添加到缓冲区中,我将从中执行操作,
但是,我遇到了一个问题,我的 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'.
此外,代码中断并转到此处:
我怀疑我正在尝试读取不可读的内存(部分的数据),但我不确定,
感谢您的宝贵时间。
【问题讨论】:
-
显示您的错误消息会有所帮助。要调试: 想法:memcpy_s() 有助于保护目标免于过度运行,但它和 memcpy() 不验证 src 和 dest 指针。通过一次取消引用每个字节的 for 循环来验证 src,对目标执行相同的操作。
标签: c++ winapi memory memcpy portable-executable