如何从stdin逐行拆卸?

时间:2016-11-17 13:41:38

标签: bash shell x86-64 disassembly linux-x32-abi

我的程序输出编码指令,如下所示:

0x81FB4300000090
0x69FC4300000090
0x81FC4300000090
0x69FD4300000090
0x81FD4300000090
0x69FE4300000090
0x81FE4300000090
0x69FF4300000090
0x81FF4300000090
0x00054400000090
0x01054400000090
0x02054400000090
0x03054400000090
0x08054400000090
0x09054400000090
0x0A054400000090
0x0B054400000090
0x10054400000090
0x11054400000090
0x12054400000090
0x13054400000090
0x18054400000090
0x19054400000090
0x1A054400000090
0x1B054400000090
0x20054400000090
0x21054400000090
0x22054400000090
0x23054400000090
0x28054400000090
0x29054400000090
0x2A054400000090
0x2B054400000090
0x30054400000090
0x31054400000090
0x32054400000090
0x33054400000090
0x38054400000090
0x39054400000090
0x3A054400000090
0x3B054400000090
0x40054400000090
0x41054400000090
0x42054400000090
0x43054400000090
0x44054400000090
0x45054400000090
0x46054400000090
0x47054400000090

上面的每一行都是独立的指令集,需要作为单独的程序进行反汇编。 每行包含7个字节的指令。我可以直接输出二进制,***在这种情况下,每个7字节的块需要单独拆解。

在运行我的程序的bash脚本中,我想过滤掉包含静态跳转的行。

那么,如何将每行与stdin分开? (我想做./my_C_program | the_disassembler | grep loopne之类的事情 我尝试了objdump,但它拒绝使用/dev/stdin作为输入文件。

2 个答案:

答案 0 :(得分:1)

time bash -c 'for i in $(cat insns.txt); do \
        echo ".quad $i" | \
        as --64 | \
        objdump --disassemble; \
    done'

我的机器花了192毫秒。永远不要以为你知道事情太慢了。

它们是一堆带有垃圾的nop指令。它们的顺序是错误的吗?当以十六进制写入时,最重要的(最后一个)字节是第一个。

答案 1 :(得分:0)

既然你说为每一行分叉一个反汇编程序会太慢,你需要一些方法来分离一个反汇编输出流。

使用诸如xxd -r之类的内容取消对输入进行取消转换,并通过反汇编程序管道输入,并将反汇编程序输出管道输入perl程序或其他内容。或者只是grep-with-context:grep -C8 loopne在找到匹配项时打印8条周围的行。

有助于将输出分离回单独的记录:可能会添加某些未出现在任何行中的标记(如UD2指令)。既然你说序列可能不会在指令边界上结束,那么像90 90 90 90 90 90 90 90 90 0F 0B这样的标记应该安全地吸收任何额外的字节。这是9个字节的NOP,以防一个序列以指令的开头结束,寻找imm32和disp32作为寻址模式的一部分。 (还有第9个NOP用于测量,因为我没有检查0x90表示什么是ModRM或SIB字节)。

如果序列的字节数相同,则可以使用它来查找地址范围。

顺便说一句,我建议像perl这样的东西,可以轻松地将多行作为一组你可以模式匹配。

如果您需要高效,则需要确保将一个反汇编程序流的输出分离回单独的块,否则您需要将反汇编程序嵌入到生成这些行的过程中(和首先不要将它们打印成ASCII字符串。)

没有完全通用的方法来做到这一点也很快。你不能吃蛋糕也不能吃。如果这是一个问题,那么你将不得不让数字生成程序更多地了解x86机器代码。

我能看到的另一个选项是创建一个目标文件,其中的符号标记每个块的开头,但这意味着在将每一行转换为类似的东西后,通过汇编程序将整个内容输入:

label1234: dq 0x11054400000090

这个选项看起来很糟糕,所以我没有尝试解决任何字节顺序问题。 它可能会占用大量内存,因为大多数x86汇编程序都不是单程,并且可能不是为了组装大量数据而设计的,没有需要选择短编码或长编码的跳转指令。