shellcode 中 null byte 的成因和避免方式总结

本文探讨了Shellcode编写中遇到的NullByte问题及其成因,包括数值过小和指令自身导致的NullByte。提出了两种解决方案:使用负数替代小数以及更换指令中的寄存器。此外,还提及了call和jmp指令可能产生的NullByte,但未展开详细讨论。总结中强调了在开发Shellcode时避免NullByte的重要性,并提供了实际操作建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

shellcode 中要避免 null byte(\x00)这个是个通用的概念(windows,linux 都是一样),因为栈溢出的数据作为字符串写入到栈上,\x00 会作为字符串终止符,毁掉整个 shellcode。

这就是为什么无论什么类型的栈溢出,无论用到什么技巧,在开发过程中都要千方百计避免 null byte 的出现。当然,还有应用自身的坏字符检测,这个我们以后再讨论,自己写 shellcode 的好处就是能够规避已知的坏字符。在某些特殊情况下,还能节省很多的栈空间(如果栈空间并不大的话,这就是好消息)。

今天我们讨论下 null byte 的成因,以及几个自己写 shellcode 的时候避免 null byte 的小技巧。

Null Byte 成因

开发的过程中,产生 Null Byte 的原因基本上有三个。

写入寄存器的值过小

例如我们需要寻找一个栈上的地址作为 Win32 API 的返回值写入地址,这个地址我们选择在 esp-0x260 的位置上。如果直接在作为减数的寄存器中写入 0x260,就会产生 null byte。

mov eax, esp
mov ecx, x260
sub eax, ecx

在这里插入图片描述

指令本身产生的 Null Byte

例如 mov eax, [eax] 指令,就会产生 null byte。

在这里插入图片描述

说完了两个最基本的成因,我们分享一下避免 null byte 的小技巧。

call 和 jmp 指令产生的 Null Byte

这个部分有机会写到自定义 shellcode 话再深入说。由于汇编也是从上到下执行的,这就涉及到代码逻辑的调整以及 call 指令的地址性质,得花点篇幅好好说。

避免 Null Byte(前两个成因)

解决小数产生的 Null Byte

方法1

针对第一种成因,我们可以选择使用负数的方式来解决。
拿上面的例子来说,我们可以取 0x260 的负数值,得到

fffffda0

在这里插入图片描述

然后使用加法而不是减法,得到相同的结果。

在这里插入图片描述

所有的数值过小的成因,都可以用这种方法解决。

方法2

或者,也可以使用 neg 指令,更加方便。

; 先将 0x260 的负数值写入 ecx,然后取负
mov ecx, 0xfffffda0
neg ecx

可以看到 opcode 里面没有 null byte。

在这里插入图片描述

同时运行起来,寄存器中也是我们想要的值。

在这里插入图片描述

在这里插入图片描述

解决指令本身产生的 Null Byte

针对第二种成因,很简单了,就是换个寄存器 😄

在这里插入图片描述

总结

第一种避免 null byte 的方式其实很简单,开发过程中注意就行,有小数都换成大数加负数或者负数取负即可。

第二种避免 null byte 的方式得结合实际情况,看当时哪个寄存器可用。可以看到除了特定的 mov eax, [eax] 会产生 null byte 外,使用其他寄存器都是安全的。

在这里插入图片描述

call 和 jmp 指令产生的 Null Byte,得从头开始讲了。不随便挖坑,还有坑没填完 😄

KEEP CALM AND HACK AWAY!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值