-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexe_info.rb
More file actions
156 lines (142 loc) · 4.83 KB
/
exe_info.rb
File metadata and controls
156 lines (142 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# http://mzc.narod.ru/Creating/Step008.htm
# This file prints PE-files (EXE, DLL...) headers information
# Example
# ExeInfo.new "C:/Windows/Sustem32/ctfmon.exe"
class ExeInfo
class Structure
class StructureBuilder
def initialize
@fields = {}
@last_byte = 0
end
def add_field name, length
@fields[name.to_sym] = @last_byte..(@last_byte + length - 1)
@last_byte += length
end
end
def initialize file, header_address
file.seek header_address
@header = file.readpartial self.class.const_get :STRUCTURE_LENGHT
p self.class.name
p "-------"
structure.each do |name, value|
p "#{name} = #{@header[value]}"
end
end
def self.set_structure &block
builder = StructureBuilder.new
builder.instance_eval &block
const_set :STRUCTURE, builder.instance_variable_get(:@fields)
const_set :STRUCTURE_LENGHT, builder.instance_variable_get(:@last_byte)
end
def get name
value = @header[field_addr(name)]
case value.size
when 2 then value.unpack("v").first
when 4 then value.unpack("V").first
else value
end
end
def structure
self.class.const_get(:STRUCTURE)
end
def field_addr name
structure[name.to_s.downcase.to_sym]
end
end
class MsDosHeader < Structure
set_structure do
first_words = %w{magic last_page_byte_count pages_count relocations_count headers_size min_headers_alloc max_headers_alloc initial_ss_value initial_sp_value check_sum initial_ip_value initial_cs_value relocations_address overlays_count}
first_words.each_with_index do |name, index|
add_field name, 2
end
add_field :reserve_1, (0x1C..0x23).count
add_field :oem_identifier, (0x24..0x25).count
add_field :oem_info, (0x26..0x27).count
add_field :reserve_2, (0x28..0x3B).count
add_field :pe_header_address, (0x3C..0x3F).count
end
end
class PeHeader < Structure
set_structure do
add_field :magic, (0..3).count
add_field :cpu_type, (4..5).count
add_field :sections_count, (6..7).count
add_field :linker_date, (8..0x0B).count
add_field :symbol_table_address, (0x0C..0x0F).count
add_field :sumbol_table_size, (0x10..0x13).count
add_field :optional_header_size, (0x14..0x15).count
add_field :flag, (0x16..0x17).count
end
end
class PeOptionalHeader < Structure
set_structure do
add_field :magic, 2
add_field :major_linker_version, 1
add_field :minor_linker_version, 1
add_field :code_size, 4
add_field :init_data_size, 4
add_field :uninit_data_size, 4
add_field :entry_point_address, 4
add_field :code_base, 4
add_field :data_base, 4
add_field :image_base, 4
add_field :section_align, 4
add_field :file_align, 4
add_field :major_os_verion, 2
add_field :minor_os_verion, 2
add_field :major_image_verion, 2
add_field :minor_image_verion, 2
add_field :major_subsystem_verion, 2
add_field :minor_subsystem_verion, 2
add_field :reserve_1, 4
add_field :image_size, 4
add_field :header_size, 4
add_field :check_sum, 4
add_field :subsystem, 2
add_field :dll_flags, 2
add_field :stack_reserve_size, 4
add_field :stack_commit_size, 4
add_field :heap_reserve_size, 4
add_field :heap_commit_size, 4
add_field :loader_flags, 4
add_field :data_dir_size, 4
end
end
class DataDirHeader < Structure
set_structure do
%w{export improt resource exception security base_reloc debug copyright cpu_spec tls config res1 res2 res3 res4 res5}.each do |name|
add_field "#{name}_dir_addr", 4
add_field "#{name}_dir_size", 4
end
end
end
class SectionHeader < Structure
set_structure do
add_field :section_name, 8
add_field :virtual_size, 4
add_field :virtual_addr, 4
add_field :physical_size, 4
add_field :physical_addr, 4
add_field :reserve_1, 12
add_field :section_flags, 4
end
end
def initialize file
@file = case file
when File then file
when String then File.new file, "rb"
end
@msdos_header = MsDosHeader.new @file, 0
@pe_header = PeHeader.new @file, @msdos_header.get(:pe_header_address)
optioanl_addr = (@msdos_header.get(:pe_header_address) + PeHeader::STRUCTURE_LENGHT)
@pe_optional_header = PeOptionalHeader.new @file, optioanl_addr
data_dir_addr = optioanl_addr + PeOptionalHeader::STRUCTURE_LENGHT
@data_dir_header = DataDirHeader.new @file, data_dir_addr
sections_addr = data_dir_addr + DataDirHeader::STRUCTURE_LENGHT
@sections = []
1.upto(@pe_header.get(:sections_count)) do |section|
@sections.push SectionHeader.new @file, sections_addr + SectionHeader::STRUCTURE_LENGHT * (section - 1)
end
end
end