Modding[Release]Ghetto Achievement & Avatar Award Unlocker + Source
Posted:

Modding[Release]Ghetto Achievement & Avatar Award Unlocker + SourcePosted:

XeCrippy
  • Fairy Master
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
I haven't made anything in a while and have been busy with a new job but I was bored this morning and put this together. Not sure what method is floating around that everyone is using so I decided to make this public and maybe someone can improve on it. Or maybe some nerds will go ahead and post the real method.

Source

Download


*EDIT: I forgot that I built this on .net 9 in visual studio 2022 preview. If anyone is having trouble, that could be why.

https://i.gyazo.com/2b3c11e5ed38449771e1c4043778ccca.png


Last edited by XeCrippy ; edited 4 times in total

The following 2 users thanked XeCrippy for this useful post:

Wretched (09-21-2024), Treason (09-21-2024)
#2. Posted:
Treason
  • Ladder Climber
Status: Offline
Joined: Jan 29, 201311Year Member
Posts: 393
Reputation Power: 551
Motto: RGH Consoles In Stock!
Motto: RGH Consoles In Stock!
Status: Offline
Joined: Jan 29, 201311Year Member
Posts: 393
Reputation Power: 551
Motto: RGH Consoles In Stock!
says missing .exe when trying to run or build in vb code looks sweet though, do i have to add UI
#3. Posted:
XeCrippy
  • Rated Awesome
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Treason wrote says missing .exe when trying to run or build in vb code looks sweet though, do i have to add UI


It's c# not VB. If you want to build the source you need to add xdevkit.dll and jrpc.dll and change the reference from JRPCPlusPlus to JRPC_Client (normal jrpc). I mean really this is all it is are these two functions that are needed


private uint LocateInstruction()
        {
            byte[] targetSequence = { 0x60, 0x84, 0x00, 0x08 };
            byte[] bytes = console.GetMemory(0x82000000, 0x3000000);

            for (int i = 0; i <= bytes.Length - targetSequence.Length; i++)
            {
                bool match = true;
                for (int j = 0; j < targetSequence.Length; j++)
                {
                    if (bytes[i + j] != targetSequence[j])
                    {
                        match = false;
                        break;
                    }
                }
                uint address = 0x82000000 + (uint)i;
                if (match)
                {
                    uint addr2 = address - 0x8;
                    byte[] testBytes = console.GetMemory(addr2, 4);
                    byte[] target2 = { 0x38, 0xE0, 0x00, 0x08 };
                    if (testBytes.Length == target2.Length && testBytes.SequenceEqual(target2))
                    {
                        return address;
                    }
                }
            }
            return 0;
        }

        private void XUserWriteAchievements(uint achievementCallAddr, uint achievementIdPtr, uint xoverlappedPtr, int achievementCount)
        {
            console.WriteUInt32(xoverlappedPtr, 0);

            for (int i = 0; i < achievementCount; i++)
            {
                console.WriteUInt64(achievementIdPtr, (ulong)i);
                console.CallVoid(achievementCallAddr, 1, achievementIdPtr, xoverlappedPtr);

                while (console.ReadUInt32(xoverlappedPtr) != 0) Thread.Sleep(30);
            }
            Thread.Sleep(250);
        }

private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                if (connected)
                {
                    uint callAddr = LocateInstruction() - 0x24;
                    if (callAddr != 0)
                        XUserWriteAchievements(callAddr, 0x91D0D9E0, 0x91D0D9E8, 350); // i set the count high because the id's are not always in sequence. better chance to get all of them
                    else
                        MessageBox.Show("Failed to find the function address!");
                }
                else
                    MessageBox.Show("Not connected to console!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
#4. Posted:
XeCrippy
  • Vantage
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
So to be a little more clear, to build the GitHub source clone the repo and then once it's opened in visual studio remove the current references to xdevkit and jrpc. Then re-add them and change the using JRPCPlusPlus to JRPC_Client. Then it will build a .exe. It has a UI but it's just two buttons.

All it's doing is searching the xex for a specific sequence of bytes that I know is part of the function to write achievements. Then calculating the function address once it finds it. That address will be the start of XUserWriteAchievements within the specific game you're on. Then it calls XUserWriteAchievements with the proper arguments.
#5. Posted:
XeCrippy
  • Blind Luck
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Added avatar award unlocker also and included the prebuilt binaries in the release tab. There is .NET 6 and .NET 9 versions, you will need to have one of those installed probably.

Downloads
#6. Posted:
XeCrippy
  • Rated Awesome
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Status: Offline
Joined: May 12, 20168Year Member
Posts: 1,909
Reputation Power: 1262
Users browsing this topic: None
Jump to:


RECENT POSTS

HOT TOPICS