我目前正在研究PE结构。 我正在尝试使用perl而不是C来解析它。
这不是重要的事情,但是,如果您读取二进制文件,则必须跳到某个部分。 (例如,阅读e_lfanew)
我想在0x78点读取数据,该数据由$ buf用0x200数据读取。
我想过两种方法可以提取0x78处的数据。
my ($ dummy, $ data) = unpack ("A0x78 A*", $buf);
or
seek (F, 0x78,0); read F, $buf, 0x200; print ~
我想知道这两种方法中的哪种方法比减去虚拟数据,读取数据以及通过搜索读取新数据更有效。
答案 0 :(得分:5)
驱动器的最小存储单元称为sector。对于硬盘驱动器,通常大小为512字节(尽管您也可以找到具有4096字节扇区的驱动器)。
您的文件跨越两个扇区。
000 078 200 278 400
+--------------+--------------+---...
| ****************
+--------------+--------------+---...
并且由于关注的块部分位于第一扇区中,因此您所描述的两种方法都需要读取相同数量的扇区。
由于实际上从磁盘读取数据是很慢的部分,因此这两种方法之间没有真正的区别。
哦,但是您缓冲了IO,而不是使用sysread
。使用缓冲的IO(例如read
)时,Perl会以4 KiB或8 KiB块(取决于您的Perl版本)从操作系统读取数据。因此,如果您从位置0开始读取,则从磁盘装入8或16个扇区,如果首先seek
,则从磁盘装入9或17个扇区。因此,通过尝试减少阅读,您实际上正在阅读更多!
也就是说,差异很小,以至于速度差异应该在噪音中消失。