Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
url = https://github.com/open-ead/nnheaders.git
[submodule "tools/common"]
path = tools/common
url = https://github.com/open-ead/nx-decomp-tools
url = https://github.com/DexrnZacAttack/nx-decomp-tools
[submodule "toolchain/musl"]
path = toolchain/musl
url = https://github.com/open-ead/botw-lib-musl
Expand Down
1 change: 1 addition & 0 deletions data/data_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Address,Name
0x0000007101781BBC,AABB__sThreadStorageCount
0x0000007101781BC0,AABB__sDefaultThreadStorage
0x0000007101781BE0,_ZN6Blocks8RegistryE
Expand Down
24 changes: 24 additions & 0 deletions data/sections.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Name,Start Address,End Address,Real Address,O,R,W,X,V,A
.shstrtab,0x0000007100000000,0x0000007100000088,0x00000000000006a8,False,True,False,False,False,False
.init,0x0000007100000088,0x0000007100000160,0x0000000000000730,False,True,False,True,False,False
.fini,0x0000007100000160,0x0000007100000194,0x0000000000000808,False,True,False,True,False,False
.text,0x0000007100000194,0x00000071009c9a18,0x000000000000083c,False,True,False,True,False,False
.plt,0x00000071009c9a18,0x00000071009cbc28,0x00000000009ca0c0,False,True,False,True,False,False
.rodata,0x00000071009cc000,0x00000071009cc090,0x00000000009cc2d0,False,True,False,False,False,False
.rela.dyn,0x00000071009cc090,0x0000007100d5a950,0x00000000009cc360,False,True,False,False,False,False
.rela.plt,0x0000007100d5a950,0x0000007100d5dc38,0x0000000000d5ac20,False,True,False,False,False,False
.hash,0x0000007100d5dc38,0x0000007100d5eefc,0x0000000000d5df08,False,True,False,False,False,False
.rodata,0x0000007100d5eefc,0x0000007100d62e90,0x0000000000d5f1cc,False,True,False,False,False,False
.dynstr,0x0000007100d62e90,0x0000007100d695a4,0x0000000000d63160,False,True,False,False,False,False
.rodata,0x0000007100d695a4,0x0000007101016af4,0x0000000000d69874,False,True,False,False,False,False
.note,0x0000007101016af4,0x0000007101016b14,0x0000000001016dc4,False,True,False,False,False,False
.rodata,0x0000007101016b14,0x0000007101016cbf,0x0000000001016de4,False,True,False,False,False,False
.data,0x0000007101017000,0x0000007101769a40,0x0000000001016f8f,False,True,True,False,False,False
.got.plt,0x0000007101769a40,0x000000710176ab50,0x00000000017699cf,False,True,True,False,False,False
.got,0x000000710176ab50,0x0000007101781780,0x000000000176aadf,False,True,True,False,False,False
.data,0x0000007101781780,0x00000071017817b8,0x000000000178170f,False,True,True,False,False,False
.init_array,0x00000071017817b8,0x0000007101781b00,0x0000000001781747,False,True,True,False,False,False
.bss,0x0000007101781b00,0x00000071023fd000,,False,True,True,False,False,False
.prgend,0x00000071023fd000,0x00000071023fd001,,False,False,False,False,False,False
extern,0x00000071023fd008,0x00000071023fe4b8,,False,False,False,False,False,False
abs,0x00000071023fe4b8,0x00000071023fe4c0,,False,False,False,False,False,False
2 changes: 2 additions & 0 deletions tools/config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
functions_csv = "data/mcswitch_functions.csv"
data_csv = "data/data_symbols.csv"
sections_csv = "data/sections.csv"
build_target = "mcswitch"

[decomp_me]
Expand Down
57 changes: 57 additions & 0 deletions tools/ida/export_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import csv
import ida_kernwin
import idc
import idautils
import os

# TODO later I can probably write some compat classes so this script will run on Ghidra as well. -Dexrn

common = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "common"))
sys.path.append(common)

from util import config

output = config.get_data_csv_path()
if not output:
output = ida_kernwin.ask_file(1, "*.csv", "Choose a path to write the CSV file to")

print(f"[OUTPUT] {output}")

f = ['Address', 'Name']
existing_data = {}
if output and os.path.exists(output):
with open(output, 'r', newline='') as csv:
reader = csv.DictReader(csv)

for row in reader:
if len(row) >= 2:
addr, name = row["Address"], row["Name"]
existing_data[addr] = name

if output:
seg = idaapi.get_segm_by_name(".bss")

start = seg.start_ea
end = seg.end_ea

for ea, sym in idautils.Names():
if start <= ea < end:
if not sym:
continue

addr = f'0x{ea:016X}'
existing_data[addr] = sym

with open(output, 'w', newline='') as csv:
writer = csv.DictWriter(csv, fieldnames=f)
writer.writeheader()

for addr, name in sorted(existing_data.items(), key=lambda item: int(item[0], 16)):
writer.writerow({
'Address': addr,
'Name': name
})

print("[EXPORT_DATA] Done!")
else:
print("[EXPORT_DATA] Cancelled.")
43 changes: 0 additions & 43 deletions tools/ida/export_data_as_csv.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,33 @@
import idc
import os

output_file_path = ida_kernwin.ask_file(1, "*.csv", "Select the CSV file to update, checked functions will be preserved")
common = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "common"))
sys.path.append(common)

from util import config

output = config.get_data_csv_path()
if not output:
output = ida_kernwin.ask_file(1, "*.csv", "Choose a path to write the CSV file to")

print(f"[OUTPUT] {output}")

def is_valid_name(name: str) -> bool:
return not name.startswith(("sub_", "nullsub_", "j_"))

# Load the existing csv if it exists

fieldnames = ['Address', 'Quality', 'Size', 'Name']
existing_data = {}
if output_file_path and os.path.exists(output_file_path):
with open(output_file_path, 'r', newline='') as csvfile:
if output and os.path.exists(output):
with open(output, 'r', newline='') as csvfile:

reader = csv.DictReader(csvfile)
for row in reader:
address = row['Address']
existing_data[address] = row

if output_file_path:
with open(output_file_path, 'w', newline='') as csvfile:
fieldnames = ['Address', 'Quality', 'Size', 'Name']
if output:
with open(output, 'w', newline='') as csvfile:
csvwriter = csv.DictWriter(csvfile, fieldnames=fieldnames)
csvwriter.writeheader()

Expand All @@ -37,6 +47,6 @@ def is_valid_name(name: str) -> bool:
'Name': func_name if is_valid_name(func_name) else ''
})

print(f"CSV file '{output_file_path}' has been updated.")
print("[EXPORT_FUNCTIONS] Done!")
else:
print("Operation cancelled by the user.")
print("[EXPORT_FUNCTIONS] Cancelled.")
93 changes: 49 additions & 44 deletions tools/ida/rename_data.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,54 @@
import csv
import os
import sys

# gotta do this otherwise it won't find the util folder
common = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "common"))
sys.path.append(common)

from util import config

input = config.get_data_csv_path()
print(f"[INPUT] {input}")

import ida_kernwin
import idc
import idautils

input_file_path = ida_kernwin.ask_file(0, "*.csv", "Select CSV file")

if input_file_path:
with open(input_file_path, 'r', newline='') as csvfile:
csvreader = csv.reader(csvfile)

print(csvfile)

for row in csvreader:
if len(row) < 2:
continue

address_str, name = row[0], row[1]

if not address_str or not name:
continue

try:
address = int(address_str, 16)
except ValueError:
print(f"Invalid address format: {address_str}", flush=True)
continue

seg = idc.get_segm_name(address)
if seg != '.bss':
print(f"Address {address_str} not in .bss, skipping.", flush=True)
continue

# Attempt to rename
current_name = idc.get_name(address)
if not current_name:
if idc.set_name(address, name, idc.SN_CHECK):
print(f"Added new name '{name}' at {address_str}", flush=True)
else:
print(f"Failed to add name '{name}' at {address_str}", flush=True)
elif current_name != name:
if idc.set_name(address, name, idc.SN_CHECK):
print(f"Renamed '{current_name}' to '{name}' at {address_str}", flush=True)
else:
print(f"Failed to rename '{current_name}' at {address_str} to '{name}'", flush=True)

print("Renaming from CSV completed.", flush=True)
else:
print("Operation cancelled by the user.", flush=True)
with open(input, 'r', newline='') as f:
reader = csv.DictReader(f)

for row in reader:
# print(row)

if len(row) < 2:
continue

addr, name = row["Address"], row["Name"]

if not addr or not name:
continue

try:
address = int(addr, 16)
except ValueError:
print(f"[ERR] Invalid address str: {addr}", flush=True) # in what world would this ever happen???????
continue

seg = idc.get_segm_name(address)
if seg != '.bss':
continue

cur_name = idc.get_name(address)
if not cur_name:
if idc.set_name(address, name, idc.SN_CHECK):
print(f"[CREATE] -> {addr}: '{name}'", flush=True)
else:
print(f"[ERR] Failed to set name '{name}' at {addr}", flush=True)
elif cur_name != name:
if idc.set_name(address, name, idc.SN_CHECK):
print(f"[RENAME] -> {addr}: '{cur_name}' -> '{name}'", flush=True)
else:
print(f"[ERR] Failed to rename '{cur_name}' at {addr} to '{name}'", flush=True)

print("[RENAME_DATA] Done!", flush=True)
13 changes: 10 additions & 3 deletions tools/ida/rename_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import idc
import ida_funcs
import ida_range
import ida_auto
import idautils
import idaapi
import ida_hexrays
import os
import sys

Expand Down Expand Up @@ -59,24 +61,29 @@ def can_overwrite_name(addr: int, new_name: str):

for fn in reader:
addr = int(fn[0], 16)
progress = fn[1]
size = int(fn[2])
name = fn[3]

func = ida_funcs.get_func(addr)

if func is None:
print(f"Creating function at {hex(addr)} with name {name}")
print(f"[CREATE] -> {hex(addr)}: {name}")
ida_funcs.add_func(addr)
ida_funcs.set_func_end(addr, addr + size)
elif func.start_ea != addr:
print(f"Fixing function at {hex(addr)} with name {name}")
print(f"[FIX] -> {hex(addr)}: {name}")
ida_funcs.set_func_end(prev_addr, prev_addr + prev_size)
ida_funcs.add_func(addr)
ida_funcs.set_func_end(addr, addr + size)

if can_overwrite_name(addr, name):
idc.set_name(addr, name, idc.SN_CHECK | idc.SN_NOWARN)

if progress == "O":
idc.set_color(addr, idc.CIC_FUNC, 0x276e20)

prev_addr = addr
prev_size = size

print("Renaming from functions completed.")
print("[RENAME_FUNCTIONS] Done!")