Fix/add LookupAttachment gamedata for cstrike/dod/hl2mp (fixes #2337)
Some checks failed
Continuous Integration / ${{ matrix.os_short }}-${{ matrix.compiler_cc }} (clang, clang++, ubuntu-latest, linux) (push) Has been cancelled
Continuous Integration / ${{ matrix.os_short }}-${{ matrix.compiler_cc }} (clang-14, clang++-14, ubuntu-22.04, linux) (push) Has been cancelled
Continuous Integration / ${{ matrix.os_short }}-${{ matrix.compiler_cc }} (msvc, windows-latest, win) (push) Has been cancelled
hl2sdk-mock tests / mock (push) Has been cancelled
SourcePawn scripting / build (ubuntu-latest, linux) (push) Has been cancelled
SourcePawn scripting / build (windows-latest, win) (push) Has been cancelled

This commit is contained in:
Nicholas Hastings 2025-06-21 16:09:19 -04:00
parent 6f0fde48f3
commit 4afbf9d573
6 changed files with 72 additions and 39 deletions

View File

@ -147,5 +147,19 @@
"linux64" "212" "linux64" "212"
} }
} }
"Signatures"
{
"LookupAttachment"
{
/* CBaseAnimating::LookupAttachment */
/* String: "vehicle_driver_eyes", middle length top function, with 4 calls, pick the first one. */
"library" "server"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x80\xBE\x2A\x03\x00\x00\x00\x75\x2A\x83\xBE\x2A\x04\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x8B\x86\x2A\x04\x00\x00\x85\xC0\x74\x2A\x83\x38\x00\x74\x2A\xFF\x75\x08\x50\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08\x40"
"windows64" "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x80\xB9\x55\x04\x00\x00\x00\x48\x8B\xFA\x48\x8B\xD9\x75\x2A\x48\x83\xB9\xB0\x05\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x48\x85\xC0\x74\x2A\x48\x8B\xCB\xE8\x2A\x2A\x2A\x2A\x48\x8B\x8B\xB0\x05\x00\x00\x48\x85\xC9\x74\x2A\x48\x83\x39\x00\x74\x2A\x48\x8B\xD7\xE8"
"linux" "@_ZN14CBaseAnimating16LookupAttachmentEPKc"
"linux64" "@_ZN14CBaseAnimating16LookupAttachmentEPKc"
}
}
} }
} }

View File

@ -128,5 +128,19 @@
"GameRulesProxy" "CDODGameRulesProxy" "GameRulesProxy" "CDODGameRulesProxy"
"GameRulesDataTable" "dod_gamerules_data" "GameRulesDataTable" "dod_gamerules_data"
} }
"Signatures"
{
"LookupAttachment"
{
/* CBaseAnimating::LookupAttachment */
/* String: "vehicle_driver_eyes", middle length top function, with 4 calls, pick the first one. */
"library" "server"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x80\xBE\x2A\x03\x00\x00\x00\x75\x2A\x83\xBE\x2A\x04\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x8B\x86\x2A\x04\x00\x00\x85\xC0\x74\x2A\x83\x38\x00\x74\x2A\xFF\x75\x08\x50\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08\x40"
"windows64" "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x80\xB9\x55\x04\x00\x00\x00\x48\x8B\xFA\x48\x8B\xD9\x75\x2A\x48\x83\xB9\xB0\x05\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x48\x85\xC0\x74\x2A\x48\x8B\xCB\xE8\x2A\x2A\x2A\x2A\x48\x8B\x8B\xB0\x05\x00\x00\x48\x85\xC9\x74\x2A\x48\x83\x39\x00\x74\x2A\x48\x8B\xD7\xE8"
"linux" "@_ZN14CBaseAnimating16LookupAttachmentEPKc"
"linux64" "@_ZN14CBaseAnimating16LookupAttachmentEPKc"
}
}
} }
} }

View File

@ -16,12 +16,15 @@
{ {
"Signatures" "Signatures"
{ {
/* CBaseAnimating::LookupAttachment */
"LookupAttachment" "LookupAttachment"
{ {
/* CBaseAnimating::LookupAttachment */
/* String: "vehicle_driver_eyes", middle length top function, with 4 calls, pick the first one. */
"library" "server" "library" "server"
"windows" "\x55\x8B\xEC\x56\x8B\xF1\x80\xBE\x31\x03\x00\x00\x00\x75\x2A\x83\xBE\x50\x04\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x8B\x86\x50\x04\x00\x00\x85\xC0\x74\x2A\x83\x38\x00\x74\x2A\xFF\x75\x08\x50\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08\x40" "windows" "\x55\x8B\xEC\x56\x8B\xF1\x80\xBE\x2A\x03\x00\x00\x00\x75\x2A\x83\xBE\x2A\x04\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x8B\x86\x2A\x04\x00\x00\x85\xC0\x74\x2A\x83\x38\x00\x74\x2A\xFF\x75\x08\x50\xE8\x2A\x2A\x2A\x2A\x83\xC4\x08\x40"
"windows64" "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x80\xB9\x55\x04\x00\x00\x00\x48\x8B\xFA\x48\x8B\xD9\x75\x2A\x48\x83\xB9\xB0\x05\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x48\x85\xC0\x74\x2A\x48\x8B\xCB\xE8\x2A\x2A\x2A\x2A\x48\x8B\x8B\xB0\x05\x00\x00\x48\x85\xC9\x74\x2A\x48\x83\x39\x00\x74\x2A\x48\x8B\xD7\xE8"
"linux" "@_ZN14CBaseAnimating16LookupAttachmentEPKc" "linux" "@_ZN14CBaseAnimating16LookupAttachmentEPKc"
"linux64" "@_ZN14CBaseAnimating16LookupAttachmentEPKc"
} }
"FireOutput" "FireOutput"
{ {

@ -1 +1 @@
Subproject commit ab76f94ee4ef28187cc08030599577996fcba3be Subproject commit 4c933195789e9a0551a49c929dc3a2dd1e8fb97f

@ -1 +1 @@
Subproject commit 0fd19ef0eb99a76f6c985cc97c63f7ce43b81301 Subproject commit 11b22edb634b9764d19fd28699e03289cfd18520

View File

@ -1,3 +1,4 @@
#from __future__ import print_function
"""vtable_dump.py: IDAPython script to dump a linux vtable (and a reconstructed windows one) from a binary.""" """vtable_dump.py: IDAPython script to dump a linux vtable (and a reconstructed windows one) from a binary."""
""" """
@ -43,6 +44,7 @@ classname = None
offsetdata = {} offsetdata = {}
# Detect address size # Detect address size
__EA64__ = ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFF
adr_size = 8 if __EA64__ else 4 adr_size = 8 if __EA64__ else 4
def ExtractTypeInfo(ea, level = 0): def ExtractTypeInfo(ea, level = 0):
@ -56,14 +58,14 @@ def ExtractTypeInfo(ea, level = 0):
while len(Name(end)) == 0: while len(Name(end)) == 0:
end += adr_size end += adr_size
while Dword(end - adr_size) == 0: while (end - adr_size) == 0:
end -= adr_size end -= adr_size
# Skip vtable # Skip vtable
ea += adr_size ea += adr_size
# Get type name # Get type name
name = Demangle("_Z" + GetString(Dword(ea)), GetLongPrm(INF_LONG_DN)) name = idc.demangle_name("_Z" + ida_bytes.get_strlit_contents(ea), ida_ida.inf_get_long_demnames())
ea += adr_size ea += adr_size
if classname is None and level == 0: if classname is None and level == 0:
@ -73,20 +75,20 @@ def ExtractTypeInfo(ea, level = 0):
innerclass = name innerclass = name
catchclass = False catchclass = False
print " %*s%s" % (level, "", name) print(" %*s%s" % (level, "", name))
if not ea < end: # Base Type if not ea < end: # Base Type
pass pass
elif Dword(ea) != 0: #elif isData(GetFlags(Dword(ea))): # Single Inheritance elif ea != 0: #elif isData(GetFlags(ea)): # Single Inheritance
ExtractTypeInfo(Dword(ea), level + 1) ExtractTypeInfo(ea, level + 1)
ea += adr_size ea += adr_size
else: # Multiple Inheritance else: # Multiple Inheritance
ea += 8 ea += 8
while ea < end: while ea < end:
catchclass = True catchclass = True
ExtractTypeInfo(Dword(ea), level + 1) ExtractTypeInfo(ea, level + 1)
ea += adr_size ea += adr_size
offset = Dword(ea) offset = ea
ea += adr_size ea += adr_size
#print "%*s Offset: 0x%06X" % (level, "", offset >> 8) #print "%*s Offset: 0x%06X" % (level, "", offset >> 8)
if (offset >> 8) != 0: if (offset >> 8) != 0:
@ -100,29 +102,29 @@ def twos_comp(val, bits):
return val return val
def Analyze(): def Analyze():
SetStatus(IDA_STATUS_WORK) ida_auto.set_ida_state(IDA_STATUS_WORK)
if GetLongPrm(INF_COMPILER).id != COMP_GNU: if ida_ida.inf_get_cc_id() != COMP_GNU:
Warning("This script is for binaries compiled with GCC only.") Warning("This script is for binaries compiled with GCC only.")
SetStatus(IDA_STATUS_READY) ida_auto.set_ida_state(IDA_STATUS_READY)
return return
ea = ScreenEA() ea = idc.get_screen_ea()
end = ea + adr_size end = ea + adr_size
while Demangle(Name(end), GetLongPrm(INF_LONG_DN)) is None: while idc.demangle_name(idc.get_name(end, ida_name.GN_VISIBLE), ida_ida.inf_get_long_demnames()) is None:
end += adr_size end += adr_size
while Dword(end - adr_size) == 0: while (end - adr_size) == 0:
end -= adr_size end -= adr_size
while Demangle(Name(ea), GetLongPrm(INF_LONG_DN)) is None: while idc.demangle_name(idc.get_name(ea, ida_name.GN_VISIBLE), ida_ida.inf_get_long_demnames()) is None:
ea -= adr_size ea -= adr_size
name = Demangle(Name(ea), GetLongPrm(INF_LONG_DN)) name = idc.demangle_name(idc.get_name(ea, ida_name.GN_VISIBLE), ida_ida.inf_get_long_demnames())
if ea == BADADDR or name is None or not re.search(r"vf?table(?: |'\{)for", name): if ea == ida_idaapi.BADADDR or name is None or not re.search(r"vf?table(?: |'\{)for", name):
Warning("No vtable selected!\nSelect vtable block first.") Warning("No vtable selected!\nSelect vtable block first.")
SetStatus(IDA_STATUS_READY) ida_auto.set_ida_state(IDA_STATUS_READY)
return return
linux_vtable = [] linux_vtable = []
@ -135,22 +137,22 @@ def Analyze():
# Extract vtable # Extract vtable
while ea < end: while ea < end:
# Read thisoffs # Read thisoffs
offset = -twos_comp(Dword(ea), 32) offset = -twos_comp(ea, 32)
#print "Offset: 0x%08X (%08X)" % (offset, ea) #print "Offset: 0x%08X (%08X)" % (offset, ea)
ea += adr_size ea += adr_size
# Read typeinfo address # Read typeinfo address
typeinfo = Dword(ea) typeinfo = ea
ea += adr_size ea += adr_size
if offset == 0: # We only need to read this once if offset == 0: # We only need to read this once
print "Inheritance Tree:" print("Inheritance Tree:")
ExtractTypeInfo(typeinfo) ExtractTypeInfo(typeinfo)
while ea < end and (isCode(GetFlags(Dword(ea))) or Name(Dword(ea)) == "___cxa_pure_virtual"): while (ea < end) and (ida_bytes.is_code(ida_bytes.get_full_flags(ea)) or idc.get_name(ea, ida_name.GN_VISIBLE) == "___cxa_pure_virtual"):
name = Name(Dword(ea)) name = idc.get_name(ea, ida_name.GN_VISIBLE)
demangled = Demangle(name, GetLongPrm(INF_LONG_DN)) demangled = idc.demangle_name(name, ida_ida.inf_get_long_demnames())
#print "Name: %s, Demangled: %s" % (name, demangled) #print "Name: %s, idc.demangle_named: %s" % (name, demangled)
name = demangled if demangled else name name = demangled if demangled else name
@ -216,18 +218,18 @@ def Analyze():
while len(overload_stack) > 0: while len(overload_stack) > 0:
windows_vtable.append(overload_stack.pop()) windows_vtable.append(overload_stack.pop())
print "\nVTable for %s: (0, 0)" % (classname) print("\nVTable for %s: (0, 0)" % (classname))
print " Lin Win Function" print(" Lin Win Function")
for i, v in enumerate(linux_vtable): for i, v in enumerate(linux_vtable):
if "__cxa_pure_virtual" in v: if "__cxa_pure_virtual" in v:
print "P%3d" % (i) print("P%3d" % (i))
continue continue
winindex = windows_vtable.index(v) if v in windows_vtable else None winindex = windows_vtable.index(v) if v in windows_vtable else None
if winindex is not None: if winindex is not None:
print "%4d %4d %s" % (i, winindex, v) print("%4d %4d %s" % (i, winindex, v))
else: else:
print "%4d %s" % (i, v) print("%4d %s" % (i, v))
for k in temp_other_windows_vtables: for k in temp_other_windows_vtables:
for i, v in enumerate(temp_other_windows_vtables[k]): for i, v in enumerate(temp_other_windows_vtables[k]):
@ -260,20 +262,20 @@ def Analyze():
prev_symbol = v prev_symbol = v
for k in other_linux_vtables: for k in other_linux_vtables:
print "\nVTable for %s: (%d, %d)" % (offsetdata[k], offsetdata.keys().index(k) + 1, k) print("\nVTable for %s: (%d, %d)" % (offsetdata[k], offsetdata.keys().index(k) + 1, k))
print " Lin Win Function" print(" Lin Win Function")
for i, v in enumerate(other_linux_vtables[k]): for i, v in enumerate(other_linux_vtables[k]):
if "__cxa_pure_virtual" in v: if "__cxa_pure_virtual" in v:
print "P%3d" % (i) print("P%3d" % (i))
continue continue
winindex = other_windows_vtables[k].index(v) winindex = other_windows_vtables[k].index(v)
if v not in other_thunk_linux_vtables[k]: if v not in other_thunk_linux_vtables[k]:
print "%4d %4d %s" % (i, winindex, v) print("%4d %4d %s" % (i, winindex, v))
else: else:
print "T%3d %4d %s" % (i, winindex, v) print("T%3d %4d %s" % (i, winindex, v))
SetStatus(IDA_STATUS_READY) ida_auto.set_ida_state(IDA_STATUS_READY)
if __name__ == '__main__': if __name__ == '__main__':
Analyze() Analyze()