Dtrace 显示 posix_spawn 仅使用 3 个参数调用。尝试手动启动

Dtrace 显示 posix_spawn 仅使用 3 个参数调用。尝试手动启动

我运行了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/filefile_actionsaatrp和。argvenvp

我在运行的同时逐步执行 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 不支持循环。我认为是因为跟踪引入内核中无限循环的可能性是不可接受的。

相关内容