首页 > 解决方案 > 传递特殊字符作为参数

问题描述

我需要将一个十六进制字符串00 2C 00 21 作为我无法执行的命令行参数传递给我的程序。

#include<stdio.h>
int main(int argc,char* argv[]){

// argv[1] should have the string that the above hex represents 

//... the program will use that string inside the program

//...also please explain what should i do if i (am/am not) allowed to modify the source  

}

由于 00 是 NULL 字符,我无法在命令行中表示它并将其传递给程序。我还需要传递由十六进制值类似于 01 或 02 (例如)的各种其他字符组成的字符串,您不能直接从键盘输入并作为参数传递。

我应该怎么做才能让我的程序接收十六进制表示为00 2C 00 21.

$./a.out " what should i write here?  " 

标签: cbash

解决方案


你应该让你的程序接受一个带有转义的字符串,然后自己解析它们。所以它会像这样被调用:

$ ./myprogram '\x00\x2c\x00\x21'

例如(\x与 C 本身使用的匹配,因此用户可以熟悉)。单引号是为了保护反斜杠免受 shell 的影响,不是 100% 确定,也不是现在在适当的提示下。

结果不会是字符串,因为 C 中的字符串不能包含 0 字符。

这是一个看起来如何的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static size_t decode(void *buf, size_t buf_max, const char *s)
{
    unsigned char *put = buf;
    unsigned char * const put_max = put + buf_max;
    while (*s != '\0' && put != put_max)
    {
        if (*s == '\\')
        {
            ++s;
            if (*s == '\\')
                *put++ = *s++;
            else if (*s == 'x')
            {
                ++s;
                char *endp;
                const unsigned long v = strtoul(s, &endp, 16);
                if (endp == s)
                    break;
                *put++ = (unsigned char) v;
                s = endp;
            }
            else
                break;
        }
        else
            *put++ = *s++;
    }
    return put - (unsigned char *) buf;
}

int main(int argc, char *argv[])
{
    unsigned char buf[32];
    const size_t len = decode(buf, sizeof buf, "\\x0hello\\x1\\xaa\\xfe\\xed");
    for (size_t i = 0; i < len; ++i)
    {
        printf("%x\n", buf[i]);
    }
    return 0;
}

请注意,main()在您的情况下,测试“驱动程序”将被替换,您希望通过argv[1]例如decode(). 双反斜杠可以防止 C 编译器,我们真的希望得到一个包含反斜杠转义的字符串。


推荐阅读