Close
0%
0%

Ricoh GRIII(x) firmware exploration and hacking

My motivation is to discover methods for running custom applications on the Ricoh GR3(x) camera while keeping the firmware intact.

Similar projects worth following
91 views
0 followers
The Ricoh GR3(x) is a camera with firmware that I am exploring to find ways to run custom applications without altering the firmware itself, similar to projects like MagicLantern.
The camera runs a customized Poky 2.2 on Linux kernel v4.4 and has various system daemons controlling its functions, along with a few custom libraries.

I've been diving deep into this project, analyzing the firmware image, building the kernel, and creating a Docker container for easy system and application testing. Started reverse engineering the webapid, sysmgrd, camctrld, and custom libraries is also underway.
Moving forward, I'll be focusing on getting the system up and running with mocked components, exploring the firmware update process, and investigating display output. I'm also on the lookout for potential vulnerabilities in order to inject own code or gain remote shell access.

Motivation

My motivation is to discover methods for running custom applications on the Ricoh GR3(x) camera while keeping the firmware intact. This would allow to extend the camera's functionality and explore new possibilities.

Contents

The repository includes:

  • Tools specifically tailored for analyzing and working with Ricoh GR3(x) firmware.
  • Docker environments configured with the necessary dependencies for firmware analysis.

Getting started

  • You need to clone the repository with submodules (git clone --recursive ...)
  • First you need to obtain a firmware file from: https://www.ricoh-imaging.co.jp/english/support/digital/gr3x_s.html
  • I prefer to put it in a directory called firmware and append the firmware version to the filename, e.g.: firmware/fwdc243b-v121.bin
  • The next step is to extract the firmware: tools/extract-firmware.sh firmware/fwdc243b-v121.bin
  • Now you can try to run the system in a docker container: tools/run-system-docker.sh firmware/fwdc243b-v121.bin
    • At the moment the system will not fully boot, since the shared memory (hardware access) and IPC are not working, so the camctld daemon will fail to fully initialize.
    • If you're interested into the startup script, please have a look at start.sh, this is a slightly modified version of the original /etc/rc.local
  • Now you can try to compile and install the mocks for shmem and IPCU related functions:
    • tools/build-mocks.sh firmware/fwdc243b-v121.bin
    • tools/install-mocks.sh firmware/fwdc243b-v121.bin
    • In order to rebuild the docker system image you need to remove the old docker image before: docker image rm gr3x-system-fwdc243b-v121
    • Now you can run tools/run-system-docker.sh firmware/fwdc243b-v121.bin again and the system will start with the mocked libraries.
  • Building the kernel is possible with: tools/build-kernel.sh firmware/fwdc243b-v121.bin
    • I was, until now, not able to run the kernel in QEMU, so any support with that is highly welcome

Hardware

The Ricoh GR3(x) camera is equipped with the following hardware:

  • CPU: Milbeaut SC2000 (Quad Core ARM CORTEX-A7) (Please note that this is my best guess based on kernel config and is yet to be confirmed)

Software

The camera runs a custom Poky (Yocto Project Reference Distro) 2.2 operating system on a Linux kernel v4.4. It utilizes several system daemons, custom libraries, and the /etc/rc.local script for the startup process.

Daemons

  • camctld (C++): The camera controller daemon.
  • sysmgrd (C++): Functionality not analyzed yet.
  • netmgrd (C++): Functionality not analyzed yet.
  • bled (C++): Serves the BLE (Bluetooth Low Energy) interface.
  • webapid (C++): Serves the camera's remote control and image download web API. Utilizes the CrowCpp web server library.
  • usbd (C++): Sets up the USB device configuration.
  • mtpd (C++): Serves the MTP (Media Transfer Protocol) interface.

Libraries

  • libshmem_manager.so (C): Provides functions to manage and utilize shared memory for IPC (Inter-Process Communication) and potentially hardware communication. [Mock]
  • libcmfwk.so (C): Offers functions for managing IPCU, mmaped memory, and shmem. [Mock]
  • libcamera-controller.so (C++): Serves as the interface to the camera functionality.

Project Progress

I have made significant progress in my exploration of the Ricoh GR3(x) firmware. Here are some notable achievements and ongoing tasks:

  • Extracted the firmware image using gr_unpack (Big thanks goes out to: @yeahnope!)
  • Analyzed the firmware image contents using binwalk and identified files of interest.
  • Extracted the kernel configuration.
  • Built the kernel from the source code provided by RICOH IMAGING.
  • Extracted the rootfs from the firmware image.
  • Created a Docker container to:
    • Run the entire system.
    • Run and debug single applications.
  • Initiated reverse engineering efforts on various components, including:
    • webapid
    • sysmgrd
    • camctrld
    • libcamera-controller.so
    • libcmfwk.so
    • libshmem_manager.so
  • Started writing mocks for:
    • libcmfwk.so
    • libshmem_manager.so
  • Explored running the system in QEMU.
  • Analyze firmware with: cwe_checker...
Read more »

  • Improving mocks

    Harry Hornbacher07/05/2023 at 15:48 0 comments

    Improving mocks

    I have decided to use Rust for mocking libcmfwk and libshmem_manager, as it is the language I am most comfortable with. By creating accurate mocks for these libraries, I aim to resolve the issue where camctld hangs while trying to send an IPCU message in the CameraCommandSync section and waiting for a response. The goal is to ensure the smooth execution of the boot process (/etc/rc.local / docker/start.sh). My current progress shows that camctld makes several calls to FJ_IPCU_Open and FJ_IPCU_SetReceiverCB with different parameters. It then tries to send an IPCU message using FJ_IPCU_Send.

    System log

    user.info camctld[75]: [camctl] logger has been initialized.
    user.info camctld[75]: [camctl] loglevel has been changed to (trace).
    user.info camctld[75]: ########## camera-controller-daemon ##########
    user.info camctld[75]: signal handler has been initialized.
    shmem_init_config(0x4fed0000, 0x30000, 0x50000000, 0x800000, 0xfffef944, 0xa )
    shmem_init_config -> Offset: 0x4fed0000
    shmem_init_config -> Length: 0x30000
    shmem_init(0x4fed0000, 0x30000, 0x50000000, 0x800000 )
    shmem_init -> Offset1: 0x4fed0000
    shmem_init -> Length1: 0x30000
    shmem_init -> Offset2: 0x50000000
    shmem_init -> Length2: 0x800000
    user.info camctld[75]: shmem init has done.
    FJ_IPCU_Open(0x1, 0xfffef7bb)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),    ],    receiver_cbs: [],
    }
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/ipcu_wrapper/ipcu_channel.cpp line #19] [camctl] [IpcuChannel] leave constructor for ipcu(255).
    FJ_IPCU_Open(0x0, 0xfffef7bb)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),        (            0x0,            0xfffef7bb,        ),    ],    receiver_cbs: [],
    }
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/ipcu_wrapper/ipcu_channel.cpp line #19] [camctl] [IpcuChannel] leave constructor for ipcu(255).
    FJ_IPCU_Open(0x4, 0xfffef7bb)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),        (            0x0,            0xfffef7bb,        ),        (            0x4,            0xfffef7bb,        ),    ],    receiver_cbs: [],
    }
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/ipcu_wrapper/ipcu_channel.cpp line #19] [camctl] [IpcuChannel] leave constructor for ipcu(255).
    FJ_IPCU_Open(0xd, 0xfffef7bb)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),        (            0x0,            0xfffef7bb,        ),        (            0x4,            0xfffef7bb,        ),        (            0xd,            0xfffef7bb,        ),    ],    receiver_cbs: [],
    }
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/ipcu_wrapper/ipcu_channel.cpp line #19] [camctl] [IpcuChannel] leave constructor for ipcu(255).
    FJ_IPCU_Open(0xc, 0xfffef7bb)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),        (            0x0,            0xfffef7bb,        ),        (            0x4,            0xfffef7bb,        ),        (            0xd,            0xfffef7bb,        ),        (            0xc,            0xfffef7bb,        ),    ],    receiver_cbs: [],
    }
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/ipcu_wrapper/ipcu_channel.cpp line #19] [camctl] [IpcuChannel] leave constructor for ipcu(255).
    FJ_IPCU_Open(0x5, 0xfffef7bb)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),        (            0x0,            0xfffef7bb,        ),        (            0x4,            0xfffef7bb,        ),        (            0xd,            0xfffef7bb,        ),        (            0xc,            0xfffef7bb,        ),        (            0x5,            0xfffef7bb,        ),    ],    receiver_cbs: [],
    }
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/ipcu_wrapper/ipcu_channel.cpp line #19] [camctl] [IpcuChannel] leave constructor for ipcu(255).
    FJ_IPCU_SetReceiverCB(0xff, 0x927e8)
    Current state: InnerState {    channels: [        (            0x1,            0xfffef7bb,        ),        (            0x0,            0xfffef7bb,        ),        (            0x4,            0xfffef7bb,        ),        (            0xd,            0xfffef7bb,        ),        (            0xc,            0xfffef7bb,        ),        (            0x5,            0xfffef7bb,        ),    ],    receiver_cbs: [        (            0xff,            0x000927e8,        ),    ],
    }
    FJ_IPCU_SetReceiverCB(0xff, 0x927e8)
    FJ_IPCU_SetReceiverCB(0xff, 0x927e8)
    user.info camctld[75]: FinishBoot
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/camera_core/cameraif_impl.cpp line #89] [ENTER] CameraCommandSync
    user.debug camctld[75]: [/usr/src/debug/camera-controller/1.0-r0/git/src/camera_core/camera_command_task.cpp line #44] [CamCmd] send: cmd(0x00000100), subcmd(0x00000100)
    user.debug camctld[75]:...
    Read more »

View project log

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates