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