Hacking RPC File System Read File Issues

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,477
Country
Germany
So I've been trying to implement extracting files using RPC in Java. So far most of the code is working but it gets stuck on reading the file. It still opens the file successfully though.

Code:
@Test
public void extractFile() throws IOException
{
    String filePath = "/vol/content/some/file/that/really/exists";

    FileSystemStatus status;
    RemoteFileSystem fileSystem = new RemoteFileSystem();

    try (FileSystemClient client = new FileSystemClient();
         FileSystemCommandBlock commandBlock = new FileSystemCommandBlock();
         FileSystemHandle fileDescriptor = new FileSystemHandle();
         FileSystemPath path = new FileSystemPath(filePath);
         FileSystemAccessMode accessMode = new FileSystemAccessMode(FileAccessMode.READ);
         AllocatedMemory destinationBuffer = new AllocatedMemory(0x400 * 256, 0x40))
    {
        // Initialize the file system
        status = fileSystem.initialize();

        if (status != FileSystemStatus.OK)
        {
            Assert.fail("Failed initializing file system: " + status);
        }

        // Initialize the command block
        fileSystem.initializeCommandBlock(commandBlock);

        // Register the client
        status = fileSystem.addClient(client);

        if (status != FileSystemStatus.OK)
        {
            Assert.fail("Failed registering client: " + status);
        }

        // Open the file
        status = fileSystem.openFile(client,
                commandBlock,
                path,
                accessMode,
                fileDescriptor,
                FileSystemReturnFlag.ALL);

        if (status != FileSystemStatus.OK)
        {
            Assert.fail("Failed opening file: " + status);
        }

        ByteArrayOutputStream fileBytesBuffer = new ByteArrayOutputStream();
        int bytesRead;

        // ########### Once it executes this, it gets stuck ############
        while ((bytesRead = fileSystem.readFile(client,
                commandBlock,
                destinationBuffer,
                fileDescriptor,
                FileSystemReturnFlag.ALL)) > 0)
        {
            MemoryReader memoryReader = new MemoryReader();
            byte[] readBytes = memoryReader.readBytes(destinationBuffer.getAddress(), bytesRead);
            fileBytesBuffer.write(readBytes);
        }

        status = FileSystemStatus.getStatus(bytesRead);
        System.out.println("File reading exit status: " + status);

        // Close the file
        status = fileSystem.closeFile(client, commandBlock, fileDescriptor, FileSystemReturnFlag.NONE);

        if (status != FileSystemStatus.OK)
        {
            Assert.fail("Failed closing file: " + status);
        }

        // Delete the client registration
        status = fileSystem.unRegisterClient(client, FileSystemReturnFlag.NONE);

        if (status != FileSystemStatus.OK)
        {
            Assert.fail("Failed un-registering client: " + status);
        }

        storeFile(filePath, fileBytesBuffer);
    }
}

private void storeFile(String filePath, ByteArrayOutputStream outputStream) throws IOException
{
    Path targetFilePath = Paths.get(filePath);

    // Create parent directory (if it doesn't exist yet)
    Path parentDirectory = targetFilePath.getParent();
    Files.createDirectories(parentDirectory);

    // Write the bytes
    byte[] bytes = outputStream.toByteArray();
    Files.write(targetFilePath, bytes);
}
As comparison, here is the C code Dimok uses in ddd which is working:
Code:
static void DumpFile(void *client,
                     void *commandBlock,
                     SendData *sendData,
                     char *path,
                     unsigned int fileSize) {
    sendData->tag = 0x02;
    memcpy(&sendData->data[0], &fileSize, 4);
    sendData->length = snprintf((char *) sendData->data + 4, BUFFER_SIZE - 4, "%s", path) + 4 + 1;
    sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length);

    int ret = recvwait(iClientSocket, (char *) sendData, sizeof(SendData) + 1);
    if (ret < (int) (sizeof(SendData) + 1) || (sendData->data[0] != 1)) {
        return;
    }

    unsigned char *dataBuffer = (unsigned char *) memalign(0x40, BUFFER_SIZE);
    if (!dataBuffer) {
        return;
    }

    int fileDescriptor = 0;
    if (FSOpenFile(client, commandBlock, path, "r", &fileDescriptor, -1) != FS_STATUS_OK) {
        free(dataBuffer);
        sendData->tag = 0x04;
        sendData->length = 0;
        sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length);
        return;
    }

    unsigned int size = 0;

    // Copy rpl in memory
    while ((ret = FSReadFile(client, commandBlock, dataBuffer, 0x1, BUFFER_SIZE, fileDescriptor, 0, -1)) > 0) {
        size += ret;

        sendData->tag = 0x03;
        sendData->length = ret;
        memcpy(sendData->data, dataBuffer, sendData->length);

        if (sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length) < 0) {
            break;
        }
    }

    sendData->tag = 0x04;
    sendData->length = 0;
    sendwait(iClientSocket, sendData, sizeof(SendData) + sendData->length);

    FSCloseFile(client, commandBlock, fileDescriptor, -1);
    free(dataBuffer);
}
I'm passing the same parameters but it's not returning after the call:
Code:
public int readFile(FileSystemClient client,
                    FileSystemCommandBlock commandBlock,
                    AllocatedMemory dataBuffer,
                    FileSystemHandle fileDescriptor,
                    FileSystemReturnFlag returnFlag) throws IOException
{
    ExportedSymbol readFile = remoteProcedureCall.getSymbol(RPL.CORE_INIT.toString(), "FSReadFile");

    return remoteProcedureCall.callInt(readFile,
            client.getAddress(),
            commandBlock.getAddress(),
            dataBuffer.getAddress(),
            0x1,
            0x1000,
            // dataBuffer.getSize(),
            fileDescriptor.dereference(),
            0,
            // returnFlag.getValue());
            -1);
}
See here for the full Java code.

Thanks!

@dimok
@QuarkTheAwesome
@Maschell
@gudenaurock
@timogus
@NWPlayer123
 

BullyWiiPlaza

Nintendo Hacking <3
OP
Member
Joined
Aug 2, 2014
Messages
1,932
Trophies
0
XP
2,477
Country
Germany
I would recommend logging this in wireshark and making sure that you are sending the correct data, there could be some slight issue somewhere that you can not see. Happens to me more that it should
True, you have no idea how long I have been messing around with those minor details that might screw it all up. Maybe someone can implement a TCP Gecko command for this? :)
 
Last edited by BullyWiiPlaza,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    K3Nv2 @ K3Nv2: Nut on the hill