关于PE病毒编写的学习(六)——关于PE文件结构操作的程序编写
2011-03-17 17:12
399 查看
对PE文件结构的各个值定义和作用,这里不提了,网上资源很多,百度一下就好了。所以,本章只说一下,作为代码编写者对PE文件结构操作的方法和技巧。
还是通过改进代码,来体会一下吧。
你应该记得前面的BOOL IsPEFile(HANDLE hFIle) 这个函数吧,它的作用是判断文件是否为PE格式文件。它把文件句柄作为参数,虽然许多函数需要文件句柄这个参数,但是作为对PE文件结构操作的函数,这样做是不恰当的,因为如果这样做就要频繁的使用SetFilePointer()、ReadFile()、WriteFile()。假若以文件指针作为参数,那么这一类关于PE结构文件操作的代码,将大大简化。
举例:
BOOL IsPEFile(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDosHeader=NULL;
PIMAGE_NT_HEADERS32 pNtHeaders=NULL;
//指针安全检查
if(!ImageBase)
return FALSE;
//dos头检查
pDosHeader=(PIMAGE_DOS_HEADER)ImageBase;
if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
return FALSE;
//NT文件头检查
pNtHeaders=(PIMAGE_NT_HEADERS32)pDosHeader->e_lfanew;
if(pNtHeaders->Signauture!=IMAGE_NT_SIGNATURE)
return FALSE;
return TRUE;
}
当然为了使文件以指针传入,需要将其映射到内存中,并且由于许多函数需要文件句柄,所以原来的HANDLE OpenHostFile()需要改造。
typedef struct PEFileInformation//用这个名字是因为将来还要添加其他成员
{
HANDLE hFile;
HANLDE hMap;
LPVOID ImageBase;
}INFORMATION_PE_FILE,*PINFORMATION_PE_FILE;
PINFORMATION_PE_FILE OpenHostFile(PINFORMATION_PE_FILE pFile,/
const WIN32_FIND_DATA *pHost,/
DWORD *nCount)
{
pFile.hFile=CreateFile(pHost->cFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
NULL,
NULL);
if(pFile.hFile!=INVALID_HANDLE_VALUE)
{
pFile.hMap=CreateFileMapping(pFile.hFile,NULL,PAGE_READONLY,0,0,NULL);
pFile.ImageBase=MapViewOfFile(pFile.hMap,FILE_MAP_WRITE |FILE_MAP_READ,/
0,0,0,0);
if(pFile.ImageBase!=NULL)
(*nCount)++;
else
return NULL;
}
else
return NULL;
return pFile;
}
OK,估计真正你已经了解PE文件结构操作的方法,即以DOS头为起点,逐步通过指针偏移,扫描PE结构,以下是一些获取常用PE结构参考代码
//获取NT文件头
PIMAGE_NT_HEADERS32 GetNtHeaders(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDosHeader=NULL;
PIMAGE_NT_HEADERS32 pNtHeaders=NULL;
if(!ImageBase)
return NULL;
pDosHeader=(PIMAGE_DOS_HEADER)ImageBase;
pNtHeaders=(PIMAGE_NT_HEADERS32)pDosHeader->e_lfanew;
return pNtHeaders;
}
//获取PE可选文件头
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase)
{
PIMAGE_NT_HEADERS32 pNtHeaders=NULL;
pNtHeaders=GetNtHeaders(ImageBase);
if(!pNtHeader)
return NULL;
else
return &pNtHeaders->Header;
}
//获得区块表指针
PIMAGE_SECTION_HEADER GetSectionHeader(LPVOID ImageBase)
{
return (PIMAGE_SECTION_HEADER)(GetOptionalHeader(ImageBase)+sizeof(IMAGE_OPTIONAL_HEADER));
}
PE结构上还要许多重要的位置,用的时候以上面的函数为基点,编写自己的函数吧
还是通过改进代码,来体会一下吧。
你应该记得前面的BOOL IsPEFile(HANDLE hFIle) 这个函数吧,它的作用是判断文件是否为PE格式文件。它把文件句柄作为参数,虽然许多函数需要文件句柄这个参数,但是作为对PE文件结构操作的函数,这样做是不恰当的,因为如果这样做就要频繁的使用SetFilePointer()、ReadFile()、WriteFile()。假若以文件指针作为参数,那么这一类关于PE结构文件操作的代码,将大大简化。
举例:
BOOL IsPEFile(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDosHeader=NULL;
PIMAGE_NT_HEADERS32 pNtHeaders=NULL;
//指针安全检查
if(!ImageBase)
return FALSE;
//dos头检查
pDosHeader=(PIMAGE_DOS_HEADER)ImageBase;
if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
return FALSE;
//NT文件头检查
pNtHeaders=(PIMAGE_NT_HEADERS32)pDosHeader->e_lfanew;
if(pNtHeaders->Signauture!=IMAGE_NT_SIGNATURE)
return FALSE;
return TRUE;
}
当然为了使文件以指针传入,需要将其映射到内存中,并且由于许多函数需要文件句柄,所以原来的HANDLE OpenHostFile()需要改造。
typedef struct PEFileInformation//用这个名字是因为将来还要添加其他成员
{
HANDLE hFile;
HANLDE hMap;
LPVOID ImageBase;
}INFORMATION_PE_FILE,*PINFORMATION_PE_FILE;
PINFORMATION_PE_FILE OpenHostFile(PINFORMATION_PE_FILE pFile,/
const WIN32_FIND_DATA *pHost,/
DWORD *nCount)
{
pFile.hFile=CreateFile(pHost->cFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
NULL,
NULL);
if(pFile.hFile!=INVALID_HANDLE_VALUE)
{
pFile.hMap=CreateFileMapping(pFile.hFile,NULL,PAGE_READONLY,0,0,NULL);
pFile.ImageBase=MapViewOfFile(pFile.hMap,FILE_MAP_WRITE |FILE_MAP_READ,/
0,0,0,0);
if(pFile.ImageBase!=NULL)
(*nCount)++;
else
return NULL;
}
else
return NULL;
return pFile;
}
OK,估计真正你已经了解PE文件结构操作的方法,即以DOS头为起点,逐步通过指针偏移,扫描PE结构,以下是一些获取常用PE结构参考代码
//获取NT文件头
PIMAGE_NT_HEADERS32 GetNtHeaders(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDosHeader=NULL;
PIMAGE_NT_HEADERS32 pNtHeaders=NULL;
if(!ImageBase)
return NULL;
pDosHeader=(PIMAGE_DOS_HEADER)ImageBase;
pNtHeaders=(PIMAGE_NT_HEADERS32)pDosHeader->e_lfanew;
return pNtHeaders;
}
//获取PE可选文件头
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase)
{
PIMAGE_NT_HEADERS32 pNtHeaders=NULL;
pNtHeaders=GetNtHeaders(ImageBase);
if(!pNtHeader)
return NULL;
else
return &pNtHeaders->Header;
}
//获得区块表指针
PIMAGE_SECTION_HEADER GetSectionHeader(LPVOID ImageBase)
{
return (PIMAGE_SECTION_HEADER)(GetOptionalHeader(ImageBase)+sizeof(IMAGE_OPTIONAL_HEADER));
}
PE结构上还要许多重要的位置,用的时候以上面的函数为基点,编写自己的函数吧
相关文章推荐
- 关于PE病毒编写的学习(六)——关于PE文件结构操作的程序编写
- 关于PE病毒编写的学习(六)——关于PE文件结构操作的程序编写
- 关于PE病毒编写的学习(6)——关于PE文件结构操作的程序编写
- PE结构学习笔记--关于AddressOfEntryPoint位置在文件中怎么确定问题
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
- PE程序壳编写学习过程(一)PE文件的读取
- PE结构学习笔记--关于AddressOfEntryPoint位置在文件中怎么确定问题
- 关于PE病毒编写的学习(三)
- Linux学习4:目录结构及文件基本操作
- 关于Excel操作编写的一个软件设计构思案例[连载] --如何把处理好后的数据导出Excel文件中(含背景\字体颜色设置)
- 关于PE病毒编写的学习(四)——关于历遍磁盘的讨论
- PE文件结构学习笔记
- 关于:SQL 以前的某个程序安装已在安装计算机上创建挂起的文件操作 解决办法
- 关于PE病毒编写的学习(四)——关于历遍磁盘的讨论
- 关于AutoCAD的dwg文件操作学习
- PE文件结构-学习笔记
- Linux 学习日记 2: 目录结构和文件操作
- 关于:以前的某个程序安装已在安装计算机上创建挂起的文件操作 解决办法
- iOS关于数据库操作之二 将工程里的数据库文件在程序加载时移至沙盒
- 关于PE病毒编写的学习(五)——病毒如何做标记和记录信息