能力值:
( LV4,RANK:50 )
|
-
-
2 楼
没人知道吗?
版主,快来啊。
|
能力值:
( LV13,RANK:370 )
|
-
-
3 楼
首先你得明白[ebx].OptionalHeader.SizeOfHeaders 表示什么意思!
[ebx].OptionalHeader.SizeOfHeaders 是(DOS头大小+PE头大小+所有区块表大小)按FileAlignment
对齐后的值,如果你添加一个新节后将改变上式中“所有区块表大小”。若新合成的大小不超过SizeOfHeaders便可以添加,否则区块表不能添加进去。
add eax,pe_header_off 所有节表的大小 + PE文件头偏移 = ???(1)
应该就是原先所有区块表的大小加上DOS头的大小。
感觉上面好像少掉了"PE\0\0"的四字节
|
能力值:
( LV4,RANK:50 )
|
-
-
4 楼
我把注释全加上
;***************************************************************
;判断是否有足够空间存储新节
;28h=sizeof IMAGE_SECTION_HEADER ,18h=sizeof IMAGE_FILE_HEADER
;edi将指向新节
;***************************************************************
movzx eax,[ebx].FileHeader.NumberOfSections ;节的数目
mov ecx,28h ;为乘法作准备
mul ecx ;eax=eax*ecx 节的数目*单个节的大小=节的总大小
add eax,pe_header_off 节的总大小+PE文件头偏移=???(1)
add eax,18h ;???(1) + IMAGE_FILE_HEADER的大小=???(2)
movzx esi,[ebx].FileHeader.SizeOfOptionalHeader
add eax,esi ;???(2) + IMAGE_OPTIONAL_HEADER32结构的长度=???(3)
mov edi,eax
add edi,pMapping ;I forgot this first ???(3)+内存映射文件的指钟 为后面的操作作准备
add eax,28h ???(3)+ 节表的大小( sizeof IMAGE_SECTION_HEADER)=???(4) (此处节表是新增的)
.IF eax>[ebx].OptionalHeader.SizeOfHeaders ;上面运算得到的总和如果大于(所有头+节表的 大小)说明空间不够
;当然SizeOfHeaders肯定包括dos, coff, pe头 和 段表的大小
jmp Exit ;如果空间不够结束程序
.ENDIF
[QUOTE=llydd]感觉上面好像少掉了"PE\0\0"的四字节[/QUOTE]
不知道你说少了PE文件标识(Signature)这双字节作用在哪,Signature好像只在判断是否为合法的PE才用到,难道在这里也要用
到它??(在代码的第一行开始就承认是合法的PE了)
上面的代码完全能编译通过正常运行。
作者的意思是可能是:
SizeOfHeaders和单步求出表和头的总和相比较,如果后者大说明空间不够不能添加新节。
但是他在单步求表和头的总和表叙令我费解......
|
能力值:
( LV13,RANK:370 )
|
-
-
5 楼
感觉上面好像少掉了"PE\0\0"的四字节
我不太清楚程序中pe_header_off此时到底是什么值,如果此时pe_header_off指向的是
IMAGE_NT_HEADERS结构那么就少了"PE\0\0"四字节,如果指向的是IMAGE_FILE_HEADER,那我的想法就是多余的了。!!
首先 只要求(DOS头大小+PE头大小+所有区块表大小)<= SizeOfHeaders满足便可
PE头大小包括Signature的四字节,IMAGE_FILE_HEADER的20字节,IMAGE_OPTIONAL_HEADER的224字节(一般是224字节)
add eax,pe_header_off 节的总大小+PE文件头偏移=???(1)
节的总大小+DOS头的大小(PE文件头偏移便是DOS头的大小)
add eax,18h ;???(1) + IMAGE_FILE_HEADER的大小=???(2)
节的总大小+DOS头大小+IMAGE_FILE_HEADER的大小
add eax,esi ;???(2) + IMAGE_OPTIONAL_HEADER32结构的长度=???(3)
节的总大小+DOS头大小+IMAGE_FILE_HEADER的大小+IMAGE_OPTIONAL_HEADER大小
add eax,28h ???(3)+ 节表的大小( sizeof IMAGE_SECTION_HEADER)=???(4)
节的总大小+DOS头大小+IMAGE_FILE_HEADER的大小+IMAGE_OPTIONAL_HEADER大小+新加块表的大小 最后补充一下 typedef struct _IMAGE_NT_HEADERS64 { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER64 OptionalHeader; } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
这个结构可能你没有弄清楚
|
能力值:
(RANK:220 )
|
-
-
6 楼
基本上这种情况不会发生,因为Section Header的空间都有 4096 字节,一般一个PE的Section也没几个。
这里判断的是 Section Header 的空间中是否有足够的空间来添加一个Section Header(sizeof(..SEC...HDR...)),而不是Section本身。
要理解这些东西,最好用C/C++代码,ASM变成误导了很多初学者的观念,大大降低了代码工程化效率(运行效率或许有那么一点点提升)。
|
能力值:
(RANK:220 )
|
-
-
7 楼
// Open source file
CMemFile fSrc(ptzSrc);
if (!fSrc)
{
return FALSE;
}
// Verify DOS signature
PBYTE pbSrc = fSrc;
if (((PIMAGE_DOS_HEADER) pbSrc)->e_magic != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
// Verify PE signature
PIMAGE_NT_HEADERS pNTHdr = (PIMAGE_NT_HEADERS) (pbSrc + ((PIMAGE_DOS_HEADER) pbSrc)->e_lfanew);
if (pNTHdr->Signature != IMAGE_NT_SIGNATURE)
{
return FALSE;
}
// Verify sections header space
if ((pNTHdr->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER) > pNTHdr->OptionalHeader.SizeOfHeaders)
{
return FALSE;
}
用 C/C++ 表达一下,楼主的代码相当于“Verify sections header space”部分
|
能力值:
( LV4,RANK:50 )
|
-
-
8 楼
谢谢你!完全搞懂了。
节的总大小+DOS头的大小(PE文件头偏移便是DOS头的大小)
就是这个地方理解误导了我。
e_lfanew DWORD ? ;指向PE文件头
它是DOS头的最后一个双字节,它的编移量就是DOS头的大小。呵呵!没有仔细去想它。最后导致整段代码不能理解。 附:PE文件头汇编完整结构定义
IMAGE_NT_HEADERS STRUCT
Signature DWORD ? ;PE文件标识
FileHeader IMAGE_FILE_HEADER <>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS
PE文件头的第一个双字是一个标志,它被定义为00004550h,也就是字符“P”,“E”加上两个0,这也是“PE”这个称呼的由来,大部分的文件属性由标志后面的IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER32结构来定义。
|
|
|