annotate pytouhou/formats/exe.py @ 261:2876c267be00

Add heuristics to extract character data from the demo .exe.
author Thibaut Girka <thib@sitedethib.com>
date Mon, 23 Jan 2012 00:03:06 +0100
parents 741860192b56
children 92a6fd2632f1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
1 # -*- encoding: utf-8 -*-
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2 ##
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com>
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
4 ## Copyright (C) 2011 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
5 ##
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 ## This program is free software; you can redistribute it and/or modify
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 ## it under the terms of the GNU General Public License as published
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8 ## by the Free Software Foundation; version 3 only.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9 ##
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 ## This program is distributed in the hope that it will be useful,
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 ## GNU General Public License for more details.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14 ##
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
15
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
16 from copy import copy
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17 from struct import Struct, unpack
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
18
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19 from pytouhou.utils.pe import PEFile
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 from pytouhou.utils.helpers import get_logger
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23 logger = get_logger(__name__)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 SQ2 = 2. ** 0.5 / 2.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29 class Shot(object):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 def __init__(self):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 self.interval = 0
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
32 self.delay = 0
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 self.pos = (0., 0.)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 self.hitbox = (0., 0.)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 self.angle = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 self.speed = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37 self.damage = 0
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38 self.orb = 0
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
39 self.type = 0
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
40 self.sprite = 0
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41 self.unknown1 = None
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44 class SHT(object):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
45 def __init__(self):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
46 #self.unknown1 = None
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 #self.bombs = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 #self.unknown2 = None
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49 self.hitbox = 4.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 self.graze_hitbox = 42.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51 self.autocollection_speed = 8.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52 self.item_hitbox = 38.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
53 # No percentage_of_cherry_loss_on_die
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
54 self.point_of_collection = 128 #TODO: find the real default.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
55 self.horizontal_vertical_speed = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
56 self.horizontal_vertical_focused_speed = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
57 self.diagonal_speed = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
58 self.diagonal_focused_speed = 0.
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
59 self.shots = {}
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
60
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
61
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
62 @classmethod
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
63 def find_character_defs(cls, pe_file):
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
64 """Generator returning the possible VA of character definition blocks.
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
65
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
66 Based on knowledge of the structure, it tries to find valid definition blocks
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
67 without embedding any copyrighted material or hard-coded offsets that would
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
68 only be useful for a specific build of the game.
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
69 """
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
70
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
71 format = Struct('<4f2I')
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
72 data_section = [section for section in pe_file.sections
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
73 if section.Name.startswith('.data')][0]
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
74 text_section = [section for section in pe_file.sections
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
75 if section.Name.startswith('.text')][0]
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
76 data_va = pe_file.image_base + data_section.VirtualAddress
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
77 data_size = data_section.SizeOfRawData
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78 text_va = pe_file.image_base + text_section.VirtualAddress
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
79 text_size = text_section.SizeOfRawData
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
80
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
81 # Search the whole data segment for 4 successive character definitions
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
82 for addr in xrange(data_va, data_va + data_size, 4):
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
83 for character_id in xrange(4):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
84 pe_file.seek_to_va(addr + character_id * 24)
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
85 (speed1, speed2, speed3, speed4,
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
86 ptr1, ptr2) = format.unpack(pe_file.file.read(format.size))
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
87
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
88 # Check whether the character's speed make sense,
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
89 # and whether the function pointers point to valid addresses
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
90 if not (all(0. < x < 10. for x in (speed1, speed2, speed3, speed4))
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
91 and speed2 <= speed1
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
92 and 0 <= ptr1 - text_va < text_size - 8
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
93 and 0 <= ptr2 - text_va < text_size - 8):
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
94 break
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
95
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
96 # So far, this character definition seems to be valid.
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
97 # Now, make sure the shoot function wrappers pass valid addresses
261
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
98
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
99 # Search for the “push” instruction
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
100 for i in xrange(20):
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
101 # Find the “push” instruction
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
102 pe_file.seek_to_va(ptr1 + i)
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
103 instr1, shtptr1 = unpack('<BI', pe_file.file.read(5))
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
104 pe_file.seek_to_va(ptr2 + i)
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
105 instr2, shtptr2 = unpack('<BI', pe_file.file.read(5))
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
106 if instr1 == 0x68 and instr2 == 0x68 and (0 <= shtptr1 - data_va < data_size - 12
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
107 and 0 <= shtptr2 - data_va < data_size - 12):
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
108 # It is unlikely this character record is *not* valid, but
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
109 # just to be sure, let's check the first SHT definition.
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
110 pe_file.seek_to_va(shtptr1)
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
111 nb_shots, power, shotsptr = unpack('<III', pe_file.file.read(12))
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
112 if (0 < nb_shots <= 1000
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
113 and 0 <= power < 1000
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
114 and 0 <= shotsptr - data_va < data_size - 36*nb_shots):
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
115 break
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
116 # Check if everything is fine...
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
117 if not (0 <= shtptr1 - data_va < data_size - 12
261
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
118 and 0 <= shtptr2 - data_va < data_size - 12
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
119 and 0 < nb_shots <= 1000
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
120 and 0 <= power < 1000
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
121 and 0 <= shotsptr - data_va < data_size - 36*nb_shots):
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
122 break
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
123
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
124 else:
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
125 # XXX: Obscure python feature! This only gets executed if the
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
126 # XXX: loop ended without a break statement.
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
127 # In our case, it's only executed if all the 4 character
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
128 # definitions are considered valid.
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
129 yield addr
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
130
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
131
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
132 @classmethod
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
133 def read(cls, file):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
134 pe_file = PEFile(file)
261
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
135 data_section = [section for section in pe_file.sections
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
136 if section.Name.startswith('.data')][0]
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
137 text_section = [section for section in pe_file.sections
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
138 if section.Name.startswith('.text')][0]
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
139 data_va = pe_file.image_base + data_section.VirtualAddress
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
140 data_size = data_section.SizeOfRawData
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
141 text_va = pe_file.image_base + text_section.VirtualAddress
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
142 text_size = text_section.SizeOfRawData
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
143
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
144 character_records_va = list(cls.find_character_defs(pe_file))[0]
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
145
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
146 characters = []
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
147 shots_offsets = {}
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
148 for character in xrange(4):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
149 sht = cls()
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
150
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
151 pe_file.seek_to_va(character_records_va + 6*4*character)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
152
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
153 data = unpack('<4f2I', file.read(6*4))
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
154 (speed, speed_focused, speed_unknown1, speed_unknown2,
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
155 shots_func_offset, shots_func_offset_focused) = data
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
156
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
157 sht.horizontal_vertical_speed = speed
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
158 sht.horizontal_vertical_focused_speed = speed_focused
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
159 sht.diagonal_speed = speed * SQ2
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
160 sht.diagonal_focused_speed = speed_focused * SQ2
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
161
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
162 # Characters might have different shot types whether they are
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
163 # focused or not, but properties read earlier apply to both modes.
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
164 focused_sht = copy(sht)
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
165 characters.append((sht, focused_sht))
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
166
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
167 for sht, func_offset in ((sht, shots_func_offset), (focused_sht, shots_func_offset_focused)):
261
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
168 # Search for the “push” instruction
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
169 for i in xrange(20):
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
170 # Find the “push” instruction
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
171 pe_file.seek_to_va(func_offset + i)
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
172 instr, offset = unpack('<BI', file.read(5))
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
173 if instr == 0x68 and 0 <= offset - data_va < data_size - 12:
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
174 pe_file.seek_to_va(offset)
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
175 nb_shots, power, shotsptr = unpack('<III', pe_file.file.read(12))
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
176 if (0 < nb_shots <= 1000
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
177 and 0 <= power < 1000
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
178 and 0 <= shotsptr - data_va < data_size - 36*nb_shots):
2876c267be00 Add heuristics to extract character data from the demo .exe.
Thibaut Girka <thib@sitedethib.com>
parents: 236
diff changeset
179 break
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
180 if offset not in shots_offsets:
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
181 shots_offsets[offset] = []
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
182 shots_offsets[offset].append(sht)
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
183
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
184 for shots_offset, shts in shots_offsets.iteritems():
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
185 pe_file.seek_to_va(shots_offset)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
186
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
187 level_count = 9
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
188 levels = []
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
189 for i in xrange(level_count):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
190 shots_count, power, offset = unpack('<III', file.read(3*4))
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
191 levels.append((shots_count, power, offset))
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
192
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
193 shots = {}
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
194
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
195 for shots_count, power, offset in levels:
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
196 shots[power] = []
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
197 pe_file.seek_to_va(offset)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
198
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
199 for i in xrange(shots_count):
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
200 shot = Shot()
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
201
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
202 data = unpack('<HH6fHBBhh', file.read(36))
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
203 (shot.interval, shot.delay, x, y, hitbox_x, hitbox_y,
230
1c24a6d93c1b Improve find_character_defs, clean up a bit, and disable attack types 2 and 3 for now
Thibaut Girka <thib@sitedethib.com>
parents: 229
diff changeset
204 shot.angle, shot.speed, shot.damage, shot.orb, shot.type,
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
205 shot.sprite, shot.unknown1) = data
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
206
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
207 shot.pos = (x, y)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
208 shot.hitbox = (hitbox_x, hitbox_y)
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
209
235
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
210 shots[power].append(shot)
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
211
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
212 for sht in shts:
e59bd7979ddc Do a little cleanup, and fix PCB SHT usage.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 230
diff changeset
213 sht.shots = shots
229
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
214
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
215
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
216 return characters
5afc75f71fed Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
217