Skip to content

Commit

Permalink
create fake string segment to allow ida to show the actual strings, a…
Browse files Browse the repository at this point in the history
…lso add custom xref between methodinfo and method when both exist
  • Loading branch information
LukeFZ committed Feb 16, 2024
1 parent 42d9781 commit 0f7cd02
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 11 deletions.
8 changes: 6 additions & 2 deletions Il2CppInspector.Common/Outputs/JSONMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,14 @@ private void writeUsages() {
// Metedata usage methods
writeArray("methodInfoPointers",
() => {
foreach (var method in model.Methods.Values.Where(m => m.HasMethodInfo)) {
writeObject(() => {
foreach (var method in model.Methods.Values.Where(m => m.HasMethodInfo))
{
writeObject(() =>
{
writeName(method.MethodInfoPtrAddress, method.ToMangledMethodInfoString());
writeDotNetSignature(method.Method);
if (method.HasCompiledCode)
writer.WriteString("methodAddress", method.MethodCodeAddress.ToAddressString());
});
}
}, "MethodInfo pointers");
Expand Down
11 changes: 6 additions & 5 deletions Il2CppInspector.Common/Outputs/ScriptResources/Targets/Ghidra.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ def script_prologue(status):
if currentProgram.getExecutableFormat().endswith('(ELF)'):
currentProgram.setImageBase(toAddr(%IMAGE_BASE%), True)

def script_epilogue(status): pass

def get_script_directory():
return getSourceFile().getParentFile().toString()
def get_script_directory(): return getSourceFile().getParentFile().toString()

def script_epilogue(status): pass
def add_function_to_group(addr, group): pass

def add_xref(addr, to): pass
def create_fake_segment(name, size): pass
def write_string(addr, string): pass
def write_address(addr, value): pass
class StatusWrapper(BaseStatusHandler): pass
39 changes: 37 additions & 2 deletions Il2CppInspector.Common/Outputs/ScriptResources/Targets/IDA.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
cached_genflags = 0
skip_make_function = False
func_dirtree = None
is_32_bit = False
fake_segments_base = None

def script_prologue(status):
global cached_genflags, skip_make_function, func_dirtree
global cached_genflags, skip_make_function, func_dirtree, is_32_bit, fake_segments_base
# Disable autoanalysis
cached_genflags = ida_ida.inf_get_genflags()
ida_ida.inf_set_genflags(cached_genflags & ~ida_ida.INFFL_AUTO)
Expand Down Expand Up @@ -63,8 +65,9 @@ def script_prologue(status):

if FOLDERS_AVAILABLE:
func_dirtree = ida_dirtree.get_std_dirtree(ida_dirtree.DIRTREE_FUNCS)


is_32_bit = ida_ida.inf_is_32bit_exactly()

def script_epilogue(status):
# Reenable auto-analysis
global cached_genflags
Expand Down Expand Up @@ -159,6 +162,38 @@ def add_function_to_group(addr, group):
name = ida_funcs.get_func_name(addr)
func_dirtree.rename(name, f"{group}/{name}")

def add_xref(addr, to):
ida_xref.add_dref(addr, to, ida_xref.XREF_USER | ida_xref.dr_I)

def write_string(addr, string):
encoded_string = string.encode() + b'\x00'
string_length = len(encoded_string)
ida_bytes.put_bytes(addr, encoded_string)
ida_bytes.create_strlit(addr, string_length, ida_nalt.STRTYPE_C)

def write_address(addr, value):
global is_32_bit

if is_32_bit:
ida_bytes.put_dword(addr, value)
else:
ida_bytes.put_qword(addr, value)

def create_fake_segment(name, size):
global is_32_bit

start = ida_ida.inf_get_max_ea()
end = start + size

ida_segment.add_segm(0, start, end, name, "DATA")
segment = ida_segment.get_segm_by_name(name)
segment.bitness = 1 if is_32_bit else 2
segment.perm = ida_segment.SEGPERM_READ
segment.update()

return start

# Status handler

class StatusHandler(BaseStatusHandler):
def __init__(self):
Expand Down
23 changes: 21 additions & 2 deletions Il2CppInspector.Common/Outputs/ScriptResources/shared-main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ def define_il_method(jsonDef):
def define_il_method_info(jsonDef):
addr = parse_address(jsonDef)
set_name(addr, jsonDef['name'])
set_type(addr, r'struct MethodInfo *')
set_comment(addr, jsonDef['dotNetSignature'])
set_type(addr, r'struct MethodInfo *')
if 'methodAddress' in jsonDef:
add_xref(from_hex(jsonDef["methodAddress"]), addr)


def define_cpp_function(jsonDef):
addr = parse_address(jsonDef)
Expand All @@ -24,7 +27,6 @@ def define_cpp_function(jsonDef):
def define_string(jsonDef):
addr = parse_address(jsonDef)
set_name(addr, jsonDef['name'])
set_type(addr, r'struct String *')
set_comment(addr, jsonDef['string'])

def define_field(addr, name, type, ilType = None):
Expand Down Expand Up @@ -93,10 +95,27 @@ def process_json(jsonData, status):
# String literals for version >= 19
if 'virtualAddress' in jsonData['stringLiterals'][0]:
status.update_step('Processing string literals (V19+)', len(jsonData['stringLiterals']))

total_string_length = 0
for d in jsonData['stringLiterals']:
total_string_length += len(d["string"]) + 1

aligned_length = total_string_length + (4096 - (total_string_length % 4096))
segment_base = create_fake_segment(".fake_strings", aligned_length)

current_string_address = segment_base
for d in jsonData['stringLiterals']:
define_string(d)

ref_addr = parse_address(d)
write_string(current_string_address, d["string"])
write_address(ref_addr, current_string_address)
set_type(ref_addr, r'const char* const')

current_string_address += len(d["string"]) + 1
status.update_progress()


# String literals for version < 19
else:
status.update_step('Processing string literals (pre-V19)')
Expand Down

0 comments on commit 0f7cd02

Please sign in to comment.