Linux 带限制的外壳代码
对于任务,我需要创建简单的外壳代码,但不允许它包含\x80 注意:要在linux上进行系统调用(如写入或退出),除其他外,您需要以下行:Linux 带限制的外壳代码,linux,assembly,nasm,system-calls,shellcode,Linux,Assembly,Nasm,System Calls,Shellcode,对于任务,我需要创建简单的外壳代码,但不允许它包含\x80 注意:要在linux上进行系统调用(如写入或退出),除其他外,您需要以下行:int0x80,这最终将生成包含\x80的外壳代码 然而,我需要进行系统调用,所以我现在的想法是使用一个变量作为中断向量数。例如0x40,然后将其与2相乘,因此最终外壳代码中会出现\x40而不是\x80 问题是int没有将变量作为参数,我尝试了以下测试: section .data nr db 0x80 section .text global _star
int0x80
,这最终将生成包含\x80的外壳代码
然而,我需要进行系统调用,所以我现在的想法是使用一个变量作为中断向量数。例如0x40,然后将其与2相乘,因此最终外壳代码中会出现\x40而不是\x80
问题是int没有将变量作为参数,我尝试了以下测试:
section .data
nr db 0x80
section .text
global _start
_start:
xor eax, eax
inc eax
xor ebx, ebx
mov ebx, 0x1
int [nr]
得到
错误:操作码和操作数的组合无效
我怎样才能让我的想法发挥作用?或者您对该问题有不同的解决方案吗?
PS.sysenter和syscall不工作->指令非法
我在x86-32位机器上使用nasm。可能是这样的,但千万不要在严肃的代码中使用它
format ELF executable
use32
entry start
segment executable writeable
start:
;<some code>
inc byte [ here + 1 ] ;<or some other math>
jmp here
here:
int 0x7f
segment readable writeable
格式化ELF可执行文件
用法32
入门
段可执行可写
开始:
;
inc字节[此处为+1];
这里是jmp
在这里:
int 0x7f
段可读写
(这是fasm代码)允许自修改代码吗?
int
不接受内存操作数。只是即时值。我只是好奇,但在正常情况下,值为0x00的shell代码会带来问题。好奇什么样的设计考虑使0x80成为一个问题?作为Ross Ridge提到的扩展,您可以在32位Linux上通过[gs:10H]附近的调用来实现。这是通过gs:0x10地址的间接跳转,该地址通常是VDSO系统调用蹦床地址。是否有可能将整条指令(如int 0x80)推送到堆栈中,并从堆栈中执行该指令?不是这样吗?int 0x80究竟是如何执行的?它会被推到堆栈中吗?谢谢你的回答,但我不知道这将如何调用int 0x80?1。一些代码计算值0x80并将其写入al,2。mov在int
之后写入此值,因为它是一个2字节的操作码:0xCD 0x80,3。最后执行。啊,现在我明白了,谢谢!我用nasm试过你的代码,我得到程序接收信号SIGSEGV,分段错误。
在这一行mov byte[here+1],al
。但是为什么呢?解决方法是什么?@Krupuk您的.text
部分可能无法写入。此外,在代码修改和修改后的代码之间还需要jmp指令(例如jmp here`)。这让CPU知道代码已被修改,它应该丢弃任何缓存的副本。@PeterCordes英特尔保证,无论中间有跳转或串行化指令,自修改的代码都能工作。请参阅《英特尔64和IA-32体系结构软件开发人员手册》,第3卷,8.1.3处理自修改和交叉修改代码