]> cvs.zerfleddert.de Git - usb-driver/blobdiff - usb-driver.c
More robust search for filename in memory at runtime
[usb-driver] / usb-driver.c
index 252e3279c07b5adab1ba68da5cde70990ceb73d8..3b8b51d4747d2f8c9edf631f627171000268d78d 100644 (file)
@@ -41,6 +41,7 @@
 #include <bits/wordsize.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
+#include <sys/mman.h>
 #include <syscall.h>
 #include <linux/personality.h>
 #include "usb-driver.h"
@@ -673,32 +674,88 @@ long int _Z14isModuleLoadedPci(char *module_name, int i) {
        return 1;
 }
 
+void cpr_segv_handler(int sig, siginfo_t *info, void *context) {
+       void *newmem;
+
+       DPRINTF("SEGV at %p, mapping memory\n", info->si_addr);
+       errno = 0;
+       newmem = mmap(info->si_addr, 1, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+       if (newmem != info->si_addr) {
+               perror("libusb-driver.so: Can't map memory, crashing now");
+               exit(EXIT_FAILURE);
+       }
+}
+
 /* XilCommNS::CPortResources::Instance() */
 void* _ZN9XilCommNS14CPortResources8InstanceEv() {
        static void* (*func) (void) = NULL;
+       char *filename = NULL;
        void *ret;
+       int i;
+
+       if (!func) {
+               struct sigaction act, oldact;
+               int sighand_installed = 0;
 
-       if (!func)
                func = (void* (*) (void)) dlsym(RTLD_NEXT, "_ZN9XilCommNS14CPortResources8InstanceEv");
 
-       DPRINTF("-> XilCommNS::CPortResources::Instance()\n");
+               DPRINTF("Installing signal-handler for SIGSEGV\n");
+               bzero(&act, sizeof(struct sigaction));
+               act.sa_sigaction = cpr_segv_handler;
+               act.sa_flags = SA_SIGINFO;
+               if (sigaction(SIGSEGV, &act, &oldact) == 0) {
+                       sighand_installed = 1;
+               }
 
-       ret = func();
+               DPRINTF("Searching for filename starting at %p\n", func);
+               for(i = 0; i < 32768; i++) {
+                       if (!strcmp(((char*)func)+i, "/proc/sys/dev/parport/%s/base-addr")) {
+                               filename = ((char*)func)+i;
+                               DPRINTF("Filename found at offset %p\n", (void*)(filename - ((char*)func)));
+                               break;
+                       }
+               }
+               if (sighand_installed) {
+                       DPRINTF("Restoring signal-handler for SIGSEGV\n");
+                       sigaction(SIGSEGV, &oldact, NULL);
+               }
+               if (!filename)
+                       fprintf(stderr, "libusb-driver.so: Can't find memory to patch, parallel cables will probably not work!\n");
+       }
 
-#ifdef DEBUG
-       hexdump(ret, 0x29, "<-");
-       #if 0
-       {
-               void *portinfo;
-               portinfo = ((unsigned char**)ret+0x00);
-               hexdump(portinfo, 256, "PI");
-               hexdump(portinfo+0x50, 4, "BS");
-               hexdump(portinfo+0x54, 4, "BE");
-               hexdump(portinfo+0x58, 4, "ES");
-               hexdump(portinfo+0x5c, 4, "EE");
+       if (filename) {
+               long pagesize;
+               size_t protectlen;
+               void *start;
+               int len = strlen(filename) + 1;
+               int ret;
+
+               pagesize = sysconf(_SC_PAGE_SIZE);
+               DPRINTF("You have %lu bytes sized pages!\n", pagesize);
+
+               start = (void*)((long)filename & (~(pagesize-1)));
+
+               protectlen = pagesize;
+               if ((long)(filename + len) > (long)(start + protectlen))
+                       protectlen += pagesize;
+
+               DPRINTF("Unprotecting %zd bytes starting at %p\n", protectlen, start);
+               ret = mprotect(start, protectlen, PROT_READ|PROT_WRITE);
+               if (ret == -1)
+                       perror("mprotect");
+
+               DPRINTF("Replacing %s with /dev/zero\n", filename);
+               strcpy(filename, "/dev/zero");
+
+               DPRINTF("Reprotecting %zd bytes starting at %p\n", protectlen, start);
+               ret = mprotect(start, protectlen, PROT_READ|PROT_EXEC);
+               if (ret == -1)
+                       perror("mprotect");
        }
-       #endif
-#endif
+
+       DPRINTF("-> XilCommNS::CPortResources::Instance()\n");
+
+       ret = func();
 
        DPRINTF("<- XilCommNS::CPortResources::Instance()\n");
 
Impressum, Datenschutz