Hacking Replacing (Disk) Files

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,477
Country
Germany
For the TCP Gecko Installer I tried to implement a function to replace files on games. However, I'm getting an ACCESS_ERROR when calling FSOpenFile():
Code:
case COMMAND_REPLACE_FILE: {
    // Receive the file path
    char file_path[FS_MAX_FULLPATH_SIZE] = {0};
    receiveString(bss, clientfd, file_path, FS_MAX_FULLPATH_SIZE);

    considerInitializingFileSystem();

    // Create an empty file for writing. Its contents will be erased
    int handle;
    int status = FSOpenFile(client, commandBlock, file_path, "w", &handle, FS_RET_ALL_ERROR);

    if (status == FS_STATUS_OK) {
        // Send the OK status
        ((int *) buffer)[0] = status;
        ret = sendwait(bss, clientfd, buffer, 4);
        ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (OK status)")

        // Set the file handle position to the beginning
        ret = FSSetPosFile(client, commandBlock, handle, 0, FS_RET_ALL_ERROR);
        ASSERT_FUNCTION_SUCCEEDED(ret, "FSSetPosFile")

        // Allocate the file bytes buffer
        unsigned int file_buffer_size = 0x2000;
        char *fileBuffer = (char *) OSAllocFromSystem(file_buffer_size, FS_IO_BUFFER_ALIGN);
        ASSERT_ALLOCATED(fileBuffer, "File buffer")

        // Send the maximum file buffer size
        ret = sendwait(bss, clientfd, &file_buffer_size, 4);
        ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (maximum file buffer size)")

        while (true) {
            // Receive the data bytes length
            unsigned int dataLength;
            ret = recvwait(bss, clientfd, &dataLength, 4);
            ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (File bytes length)")
            ASSERT_MAXIMUM_HOLDS(file_buffer_size, dataLength, "File buffer overrun attempted")

            if (dataLength > 0) {
                // Receive the data
                ret = recvwait(bss, clientfd, fileBuffer, dataLength);
                ASSERT_FUNCTION_SUCCEEDED(ret, "recvwait (File buffer)")

                // Write the data (and advance file handle position implicitly)
                ret = FSWriteFile(client, commandBlock, fileBuffer, 1,
                                  dataLength, handle, 0, FS_RET_ALL_ERROR);
                ASSERT_FUNCTION_SUCCEEDED(ret, "FSWriteFile")
            } else {
                // Done with receiving the new file
                break;
            }
        }

        /*// Flush the file back
        ret = FSFlushFile(client, commandBlock, handle, FS_RET_ALL_ERROR);
        CHECK_FUNCTION_FAILED(ret, "FSFlushFile")*/

        // Close the file
        ret = FSCloseFile(client, commandBlock, handle, FS_RET_ALL_ERROR);
        ASSERT_FUNCTION_SUCCEEDED(ret, "FSCloseFile")

        // Free the file buffer
        OSFreeToSystem(fileBuffer);
    } else {
        // Send the status
        ((int *) buffer)[0] = status;
        ret = sendwait(bss, clientfd, buffer, 4);
        ASSERT_FUNCTION_SUCCEEDED(ret, "sendwait (status)")
    }

    break;
}
Client code in Java:
Code:
public FileSystemStatus replaceFile(String remoteFilePath, String localFilePath) throws IOException
{
    // Read the file bytes
    Path localFile = Paths.get(localFilePath);
    byte[] fileBytes = Files.readAllBytes(localFile);

    try (CloseableReentrantLock ignored = reentrantLock.acquire())
    {
        // Send the command and remote file path
        sendCommand(Command.REPLACE_REMOTE_FILE);
        writeString(remoteFilePath);
        dataSender.flush();

        FileSystemStatus status = readFileSystemStatus();

        // Continue if the file has been opened successfully
        if (status == FileSystemStatus.OK)
        {
            sendFileBytes(fileBytes);
        }

        return status;
    }
}

private void sendFileBytes(byte[] fileBytes) throws IOException
{
    int maximumChunkSize = dataReceiver.readInt();
    int fileBytesIndex = 0;

    // Send the file bytes in chunks
    while (fileBytesIndex < fileBytes.length)
    {
        int chunkSize = fileBytes.length - fileBytesIndex;

        if (chunkSize > maximumChunkSize)
        {
            chunkSize = maximumChunkSize;
        }

        // Send the current chunk size
        dataSender.writeInt(chunkSize);
        sendPartialBytes(fileBytes, fileBytesIndex, chunkSize);
        dataSender.flush();

        fileBytesIndex += chunkSize;
    }

    // Let the server know that we're done
    dataSender.writeInt(0);
    dataSender.flush();
}

private void sendPartialBytes(byte[] bytes, int startingIndex, int length) throws IOException
{
    byte[] sendBytes = new byte[length];
    System.arraycopy(bytes, startingIndex, sendBytes, 0, length);
    dataSender.write(sendBytes);
}
In case you're wondering, Cafiine does not actually replace files the same way I'm trying to. It only fools the Wii U into pulling the files from the network instead of the disk. However, I'm trying to just replace the file so the replacement file is being used from now on instead without requesting it over the network over and over again. I'm not sure if this is even possible since the SDK says this about the error message:
Code:
Access mode is invalid (e.g. specified "r+" for read-only media).
It might mean that disks just aren't writable (I'm using the digital version though) but isn't there maybe a way to do it? This project might help as well. Thanks :)

@dimok
@QuarkTheAwesome
@Maschell
@FIX94
@wj44
@NWPlayer123
 
Last edited by BullyWiiPlaza,

wj44

Well-Known Member
Member
Joined
Jun 18, 2015
Messages
477
Trophies
0
XP
506
Country
Gambia, The
If you really want to replace the file you either need to use libiosuhax or the MCPCopyFile Command(eShop games only). Alternativly You can just write the file to the sd and open It everywhere with libiosuhax.
 
  • Like
Reactions: BullyWiiPlaza

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,477
Country
Germany
If you really want to replace the file you either need to use libiosuhax
Wouldn't that be permanent? A temporary replacement would be better I guess since FTPiiu everywhere is probably best suited for permanent replacements. How would go about using libiosuhax to replace the file(s)?
Usually odd03 has the content. Some games have content on odd04. The data you get from there is /code /content /meta, as required by loadiine.
The code should look similar to this then?
Code:
// initialize IOSUHAX
int res = IOSUHAX_Open();

// initialize FSA fd
int fsaFd = IOSUHAX_FSA_Open();

// mount "/dev/odd03" to "/vol/storage_virt_odd" and bind it to our virt PPC path "odd:/"
// if 3rd parameter is NULL it only binds the /vol path (e.g. /vol/system)  to our virt PPC path
res = mount_fs("odd", fsaFd, "/dev/odd03", "/vol/storage_virt_odd");

// Open the file, write and close it again
IOSUHAX_FSA_OpenFile(fsaFd, systemXmlPath, "wb", &slcFd);
IOSUHAX_FSA_WriteFile(fsaFd, data, size, cnt, pFile, flags);
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
// ...
Haxchi makes a nice example of writing with iosuhax :P
 
Last edited by BullyWiiPlaza,
  • Like
Reactions: KiiWii

wj44

Well-Known Member
Member
Joined
Jun 18, 2015
Messages
477
Trophies
0
XP
506
Country
Gambia, The
Wouldn't that be permanent? A temporary replacement would be better I guess since FTPiiu everywhere is probably best suited for permanent replacements. How would go about using libiosuhax to replace the file(s)?

The code should look similar to this then?
Code:
// initialize IOSUHAX
int res = IOSUHAX_Open();

// initialize FSA fd
int fsaFd = IOSUHAX_FSA_Open();

// mount "/dev/odd03" to "/vol/storage_virt_odd" and bind it to our virt PPC path "odd:/"
// if 3rd parameter is NULL it only binds the /vol path (e.g. /vol/system)  to our virt PPC path
res = mount_fs("odd", fsaFd, "/dev/odd03", "/vol/storage_virt_odd");

// Open the file, write and close it again
IOSUHAX_FSA_OpenFile(fsaFd, systemXmlPath, "wb", &slcFd);
IOSUHAX_FSA_WriteFile(fsaFd, data, size, cnt, pFile, flags);
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
// ...
Haxchi makes a nice example of writing with iosuhax :P
Of course this would be permanent. If you want temporaly you need to make fs patches like in Cafiine.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • Veho @ Veho:
    Oh God no :ohnoes:
    +2
  • Psionic Roshambo @ Psionic Roshambo:
    Pineapple is the safe word?
  • Psionic Roshambo @ Psionic Roshambo:
    But you said pine apple...
  • Psionic Roshambo @ Psionic Roshambo:
    Ughh gonna be bored today, class for new job has a lot of networking material and I'm certified in that already...
  • Veho @ Veho:
    Peen apple.
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    "pine unf apple" doesn't count! Lol
  • Psionic Roshambo @ Psionic Roshambo:
    Employee code of conduct videos are awesome!!! Did you know eating the other employees is bad? I didn't know... Lol
    +1
  • AncientBoi @ AncientBoi:
    Anymore males there? :blush:
  • Psionic Roshambo @ Psionic Roshambo:
    All of us lol
  • Psionic Roshambo @ Psionic Roshambo:
    I got free every channel so that's awesome lol
    +1
  • AncientBoi @ AncientBoi:
    Give me ALL the gay pron channels, since you won't be watching them :blush::D
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Lol they exist?
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Hmmm so Mario Does Luigi's plumbing is a bad movie? Lol
  • Psionic Roshambo @ Psionic Roshambo:
    These videos are soooo dry
  • Psionic Roshambo @ Psionic Roshambo:
    Please click all suspicious links sent your email
  • BigOnYa @ BigOnYa:
    What to do today? Cut grass for 3-4 hours, or just get drunk and play video games... Hmm
  • BigOnYa @ BigOnYa:
    I need a remote controlled mower, so I can sit on the couch and do both.
  • BigOnYa @ BigOnYa:
    Sounds good to me, video games and booze it is then.
    +1
  • denpafan @ denpafan:
    Good choice
    +1
  • BigOnYa @ BigOnYa:
    Now what to play, Starfield or Fallout4. And what to drink, beer or Whiskey and Coke. Such tough decisions.
  • BigOnYa @ BigOnYa:
    Looks like its whiskey & coke, only 4 beers left. And think ill start with Falllout. :grog:
    BigOnYa @ BigOnYa: Looks like its whiskey & coke, only 4 beers left. And think ill start with Falllout. :grog: