【问题标题】:How to decode this information from strace output如何从 strace 输出中解码此信息
【发布时间】:2014-10-31 13:10:09
【问题描述】:

我写了一个小的 go 脚本并使用 strace 跟踪它 虽然这个脚本,我正在尝试使用 netlink 协议从内核获取审计消息,就像 auditd 一样。

以下是我的 go 脚本上的 strace 输出-http://paste.ubuntu.com/8272760/

我正在尝试查找 auditd 提供给 sendto 函数的参数。 当我在 auditd 上运行 strace 时,我得到以下输出

sendto(3, "\20\0\0\0\350\3\5\0\1\0\0\0\0\0\0\0", 16, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 16

当我 strace 我的 go 文件时,我得到以下输出。 我正在寻找解码此语句的第二个参数

sendto(3, "\21\0\0\0\350\3\5\0\1\0\0\0\0\0\0\0\t", 17, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 17

具体一点

"\21\0\0\0\350\3\5\0\1\0\0\0\0\0\0\0\t" 

现在我想将其转换为字符串或字节数组,有没有办法将其转换为字符串或字节数组?

在我实际的 go 代码中,这个参数是一个字节数组。

https://github.com/mozilla/Audit-Go/blob/testing/netlink_old.go#L58

【问题讨论】:

  • Hrm:看起来你的源代码中的wb 已经 []byte,所以我不明白提出的问题,或者为什么涉及 strace . (发生了什么使得 strace 变得必要而不是依赖于 Go 代码的检测?)
  • 另外,it's conventional to avoid dot imports 就像`。 “系统调用”。
  • 我不确定,但问题可能在于您正在处理的 strace 输出并非全部来自您的代码,而且您不确定如何解析它。我所拥有的可能不是最佳实践方法,但我认为 JavaScript 使用的引用规则足够接近相同的引用规则,您可以将字符串放入脚本中:jsfiddle.net/2tukw37o

标签: c go audit strace netlink


【解决方案1】:

我对您的问题的理解是您尝试通过比较 strace 输出来比较 auditd 发送的内容与程序发送的内容,并且您在将 strace 提供的字符串转换为 Go []byte 数据类型时遇到问题。

strace 输出遵循字符串文字的 GNU C 表示,其字符可以如下转义:

\\ Backslash character. 
\? Question mark character.
\' Single quotation mark. 
\" Double quotation mark. 
\a Audible alert. 
\b Backspace character. 
\e <ESC> character. (This is a GNU extension.) 
\f Form feed. 
\n Newline character. 
\r Carriage return. 
\t Horizontal tab. 
\v Vertical tab.
\o, \oo, \ooo Octal number.
\xh, \xhh, \xhhh, ... Hexadecimal number.

请注意,八进制或十六进制数字的数量是可变的。在 Go 中,字符也可以转义,但规则不同 - 请参阅 http://golang.org/ref/spec#Rune_literals

特别是,八进制值系统地使用 3 位数字以避免任何歧义。要声明具有这样一个字符序列的 []byte,您必须编写如下内容:

// In strace, it was "\21\0\0\0\350\3\5\0\1\0\0\0\0\0\0\0\t"
wb := []byte("\021\000\000\000\350\003\005\000\001\000\000\000\000\000\000\000\t")

请注意,strace 中的 -x 选项将对不可打印的字符使用固定长度的十六进制编码,这使得在 Go 程序中直接使用这些字符串更容易。 -xx 选项即使对于可打印字符也会输出十六进制编码字节,这使得 IMO 更容易。

不管怎样,使用字面量字符串来初始化[]byte,不一定是一种好的风格(甚至是一个好主意)。字符串用于 UTF-8 字符,而不用于二进制数据。

【讨论】:

    【解决方案2】:

    \21\0\0\0\350\3\5\0\1\0\0\0\0\0\0\0\t

    这些是ANSI X3.159-1989(又名ANSI C89,请查看PDF file)中定义的字符转义序列。你可以find官方草稿页面port70.net

    这是man printf中的简短摘要:

    • \a 写一个&lt;bell&gt; 字符。
    • \b 写一个&lt;backspace&gt; 字符。
    • \c 忽略此字符串中的剩余字符。
    • \e 写一个&lt;escape&gt; 字符。
    • \f 写一个&lt;form-feed&gt; 字符。
    • \r 写一个&lt;carriage return&gt; 字符。
    • \n 写一个&lt;new-line&gt; 字符。
    • \t 写一个&lt;tab&gt; 字符。
    • \v 写一个&lt;vertical tab&gt; 字符。
    • \' 写一个&lt;single quote&gt; 字符。
    • \" 写一个&lt;double quote&gt; 字符。
    • \\写一个反斜杠字符。
    • \num, \0num 写一个 8 位字符,其 ASCII 值为 1 位、2 位或 3 位八进制数。

    要将这些字符解释为字符串,您可以使用printf,例如shell中的命令:

    printf "%b" "\21\0\0\0\350\3\5\0\1\0\0\0\0\0\0\0\t"
    

    更多解析示例,请查看:How to parse strace in shell into plain text?

    【讨论】:

    • 对我来说不能正常工作。例如。 \0374printf 解码为fc,而实际上它是1f34
    【解决方案3】:

    如果您希望 strace 打印十六进制字符串而不是 ASCII 和转义序列,请使用 -x-xx,详情请咨询 man。

    【讨论】: