When starting frida you can provide path to an executable that frida should execute and attach to it:
frida -l myscript.js process_to_spawn.exe
I have an executable needs to be started with additional parameters, otherwise it directly terminates. Is there a way to start a new executable and provide command-line arguments for the newly started process?
I already tried
frida -l myscript.js process_to_spawn.exe --argForProcess
frida -l myscript.js "process_to_spawn.exe --argForProcess"
but both variants don't work. Frida tries to interpret all arguments and thus can not pass arguments to the spawned process. And the second variant also does not work because frida is not able to find the executable to be started.
Is there a way to spawn an executable on the local OS (e.g. Windows or Linux) by frida and provide command-line arguments?
I can not attach to a running process because the functions I want to hook are only executed once directly after start-up, so I have to spawn the process using frida.
CodePudding user response:
The problem seems to be that the argument starts with a -
. For regular arguments that don't start with a -
using the frida option -f
works:
frida -l myscript.js -f process_to_spawn.exe argForProcess
But as I need the argument --argForProcess
the only way I found was hooking the main method which processes the command-line arguments and modify the arguments before main is called.
The following code works on Windows 10 which seem to pass the arguments as wchar/"Unicode"/UTF-16 string. It changes argc
and argv
parameters of main
from one argument (the executable itself) to two (the executable plus one argument).
let mainPointer = DebugSymbol.fromName("main").address;
Interceptor.attach(mainPointer, {
onEnter(args) {
// args[0] = int argc
// args[1] = wchar *argv[]
let myarg1 = Memory.allocUtf16String("Myexecutable.exe");
let myarg2 = Memory.allocUtf16String("--argumentX");
let newArgv = Memory.alloc(2 * Process.pointerSize); // allocate space for the two argument pointers
newArgv.writePointer(myarg1);
newArgv.add(Process.pointerSize).writePointer(myarg2);
// save all created memory blocks so they don't get garbage collected before main method is completed
this.myarg1 = myarg1;
this.myarg2 = myarg2;
this.newArgs = newArgv;
// Overwrite the argument counter and the argument char**
args[0] = ptr(2);
args[1] = newArgs;
console.log("main(" args[0] ", " args[1].readPointer().readUtf16String() ", " args[1].add(Process.pointerSize).readPointer().readUtf16String() ")");
}
});