-
Notifications
You must be signed in to change notification settings - Fork 23
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
Changes from 12 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
67fa307
In xochitl tests
timower fdf65d1
Correctly propagate waveform and mode
timower 6dff567
Handle sync
timower cbff4d0
Hook qtputenv to auto flip the screen in client
timower 303068a
Hook xohitl in client!
timower a87ef55
Remove frida example
timower e5ae655
Some cleanup
timower bd09f2d
More cleanup
timower fc79ae5
Even more cleanup
timower 70a0a98
Review comments
timower 9a5e21d
Correct error strings
timower 89b9136
Actually correct error messages
timower b1f4e7e
Handle unknown waveforms
timower File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
} | ||
} | ||
|
@@ -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; | ||
} | ||
} | ||
|
@@ -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; | ||
} | ||
|
||
|
@@ -133,13 +170,147 @@ 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); | ||
} | ||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
std::cerr << "PLEASE SEE " | ||
"https://github.com/ddvk/remarkable2-framebuffer/issues/18" | ||
<< 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 create threads fn" << std::endl; | ||
std::cerr << "PLEASE SEE " | ||
"https://github.com/ddvk/remarkable2-framebuffer/issues/18" | ||
<< std::endl; | ||
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 wait threads fn" << std::endl; | ||
std::cerr << "PLEASE SEE " | ||
"https://github.com/ddvk/remarkable2-framebuffer/issues/18" | ||
<< std::endl; | ||
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 shutdown fn" << std::endl; | ||
std::cerr << "PLEASE SEE " | ||
"https://github.com/ddvk/remarkable2-framebuffer/issues/18" | ||
<< std::endl; | ||
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 fn error" << std::endl; | ||
return -1; | ||
} | ||
|
||
if (gum_interceptor_replace(interceptor, create_threads_fn, | ||
(void *)new_create_threads, | ||
nullptr) != GUM_REPLACE_OK) { | ||
std::cerr << "replace create threads fn error" << std::endl; | ||
return -1; | ||
} | ||
|
||
if (gum_interceptor_replace(interceptor, wait_fn, (void *)new_wait, | ||
nullptr) != GUM_REPLACE_OK) { | ||
std::cerr << "replace wait clear fn error" << std::endl; | ||
return -1; | ||
} | ||
|
||
if (gum_interceptor_replace(interceptor, shutdown_fn, (void *)new_shutdown, | ||
nullptr) != GUM_REPLACE_OK) { | ||
std::cerr << "replace shutdown fn error" << std::endl; | ||
return -1; | ||
} | ||
} | ||
|
||
typeof(&__libc_start_main) func_main = | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice