2014-04-30 39 views
0

更改Linux'ps'输出我试图让一个程序改变'ps'显示为进程的CMD名称,使用我所见过的技术推荐的简单覆盖指向的内存通过argv [0]。这是我写的示例程序。通过更改argv [0]

#include <iostream> 
#include <cstring> 
#include <sys/prctl.h> 
#include <linux/prctl.h> 
using std::cout; 
using std::endl; 
using std::memcpy; 

int main(int argc, char** argv) { 
    if (argc < 2) { 
     cout << "You forgot to give new name." << endl; 
     return 1; 
    } 

    // Set new 'ps' command name - NOTE that it can't be longer than 
    // what was originally in argv[0]! 

    const char *ps_name = argv[1]; 
    size_t arg0_strlen = strlen(argv[0]); 
    size_t ps_strlen = strlen(ps_name); 
    cout << "Original argv[0] is '" << argv[0] << "'" << endl; 

    // truncate if needed 
    size_t copy_len = (ps_strlen < arg0_strlen) ? ps_strlen+1 : arg0_strlen; 
    memcpy((void *)argv[0], ps_name, copy_len); 
    cout << "New name for ps is '" << argv[0] << "'" << endl; 

    cout << "Now spin. Go run ps -ef and see what command is." << endl; 
    while (1) {}; 
} 

的输出是:

$ ./ps_test2 foo 
Original argv[0] is './ps_test2' 
New name for ps is 'foo' 
Now spin. Go run ps -ef and see what command is. 

PS -ef的输出是:

5079  28952 9142 95 15:55 pts/20 00:00:08 foo _test2 foo 

显然, “foo” 的插入,但它的空终止被忽略或接通变成空白。原始argv [0]的尾部仍然可见。

我该如何替换'ps'打印的字符串?

+0

章,什么是'的/ proc/$ PID/cmdline'特殊文件里面?你可以做'hexdump -C'吗? – osgx

+0

00000000 66 6f 6f 00 5f 74 65 73 74 00 66 6f 6f 00 62 61 | foo._test.foo.ba | 00000010 72 00 | r。| – Chap

+0

@osgx:好吧,我似乎无法正确格式化,但它对应于下面的tetromino描述。 – Chap

回答

2

您需要重写整个命令行,该命令行在Linux中存储为连续缓冲区,参数用零分隔。

喜欢的东西:

size_t cmdline_len = argv[argc-1] + strlen(argv[argc-1]) - argv[0]; 
size_t copy_len = (ps_strlen + 1 < cmdline_len) ? ps_strlen + 1 : cmdline_len; 
memcpy(argv[0], ps_name, copy_len); 
memset(argv[0] + copy_len, 0, cmdline_len - copy_len); 
+1

这似乎是正确的。我已经验证了argv [1..n]指向那些以null结尾的参数,这意味着我最终会破坏argv [1..n]。有些事情要注意。 – Chap