comparison pytouhou/formats/exe.py @ 590:e15672733c93

Switch to Python 3.x instead of 2.7.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 30 Sep 2014 17:14:24 +0200
parents b11953cf1d3b
children d1f0bb0b7a17
comparison
equal deleted inserted replaced
589:0768122da817 590:e15672733c93
72 only be useful for a specific build of the game. 72 only be useful for a specific build of the game.
73 """ 73 """
74 74
75 format = Struct('<4f2I') 75 format = Struct('<4f2I')
76 data_section = [section for section in pe_file.sections 76 data_section = [section for section in pe_file.sections
77 if section.Name.startswith('.data')][0] 77 if section.Name.startswith(b'.data')][0]
78 text_section = [section for section in pe_file.sections 78 text_section = [section for section in pe_file.sections
79 if section.Name.startswith('.text')][0] 79 if section.Name.startswith(b'.text')][0]
80 data_va = pe_file.image_base + data_section.VirtualAddress 80 data_va = pe_file.image_base + data_section.VirtualAddress
81 data_size = data_section.SizeOfRawData 81 data_size = data_section.SizeOfRawData
82 text_va = pe_file.image_base + text_section.VirtualAddress 82 text_va = pe_file.image_base + text_section.VirtualAddress
83 text_size = text_section.SizeOfRawData 83 text_size = text_section.SizeOfRawData
84 84
85 # Search the whole data segment for 4 successive character definitions 85 # Search the whole data segment for 4 successive character definitions
86 for addr in xrange(data_va, data_va + data_size, 4): 86 for addr in range(data_va, data_va + data_size, 4):
87 for character_id in xrange(4): 87 for character_id in range(4):
88 pe_file.seek_to_va(addr + character_id * 24) 88 pe_file.seek_to_va(addr + character_id * 24)
89 (speed1, speed2, speed3, speed4, 89 (speed1, speed2, speed3, speed4,
90 ptr1, ptr2) = format.unpack(pe_file.file.read(format.size)) 90 ptr1, ptr2) = format.unpack(pe_file.file.read(format.size))
91 91
92 # Check whether the character's speed make sense, 92 # Check whether the character's speed make sense,
99 99
100 # So far, this character definition seems to be valid. 100 # So far, this character definition seems to be valid.
101 # Now, make sure the shoot function wrappers pass valid addresses 101 # Now, make sure the shoot function wrappers pass valid addresses
102 102
103 # Search for the “push” instruction 103 # Search for the “push” instruction
104 for i in xrange(20): 104 for i in range(20):
105 # Find the “push” instruction 105 # Find the “push” instruction
106 pe_file.seek_to_va(ptr1 + i) 106 pe_file.seek_to_va(ptr1 + i)
107 instr1, shtptr1 = unpack('<BI', pe_file.file.read(5)) 107 instr1, shtptr1 = unpack('<BI', pe_file.file.read(5))
108 pe_file.seek_to_va(ptr2 + i) 108 pe_file.seek_to_va(ptr2 + i)
109 instr2, shtptr2 = unpack('<BI', pe_file.file.read(5)) 109 instr2, shtptr2 = unpack('<BI', pe_file.file.read(5))
135 135
136 @classmethod 136 @classmethod
137 def read(cls, file): 137 def read(cls, file):
138 pe_file = PEFile(file) 138 pe_file = PEFile(file)
139 data_section = [section for section in pe_file.sections 139 data_section = [section for section in pe_file.sections
140 if section.Name.startswith('.data')][0] 140 if section.Name.startswith(b'.data')][0]
141 data_va = pe_file.image_base + data_section.VirtualAddress 141 data_va = pe_file.image_base + data_section.VirtualAddress
142 data_size = data_section.SizeOfRawData 142 data_size = data_section.SizeOfRawData
143 143
144 try: 144 try:
145 character_records_va = next(cls.find_character_defs(pe_file)) 145 character_records_va = next(cls.find_character_defs(pe_file))
146 except StopIteration: 146 except StopIteration:
147 raise InvalidExeException 147 raise InvalidExeException
148 148
149 characters = [] 149 characters = []
150 shots_offsets = {} 150 shots_offsets = {}
151 for character in xrange(4): 151 for character in range(4):
152 sht = cls() 152 sht = cls()
153 153
154 pe_file.seek_to_va(character_records_va + 6*4*character) 154 pe_file.seek_to_va(character_records_va + 6*4*character)
155 155
156 data = unpack('<4f2I', file.read(6*4)) 156 data = unpack('<4f2I', file.read(6*4))
167 focused_sht = copy(sht) 167 focused_sht = copy(sht)
168 characters.append((sht, focused_sht)) 168 characters.append((sht, focused_sht))
169 169
170 for sht, func_offset in ((sht, shots_func_offset), (focused_sht, shots_func_offset_focused)): 170 for sht, func_offset in ((sht, shots_func_offset), (focused_sht, shots_func_offset_focused)):
171 # Search for the “push” instruction 171 # Search for the “push” instruction
172 for i in xrange(20): 172 for i in range(20):
173 # Find the “push” instruction 173 # Find the “push” instruction
174 pe_file.seek_to_va(func_offset + i) 174 pe_file.seek_to_va(func_offset + i)
175 instr, offset = unpack('<BI', file.read(5)) 175 instr, offset = unpack('<BI', file.read(5))
176 if instr == 0x68 and 0 <= offset - data_va < data_size - 12: 176 if instr == 0x68 and 0 <= offset - data_va < data_size - 12:
177 pe_file.seek_to_va(offset) 177 pe_file.seek_to_va(offset)
182 break 182 break
183 if offset not in shots_offsets: 183 if offset not in shots_offsets:
184 shots_offsets[offset] = [] 184 shots_offsets[offset] = []
185 shots_offsets[offset].append(sht) 185 shots_offsets[offset].append(sht)
186 186
187 for shots_offset, shts in shots_offsets.iteritems(): 187 for shots_offset, shts in shots_offsets.items():
188 pe_file.seek_to_va(shots_offset) 188 pe_file.seek_to_va(shots_offset)
189 189
190 level_count = 9 190 level_count = 9
191 levels = [] 191 levels = []
192 for i in xrange(level_count): 192 for i in range(level_count):
193 shots_count, power, offset = unpack('<III', file.read(3*4)) 193 shots_count, power, offset = unpack('<III', file.read(3*4))
194 levels.append((shots_count, power, offset)) 194 levels.append((shots_count, power, offset))
195 195
196 shots = {} 196 shots = {}
197 197
198 for shots_count, power, offset in levels: 198 for shots_count, power, offset in levels:
199 shots[power] = [] 199 shots[power] = []
200 pe_file.seek_to_va(offset) 200 pe_file.seek_to_va(offset)
201 201
202 for i in xrange(shots_count): 202 for i in range(shots_count):
203 shot = Shot() 203 shot = Shot()
204 204
205 data = unpack('<HH6fHBBhh', file.read(36)) 205 data = unpack('<HH6fHBBhh', file.read(36))
206 (shot.interval, shot.delay, x, y, hitbox_x, hitbox_y, 206 (shot.interval, shot.delay, x, y, hitbox_x, hitbox_y,
207 shot.angle, shot.speed, shot.damage, shot.orb, shot.type, 207 shot.angle, shot.speed, shot.damage, shot.orb, shot.type,