Files
2025-09-29 00:52:08 +02:00

58 lines
2.0 KiB
Python
Executable File

from construct import *
# FPO DATA
FPO_DATA = Struct("FPO_DATA",
ULInt32("ulOffStart"), # offset 1st byte of function code
ULInt32("cbProcSize"), # number of bytes in function
ULInt32("cdwLocals"), # number of bytes in locals/4
ULInt16("cdwParams"), # number of bytes in params/4
Embed(BitStruct("BitValues",
Octet("cbProlog"), # number of bytes in prolog
BitField("cbFrame",2), # frame type
Bit("reserved"), # reserved for future use
Flag("fUseBP"), # TRUE if EBP has been allocated
Flag("fHasSEH"), # TRUE if SEH in func
BitField("cbRegs",3), # number of regs saved
)),
)
# New style FPO records with program strings
FPO_DATA_V2 = Struct("FPO_DATA_V2",
ULInt32("ulOffStart"),
ULInt32("cbProcSize"),
ULInt32("cbLocals"),
ULInt32("cbParams"),
ULInt32("maxStack"), # so far only observed to be 0
ULInt32("ProgramStringOffset"),
ULInt16("cbProlog"),
ULInt16("cbSavedRegs"),
FlagsEnum(ULInt32("flags"),
SEH = 1,
CPPEH = 2, # conjectured
fnStart = 4,
),
)
# Ranges for both types
FPO_DATA_LIST = GreedyRange(FPO_DATA)
FPO_DATA_LIST_V2 = GreedyRange(FPO_DATA_V2)
# Program string storage
# May move this to a new file; in private symbols the values
# include things that are not just FPO related.
FPO_STRING_DATA = Struct("FPO_STRING_DATA",
Const(Bytes("Signature",4), "\xFE\xEF\xFE\xEF"),
ULInt32("Unk1"),
ULInt32("szDataLen"),
Union("StringData",
String("Data",lambda ctx: ctx._.szDataLen),
Tunnel(
String("Strings",lambda ctx: ctx._.szDataLen),
GreedyRange(CString("Strings")),
),
),
ULInt32("lastDwIndex"), # data remaining = (last_dword_index+1)*4
HexDumpAdapter(String("UnkData", lambda ctx: ((ctx.lastDwIndex+1)*4))),
Terminator,
)