Skip to content

Commit

Permalink
fixes #56; decl spec parsing for versions 22 and below
Browse files Browse the repository at this point in the history
  • Loading branch information
huettenhain committed Aug 27, 2024
1 parent ef049a4 commit 7c8a6b1
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
32 changes: 20 additions & 12 deletions refinery/units/formats/ifps.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,28 +381,31 @@ def __repr__(self):
return self.represent(self.name or '(*)')

@classmethod
def ParseF(cls, reader: StructReader[bytes]):
def readcc():
def ParseF(cls, reader: StructReader[bytes], load_flags: bool):
def ascii():
return reader.read_c_string('latin1')

def boolean():
return bool(reader.u8())

def cc():
return {
0: 'register',
1: 'pascal',
2: 'cdecl',
3: 'stdcall',
}.get(reader.u8(), cls.calling_convention)

kw = {}
parameters = None
if reader.peek(4) == b'dll:':
reader.seekrel(4)
if reader.peek(6) == B'files:':
reader.seekrel(6)
kw.update(
module=reader.read_c_string('latin1'),
name=reader.read_c_string('latin1'),
calling_convention=readcc(),
delay_load=bool(reader.u8()),
load_with_altered_search_path=bool(reader.u8())
)
void = not reader.u8()
kw.update(module=ascii(), name=ascii(), calling_convention=cc())
if load_flags:
kw.update(delay_load=boolean(), load_with_altered_search_path=boolean())
void = not boolean()
elif reader.peek(6) == b'class:':
reader.seekrel(6)
if reader.remaining_bytes == 1:
Expand All @@ -420,7 +423,7 @@ def readcc():
if name[-1] == '@':
kw.update(is_property=True)
name = name[:-1]
kw.update(name=name, calling_convention=readcc())
kw.update(name=name, calling_convention=cc())
void = not reader.u8()
else:
void = not reader.u8()
Expand Down Expand Up @@ -589,6 +592,10 @@ def __init__(self, reader: StructReader[memoryview]):
self._load_functions()
self._load_variables()

@property
def _load_flags(self):
return self.version >= 23

def _load_types(self):
reader = self.reader
types = self.types
Expand Down Expand Up @@ -687,7 +694,8 @@ def _load_functions(self):
if imported:
name = reader.read_length_prefixed_ascii(8)
if exported:
decl = DeclSpec.ParseF(StructReader(bytes(reader.read_length_prefixed())))
read = StructReader(bytes(reader.read_length_prefixed()))
decl = DeclSpec.ParseF(read, self._load_flags)
else:
offset = reader.u32()
size = reader.u32()
Expand Down
6 changes: 6 additions & 0 deletions test/units/formats/test_ifps.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ def test_pup_installer_script(self):
R'https''://''d1pqn6m5ywnw3a.cloudfront''.''net/f/',
):
self.assertIn(string, strings)

def test_function_signature_parsing_version_22(self):
data = self.download_sample('fb0fc2e3c2059e6159540920a4ff7f75f92212639b318da7eb7fadece4a46ecc')
goal = {'path', 'b512c1_Flash7231FixClass_b512c1', 'mp3-cd-ripper-beta-', 'A1ADB8BE8E677894E', 'M'}
test = data | self.ldu('ifpsstr') | {str}
self.assertSetEqual(test, goal)

0 comments on commit 7c8a6b1

Please sign in to comment.