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

0 篇文章 0 订阅

参考书籍《加密与解密》第三版

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()的函数会造成内存错误,并没有成功解决,虽然不影响程序运行结果,但如果谁有解决方法请务必告诉我。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值