1

I am currently trying to reverse an IoT machine running the 2.6 Linux Kernel on which I have root. On this machine, software writes to /dev/some_device to control what I believe to be are GPIO pins for a serial bus. In order to take control of these GPIO pins, I have been attempting to reverse the on-board software to grasp how the drivers are looking for input, but the decompilation has been messy/missing parts.

Thus, my question: Am I able to redirect program output intended for /dev/some_device to a text file for analysis?

For example, the current mapping:

Program -> (char sequence) -> /dev/*char_device*

I am looking for a way to redirect the program output from the device to a text file, or better, any writes to the device to a text file. Example:

Program -> (char sequence) --\       /dev/*char_device*
                              \
                               \-----> *my_text_file*

Again, my motivation to do so is to analyze how the driver is expecting input. I already know my logical input/output/return communications on the serial bus, I just need to be able to determine the specifics of the device driver. Any help is appreciated. Let me know if more information is required.

-Update- Here is a method I tracked down in the source code decompliation. While I cannot verify that this is the exact handler for the devices I'm targeting, it used by devices with similar names.

// Address range: 0x1000c470 - 0x1000c6f7
int32_t function_1000c470(int32_t * a1, int32_t a2, int32_t a3, char * path) {
    int32_t v1 = (int32_t)a1;
    int32_t v2; // bp-144
    int32_t v3 = &v2; // 0x1000c470_0
    v2 = v3;
    g602 = v3;
    int32_t fd = open(path, O_RDWR);
    int32_t * fd2 = (int32_t *)(v1 + 4); // 0x1000c4a8_0
    *fd2 = fd;
    if (*fd2  0x1000c6d8
    } else {
        // 0x1000c500
        fprintf(g94, "opening serial device %s with fd %d\n", path, *fd2);
        int32_t termios_p;
        tcgetattr(*fd2, (struct termios *)&termios_p);
        cfmakeraw((struct termios *)&termios_p);
        cfsetospeed((struct termios *)&termios_p, 9);
        cfsetispeed((struct termios *)&termios_p, 9);
        tcsetattr(*fd2, TCSANOW, (struct termios *)&termios_p);
        ioctl(*fd2, 0x5415);
        g1 &= -0x2000001;
        ioctl(*fd2, 0x5418);
        *(int32_t *)(v1 + 16) = 0;
        *(int32_t *)(v1 + 20) = 0;
        int32_t * v4 = (int32_t *)(4 * *fd2 / 32 + v1 + 1668); // 0x1000c630_0
        *v4 = 1  0x1000c674
        }
        // 0x1000c674
        *(int32_t *)(v1 + 8) = v7 + 1;
        *(int32_t *)(v1 + 1624) = 0;
        *(int32_t *)(v1 + 1620) = 0;
        *(int32_t *)(v1 + 1628) = 0;
        memset((char *)(v1 + 120), 0, 1500);
        function_1000c6f8(*fd2, 0);
        // branch -> 0x1000c6d8
    }
    int32_t v8 = v2; // 0x1000c6dc
    g602 = *(int32_t *)(v8 - 4);
    return *(int32_t *)(v8 + 4);
}
  • To add, the /dev/device I am targeting is a character device. It'd like to divert its input steam to an output file. – J. Bednard Oct 7 '17 at 21:28
  • Part of my thought believes that the /dev device is just a pointer to the driver handler. If that is case, would I be able to overwrite the pointer to my own device? – J. Bednard Oct 8 '17 at 5:08
  • It is also a file. Which interface this software use for accessing device? Is it uses open(2)? – de6f Oct 8 '17 at 18:08
  • @de6f I have updated the original post with the decompiled source code which is working on the device file. – J. Bednard Oct 9 '17 at 0:55
  • Ideally, I should be able to take the supplied code and recompile it into my own program and try to harness termios to setup a serial connection. I'm a bit weary on this being the correct code those as the /dev/device I am trying to target is an IBM SDLC serial bus. In fact, I'm going to make the assumption that the code in the post is not for the device that I am targetting. – J. Bednard Oct 9 '17 at 2:07
2

I have used /dev/ptmx for that purpose:

Say i want to intercept data written to /dev/somedevice

  • First i open the master: /dev/ptmx.
  • Then i allocate a slave by calling ptsname.
  • Now rename /dev/somedevice to /dev/somedevice.orig
  • Symlink /dev/somedevice to the pts slave.
  • open the original device /dev/somedevice.orig

  • start copying data between the master and the original device. recording data to a log file.

Make sure the interceptor gets started before the original program opens the device.

Also, i think you may run into problems handling ioctls this way.

| improve this answer | |
  • Thank you William. I'll give this a try when I sit down next. I'll report back. – J. Bednard Oct 10 '17 at 4:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.