Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for running xochitl using the client. #29

Merged
merged 13 commits into from
Dec 7, 2020
Empty file modified rm2fb.pro
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion src/client/client.pro
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ DEFINES += QT_DEPRECATED_WARNINGS

# Input
SOURCES += main.cpp
LIBS += -lrt -ldl
LIBS += -lrt -ldl frida/libfrida-gum.a
51,219 changes: 51,219 additions & 0 deletions src/client/frida/frida-gum.h

Large diffs are not rendered by default.

Binary file added src/client/frida/libfrida-gum.a
Binary file not shown.
165 changes: 160 additions & 5 deletions src/client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,38 @@
#include <string>
#include <unistd.h>

#include <QByteArray>

#include "../shared/ipc.cpp"
#include "../shared/signature.cpp"

#include "frida/frida-gum.h"

#define FB_ID "mxcfb"

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

using namespace std;
int msg_q_id = 0x2257c;
swtfb::ipc::Queue MSGQ(msg_q_id);

uint16_t *SHARED_BUF;

const int BYTES_PER_PIXEL = sizeof(uint16_t);

bool IN_XOCHITL = false;

extern "C" {
struct stat;

// QImage(width, height, format)
static void (*qImageCtor)(void *that, int x, int y, int f) = 0;
// QImage(uchar*, width, height, bytesperline, format)
static void (*qImageCtorWithBuffer)(void *that, uint8_t *, int32_t x, int32_t y,
int32_t bytes, int format, void (*)(void *),
void *) = 0;

static void _libhook_init() __attribute__((constructor));
static void _libhook_init() {
std::ios_base::Init i;
Expand All @@ -41,9 +55,30 @@ static void _libhook_init() {
} else {
setenv("RM2FB_ACTIVE", "1", true);
}

qImageCtor = (void (*)(void *, int, int, int))dlsym(
RTLD_NEXT, "_ZN6QImageC1EiiNS_6FormatE");
qImageCtorWithBuffer = (void (*)(
void *, uint8_t *, int32_t, int32_t, int32_t, int, void (*)(void *),
void *))dlsym(RTLD_NEXT, "_ZN6QImageC1EPhiiiNS_6FormatEPFvPvES2_");

SHARED_BUF = swtfb::ipc::get_shared_buffer();
}

bool FIRST_ALLOC = true;
void _ZN6QImageC1EiiNS_6FormatE(void *that, int x, int y, int f) {
if (IN_XOCHITL && x == swtfb::WIDTH && y == swtfb::HEIGHT && FIRST_ALLOC) {
fprintf(stderr, "REPLACING THE IMAGE with shared memory\n");

FIRST_ALLOC = false;
qImageCtorWithBuffer(that, (uint8_t *)SHARED_BUF, swtfb::WIDTH,
swtfb::HEIGHT, swtfb::WIDTH * BYTES_PER_PIXEL, f,
nullptr, nullptr);
return;
}
qImageCtor(that, x, y, f);
}

int open64(const char *pathname, int flags, mode_t mode = 0) {
static int (*func_open)(const char *, int, mode_t) = NULL;

Expand All @@ -53,7 +88,7 @@ int open64(const char *pathname, int flags, mode_t mode = 0) {

auto r = func_open(pathname, flags, mode);
if (not IN_XOCHITL) {
if (pathname == string("/dev/fb0")) {
if (pathname == std::string("/dev/fb0")) {
return swtfb::ipc::SWTFB_FD;
}
}
Expand All @@ -70,7 +105,7 @@ int open(const char *pathname, int flags, mode_t mode = 0) {

auto r = func_open(pathname, flags, mode);
if (not IN_XOCHITL) {
if (pathname == string("/dev/fb0")) {
if (pathname == std::string("/dev/fb0")) {
return swtfb::ipc::SWTFB_FD;
}
}
Expand All @@ -92,7 +127,9 @@ int ioctl(int fd, unsigned long request, char *ptr) {

return 0;
} else if (request == MXCFB_WAIT_FOR_UPDATE_COMPLETE) {

#ifdef DEBUG
std::cerr << "CLIENT: sync" << std::endl;
#endif
return 0;
}

Expand Down Expand Up @@ -133,13 +170,131 @@ int ioctl(int fd, unsigned long request, char *ptr) {
return func_ioctl(fd, request, ptr);
}

static const auto touchArgs = QByteArray("rotate=180:invertx");

bool _Z7qputenvPKcRK10QByteArray(const char *name, const QByteArray &val) {
static auto orig_fn = (bool (*)(const char *, const QByteArray &))dlsym(
RTLD_NEXT, "_Z7qputenvPKcRK10QByteArray");

if (strcmp(name, "QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS") == 0) {
return orig_fn(name, touchArgs);
}
Comment on lines +179 to +181
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice


return orig_fn(name, val);
}

void (*old_update)(void *, int, int, int, int, int, int) = 0;
int (*old_create_threads)(const char *, void *) = 0;
int (*old_wait)(void) = 0;
int (*old_shutdown)(void) = 0;

void new_update(void *instance, int x1, int y1, int x2, int y2, int waveform,
int flags) {
#ifdef DEBUG
std::cerr << "UPDATE HOOK CALLED" << std::endl;
std::cerr << "x " << x1 << " " << x2 << std::endl;
std::cerr << "y " << y1 << " " << y2 << std::endl;
std::cerr << "wav " << waveform << " flags " << flags << std::endl;
#endif

swtfb::xochitl_data data;
data.x1 = x1;
data.x2 = x2;
data.y1 = y1;
data.y2 = y2;
data.waveform = waveform;
data.flags = flags;
MSGQ.send(data);
}

int new_create_threads(const char *path, void *buf) {
std::cerr << "create threads called" << std::endl;
return 0;
}

int new_wait(void) {
std::cerr << "wait clear func called" << std::endl;
return 0;
}

int new_shutdown(void) {
std::cerr << "shutdown called" << std::endl;
return 0;
}

GumInterceptor *interceptor;

int __libc_start_main(int (*_main)(int, char **, char **), int argc,
char **argv, int (*init)(int, char **, char **),
void (*fini)(void), void (*rtld_fini)(void),
void *stack_end) {

if (string(argv[0]).find("xochitl") != string::npos) {
if (std::string(argv[0]).find("xochitl") != std::string::npos) {
raisjn marked this conversation as resolved.
Show resolved Hide resolved
IN_XOCHITL = true;

auto *update_fn =
swtfb::locate_signature(argv[0], "\x54\x40\x8d\xe2\x10\x50\x8d\xe2", 8);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the signature isn't found, it should point people to issue #18

if (update_fn == nullptr) {
std::cerr << "Unable to find update fn" << std::endl;
return -1;
}
update_fn -= 12;

auto *create_threads_fn = swtfb::locate_signature(
argv[0], "\x00\x40\xa0\xe1\x10\x52\x9f\xe5\x6b\x0d\xa0\xe3", 12);
if (create_threads_fn == nullptr) {
std::cerr << "Unable to find update fn" << std::endl;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad copy/paste here

return -1;
}

auto *wait_fn =
swtfb::locate_signature(argv[0], "\x01\x30\xa0\xe3\x30\x40\x9f\xe5", 8);
if (wait_fn == nullptr) {
std::cerr << "Unable to find update fn" << std::endl;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

return -1;
}

auto *shutdown_fn =
swtfb::locate_signature(argv[0], "\x01\x50\xa0\xe3\x44\x40\x9f\xe5", 8);
if (shutdown_fn == nullptr) {
std::cerr << "Unable to find update fn" << std::endl;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

return -1;
}

std::cerr << "Update fn address: " << std::hex << (void *)update_fn
<< "\nCreate th address: " << (void *)create_threads_fn
<< "\nWait for th address: " << (void *)wait_fn
<< "\nshutdown address: " << (void *)shutdown_fn << std::dec
<< std::endl;

old_update = (decltype(old_update))update_fn;
old_create_threads = (decltype(old_create_threads))create_threads_fn;
old_wait = (decltype(old_wait))wait_fn;
old_shutdown = (decltype(old_shutdown))shutdown_fn;

gum_init_embedded();
interceptor = gum_interceptor_obtain();

if (gum_interceptor_replace(interceptor, update_fn, (void *)new_update,
nullptr) != GUM_REPLACE_OK) {
std::cerr << "replace update fnerror" << std::endl;
}

if (gum_interceptor_replace(interceptor, create_threads_fn,
(void *)new_create_threads,
nullptr) != GUM_REPLACE_OK) {
std::cerr << "replace create threads error" << std::endl;
}

if (gum_interceptor_replace(interceptor, wait_fn, (void *)new_wait,
nullptr) != GUM_REPLACE_OK) {
std::cerr << "replace wait clear error" << std::endl;
}

if (gum_interceptor_replace(interceptor, shutdown_fn, (void *)new_shutdown,
nullptr) != GUM_REPLACE_OK) {
std::cerr << "replace shutdown error" << std::endl;
}
}

typeof(&__libc_start_main) func_main =
Expand Down
Loading