任意の 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 命令を実行できます。
別のオプションは、呼び出す関数のリストを作成し、リストをループして各関数を呼び出すことです。おそらく、これらのような同等の命令を作成するには、さらにトリックが必要になるでしょう。
だから私の質問はこれです:可能なオペコードのすべて(または一部)に対してそのようなことを行うことは可能ですか? おそらく多くの関数を記述する必要がありますが、与えられたアセンブリ命令に基づいて何らかの方法でコードを構築し、それを実行するパーサーを作成することは可能ですか、それとも不可能ですか?
EDIT : メモリ保護を変更したり、実行可能なメモリの場所に書き込んだりすることはできません。