-
Active Member
Diablo 3 unstripped .ELFs in the switch (almost like having the source code)
Quoting a tweet from @Spooookmon:
Blizzard left all of the master lotcheck submission files & unstripped .ELFs in the Switch title Diablo III: Eternal Collection's RomFS
Twitter
What you get from these is close to having Diablo 3 source code
The nss files from the picture are ELF files you can load in IDA and get all the juicy stuff. Please note that the switch has an ARM64 processor not an x64 (but the source should be almot the same)
You'll need the nsp that's been circulating around (google it) and then extract the files with hactool.
Code:
hactool -t pfs0 --pfs0dir=01001B300B9BE000 "Diablo III Eternal Collection [01001B300B9BE000][v0].nsp"
From the extracted folder you can get the titlekey from the .tik file (open in an hex editor and it's at offset 0x180). With that titlekey and the usual hactool keys (google them) you can extract the romfs.
Code:
hactool -k keys.dat --titlekey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --romfsdir=romfs 01001B300B9BE000/244b84153edddf42407aa2a03572202a.nca
After that just throw the nss files into IDA and enjoy.
Last edited by barthencito; 10-29-2018 at 03:55 AM.
-
Post Thanks / Like - 6 Thanks
-
Active Member
An example of what can be done (on the Switch version):
-
Post Thanks / Like - 3 Thanks
Xel,
ayssia,
johnbl (3 members gave Thanks to barthencito for this useful post)
-
Contributor
this is just the tip as well. could do a ton of stuff on ps4 so i see this getting torn all to shit soon
-
Member
How do you repack the modified .elf(.nss) to /exefs/main(.nso)?
I tried with elf2nso tool in devkitpro but failed, it seems that tool is broken.
-
Active Member
Originally Posted by
ayssia
How do you repack the modified .elf(.nss) to /exefs/main(.nso)?
I tried with elf2nso tool in devkitpro but failed, it seems that tool is broken.
I'm not modifying files on disk, just live memory editing. Take a look at:
GitHub - mdbell/Noexes: A graphical remote debugger for the Nintendo Switch
or
GitHub - jakibaki/sys-netcheat: Open-source cheat-engine for the Nintendo Switch.
Noexs has a better GUI and has a small assembler.
sys-netcheat offers Lua scripting support (if you compile it from source).
I tend to use Noexs to find stuff and then sys-netcheat to automate it.
This is the code used in the video:
Code:
function getsExperienceGrantToACDaddress()
sectionbase, size = getRegionInfo("MemType_CodeStatic", 2)
address = sectionbase + 0x700F50
return address
end
function restoreEXPPatch()
poke("u32", getsExperienceGrantToACDaddress(), 0xAA0103F4)
end
function applyEXPPatch()
poke("u32", getsExperienceGrantToACDaddress(), 0x910003F4)
end
It just changes a "MOV X20, X1" with a "MOV X20, SP" (X1 holds the experience gained, I changed it to SP as that register will hold a big number).
-
Guys, I am so noob for this could you write some hints how can I start? I think it would be insane to get access to more data with HUD...
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Member
I would also very much any tool (and instruction on how to properly use it!) that could help us figure out what gymnastics they're continuing to perform on the PC version in order to keep it well obfuscated. For instance, simply reading an "Actor's" common data id (ACD.ID) requires that you not only read a memory offset from the start of the Actor struct, but that you perform a bitwise XOR with a "crypto key" you've read from the first invalid hero structure's "Actor ID" in a completely unrelated data structure.
Reading an "Actor's" common data ID (so you can link it up to additional data about the actor):
public int ACDID => (int)SymbolTable.Current.CryptoKeys.RActorACDID ^ Read<int>(SymbolTable.Current.Actor.ACDID);
AND... by some stroke of Einsteinien insight, Enigma figured out you need to XOR the value with - not a constant, but with a bizzarely-derived value from a completely different memory structure that is supposed to contain "junk" data.
var pd = ctx.DataSegment.ObjectManager.PlayerDataManager.First(x => x.HeroClass == HeroClass.None);
var pk = 0xbc407c66 ^ pd.ActorID;
var f1 = (Func<ulong, ulong>)((c) => c ^ (ulong)pk); <-- I MEAN, HTF did he have any clue he was looking at a function delegate that needed to be applied to what seem like arbitrary parameters to get a value that XORs with a seemingly random ID to give you a meaningful ID?! Genius!
symbols.CryptoKeys.RActorACDID = (uint)f1(0x821BCA81D9BCBA5F);
symbols.CryptoKeys.PlayerDataActorID = (uint)f1(0x5E4343B43BF8399);
symbols.CryptoKeys.PlayerDataACDID = (uint)f1(0xF133B7A088777214);
symbols.CryptoKeys.ActorID = (uint)f1(0x4112B21407989591);
symbols.CryptoKeys.ACDActorSNO = (uint)f1(0xF672DFB4D10C633;
symbols.CryptoKeys.ActorType = (uint)f1(0xB91A93002F9F6082);
symbols.CryptoKeys.SSceneID = (uint)f1(0x30D32677671B0CE2);
symbols.CryptoKeys.SWorldID = (uint)f1(0x5D8D52368B6DE286);
symbols.CryptoKeys.LevelAreaSNO = (uint)f1(0x5F56F079CA9D7AB7);
symbols.CryptoKeys.TimedEventSNO = (uint)ReadRVA<long>(ctx, 0x02023517) + 0x4CE032CC;
symbols.CryptoKeys.RActorActorSNO = (uint)(__ROL8__(ReadRVA<ulong>(ctx, 0x020238DF), 2) ^ 0x38A64B54);
I gotta say that they should have hired Enigma to start immediate work on D4, not handing out cease and descist orders to crazy brilliant hobbiests!
-
Member
So bad that the main file has been blocked/deleted....I manage to get it on time...but not sure if would be safe to upload it again.