编译汇编程序以扁平状二进制包括外来“F”字符不以其它格式

问题描述:

我正在用汇编程序存在:编译汇编程序以扁平状二进制包括外来“F”字符不以其它格式

xor eax, eax  ; make eax equal to 0 
push eax   ; pushes null 
push 0x68732f2f  ; pushes /sh (//) 
push 0x6e69622f  ; pushes /bin 
mov ebx, esp  ; passes the first argument 
push eax   ; empty third argument 
mov edx, esp  ; passes the third argument 
push eax   ; empty second argument 
mov ecx, esp  ; passes the second argument 
mov al, 11   ; execve system call #11 
int 0x80   ; makes an interrupt 

当使用nasm为平坦编译-form二进制文件,我在程序的十六进制表示中看到无关的f字符。我期待看到:

0000000: 31c0 5068 2f2f 7368 682f 6269 6e89 e350 1.Ph//shh/bin..P         
0000010: 89e2 5089 e1b0 0bcd 80     ..P...... 

但真正看到:

0000000: 6631 c066 5066 682f 2f73 6866 682f 6269 f1.fPfh//shfh/bi 
0000010: 6e66 89e3 6650 6689 e266 5066 89e1 b00b nf..fPf..fPf.... 
0000020: cd80          .. 

奇怪的是,当我尝试以其他格式,如ELF-32使用nasm编译我的程序,我看到了十六进制表示我我希望(尽管许多其他十六进制的我也许不应该在我的解决方案包括):

0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............ 
0000010: 0100 0300 0100 0000 0000 0000 0000 0000 ................ 
0000020: 4000 0000 0000 0000 3400 0000 0000 2800 @.......4.....(. 
0000030: 0500 0200 0000 0000 0000 0000 0000 0000 ................ 
0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000060: 0000 0000 0000 0000 0100 0000 0100 0000 ................ 
0000070: 0600 0000 0000 0000 1001 0000 1900 0000 ................ 
0000080: 0000 0000 0000 0000 1000 0000 0000 0000 ................ 
0000090: 0700 0000 0300 0000 0000 0000 0000 0000 ................ 
00000a0: 3001 0000 2100 0000 0000 0000 0000 0000 0...!........... 
00000b0: 0100 0000 0000 0000 1100 0000 0200 0000 ................ 
00000c0: 0000 0000 0000 0000 6001 0000 3000 0000 ........`...0... 
00000d0: 0400 0000 0300 0000 0400 0000 1000 0000 ................ 
00000e0: 1900 0000 0300 0000 0000 0000 0000 0000 ................ 
00000f0: 9001 0000 1000 0000 0000 0000 0000 0000 ................ 
0000100: 0100 0000 0000 0000 0000 0000 0000 0000 ................ 
0000110: 31c0 5068 2f2f 7368 682f 6269 6e89 e350 1.Ph//shh/bin..P 
0000120: 89e2 5089 e1b0 0bcd 8000 0000 0000 0000 ..P............. 
0000130: 002e 7465 7874 002e 7368 7374 7274 6162 ..text..shstrtab 
0000140: 002e 7379 6d74 6162 002e 7374 7274 6162 ..symtab..strtab 
0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000170: 0100 0000 0000 0000 0000 0000 0400 f1ff ................ 
0000180: 0000 0000 0000 0000 0000 0000 0300 0100 ................ 
0000190: 0073 6865 6c6c 7370 6177 6e2e 6173 6d00 .shellspawn.asm. 

对于什么,我试图完成,我想我必须使用一台形式的二进制文件。

我的问题:这是什么f字符来自什么,它是什么意思;我如何删除它?

NASM version 2.10.09 compiled on Dec 29 2013

xxd V1.10 27oct98 by Juergen Weigert

+0

如果您只是想将指针传递给NULL作为第二个和第三个参数,为什么不让它们都指向第一个'push eax'结果(这也是字符串终止符)?即xor-zero/push /'mov edx,esp' /'mov ecx,esp'。另外,[man page](http://man7.org/linux/man-pages/man2/execve.2.html)说你实际上可以传递一个argv = NULL和envp = NULL(但是警告它不是可移植的并不依赖于它)。所以你可以只用'edx,edx' /'push edx'/... /'mov ecx,edx' /'lea eax,[edx + 11]'。 –

nasm -f bin一个更深入的答案设置默认模式为16位。在该模式下,32位操作数大小指令(如xor eax,eaxpush eax)必须用0x66操作数大小前缀进行编码。有关操作数大小和地址大小的模式与前缀的对比见this table。 (f0x66,以ASCII)。另请参阅标记wiki中的x86手册链接。另请参阅how to disassemble flat binaries,采用16,32或64位模式。

-f elf-felf32的同义词,所以其定位的32位模式。 -felf64靶向64位模式下(其中push eax不是encodeable)。

请参阅NASM手册中的section 6.1BITS 32告知汇编程序汇编程序为32位模式,根据输出文件格式覆盖缺省值。 IDK,如果有一个命令行选项可以生成32位代码的平面二进制文件。我在手册页或--help中看不到一个。如果由于某种原因,您确实不想更改源代码,则可以使用-felf并使用ld --oformat binary链接平面二进制文件。见How to generate plain binaries like nasm -f bin with the GNU GAS assembler?

啊,文档意味着BITS 32是唯一的方法:

使用BITS指令最可能的原因是在一个平面的二进制文件中写入32位或64位代码;你的实际代码


代码审查:

如果你只是想指针传递给NULL作为第二和第三指定参数时,为什么不能让他们都指向第一push eax结果(这也是字符串结束符)?即xor-zero/push/mov edx, esp/mov ecx, esp

此外,the man page说,你其实可以传递一个的argv = NULL和envp = NULL(但警告说,这并不便携,不依赖于它)。所以你可以只需要xor edx,edx/push edx/.../mov ecx,edx/lea eax, [edx+11]

+0

我用'BITS 32'去了,现在hex代表我想要的方式。谢谢! – jakenberg

我前言本有,我不是100%肯定这一点,但...

This website,它是一个操作数大小覆盖前缀。我要去猜测,汇编正在加倍小心,或者是设置为32位汇编输出,这是剩下的有趣的尝试,并确保您xormov指令是正确的尺寸。它似乎实际上不会影响运行时,如果该网站是正确的,所以也许只是额外的窗饰。

我会仔细检查传入NASM标志,以确保你不小心告诉它做的比预期的举动。

或者希望从铁道部近86 ASM编码器:)

+0

感谢您对Michael的帮助。我的nasm用法如下:'nasm shellspawn.asm'。我试过比这更具体,但我得到了相同的结果。我会继续研究这条大道 – jakenberg

+1

这不是一个“额外谨慎”的问题。在32位代码中,0x66操作数大小意味着16位操作数大小,所以您必须正确地获取模式。但是,是的,@jakenberg'-fbin'的默认值是16位模式。您可以使用“BITS 32”指令。我不确定是否有NASM选项将模式设置为32位,同时仍然制作平面二进制文件。 –

+0

谢谢彼得。我在'.asm'文件的顶部放置了'BITS 32',我不再看到大小操作数前缀。从你们两个人那里学到了一些东西! – jakenberg