-1

我想在 32 位 Linux 上为内核模式编写 shellcode,它将执行此操作:

commit_creds (prepare_kernel_cred(0));

所以我创建了一个文件:

xor eax, eax
call 0x1234567
call 0x1234568
ret

其中 0x1234567 是 prepare_kernel_cred 的地址,0x1234568 是 commit_creds 的地址,两者都是从 /proc/kallsyms 中找到的。

我用 nasm -f elf 和 objdump -d 组装它以获得机器码。

我得到类似的东西:

31 c0               which is xor eax, eax
e8 7c 67 06 c1      which is call prepare_kernel_cred
e8 7c 65 06 c1      which is call commit_creds
c3                  which is ret

这行不通。但是,使用e8 79代替e8 7ce8 74代替第二个e8 7c,有效。我不记得我从哪里得到第二个机器代码(我把它放在不同的文件中),但我很好奇为什么这会起作用,而不是像那样简单地组装它会起作用。

这是什么类型的CALL?为什么像上面显示的那样简单地组装代码不起作用?e8 79如果我将and用于 CALL,我的玩具漏洞利用可以很好地解决我的人工内核错误e8 74,但是当我使用来自 nasm/objdump 的组装机器代码时会失败。

4

2 回答 2

1

以 E8h 开头的 CALL 变体是对由相对于当前指令的位移指定的地址的近调用。这解释了为什么不同指令的值需要不同。不过,我不知道你是如何让 nasm 发出该代码的。你确定这不是家庭作业?

于 2013-02-19T05:17:01.580 回答
0

我发现我之前使用过以下命令来编译它:

gcc -m32 -Ttext=0 -nostdlib

这给了我与以前相同的结果。我还收到一条警告,它默认从 0x0 开始。

但是为什么 nasm 不重现这个呢?我检查了 objdump,两个文件中的起始地址似乎都是 0x0。

于 2013-02-19T16:35:51.627 回答