1. 关于PE文件的描述正确的是( )

我们学习的PE文件指的是windows操作系统中的一种可执行文件格式
我们学习的PE文件指的是”老毛桃”,”大白菜”这样的装机工具
PE文件指的是后缀名为.exe的文件
mp3音频文件是一种PE格式文件
2. 下面的函数能够初步判断传入的缓冲区中的数据是一个PE文件的是( )
① bool fun(char *pbuf) {
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pbuf;
if (pDos->e_magic==0x5A4D)
{
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pbuf + pDos->e_lfanew);
if (pNt->Signature==0x00004550)
{
return true;
}
}
return false;
}

② bool fun(char *pbuf) {
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pbuf;
if (pDos->e_magic == 0x4D5A)
{
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pbuf + pDos->e_lfanew);
if (pNt->Signature==0x00004550)
{
return true;
}
}
return false;
}

③ bool fun(char *pbuf)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pbuf;
if (pDos->e_magic == 0x00004D5A)
{
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pbuf + pDos->e_lfarlc);
if (pNt->Signature==0x00004550)
{
return true;
}
}
return false;
}

④ bool fun(char *pbuf) {
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pbuf;
if (pDos->e_magic == 0x00004550)
{
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pbuf + pDos->e_lfanew);
if (pNt->Signature == 0x00004D5A)
{
return true;
}
}
return false;
}




3. IMAGE_OPTIONAL_HEADER中的没有的字段为( )

入口点
文件对齐粒度
加载基址
区段数量

4. 以下关于PE文件中EP(Entry Point)描述正确的是( )

若为C语言编写的普通控制台程序,是main函数所在的位置 反汇编查看
随意的修改EP,并不会对程序运行产生影响
若为C语言编写的动态链接库文件,是dllmain函数所在的位置
EP只是描述PE文件第一行被执行的指令,具体是什么由编译器环境所决定

5. 已知某PE文件扩展头中AddressOfEntryPoint的值是0x19800,此PE文件的加载基址是0x00670000,文件的默认加载基址是0x00400000,那么代码是从哪里开始执行的( )

0x00670000 当前PE的加载基址
0x00400000
0x00689800
0x00419800

6. 以下关于概念描述错误的是( )

文件偏移(FOA):PE文件原始状态下(未映射到内存),相对于文件起始位置的偏移量
相对虚拟地址(RVA):PE映射到内存中,相对于加载基址的偏移量
虚拟地址(VA):虚拟内存空间中的地址值
入口点(EP):程序的起始执行位置,在PE文件中保存的是入口点VA的值 RVA(相对虚拟地址)

7. 已知某数据的FOA,如何求得其RVA( )

FOA-所在区段的下个区段FOA+所在区段RVA
FOA-所在区段RVA+所在区段FOA
FOA-所在区段FOA+所在区段RVA
FOA-所在区段的下个区段RVA+所在区段FOA

8. PE文件运行时,会从硬盘加载到内存中,以下说法正确的是( )

代码段中访问全局变量的指令内容可能会被改变 如果有重定位会被修改
一般在文件中区段的对齐按照0x200,在内存中按照0x2000
硬盘中的数据排布与内存中完全一致 对齐力度不一样
会发生导出表的填充 IAT的填充

9. 某进程的加载基址是0x00610000,某数据的RVA是0x17840,FOA是0x10000,那么此数据的VA是( )

0x00627840
0x00637840
0x00027840
0x00620000

10. 某一区段的大小为0x2189字节,RVA是0x1000,文件的对齐粒度是0x200,内存的对齐粒度是0x1000,那么此区段的下一个区段的起始RVA是( )

0x4000
0x3200
0x2200
0x3000

11. 某数据g_nData所在区段的RVA是0x10000,FOA是0x5000,g_nData的RVA是0x17830,那么g_nData在文件中的位置是( )

0x5000
0x7830
0xC830
0x12830

12. 找出以下不是导出表中含有的表( )

导出函数序号表
导出函数名称表
导出函数偏移表
导出函数地址表

13. 关于导出函数序号表的描述正确的是( )

序号表与名称表的下标一一对应
序号表中的序号都是从1开始 def导出可以序号导出,写100第一个也没问题
序号表中的序号从小到大排列
序号表与地址表的下标一一对应

14. INT的含义是( )

导入名称表
导出名称表
导入地址表
导出地址表

15. 在PE文件未映射到内存中时,以下说法正确的是( )

IAT中存放的是导入函数的地址 加载到内存
INT中的数据与IAT中的数据是完全一样的 对
INT中存放的是导入函数的地址
导入表中也有序号这一个概念,通常和函数的名称存放在一起 对

16. 关于资源表的说法错误的是( )

它是数据目录表中下标为6的那个元素 下表为5
资源表一般分三层,通过第一层能找到多少种资源,通过第二层能找到每种资源有多少个,通过第三层能够找到每个资源的位置
前两层都是由一个IMAGE_RESOURCE_DIRECTORY和多个IMAGE_RESOURCE_DIRECTORY_ENTRY结构组成
资源的种类包括位图,图标,字体目录等

17. IMAGE_RESOURCE_DIRECTORY的结构如下所示( )

typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
WORD NumberOfNamedEntries;
WORD NumberOfIdEntries;
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
请问IMAGE_RESOURCE_DIRECTORY_ENTRY的个数由什么决定?

NumberOfIdEntries
NumberOfNameEntries
NumberOfNameEntries与NumberOfIdEntries共同决定
只有在程序运行起来才能确定

18. 关于基址重定位描述正确的是( )

所有的动态链接库文件在映射到内存之后,都会进行基址重定位操作
.exe后缀名的可执行文件,在运行时也可能不会加载到默认基址上
所有的PE文件在映射到内存之后,都会进行基址重定位操作
基址重定位操作完全出于防止黑客定位攻击点的目的

19. 关于重定位公式正确是( )

重定位后的值 = 新基址-原始基址+重定位前的RVA
重定位后的值 = 原始基址-新基址+重定位前的值
重定位后的值 = 新基址-原始基址+重定位前的值
重定位后的值 = 重定位前的值+原始基址+新基址

20. 重定位表的基本结构如下

  1. typedef struct _IMAGE_BASE_RELOCATIO N {<br /> DWORD VirtualAddress;<br /> DWORD SizeOfBlock;<br /> // WORD TypeOffset[1];<br /> } IMAGE_BASE_RELOCATION;<br /> typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;<br /> 以下说法错误的是

TypeOffset的低12位存储了相对于VirtualAddress 描述位置的偏移
这一个结构描述的是由VirtualAddress描述位置为起始的0x1000字节内需要重定位的位置
重定位表中只能有一个这样的结构
TypeOffset的个数为(SizeOfBlock-8)/2
P