Now About Social Code
summaryrefslogtreecommitdiff
path: root/drvemu.c
diff options
context:
space:
mode:
authorLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2024-07-07 23:56:35 +0100
committerLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2024-07-07 23:56:35 +0100
commit87542bf71f0f594c5d567ea815439c2f98754754 (patch)
tree852f53ada37a29cc3166d2efae7ee371aa825460 /drvemu.c
parentcfebe5825512d187ce2d4ff98ee74e8da8eb901e (diff)
Get LD_PRELOAD library to highjack driver
Diffstat (limited to 'drvemu.c')
-rw-r--r--drvemu.c155
1 files changed, 153 insertions, 2 deletions
diff --git a/drvemu.c b/drvemu.c
index d16c44f..5499675 100644
--- a/drvemu.c
+++ b/drvemu.c
@@ -1,25 +1,176 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
#include <assert.h>
#include <dlfcn.h>
+#include <dirent.h>
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+#include <asm-generic/ioctl.h>
+
+#include "xf86drm.h"
+
+#define DRM_PVR_RESERVED1 (DRM_COMMAND_BASE + 0)
+#define DRM_PVR_RESERVED2 (DRM_COMMAND_BASE + 1)
+#define DRM_PVR_RESERVED3 (DRM_COMMAND_BASE + 2)
+#define DRM_PVR_RESERVED4 (DRM_COMMAND_BASE + 3)
+#define DRM_PVR_RESERVED5 (DRM_COMMAND_BASE + 4)
+#define DRM_PVR_RESERVED6 (DRM_COMMAND_BASE + 5)
+
+/* PVR includes */
+#define SUPPORT_MEMINFO_IDS
+#define SUPPORT_DRI_DRM_EXT
+#include <config_kernel.h>
+#include <sgxfeaturedefs.h>
+#include <pvr_bridge.h>
+#include <sgx_bridge.h>
+#include <pvr_drm_shared.h>
+#include <sgxconfig.h>
+#include <sgx_mkif_km.h>
+//#include <pvr_drm.h>
+
+static int false_fd = 10241024;
+
#define PROLOG(func) \
static typeof(func) *orig_##func = NULL; \
if(!orig_##func) \
orig_##func = dlsym(RTLD_NEXT, #func);
+int open(const char *pathname, int flags, mode_t mode) {
+ printf("Called open on %s (%d)\n", pathname, flags);
+ PROLOG(open);
+ return orig_open(pathname, flags, mode);
+}
+
int open64(const char *pathname, int flags, ...) {
printf("Called open64 on %s (%d)\n", pathname, flags);
PROLOG(open64);
int fd = orig_open64(pathname, flags);
- //check_fd(fd, pathname);
+ if (strcmp(pathname, "/dev/dri/renderD128") == 0) {
+ printf("Spoofing FD!\n");
+ return false_fd;
+ }
return fd;
}
+#define DEV_NAME "pvr"
+#define DEV_DATE "20110701"
+#define DEV_DESC "Imagination Technologies PVR DRM"
+
+static bool spoof_ioctl(int fd, int request, void *ptr) {
+ int ioctl_nr = _IOC_NR(request);
+ switch(ioctl_nr) {
+ case _IOC_NR(DRM_IOCTL_VERSION): {
+ printf("Spoofing device info\n");
+ drmVersionPtr version = (drmVersionPtr)ptr;
+ version->version_major = 1;
+ version->version_minor = 13;
+ version->version_patchlevel = 3341330;
+ version->name_len = sizeof(DEV_NAME);
+ version->date_len = sizeof(DEV_DATE);
+ version->desc_len = sizeof(DEV_DESC);
+
+ if (version->name)
+ strcpy(version->name, DEV_NAME);
+ if (version->date)
+ strcpy(version->date, DEV_DATE);
+ if (version->desc)
+ strcpy(version->desc, DEV_DESC);
+
+ break;
+ }
+
+#if 0
+ case _IOC_NR(DRM_IOCTL_GET_MAGIC):
+ printf(">>> ioctl(DRM_IOCTL_GET_MAGIC)\n");
+ break;
+ case _IOC_NR(DRM_IOCTL_GET_UNIQUE):
+ printf(">>> ioctl(DRM_IOCTL_GET_UNIQUE)\n");
+ break;
+ case _IOC_NR(DRM_IOCTL_SET_VERSION):
+ printf(">>> ioctl(DRM_IOCTL_SET_VERSION)\n");
+ {
+ struct drm_set_version *data = ptr;
+ printf("\t%d %d %d %d\n", data->drm_di_major,
+ data->drm_di_minor,
+ data->drm_dd_major,
+ data->drm_dd_minor);
+ }
+ break;
+#endif
+ case _IOC_NR(DRM_IOCTL_DROP_MASTER):
+ printf(">>> ioctl(DRM_IOCTL_DROP_MASTER)\n");
+ return 0;
+ case PVR_DRM_SRVKM_CMD:
+ printf("srv command 0x%x\n", PVR_DRM_SRVKM_CMD);
+ //fwrite(ptr, 1, sizeof(PVRSRV_BRIDGE_PACKAGE), log_file);
+ //PPRINT(stdout, ptr, PVRSRV_BRIDGE_PACKAGE);
+ //return pvrsrv_ioctl(fd, ptr);
+ break;
+ case PVR_DRM_IS_MASTER_CMD:
+ printf(">>> ioctl(PVR_DRM_IS_MASTER_CMD) 0x%x\n", PVR_DRM_SRVKM_CMD);
+ /* From KMD source code this seems to always return 0 */
+ break;
+ default:
+ printf("Unimplemented ioctl 0x%x\n", ioctl_nr);
+ assert(false);
+ break;
+ }
+ return 0;
+}
+
+int ioctl(int fd, int request, ...) {
+ PROLOG(ioctl);
+ int ioc_size = _IOC_SIZE(request);
+ bool pvr = fd == false_fd;
+
+ //printf("Size is %d\n", ioc_size);
+ void *ptr = NULL;
+ if(ioc_size) {
+ va_list args;
+ va_start(args, request);
+ ptr = va_arg(args, void *);
+ va_end(args);
+ }
+
+ printf("Got ioctl %d!\n", fd);
+
+ if (pvr)
+ return spoof_ioctl(fd, request, ptr);
+ else
+ return orig_ioctl(fd, request, ptr);
+}
+
int openat(int dirfd, const char *pathname, int flags, ...) {
- assert(false && "openat not implemented");
printf("Called openat on %s (%d) (%d)\n", pathname, dirfd, flags);
PROLOG(openat);
+
return orig_openat(dirfd, pathname, flags);
}
+
+int openat64(int fd, const char * path, int oflag, ...) {
+ printf("Called openat64 %s\n", path);
+ PROLOG(openat64);
+ return orig_openat64(fd, path, oflag);
+}
+
+DIR *opendir(const char *dirname) {
+ printf("Opening dir %s\n", dirname);
+ PROLOG(opendir);
+ return orig_opendir(dirname);
+}
+
+struct dirent *readdir(DIR *dirp) {
+ PROLOG(readdir);
+ struct dirent *out = orig_readdir(dirp);
+ if (out) {
+ //printf("Reading %d %d %s\n", (int)out->d_type, (int)out->d_reclen, (char*)out->d_name);
+ }
+ return out;
+}