您的位置:首页 > 其它

PE程序壳编写学习过程(一)PE文件的读取

2016-08-26 09:14 513 查看
参考书籍《加密与解密》第三版

CODEBLOCK下编写

一,头文件的包含。

由于使用WinGw编译,需要包含windef.h。然后为了windows文件的读取,包含winbase.h。又由于提示缺少va_list的声明,包含stdarg.h解决。

二,程序代码。

读取的原理是先定位到IMAGE_NT_HEADERS,然后再逐个读取IMAGE_SECTION_HEADER。

还有一种简单的读取方式是申请整个文件大小的内存空间,然后将文件直接读入内存,但这种读取方式对以后的操作会造成不便,故不采用。

UINT m_nImageSize = 0;//映像大小
PIMAGE_NT_HEADERS m_pntHeaders = 0;//PE结构指针
PIMAGE_SECTION_HEADER m_psecHeader = 0;//第一个SECTION结构指针
PCHAR m_pImageBase = 0 ; //映像基址

先声明几个全局变量,方便以后使用。

HANDLE hFile = CreateFile("notepad.exe",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if( hFile == INVALID_HANDLE_VALUE){
cout<<"Fail to open the file!"<<endl;
return 0;
}
//读DOS头
DWORD fsize=GetFileSize(hFile,NULL);
DWORD buffersize=fsize;//+0x2000;
BYTE *buffer = new BYTE[buffersize];
DWORD read;
ReadFile(hFile,buffer,fsize,&read,NULL);
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) buffer;//获取到dos头
cout << "DOS signature: " << dosHeader->e_magic << endl;
if (dosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
cout << "DOS signature mismatch!" << endl;

PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)&buffer[dosHeader->e_lfanew];//获取到NT头
cout << "NT signature: " << ntHeaders->Signature << endl;
if (ntHeaders->Signature!=IMAGE_NT_SIGNATURE)
cout << "NT signature mismatch!" << endl;

需要注意的是获取NT头时,要在dosHeader的之后加上dosHeader的长度,然后再将其整体转换成PIMAGE_NT_HEADER的形式。

m_pImageBase = new char[m_nImageSize];
memset(m_pImageBase,0,m_nImageSize);//清空申请内存
SetFilePointer(hFile,0,NULL,FILE_BEGIN);
ReadFile(hFile,m_pImageBase,nHeaderSize,&read,NULL);//这个语句会导致内存错误,原因暂时不明
m_pntHeaders = (PIMAGE_NT_HEADERS)((DWORD)m_pImageBase + dosHeader->e_lfanew);
//计算IMAGE_NT_HEADERS大小
DWORD nNtHeaderSize = sizeof(ntHeaders->FileHeader)+sizeof(ntHeaders->Signature)+ntHeaders->FileHeader.SizeOfOptionalHeader;
//cout<<nNtHeaderSize<<endl;
m_psecHeader = (PIMAGE_SECTION_HEADER)((DWORD)m_pntHeaders + nNtHeaderSize);
//循环依次读出SECTION数据到映像中的虚拟地址处
PIMAGE_SECTION_HEADER psecHeader = m_psecHeader;
for(WORD nIndex = 0;nIndex<nSectionNum;++nIndex,++psecHeader)
{
DWORD nRawDataSize = psecHeader->SizeOfRawData;
DWORD nRawDataOffset = psecHeader->PointerToRawData;
DWORD nVirtualAddress = psecHeader->VirtualAddress;
DWORD nvirtualSize = psecHeader->Misc.VirtualSize;
SetFilePointer(hFile,nRawDataOffset,NULL,FILE_BEGIN);//定位到下一SECTION
ReadFile(hFile,&m_pImageBase[nVirtualAddress],nRawDataSize,NULL,NULL);//读数据到映像中
cout<<nIndex<<endl;
}
其中有一个ReadFile()的函数会造成内存错误,并没有成功解决,虽然不影响程序运行结果,但如果谁有解决方法请务必告诉我。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  windows 解密 加密
相关文章推荐