فهرست منبع

UserspaceEmulator: Implement the execve() syscall :^)

This virtual syscall works by exec'ing the UserspaceEmulator itself,
with the emulated program's provided arguments as the arguments to the
new UserspaceEmulator instance.

This means that we "follow" exec'ed programs and emulate them as well.
In the future we might want to make this an opt-in (or opt-out, idk)
behavior, but for now it's what we do.

This is really quite cool, I think! :^)
Andreas Kling 5 سال پیش
والد
کامیت
0b287c18b9
2فایلهای تغییر یافته به همراه45 افزوده شده و 0 حذف شده
  1. 44 0
      DevTools/UserspaceEmulator/Emulator.cpp
  2. 1 0
      DevTools/UserspaceEmulator/Emulator.h

+ 44 - 0
DevTools/UserspaceEmulator/Emulator.cpp

@@ -242,6 +242,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
     dbgprintf("Syscall: %s (%x)\n", Syscall::to_string((Syscall::Function)function), function);
 #endif
     switch (function) {
+    case SC_execve:
+        return virt$execve(arg1);
     case SC_ioctl:
         return virt$ioctl(arg1, arg2, arg3);
     case SC_get_dir_entries:
@@ -872,4 +874,46 @@ int Emulator::virt$fork()
     return fork();
 }
 
+int Emulator::virt$execve(FlatPtr params_addr)
+{
+    Syscall::SC_execve_params params;
+    mmu().copy_from_vm(&params, params_addr, sizeof(params));
+
+    auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
+    Vector<String> arguments;
+    Vector<String> environment;
+
+    auto copy_string_list = [this](auto& output_vector, auto& string_list) {
+        for (size_t i = 0; i < string_list.length; ++i) {
+            Syscall::StringArgument string;
+            mmu().copy_from_vm(&string, (FlatPtr)&string_list.strings[i], sizeof(string));
+            output_vector.append(String::copy(mmu().copy_buffer_from_vm((FlatPtr)string.characters, string.length)));
+        }
+    };
+
+    copy_string_list(arguments, params.arguments);
+    copy_string_list(environment, params.environment);
+
+    dbgprintf("\n");
+    dbgprintf("==%d==  \033[33;1mSyscall:\033[0m execve\n", getpid());
+    for (auto& argument : arguments)
+        dbgprintf("==%d==    - %s\n", getpid(), argument.characters());
+
+    Vector<char*> argv;
+    Vector<char*> envp;
+
+    argv.append(const_cast<char*>("/bin/UserspaceEmulator"));
+
+    auto create_string_vector = [](auto& output_vector, auto& input_vector) {
+        for (auto& string : input_vector)
+            output_vector.append(const_cast<char*>(string.characters()));
+        output_vector.append(nullptr);
+    };
+
+    create_string_vector(argv, arguments);
+    create_string_vector(envp, environment);
+
+    return execve(argv[0], (char* const*)argv.data(), (char* const*)envp.data());
+}
+
 }

+ 1 - 0
DevTools/UserspaceEmulator/Emulator.h

@@ -71,6 +71,7 @@ private:
     void setup_stack(const Vector<String>& arguments, const Vector<String>& environment);
 
     int virt$fork();
+    int virt$execve(FlatPtr);
     int virt$get_dir_entries(int fd, FlatPtr buffer, ssize_t);
     int virt$ioctl(int fd, unsigned, FlatPtr);
     int virt$usleep(useconds_t);