在C中传递十六进制到bash命令

时间:2015-07-22 17:27:01

标签: c linux bash

我试图将bash脚本移植到c。我在将十六进制字符串传递给bash命令时遇到问题。这就是我到目前为止所拥有的。

char buffer[512];
char mp_fmt[] = "\x00\x00\x00\x00\x00\x09\x01\x10\x00\x00\x00\x01\02\x00\x01";
sprintf(buffer,"echo -e \"\x00\x00\x00\x00\x00\x09\x01\x10\x00\x00\x00\x01\02\x00\x01\" | nc 192.168.01.22 500");
//sprintf(buffer,"echo -e \"%s\" | nc 192.168.01.22 500");
system((char *)buffer);

当我运行它时,编译器返回此

test.c:7:5: warning: embedded ‘\0’ in format [-Wformat-contains-nul]
     sprintf(buffer,"echo \"\x00\x00\x00\x00\x00\x09\x01\x10\x00\x00\x00\x01\02\x00\x01\" | nc 192.168.01.22 500");

但是当我使用其他sprintf进行评论时,它并没有抱怨,但它无法正常工作,因为该设备没有响应。

同样在bash脚本中,这就是它的完成方式,我从设备获得响应。

echo -e "\0\0\0\0\0\x9\x1\x10\0\0\0\01\02\0\x01" | nc 192.168.01.22 500

感谢您阅读我的长篇文章。

3 个答案:

答案 0 :(得分:4)

这样做,你不需要0个字节,而是文字字符串\0。所以,

sprintf(buffer, "echo \"\\0\\0\\0\\0\\0\\x9\\x10 [...]

会起作用。

话虽如此,还有其他一些问题

简单的一点是:什么是缓冲区?您没有任何格式,因此请直接使用命令的字符串!

下一步:使用C中的echo?真?你像这样分叉3(!)进程。至少,对{n}使用popen(),在那里使用fwrite()输入字符串。

更好:您只需将一些数据发送到套接字。有一个完美的bsd sockets API,无需调用任何外部工具。

[edit] :通过自己使用套接字,您可以发送原始0字节。

[edit2] :一些草图代码

#include <sys/socket.h>
#include <netinet/in.h>

[...]

int fd;
struct sockaddr_in sin;
char mp_fmt[] = "\x00\x00\x00\x00\x00\x09\x01\x10\x00\x00\x00\x01\x02\x00\x01";

fd = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("192.168.1.22");
sin.sin_port = htons(500);

connect(fd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in));

write(fd, mp_fmt, 15);

shutdown(fd, SHUT_RDWR);
close(fd);

答案 1 :(得分:0)

出现警告是因为您指定的字符串中包含空字符。这是预期的,除了关闭警告之外,你无能为力。

我也猜这个:

//sprintf(buffer,"echo -e \"%s\" | nc 192.168.01.22 500");

应该是这样的:

//sprintf(buffer,"echo -e \"%s\" | nc 192.168.01.22 500", mp_fmt);

在这种情况下,您的设备不会响应,因为不会传入整个字符串。 在C中,标准是字符串以null结尾。这意味着任何库调用(例如sprintf)都不会访问超出其遇到的第一个空字符的内存。因此,在这种情况下,写入缓冲区的内容只是第一个\x00,而不是其他内容。

答案 2 :(得分:-2)

发布的代码包含多个疏忽。

为了简单起见,这是一个更正版本:

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

int main( void )
{

    char buffer[512];
    char mp_fmt[] = "\x00\x00\x00\x00\x00\x09\x01\x10\x00\x00\x00\x01\02\x00\x01";

    sprintf(buffer,"echo -e \"%s\" | nc 192.168.01.22 500", mp_fmt);
    system((char *)buffer);

    return 0;
}