![Dtrace 显示 posix_spawn 仅使用 3 个参数调用。尝试手动启动](https://linux22.com/image/1410791/Dtrace%20%E6%98%BE%E7%A4%BA%20posix_spawn%20%E4%BB%85%E4%BD%BF%E7%94%A8%203%20%E4%B8%AA%E5%8F%82%E6%95%B0%E8%B0%83%E7%94%A8%E3%80%82%E5%B0%9D%E8%AF%95%E6%89%8B%E5%8A%A8%E5%90%AF%E5%8A%A8.png)
我运行了dtruss
一个启动另一个进程的进程:英雄联盟启动器使用某些参数启动主游戏进程,而我似乎无法通过命令行传递这些参数。
引起我注意的是这行 dtruss 输出:
PID/THRD RELATIVE ELAPSD CPU SYSCALL(args) = return
9386/0x47dac: 19625 3013 1805 posix_spawn(0x2A634FC, 0x38A2A00, 0xB06A56E0) = 0 0
我查阅了的手册页posix_spawn
,它应该接受 6 个参数。它们依次为PID
、/path/to/file
、file_actions
、aatrp
和。argv
envp
我在运行的同时逐步执行 GDB dtruss
,因此我能够检查有问题的内存。
- 第一个参数指向 PID 中的 0x000024d2。
- 第二个参数指向一个字符数组:英雄联盟的可执行路径
- 第三个参数总是指向同一个东西,其中难以理解的字符串表示是
\026l<?
我不知道该怎么做。最终,我希望能够通过 C 自己使用自定义参数启动此过程,但我认为第一步是了解系统如何调用它,以及第三个参数是什么。
我的问题是:我还能做些什么来找出第三个参数是什么(?)以及我尝试做的事情(绕过启动器)是否可行?
可以直接在 Windows 命令行上通过
@start "" "League of Legends.exe" "8394" "LoLLauncher.exe" "" "spectator fspectate.op.gg:4081 tjJbtRLQ/HMV7HuAxWV0XsXoRB4OmFBr 1391881421 NA1"
但在 Mac 上,这只会重新启动启动器。
为了便于理解,我已经写了一个冗长(且未解答)的问题描述我所做的一切。
请告诉我如何改进这个问题。我花了 50 多个小时试图自己解决这个问题,通过 dtruss 输出进行强力破解,我几乎准备放弃了。
答案1
如果你阅读 dtruss 的源代码:
cat `which dtruss`
您会发现参数的数量是硬编码的。
入口:
syscall:::entry
/(OPT_command && pid == $target) ||
(OPT_pid && pid == PID) ||
(OPT_name && NAME == strstr(NAME, execname)) ||
(OPT_name && execname == strstr(execname, NAME)) ||
(self->child)/
{
/* set start details */
self->start = timestamp;
self->vstart = vtimestamp;
self->arg0 = arg0;
self->arg1 = arg1;
self->arg2 = arg2;
/* count occurances */
OPT_counts == 1 ? @Counts[probefunc] = count() : 1;
}
返回:
/* print 3 arg output - default */
syscall:::return
/self->start/
{
/* calculate elapsed time */
this->elapsed = timestamp - self->start;
self->start = 0;
this->cpu = vtimestamp - self->vstart;
self->vstart = 0;
self->code = errno == 0 ? "" : "Err#";
/* print optional fields */
/* OPT_printid ? printf("%5d/%d: ",pid,tid) : 1; */
OPT_printid ? printf("%5d/0x%x: ",pid,tid) : 1;
OPT_relative ? printf("%8d ",vtimestamp/1000) : 1;
OPT_elapsed ? printf("%7d ",this->elapsed/1000) : 1;
OPT_cpu ? printf("%6d ",this->cpu/1000) : 1;
/* print main data */
printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n",probefunc,self->arg0,
self->arg1,self->arg2,(int)arg0,self->code,(int)errno);
OPT_stack ? ustack() : 1;
OPT_stack ? trace("\n") : 1;
self->arg0 = 0;
self->arg1 = 0;
self->arg2 = 0;
}
某些系统调用有定制处理(/* mmap has 6 arguments */
)。
我复制了脚本并复制粘贴了一些self->arg*
内容, 0x%X
。
我能够将默认值更改为 6 个参数,从而实现如下输出:
posix_spawn(0x700003AA66B4, 0x7FF7B215BF10, 0x700003AA6570, 0x700003AA6610, 0x700003AA6720, 0x0) = 0 0
至于为什么我们必须复制粘贴参数而不是直接增加计数器:DTrace 不支持循环。我认为是因为跟踪引入内核中无限循环的可能性是不可接受的。