Skip to content

Instantly share code, notes, and snippets.

@SciresM
SciresM / ida_fireemblem_symbols.py
Last active July 15, 2023 18:29
Get full symbols for your Fire Emblem If/Fates IDB
import idaapi
import idautils
import idc
import struct
def do_rename(eaaddr, name):
idc.MakeCode(eaaddr)
idc.MakeFunction(eaaddr)
idc.MakeNameEx(eaaddr, name, idc.SN_NOWARN)
def fe_xor(string, key):
'''Decrypts a Fire Emblem Heroes string using a specified key.'''
if type(key) == str:
key = map(ord, key)
cur_k = (key[0] + key[1]) & 0xFF
crypt = ''
for i in range(len(string)):
cur_k ^= key[i % len(key)]
crypt += chr((cur_k ^ ord(string[i])) or ord(string[i]))
return crypt
@SciresM
SciresM / switch_fs.py
Created March 9, 2017 05:56
Parser for switch filesystem data.
from struct import unpack as up
import sys, os
dirs, files = None, None
def read_at(fp, off, len):
fp.seek(off)
return fp.read(len)
def read_u8(fp, off):
@SciresM
SciresM / Sighax.md
Last active October 13, 2023 14:06

This is being hosted here, until the reddit post I made gets approved.

I saw, in the recent reddit thread about sighax, a lot of information being posted that's factually incorrect. I'd like to go ahead and clarify how sighax works, and how it's different from arm9loaderhax, while also clearing up some misconceptions I'm seeing (I really dislike misinformation).

What is sighax?

Sighax is an exploit taking advantage of a flaw in the arm9 bootrom, causing the signatures (which those of you less technically oriented may think of as "proofs of authenticity" that normally only Nintendo can generate) for arbitrary firmwares to be read as valid. On a normal boot, if one modifies the header for the firmware partition stored in NAND, the signatur

@SciresM
SciresM / ACNL.cs
Created May 7, 2017 02:19
Encryption/Decryption of Animal Crossing: New Leaf's Bell/Money values.
private static uint DecryptACNLMoney(ulong money)
{
// Unpack 64-bit value into (u32, u16, u8, u8) values.
var enc = (uint)(money & 0xFFFFFFFF);
var adjust = (ushort)((money >> 32) & 0xFFFF);
var shift_val = (byte)((money >> 48) & 0xFF);
var chk = (byte)((money >> 56) & 0xFF);
// Validate 8-bit checksum
if ((((enc >> 0) + (enc >> 8) + (enc >> 16) + (enc >> 24) + 0xBA) & 0xFF) != chk) return 0;
@SciresM
SciresM / Signatures.txt
Last active October 13, 2023 14:04
"Perfect" sighax signatures for every Boot9 modulus.
Retail NAND FIRM:
Perfect Signature:
B6724531C448657A2A2EE306457E350A10D544B42859B0E5B0BED27534CCCC2A4D47EDEA60A7DD99939950A6357B1E35DFC7FAC773B7E12E7C1481234AF141B31CF08E9F62293AA6BAAE246C15095F8B78402A684D852C680549FA5B3F14D9E838A2FB9C09A15ABB40DCA25E40A3DDC1F58E79CEC901974363A946E99B4346E8A372B6CD55A707E1EAB9BEC0200B5BA0B661236A8708D704517F43C6C38EE9560111E1405E5E8ED356C49C4FF6823D1219AFAEEB3DF3C36B62BBA88FC15BA8648F9333FD9FC092B8146C3D908F73155D48BE89D72612E18E4AA8EB9B7FD2A5F7328C4ECBFB0083833CBD5C983A25CEB8B941CC68EB017CE87F5D793ACA09ACF7
Exponentiated Message:
0002B31331C710412333A587890F9CF0B6A86E71C8A78F96B76082903B3E54EA9AB935978BBF2493BB829E9A5A6060B0C7811881176BCF9FE8B1C5C5E0A95327DB8B52EC178A884AD9CF28DB8BBF2922C05FD034AC81BD231AEB0CBEF6F7DE6F3A30812B9F9A83BF33251891BFA18FA38A64C6FF5F77DBE11C3780C23EA9F6D00F9C01D6FC8A878591D36C4F64ACA6B8D11BBEB21476103C6E86FF2196D465BA4DB78F81F1D3BCCA186BDDD56739A12DD36122F3F5B3DD518DDAC4FA29395EA4CD9DFD80AF8A399990F4FDD3CD6B07EC2122437CCFC3B62B1D1493A7DBB442003
import os, sys
from struct import unpack as up
pkm_lst = ['Egg', 'Bulbasaur', 'Ivysaur', 'Venusaur', 'Charmander', 'Charmeleon', 'Charizard', 'Squirtle', 'Wartortle', 'Blastoise', 'Caterpie', 'Metapod', 'Butterfree', 'Weedle', 'Kakuna', 'Beedrill', 'Pidgey', 'Pidgeotto', 'Pidgeot', 'Rattata', 'Raticate', 'Spearow', 'Fearow', 'Ekans', 'Arbok', 'Pikachu', 'Raichu', 'Sandshrew', 'Sandslash', 'Nidoran-F', 'Nidorina', 'Nidoqueen', 'Nidoran-M', 'Nidorino', 'Nidoking', 'Clefairy', 'Clefable', 'Vulpix', 'Ninetales', 'Jigglypuff', 'Wigglytuff', 'Zubat', 'Golbat', 'Oddish', 'Gloom', 'Vileplume', 'Paras', 'Parasect', 'Venonat', 'Venomoth', 'Diglett', 'Dugtrio', 'Meowth', 'Persian', 'Psyduck', 'Golduck', 'Mankey', 'Primeape', 'Growlithe', 'Arcanine', 'Poliwag', 'Poliwhirl', 'Poliwrath', 'Abra', 'Kadabra', 'Alakazam', 'Machop', 'Machoke', 'Machamp', 'Bellsprout', 'Weepinbell', 'Victreebel', 'Tentacool', 'Tentacruel', 'Geodude', 'Graveler', 'Golem', 'Ponyta', 'Rapidash', 'Slowpoke', 'Slowbro', 'Magnemite', 'Magneton', 'Fa
import binascii, sys, random, asn1
from fractions import gcd
def extended_gcd(aa, bb):
lastremainder, remainder = abs(aa), abs(bb)
x, lastx, y, lasty = 0, 1, 1, 0
while remainder:
lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
x, lastx = lastx - quotient*x, x
y, lasty = lasty - quotient*y, y
from struct import unpack as up
import sys, os, hashlib
dirs, files = None, None
def read_at(fp, off, len):
fp.seek(off)
return fp.read(len)
def read_u8(fp, off):
@SciresM
SciresM / switch_romfs.py
Created July 19, 2017 01:10
Switch RomFS (IStorage) -> Files
from struct import unpack as up
import sys, os
dirs, files = None, None
def read_at(fp, off, len):
fp.seek(off)
return fp.read(len)
def read_u8(fp, off):