Ich nutzte Faketime und LD_PRELOAD zuvor, wußte aber gar nicht zu schätzen, wie vielfältig die Manipulationsmöglichkeiten sind.

Links:

  • aardA
    link
    fedilink
    arrow-up
    6
    ·
    1 month ago

    Gerade wenn man auch ein bisschen C kann, und mit den ueblichen Bibliotheksfunktionen halbwegs vertraut ist kann das sehr nuetzlich sein.

    Vor etwa 15 Jahren wollten wir mit ein paar Freunden StarCraft spielen - das damals ziemlich gut via Wine lief. Problem: Wir waren alle in unterschiedlichen Laendern. Ein VPN fuer alle war schnell zusammengeworfen - aber dummerweise ist Starcraft nur fuer lokales Spielen ausgelegt, und bindet sich einfach nur an das erste Interface.

    Dank LD_PRELOAD war das Problem 5 Minuten spaeter geloest:

    // Use with SC_BIND_ADDR=addr LD_PRELOAD="/path/to/so" wine starcraft.exe
    
    #define _GNU_SOURCE
    
    #include <stdlib.h>
    #include <netdb.h>
    #include <dlfcn.h>
    #include <string.h>
    #include <unistd.h>
    
    static inline int __write1(const char *s){
      write(1, s, strlen(s));
      return 0;
    }
    
    int (*libc_bind)(int fd, const struct sockaddr* add, socklen_t len);
    
    void _init(void){
      libc_bind = dlsym(RTLD_NEXT, "bind");
    }
    
    int bind(int fd, const struct sockaddr* addr, socklen_t len) {
      struct addrinfo *bindres;
      struct addrinfo hints;
    
      char *sc_addr;
    
      int i;
      for (i=1; i==1; i++){
        if (addr->sa_family!=AF_INET)
          break;
        if ((sc_addr=getenv("SC_BIND_ADDR"))!=NULL){
          memset(&hints, 0, sizeof hints);
          hints.ai_flags = AI_PASSIVE;
          hints.ai_socktype = SOCK_STREAM;
    
          __write1("SC_BIND_ADDR is set.\nTrying to use ");
          __write1(sc_addr); __write1("\n");
    
          getaddrinfo(sc_addr, 0, &hints, &bindres);
    
          if (bindres->ai_family==AF_INET) {
            __write1("Overwriting bind\n");
            return libc_bind(fd, bindres->ai_addr, bindres->ai_addrlen);
          } else
            break;
        }
      }
    
      __write1("Using default bind address\n");
      return libc_bind(fd, addr, len);
    }
    
      • marv99@feddit.orgOP
        link
        fedilink
        Deutsch
        arrow-up
        4
        ·
        1 month ago

        Ich denke (hoffe) @aard@kyu.de meint, dass es 5 Minuten dauerte, das bereits fertige Tool mit LD_PRELOAD vor StarCraft hängen und nicht es zu programmieren…

        • aardA
          link
          fedilink
          arrow-up
          3
          ·
          1 month ago

          Das Debugging was da jetzt nicht tut hat laenger als 5 Minuten gedauert - nachdem aber klar war (und via strace bestaetigt) wie das bind ablaeuft war obiges zusammenwerfen wirklich nur 5 Minuten, da ist nix kompliziertes dran.

    • marv99@feddit.orgOP
      link
      fedilink
      Deutsch
      arrow-up
      3
      ·
      edit-2
      1 month ago

      Volle Kontrolle über fremde Software auf dem eigenen PC. Ich liebe es!

      Die Schleife sieht ein bisschen unschleifig aus, wohl auf 1 fix eingestellt?

      for (i=1; i==1; i++){

      • aardA
        link
        fedilink
        arrow-up
        2
        ·
        1 month ago

        Ist zu lange her als dass ich noch wuesste was der Grund fuer die Bedingung ist. Grund fuer die Schleife ist klar - in dem Fall ist =break= relativ elegant um fuer alle Fehlerfaelle als Fallback das bind an die Standardadresse zu bekommen.