Per ptrace einen syscall ausführen



  • Hoi. 🙂

    Ich suche nach einem eleganten Weg, in einem getracten Prozess einen Syscall auszuführen.
    So ist mein Ansatz bis jetzt:

    unsigned long Debugger::executeSyscall(
      unsigned long code, std::vector<unsigned long> const& args) const
    {
      // Safe registers.
      Registers buRegs = getRegisters(buRegs);
      FpuRegisters buFregs = getFpuRegisters(buFregs);
    
      // Get register set to modify.
      Registers regs = buRegs;
    
      #if __WORDSIZE == 32
    
      // EAX stores the syscall code.
      regs.eax = code;
    
      // If less than 6 args exist, they are stored in registers.
      size_t argCount = args.size();
      if(argCount < 6)
      {
        while(argCount)
        {
          switch(argcount)
          {
          case 1:
            regs.ebx = args[0];
            break;
    
          case 2:
            regs.ecx = args[1];
            break;
    
          case 3:
            regs.edx = args[2];
            break;
    
          case 4:
            regs.esx = args[3];
            break;
    
          case 5:
            regs.edi = args[4];
            break;
          }
    
          --argCount;
        }
      }
    
      // Otherwise we have to use memory.
      else
      {
        // Get stack space.
        regs.esp -= argCount * sizeof(unsigned long);
    
        // Write arguments to stack.
        for(size_t i = 0; i < argCount; ++i)
          writeWord(regs.esp + i * sizeof(unsigned long), args[i]);
    
        // EBX stores the address.
        regs.ebx = regs.esp;
      }
    
      #elif __WORDSIZE == 64
      ...
      #else
        #error Unsupported platform !
      #endif
    

    writeWord/getRegs etc sind nur Wrapperfunktionen für ptrace mit entsprechenden Parametern.

    Jetzt frag ich mich nur, wie ich möglichst elegant einen Softwareinterrupt ( INT 0x80 ) erzeugen kann.
    Ja, ich weiß, die ganze Sache ist sehr hackish aber es wäre mir wichtig das hinzubekommen 🙂
    Mein einziger Ansatz wäre es eine x-beliebige Page mit rwx-Rechten zu finden, einen INT 0x80 OP-Code zu schreiben, den EIP entsprechend anzupassen, und per PTRACE_SYSCALL abzuwarten bis der Syscall durch ist um dann den entsprechenden Speicher wiederherzustellen. Klingt für mich aber zu dirty.

    Falls jemand irgendeine logische Idee hätte, bitte melden. 🙂
    Grüße,
    Ethon


Anmelden zum Antworten