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 ; //映像基址
先声明几个全局变量,方便以后使用。
需要注意的是获取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()的函数会造成内存错误,并没有成功解决,虽然不影响程序运行结果,但如果谁有解决方法请务必告诉我。
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()的函数会造成内存错误,并没有成功解决,虽然不影响程序运行结果,但如果谁有解决方法请务必告诉我。
相关文章推荐
- 关于PE病毒编写的学习(六)——关于PE文件结构操作的程序编写
- 关于PE病毒编写的学习(6)——关于PE文件结构操作的程序编写
- 关于PE病毒编写的学习(六)——关于PE文件结构操作的程序编写
- 关于PE病毒编写的学习(六)——关于PE文件结构操作的程序编写
- C语言编写读取配置文件程序
- 读取PE文件头的一段小程序
- VC读取PE文件的OEP(程序入口)
- mapreduce程序中读取文件过程详解
- Jim's游戏外挂学习笔记2——适时编写个读取状态的小程序增加一下士气
- 学习PE文件格式后编写的简单代码(C代码)
- 编写一个程序,一行行地读取输入行,直至到达文件尾。算出每行输入行的长度,然后把最长的那行打印出来。为了简单起见,你可以假定所有的输入行均不超过1000个字符
- 编写一个程序,一行行地读取输入行,直至到达文件尾。算出每行输入行的长度,然后把最长的那行打印出来。为了简单起见,你可以假定所有的输入行均不超过1000个字符
- 一个PE文件的学习程序[原创]
- 编写Shell程序,通过编写完成compress1、decompress1函数,选择“压缩”或“解压”以及输入文件名,来自动完成文件的压缩、解压过程。
- c++ 编写程序开机自动启动,读取配置文件问题
- 编写一个程序,它打开一个文本文件,逐个字符地读取该文件,直到到达文件末尾,然后指出该文件中包含多少个字符
- Jim's游戏外挂学习笔记2—适时编写个读取状态的小程序增加一下士气
- 崩溃的Python学习过程1—— 用Eclipse编写Python程序(windows)
- 编写一个程序,一行行的读取输入行,直至到达文件尾。算出每行输入行的长度,然后把最长的那行打印出来
- 学习使用AutoMake1.9的自动生成工程文件(二)——flat型程序编译实践过程