gpt4 book ai didi

c - 仅使用现有代码执行任意代码

转载 作者:太空宇宙 更新时间:2023-11-04 06:33:09 25 4
gpt4 key购买 nike

假设我想执行任意一条 mov 指令。我可以编写以下函数(使用 GCC 内联汇编):

void mov_value_to_eax()
{
asm volatile("movl %0, %%eax"::"m"(function_parameter):"%eax");
// will move the value of the variable function_parameter to register eax
}

而且我可以制作像这样的函数,它适用于所有可能的寄存器。我的意思是 -

void movl_value_to_ebx() { asm volatile("movl %0, %%ebx"::"m"(function_parameter):"%ebx"); }
void movl_value_to_ecx() { asm volatile("movl %0, %%ecx"::"m"(function_parameter):"%ecx"); }
...

以类似的方式,我可以编写函数,将任意地址的内存移动到特定的寄存器,并将特定的寄存器移动到内存中的任意地址。 (mov eax, [memory_address]mov [memory_address],eax)

现在,我可以随时执行这些基本指令,因此我可以创建其他指令。例如,将一个寄存器移动到另一个寄存器:

function_parameter = 0x028FC;
mov_eax_to_memory(); // parameter is a pointer to some temporary memory address
mov_memory_to_ebx(); // same parameter

所以我可以解析汇编指令并根据它决定使用什么函数,就像这样:

if (sourceRegister == ECX) mov_ecx_to_memory();
if (sourceRegister == EAX) mov_eax_to_memory();
...
if (destRegister == EBX) mov_memory_to_ebx();
if (destRegister == EDX) mov_memory_to_edx();
...

如果它可以工作,它允许你执行任意的 mov 指令。

另一种选择是制作一个要调用的函数列表,然后遍历列表并调用每个函数。也许需要更多的技巧来制作像这样的等效指令。

所以我的问题是:是否可以为所有(或部分)可能的操作码制作这样的东西?它可能需要编写很多函数,但是是否有可能制作一个解析器,它将根据给定的汇编指令以某种方式构建代码,然后执行它,或者这是不可能的?

编辑:您不能更改内存保护或写入可执行内存位置。

最佳答案

我真的不清楚你为什么要问这个问题。首先,这个函数...

void mov_value_to_eax()
{
asm volatile("movl %0, %%eax"::"m"(function_parameter):"%eax");
// will move the value of the variable function_parameter to register eax
}

...使用 GCC 内联汇编,但函数本身不是内联的,这意味着会有序言和尾声代码包装它,这可能会影响您的预期结果。您可能想要使用 GCC 内联汇编函数(而不是包含 GCC 内联汇编的函数),这可能会让您更接近您想要的结果,但仍然存在问题......

好的,假设您为每个可能的 x86 操作码(至少是 GCC 汇编器知道的操作码)编写一个 GCC 内联汇编函数。现在假设你想以任意顺序调用这些函数来完成你可能希望完成的任何事情(考虑到哪些操作码在第 3 环(或你正在编码的任何环)执行是合法的)。您的示例显示您使用 C 语句对逻辑进行编码以确定是否调用内联汇编函数。你猜怎么着:那些 C 语句使用处理器寄存器(甚至可能是 EAX!)来完成它们的任务。无论您想通过调用这些任意内联汇编函数来做什么,都会被编译器发出的逻辑汇编代码(if (...) 等)踩踏。反之亦然:您的内联汇编函数任意指令正在踩踏编译器发出的指令期望不会被踩踏的寄存器。结果不太可能在不崩溃的情况下运行。

如果你想用汇编写代码,我建议你简单地用汇编写,然后使用 GCC 汇编器来汇编它。或者,您可以在 asm() 语句中编写整个 C 语言可调用的汇编函数,并根据需要从您的 C 代码中调用它们。但是您编写的 C 语言可调用汇编函数需要在您使用的调用约定 (ABI) 的规则范围内运行:如果您的汇编函数使用一个被调用者保存的寄存器,您的函数将需要在该寄存器中保存原始值(一般在栈上),然后在返回给调用者之前恢复它。

关于c - 仅使用现有代码执行任意代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18320080/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com