typedef struct _IMAGE_DOS_HEADER { // DOS的.EXE头部
USHORT e_magic; // 魔术数字
USHORT e_cblp; // 文件最后页的字节数
USHORT e_cp; // 文件页数
USHORT e_crlc; // 重定义元素个数
USHORT e_cparhdr; // 头部尺寸,以段落为单位
USHORT e_minalloc; // 所需的最小附加段
USHORT e_maxalloc; // 所需的最大附加段
USHORT e_ss; // 初始的SS值(相对偏移量)
USHORT e_sp; // 初始的SP值
USHORT e_csum; // 校验和
USHORT e_ip; // 初始的IP值
USHORT e_cs; // 初始的CS值(相对偏移量)
USHORT e_lfarlc; // 重分配表文件地址
USHORT e_ovno; // 覆盖号
USHORT e_res[4]; // 保留字
USHORT e_oemid; // OEM标识符(相对e_oeminfo)
USHORT e_oeminfo; // OEM信息
USHORT e_res2[10]; // 保留字
LONG e_lfanew; // 新exe头部的文件地址
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
稍微写了一个脚本查看
$: << File.join(File.dirname(__FILE__), "..", "lib")
#require "dynamic-struct"
require 'core-ext'
#class DynamicStruct
# class_inheritable_accessor :fields_spec
#end
#DynamicStruct.fields_spec ||= []
class DynamicStruct
attr_accessor :fields
module ClassMethods
attr_accessor :fields_spec
def u2(symbol, options=nil)
@fields_spec ||= []
@fields_spec << [:u2, symbol, options ]
end
alias :USHORT :u2
def u4(symbol, options=nil)
@fields_spec ||= []
@fields_spec << [:u4, symbol, options ]
end
alias :ULONG :u4
end
extend ClassMethods
def read(file)
@fields ||= []
#puts self.class.fields_spec.inspect
self.class.fields_spec.each do |field_spec|
options = field_spec[2]
options||={}
if field_spec[0] == :u2
value = file.sysread(2)
value = value.unpack("s")[0] unless options[:format] == :string
@fields << [value, field_spec] #options
elsif field_spec[0] == :u4
value = file.sysread(4)
value = value.unpack("i")[0] unless options[:format] == :string
@fields << [value, field_spec] #options
end
end
end
def to_s(format=nil)
result = ""
if(format.nil?)
@fields.each do |value, field_spec|
#puts "converting #{value.inspect}"
result << "#{field_spec[1]}:#{value.to_s}\n"
end
end
result
end
end
class Image_Dos_Header < DynamicStruct
u2 :e_magic, :format=>:string;
u2 :e_cblp; #// 文件最后页的字节数
u2 :e_cp; #// 文件页数
u2 :e_crlc; #// 重定义元素个数
u2 :e_cparhdr; #// 头部尺寸,以段落为单位
u2 :e_minalloc; #// 所需的最小附加段
u2 :e_maxalloc; #// 所需的最大附加段
u2 :e_ss; #// 初始的SS值(相对偏移量)
u2 :e_sp; #// 初始的SP值
u2 :e_csum; #// 校验和
u2 :e_ip; #// 初始的IP值
u2 :e_cs; #// 初始的CS值(相对偏移量)
u2 :e_lfarlc; #// 重分配表文件地址
u2 :e_ovno; #// 覆盖号
u2 :e_res_0; #// 保留字
u2 :e_res_1; #// 保留字
u2 :e_res_2; #// 保留字
u2 :e_res_3; #// 保留字
u2 :e_oemid; #// OEM标识符(相对e_oeminfo)
u2 :e_oeminfo; #// OEM信息
u2 :e_res2_0; #// 保留字
u2 :e_res2_1; #// 保留字
u2 :e_res2_2; #// 保留字
u2 :e_res2_3; #// 保留字
u2 :e_res2_4; #// 保留字
u2 :e_res2_5; #// 保留字
u2 :e_res2_6; #// 保留字
u2 :e_res2_7; #// 保留字
u2 :e_res2_8; #// 保留字
u2 :e_res2_9; #// 保留字
u4 :e_lfanew; #// 新exe头部的文件地址
#field_type :image_dos_header
end
class PEFile < DynamicStruct
#image_dos_header :dos_header
end
file = ARGV[0] || "shake.exe"
f = File.new(file, "rb")
#pefile=PEFile.new
dos_header = Image_Dos_Header.new
#dos_header.read(f)
#pefile.read(f)
f.seek 0x108
puts f.sysread(4)
class Image_File_Header < DynamicStruct
USHORT :Machine;
USHORT :NumberOfSections;
ULONG :TimeDateStamp;
ULONG :PointerToSymbolTable;
ULONG :NumberOfSymbols;
USHORT :SizeOfOptionalHeader;
USHORT :Characteristics;
end
r = Image_File_Header.new
r.read(f)
puts r
f.close
#puts dos_header.to_s
输出:
PE
Machine:332
NumberOfSections:4
TimeDateStamp:1083547367
PointerToSymbolTable:0
NumberOfSymbols:0
SizeOfOptionalHeader:224
Characteristics:271