Dump All Opponents' IP Address & Important USER Record Info to NAND [Vega]
#1
Dump All Opponents' IP Address & Important USER Record Info to NAND [Vega]

NOTE: Does NOT work on Wiimmfi (due to their security patches). Yes, I have a version that works on Wiimmfi, but I won't be releasing it. This is because that version will probably get patched within 24 hours if it were released, and I don't want to be in a 'battle' going back and forth w/ the Wiimmfi staff.

This code will create a new file on your NAND called "openme" within the /shared2 directory. The openme file will contain the following info from all opponents (your info will NOT be included)...

Mii Name
Client ID
Wii ID
Friend Code
Slot in Last Race
IPv4 Address

The openme file will contain info from the last race of when it was updated. The file gets updated at the start of each race, replacing the previous race info with the updated info. If you have the info you want after the race starts and don't want the file updated again next race, leave the WW/Room once the current race is over.

How to extract the openme file from your NAND:

You can use the WiiXplorer app or the FSToolBox app. I personally prefer WiiXplorer. You can find either of those HBC apps via a quick Google Search. You will need some experience with HBC and using HBC apps as the following steps will not be a full 'baby-you-step-by-step' guide.

Mini Guide (WiiXplorer)
1. Launch WiiXplorer, go to Settings, then Boot Settings.
2. Turn on NAND Access/Permissions (must be done every time you boot the app)
3. Go to NAND root, go into the shared2 folder. Copy paste the openme file anywhere to your SD/USB.
4. Put SD/USB into computer. Use any Hex Editor to view the file (I recommend HxD). Congratz

openme Overall Player Address Values
0x00 -p1 (slot 0)
0x40 -p2 (slot 1, etc etc)
0x80 - p3
0xC0 - p4
0x100 - p5
0x140 - p6
0x180 - p7
0x1C0 - p8
0x200 - p9
0x240 - p9
0x280 - p10
0x2C0 - p11
0x300 - p12

openme Specific Player Address Offsets (add the players Overall Address value to this value to find it on the Hex Editor. Example you want to see Player 5's FC. Add 0x100 plus 0x20. At address 0x120 on the file will be the FC value of Player 5):
0x0 Mii Name (5 words)
0x14 Client ID (word)
0x18 Wii ID (double word)
0x20 FC (double word)
0x28 Player slot (byte)
0x2C IPv4 Address (word)

Note about IP slotting: If there are guests in the room, it will mess up where the IP addresses are slotted. Not much I can do about this (without making the code way longer than it already is) because the game doesn't repeat a persons' IP in RAM if that person has a guest.

For example--
If there are 6 players in the room and 2 of those have guests, then there are only 4 total IP addresses. So let's say we have these 4 IP Addresses (hex) 
11223344 (slot 0 w/ guest slot 1)
99887755 (slot 2)
10101010 (slot 3 w/ guest slot 4)
22224444 (slot 5)

This is how those IP Addresses would be listed on openme
slot 0 ip's 11223344
slot 1 ip's 99887755
slot 2 ip's 10101010
slot 3 ip's 22224444
slot 4 ip's none (all zeros)
slot 5 ip's none (all zeros)

Instead of making the code way longer than what it is, I decided to leave this up to the end user to manually adjust if they dump the info of a WW that has guests.

Final Important NOTE: This code makes use of memory addresses 0x800015A0 thru 0x800015D3, and 0x81490000 thru 0x81490003. Make sure no other codes you have on, are using those addresses!!!

NTSC-U
C20DB29C 00000003
9B440014 3984003C
3D608000 918B15D0
60000000 00000000
C261E0C8 00000003
7C630214 1C910004
3C848000 906415A0
60000000 00000000
C27AC3BC 00000031
3D808149 816C0000
2C0B0000 40A20174
908C0000 7C0B0378
7D8802A6 9421FF80
BC610008 38600340
38800020 80ADA358
80A50024 7CBA2B78
3D808022 618C9490
7D8803A6 4E800021
7C7B1B78 3F208000
632C159C 39C0000C
856C0004 2C0B0000
40A20011 35CEFFFF
4082FFF0 48000054
7D4802A6 558F063E
39EFFF60 55EFF0BE
1E0F0040 7E3B8214
91F10028 825915D0
1E0F0030 7E50902E
9251002C 392B00D2
7E69A4AA 7E71A5AA
83EB00EC 93F10014
BB8B0168 BF910018
7D4803A6 4E800020
3FA08016 48000015
2F736861 72656432
2F6F7065 6E6D6500
7C6802A6 7C7E1B78
38800000 38A00003
7CA62B78 7CA72B78
63BCABD4 7F8803A6
4E800021 2C03FF97
41A2000C 2C030000
40820050 7FC3F378
38800002 63BCADBC
7F8803A6 4E800021
2C030000 41800034
7C7F1B78 7F64DB78
38A00340 63BCB220
7F8803A6 4E800021
2C030340 40820014
7FE3FB78 63BCB2E4
7F8803A6 4E800021
7F63DB78 7F44D378
3D808022 618C9800
7D8803A6 4E800021
B8610008 38210080
7D8803A6 7D605B78
7C0903A6 00000000

PAL
C20DB33C 00000003
9B440014 3984003C
3D608000 918B15D0
60000000 00000000
C26513DC 00000003
7C630214 1C910004
3C848000 906415A0
60000000 00000000
C27BAE1C 00000031
3D808149 816C0000
2C0B0000 40A20174
908C0000 7C0B0378
7D8802A6 9421FF80
BC610008 38600340
38800020 80ADA360
80A50024 7CBA2B78
3D808022 618C9814
7D8803A6 4E800021
7C7B1B78 3F208000
632C159C 39C0000C
856C0004 2C0B0000
40A20011 35CEFFFF
4082FFF0 48000054
7D4802A6 558F063E
39EFFF60 55EFF0BE
1E0F0040 7E3B8214
91F10028 825915D0
1E0F0030 7E50902E
9251002C 392B00D2
7E69A4AA 7E71A5AA
83EB00EC 93F10014
BB8B0168 BF910018
7D4803A6 4E800020
3FA08016 48000015
2F736861 72656432
2F6F7065 6E6D6500
7C6802A6 7C7E1B78
38800000 38A00003
7CA62B78 7CA72B78
63BCAC74 7F8803A6
4E800021 2C03FF97
41A2000C 2C030000
40820050 7FC3F378
38800002 63BCAE5C
7F8803A6 4E800021
2C030000 41800034
7C7F1B78 7F64DB78
38A00340 63BCB2C0
7F8803A6 4E800021
2C030340 40820014
7FE3FB78 63BCB384
7F8803A6 4E800021
7F63DB78 7F44D378
3D808022 618C9B84
7D8803A6 4E800021
B8610008 38210080
7D8803A6 7D605B78
7C0903A6 00000000

NTSC-J
C20DB25C 00000003
9B440014 3984003C
3D608000 918B15D0
60000000 00000000
C2650A48 00000003
7C630214 1C910004
3C848000 906415A0
60000000 00000000
C27BA488 00000031
3D808149 816C0000
2C0B0000 40A20174
908C0000 7C0B0378
7D8802A6 9421FF80
BC610008 38600340
38800020 80ADA360
80A50024 7CBA2B78
3D808022 618C9734
7D8803A6 4E800021
7C7B1B78 3F208000
632C159C 39C0000C
856C0004 2C0B0000
40A20011 35CEFFFF
4082FFF0 48000054
7D4802A6 558F063E
39EFFF60 55EFF0BE
1E0F0040 7E3B8214
91F10028 825915D0
1E0F0030 7E50902E
9251002C 392B00D2
7E69A4AA 7E71A5AA
83EB00EC 93F10014
BB8B0168 BF910018
7D4803A6 4E800020
3FA08016 48000015
2F736861 72656432
2F6F7065 6E6D6500
7C6802A6 7C7E1B78
38800000 38A00003
7CA62B78 7CA72B78
63BCAB94 7F8803A6
4E800021 2C03FF97
41A2000C 2C030000
40820050 7FC3F378
38800002 63BCAD7C
7F8803A6 4E800021
2C030000 41800034
7C7F1B78 7F64DB78
38A00340 63BCB1E0
7F8803A6 4E800021
2C030340 40820014
7FE3FB78 63BCB2A4
7F8803A6 4E800021
7F63DB78 7F44D378
3D808022 618C9AA4
7D8803A6 4E800021
B8610008 38210080
7D8803A6 7D605B78
7C0903A6 00000000

NTSC-K
C20DB39C 00000003
9B440014 3984003C
3D608000 918B15D0
60000000 00000000
C263F6F4 00000003
7C630214 1C910004
3C848000 906415A0
60000000 00000000
C27A91DC 00000031
3D808149 816C0000
2C0B0000 40A20174
908C0000 7C0B0378
7D8802A6 9421FF80
BC610008 38600340
38800020 80ADA380
80A50024 7CBA2B78
3D808022 618C9B88
7D8803A6 4E800021
7C7B1B78 3F208000
632C159C 39C0000C
856C0004 2C0B0000
40A20011 35CEFFFF
4082FFF0 48000054
7D4802A6 558F063E
39EFFF60 55EFF0BE
1E0F0040 7E3B8214
91F10028 825915D0
1E0F0030 7E50902E
9251002C 392B00D2
7E69A4AA 7E71A5AA
83EB00EC 93F10014
BB8B0168 BF910018
7D4803A6 4E800020
3FA08016 48000015
2F736861 72656432
2F6F7065 6E6D6500
7C6802A6 7C7E1B78
38800000 38A00003
7CA62B78 7CA72B78
63BCAD10 7F8803A6
4E800021 2C03FF97
41A2000C 2C030000
40820050 7FC3F378
38800002 63BCAEF8
7F8803A6 4E800021
2C030000 41800034
7C7F1B78 7F64DB78
38A00340 63BCB35C
7F8803A6 4E800021
2C030340 40820014
7FE3FB78 63BCB420
7F8803A6 4E800021
7F63DB78 7F44D378
3D808022 618C9EF8
7D8803A6 4E800021
B8610008 38210080
7D8803A6 7D605B78
7C0903A6 00000000



List of Sources:

Source for IP Dynamic Word Location ('Pointer') Storage (1st ASM):

stb r26, 0x0014 (r4) #Default Instruction
addi r12, r4, 0x3C #Add 0x3C to r4. Store result to r12. r12's memory location is now exactly at player slot 0's IP
lis r11, 0x8000 #Set 1st half address of where in memory we are storing the word of r12 to
stw r12, 0x15D0 (r11) #Store the word of r12 to 0x800015D0

================================================================

Source for USER Record Pointers Storage (2nd ASM):

#r4 safe for use, gets written to by following address instruction#
#this code address never gets called for your slot#

add r3, r3, r0 #Default Instruction; r3 is player USER pointer
mulli r4, r17, 0x4 #r17 is player slot value
addis r4, r4, 0x8000
stw r3, 0x15A0 (r4)

================================================================

Source of NAND Writes (3rd ASM):

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~#
# Macros & Variables #
#~~~~~~~~~~~~~~~~~~~~#

.macro call_link address
    lis r12, \address@h
    ori r12, r12, \address@l
    mtlr r12
    blrl
.endm

.macro call_isfs address
    ori r28, r29, \address@l
    mtlr r28
    blrl
.endm

.macro push_stack #No need to backup CTR as it gets written to by default instruction at end of code
    mr r11, r0
    mflr r12
    stwu r1, -0x80 (r1)
    stmw r3, 0x8 (r1)
.endm

.macro pop_stack
    lmw r3, 0x8 (r1)
    addi r1, r1, 0x80
    mtlr r12
    mr r0, r11
.endm

.macro default_instruction
    mtctr r0
.endm

.set region, '' #Fill in E, P, J, or K within the quotes for your region when Compiling! Lowercase letters can also be used.

.if     (region == 'E' || region == 'e') # RMCE
    .set ISFS_CreateFile, 0xABD4
    .set ISFS_Open, 0xADBC
    .set ISFS_Write, 0xB220
    .set ISFS_Close, 0xB2E4
    .set Egg_Alloc, 0x80229490
    .set Egg_Free, 0x80229800
.elseif (region == 'P' || region == 'p') # RMCP
    .set ISFS_CreateFile, 0xAC74
    .set ISFS_Open, 0xAE5C
    .set ISFS_Write, 0xB2C0
    .set ISFS_Close, 0xB384
    .set Egg_Alloc, 0x80229814
    .set Egg_Free, 0x80229B84
.elseif (region == 'J' || region == 'j') # RMCJ
    .set ISFS_CreateFile, 0xAB94
    .set ISFS_Open, 0xAD7C
    .set ISFS_Write, 0xB1E0
    .set ISFS_Close, 0xB2A4
    .set Egg_Alloc, 0x80229734
    .set Egg_Free, 0x80229AA4
.elseif (region == 'K' || region == 'k') # RMCK
    .set ISFS_CreateFile, 0xAD10
    .set ISFS_Open, 0xAEF8
    .set ISFS_Write, 0xB35C
    .set ISFS_Close, 0xB420
    .set Egg_Alloc, 0x80229B88
    .set Egg_Free, 0x80229EF8
.else # Invalid Region
        .abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#        Memory Address & Register Notes      #
#   0x800015A0 = Slot 0 User Pointer (Word)   #
#         0x800015A4 = Slot 1, etc etc        #
#          0x800015CC = Slot 11 (0xB)         #
# 0x800015D0 = Pointer to IP Address Mem Area #
#          0x81490000 = Status Word           #
# r25 = Exeception Vector First Half Address  #
#    r26 = System Heap Calc Address Pointer   #
#          r27 = Heap Address Pointer         #
#           r28 = Part of ISFS Macro          #
#          r29 = 0x8016 for ISFS Calls        #
#       r30 = File Path Address Pointer       #
#             r31 = File Descriptor           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#     Status Word Check:    #
#   We don't want the code  #
# to execute more than once #
#  per race. Hence why this #
#          is done.         #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8149
lwz r11, 0x0 (r12)
cmpwi r11, 0x0
bne+ dont_execute

#~~~~~~~~~~~~~~~~~~~~#
# Update Status Word #
#~~~~~~~~~~~~~~~~~~~~#

stw r4, 0x0 (r12) #We need anything not zero for storage, r4 always has a value. Store it

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety/Backup #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#          EGG::Heap:alloc         #
#        r3 = Size of Heap         #
#          r4 = Alignment          #
#      r5 = System Heap Calc       #
# Return r3 = Heap Address Pointer #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x340
li r4, 0x20 #32-bit

.if     (region == 'E' || region == 'e')
        lwz r5, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p')
        lwz r5, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j')
        lwz r5, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k')
        lwz r5, -0x5C80(r13)
.endif 

lwz r5, 0x24 (r5)
mr r26, r5 #Backup System Heap Calc Address

call_link Egg_Alloc

mr r27, r3 #Backup Heap Address Pointer

#~~~~~~~~~~~~~~~~~#
# Pre-Loop Config #
#~~~~~~~~~~~~~~~~~#

lis r25, 0x8000
ori r12, r25, 0x159C #Set r12 to 0x8000159C
li r14, 0xC

#~~~~~~#
# Loop #
#~~~~~~#

the_loop:
lwzu r11, 0x4 (r12) #r11 contains current Player's USER Record Pointer
cmpwi r11, 0x0 #Your own slot will never be available for loading (zero)
bnel+ sub_routine
subic. r14, r14, 1
bne+ the_loop
b loop_done

#~~~~~~~~~~~~#
# Subroutine #
#~~~~~~~~~~~~#

sub_routine:
mflr r10 #Backup LR due to later use of memcpy

#~~~~~~~~~~~~~~~~~~~~~~~~#
# Player Slot Value Calc #
#~~~~~~~~~~~~~~~~~~~~~~~~#

clrlwi r15, r12, 24 #Clear out first 3 bytes (24bits) of r12's value, r12 always updated due to the loop.
addi r15, r15, -0xA0 #Subtract 0xA0 from leftover value
srwi r15, r15, 2 #Shift the word by 2 bits. Final result is the slot value. This is the same as dividing r15 by 0x4.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Calculate Player's Exact Address in the Heap #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

mulli r16, r15, 0x40
add r17, r27, r16

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store Player's Slot Value to Heap #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

stw r15, 0x28 (r17)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Player's IP Address Calculation & Store to Heap #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lwz r18, 0x15D0 (r25) #Grab IP Address Slot 0 Address Pointer from 0x800015D0
mulli r16, r15, 0x30 #Each Slot's IP Address is gapped by 0x30 in Memory
lwzx r18, r16, r18
stw r18, 0x2C (r17)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load & Store Player's Mii Name #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

addi r9, r11, 0xD2 #Set up r4 as the loading address for the following lswi instruction
lswi r19, r9, 20 #Load the 20 byte string at address of r9 into starting register 19 (r19 thru r23 are written)
stswi r19, r17, 20 #Store the 20 byte string of r19 thru r23 to address of r17 (player's beginning heap spot)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load & Store Player's Client ID #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lwz r31, 0xEC (r11)
stw r31, 0x14 (r17)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load & Store Player's Wii ID + FC #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lmw r28, 0x168 (r11)
stmw r28, 0x18 (r17)

#~~~~~~~~~~~~~~~~#
# Return to Loop #
#~~~~~~~~~~~~~~~~#

mtlr r10
blr

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Setup 1st Half Address of ISFS Functions #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

loop_done:
lis r29, 0x8016

#~~~~~~~~~~~~~~~~~~~~~~~~#
#     ISFS_CreateFile    #
# r3 = File Path Address #
#   r4 = u8 attributes   #
# r5 = Owner permission  #
# r6 = Group permission  #
# r7 = Other permission  #
#~~~~~~~~~~~~~~~~~~~~~~~~#

bl create_file

.llong 0x2F73686172656432 #String for "/shared2/openme"
.llong 0x2F6F70656E6D6500

create_file:
mflr r3
mr r30, r3 #Backup File Path Address

li r4, 0x0
li r5, 0x3
mr r6, r5
mr r7, r5

call_isfs ISFS_CreateFile

cmpwi r3, -105
beq+ file_alreadymade
cmpwi r3, 0x0
bne- free_egg

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#           ISFS_Open           #
#     r3 = File Path Address    #
# r4 = 0x2 for Write Permission #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

file_alreadymade:
mr r3, r30
li r4, 0x2

call_isfs ISFS_Open

cmpwi r3, 0x0
blt- free_egg

mr r31, r3 #Backup file descriptor

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                     ISFS_Write                      #
#                r3 = File descriptor                 #
# r4 = Address that Points to String of Data to Write #
#    r5 = Amount of Bytes to Write from the String    #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

mr r4, r27
li r5, 0x340

call_isfs ISFS_Write

cmpwi r3, 0x340
bne- free_egg

#~~~~~~~~~~~~~~~~~~~~~~#
#      ISFS_Close      #
# r3 = File descriptor #
#~~~~~~~~~~~~~~~~~~~~~~#

mr r3, r31

call_isfs ISFS_Close

#~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      EGG::Heap::free      #
# r3 = Heap Address Pointer #
#   r4 = System Heap Calc   #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~#

free_egg:
mr r3, r27
mr r4, r26

call_link Egg_Free

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety/Backup; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: Vega

Code credits: Megazig (ISFS Functions), Star (address founder for 2nd ASM), RiiDefi (EGG Functions)
Reply


Messages In This Thread
Dump All Opponents' IP Address & Important USER Record Info to NAND [Vega] - by Vega - 03-08-2019, 09:43 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)