1111
1212
1313ROOT_DIR = "."
14- DUMP_BIN = "./code/debug/test3 /dump.bin"
14+ DUMP_BIN = "./code/debug/test5 /dump.bin"
1515INFO_PATH = Path (DUMP_BIN ).parent / "info.txt"
1616LWL_DEFINES_FILE = "./code/CM7/Core/lwl/lwl.h"
1717
3636CALL_START = re .compile (r'\blwl_enter_record\s*\(' )
3737
3838DEFINE_REGEX = re .compile (
39- r'^\s*#define\s+(\w+)\s+\'(.)\' ' ,
39+ r'^\s*#define\s+(\w+)\s+(.+)$ ' ,
4040 re .MULTILINE
4141)
4242
@@ -60,13 +60,24 @@ def clean_code(text):
6060
6161def parse_defines (filepath ):
6262
63- with open (filepath , 'r' , encoding = 'utf-8' , errors = 'ignore' ) as f :
63+ defines = {}
64+
65+ with open (filepath ,'r' ,encoding = 'utf-8' ,errors = 'ignore' ) as f :
6466 content = f .read ()
6567
66- defines = {}
68+ for name ,value in DEFINE_REGEX .findall (content ):
69+
70+ value = value .strip ()
6771
68- for name , value in DEFINE_REGEX .findall (content ):
69- defines [name ] = ord (value )
72+ # char literal
73+ if value .startswith ("'" ) and value .endswith ("'" ):
74+
75+ defines [name ] = eval (value )
76+
77+ # string literal
78+ elif value .startswith ('"' ) and value .endswith ('"' ):
79+
80+ defines [name ] = value [1 :- 1 ]
7081
7182 return defines
7283
@@ -174,9 +185,13 @@ def extract_calls(text):
174185 return matches
175186
176187
177- def calculate_size (args ):
188+ def calculate_size (args , id_defines ):
189+
190+ size = 1 # module char
178191
179- size = 2
192+ function_str = id_defines [args [1 ]]
193+
194+ size += len (function_str )
180195
181196 if len (args ) < 3 :
182197 return size
@@ -237,7 +252,7 @@ def build_call_database():
237252
238253 entry = {
239254 "args" : args ,
240- "size" : calculate_size (args ),
255+ "size" : calculate_size (args , id_defines ),
241256 "key" : resolved_key
242257 }
243258
@@ -354,19 +369,40 @@ def try_decode(decoded_buffer, decoder_table):
354369
355370 while offset < len (decoded_buffer ):
356371
357- if offset + 2 > len (decoded_buffer ):
372+ if offset + 1 > len (decoded_buffer ):
358373 return False , decoded_entries , offset
359374
360- key = (
361- decoded_buffer [offset ],
362- decoded_buffer [offset + 1 ]
363- )
375+ module_char = chr (decoded_buffer [offset ])
376+
377+ matched_entry = None
378+ best_len = - 1
379+
380+ for entry in decoder_table .values ():
381+
382+ entry_module , entry_function = entry ["key" ]
383+
384+ if entry_module != module_char :
385+ continue
386+
387+ function_bytes = entry_function .encode ()
364388
365- if key not in decoder_table :
389+ start = offset + 1
390+ end = start + len (function_bytes )
391+
392+ if end > len (decoded_buffer ):
393+ continue
394+
395+ if decoded_buffer [start :end ] == function_bytes :
396+
397+ if len (function_bytes ) > best_len :
398+
399+ matched_entry = entry
400+ best_len = len (function_bytes )
401+
402+ if matched_entry is None :
366403 return False , decoded_entries , offset
367404
368- entry = decoder_table [key ]
369- size = entry ["size" ]
405+ size = matched_entry ["size" ]
370406
371407 if offset + size > len (decoded_buffer ):
372408 return False , decoded_entries , offset
@@ -460,32 +496,58 @@ def decode_buffer(decoded_buffer, decoder_table, decode_point):
460496
461497 while offset < len (decoded_buffer ):
462498
463- if offset + 2 > len (decoded_buffer ):
499+ if offset + 1 > len (decoded_buffer ):
500+
464501 print (
465- f"ERROR: truncated entry header "
466- f"at offset { offset } "
502+ f"ERROR: truncated module ID "
503+ f"at byte { decode_point + offset } "
467504 )
468505 return
469506
470- key = (
471- decoded_buffer [offset ],
472- decoded_buffer [offset + 1 ]
473- )
507+ module_char = chr (decoded_buffer [offset ])
508+
509+ matched_entry = None
510+ best_len = - 1
511+
512+ for entry in decoder_table .values ():
513+
514+ entry_module , entry_function = entry ["key" ]
474515
475- if key not in decoder_table :
516+ if entry_module != module_char :
517+ continue
518+
519+ function_bytes = entry_function .encode ()
520+
521+ start = offset + 1
522+ end = start + len (function_bytes )
523+
524+ if end > len (decoded_buffer ):
525+ continue
526+
527+ if decoded_buffer [start :end ] == function_bytes :
528+
529+ if len (function_bytes ) > best_len :
530+
531+ matched_entry = entry
532+ best_len = len (function_bytes )
533+
534+ if matched_entry is None :
476535
477536 print (
478537 f"ERROR: unknown entry "
479- f"{ chr ( key [ 0 ]) } { chr ( key [ 1 ]) } "
480- f"at byte { decode_point + offset } "
538+ f"at byte { decode_point + offset } "
539+ f"(module=' { module_char } ') "
481540 )
482541
483- return
542+ print (
543+ f"DEBUG offset={ offset } "
544+ f"bytes={ decoded_buffer [offset :offset + 15 ]} "
545+ )
484546
485- entry = decoder_table [ key ]
547+ return
486548
487- args = entry ["args" ]
488- size = entry ["size" ]
549+ args = matched_entry ["args" ]
550+ size = matched_entry ["size" ]
489551
490552 if offset + size > len (decoded_buffer ):
491553
@@ -496,62 +558,91 @@ def decode_buffer(decoded_buffer, decoder_table, decode_point):
496558
497559 return
498560
561+ module_id , function_id = matched_entry ["key" ]
562+
563+ function_bytes = function_id .encode ()
564+
499565 fmt = args [2 ][1 :- 1 ]
500566
501- pos = offset + 2
567+ pos = (
568+ offset
569+ + 1
570+ + len (function_bytes )
571+ )
572+
573+ module_str = (
574+ f"{ args [0 ]} ({ module_id } )"
575+ )
502576
503- module_str = f"{ args [0 ]} ({ chr (key [0 ])} )"
504- function_str = f"{ args [1 ]} ({ chr (key [1 ])} )"
577+ function_str = (
578+ f'{ args [1 ]} ("{ function_id } ")'
579+ )
505580
506581 arg_output = []
507582
508583 for fmt_char , name in zip (fmt , args [3 :]):
509584
510585 if fmt_char == 'c' :
586+
511587 value = decoded_buffer [pos ]
512588 pos += 1
513589
514590 elif fmt_char == 's' :
591+
515592 value = int .from_bytes (
516593 decoded_buffer [pos :pos + 2 ],
517594 'little' ,
518595 signed = True
519596 )
597+
520598 pos += 2
521599
522600 elif fmt_char == 'h' :
601+
523602 value = int .from_bytes (
524603 decoded_buffer [pos :pos + 2 ],
525604 'little' ,
526605 signed = False
527606 )
607+
528608 pos += 2
529609
530610 elif fmt_char == 'd' :
611+
531612 value = int .from_bytes (
532613 decoded_buffer [pos :pos + 4 ],
533614 'little' ,
534615 signed = True
535616 )
617+
536618 pos += 4
537619
538620 elif fmt_char == 'u' :
621+
539622 value = int .from_bytes (
540623 decoded_buffer [pos :pos + 4 ],
541624 'little' ,
542625 signed = False
543626 )
627+
544628 pos += 4
545629
546630 elif fmt_char == 'f' :
631+
547632 value = struct .unpack (
548633 '<f' ,
549634 decoded_buffer [pos :pos + 4 ]
550635 )[0 ]
636+
551637 pos += 4
552638
553639 else :
554- print (f"ERROR: unknown format '{ fmt_char } '" )
640+
641+ print (
642+ f"ERROR: unknown format "
643+ f"'{ fmt_char } '"
644+ )
645+
555646 return
556647
557648 arg_output .append (
0 commit comments