我有这段代码
__asm
{
mov eax, fs:[18h]
mov eax, [eax + 30h]
mov eax, [eax + 0Ch]
mov pmInfo, eax
}
这应该在第一行中检索TEB,在第二行中检索PEB,最后一行是包含过程模块信息的结构。
typedef struct _ProcessModuleInfo
{
unsigned int size;
unsigned int initialized;
HANDLE SsHandle;
LIST_ENTRY LoadOrder;
LIST_ENTRY InitOrder;
LIST_ENTRY MemoryOrder;
} ProcessModuleInfo, *pProcessModuleInfo;
我的问题是,如何将这个程序集转换为codeblocks的GCC编译器?我真的很无能为力......
答案 0 :(得分:2)
您可以在 GCC 文档中了解有关GCC assembler templates的更多信息。如果您想了解更多信息,Peter Cordes有一个Stackoverflow答案,其中包含inline assembler列表。 MSVC 和 GCC 差别很大。 GCC 不知道模板的作用或指令的执行情况。 GCC 取而代之的是基于constraints - 输入,输出和clobber的列表进行替换。
GCC 扩展汇编程序模板,它与 MSVC 内联汇编程序非常接近,可能如下所示:
__asm__ (
"mov %%fs:0x18, %0\n\t"
"mov 0x30(%0), %0\n\t"
"mov 0x0C(%0), %0\n\t"
: "=r"(pmInfo));
在您的情况下,您需要一个寄存器用于内部使用。它不需要是 EAX ,但可以是 GCC 可用的任何寄存器。我们使用"=r"
的输出约束,表示我们希望 GCC 选择一个可用的寄存器。我们通过汇编程序模板中的%0
引用第一个(在这种情况下是唯一的)约束。关于约束的"=r"(pmInfo)
表示当模板中的指令完成时,所选寄存器中的值将被放入pmInfo
。
GCC 扩展汇编程序是一个棘手的工作,很容易出错。使用返回指向ProcessModuleInfo结构的指针的函数创建汇编程序文件可能会更好。这样就无需理解 GCC 的扩展汇编程序模板,并处理其错综复杂的模板。
Stackoverflow用户DavidWohlferd写了GCC wiki article,说明为什么使用 GCC 内联汇编程序应该避免如果可能。
如果%0
看起来有点令人困惑,可以为每个输入和输出操作数指定一个符号名称,而不是%
和模板中的数字。代码看起来像这样:
__asm__ (
"mov %%fs:0x18, %[tempreg]\n\t"
"mov 0x30(%[tempreg]), %[tempreg]\n\t"
"mov 0x0C(%[tempreg]), %[tempreg]\n\t"
: [tempreg]"=r"(pmInfo));
方括号中的[tempreg]
为操作数提供了一个名称,作为使用序数位置的替代方法。这样也可以更容易地阅读模板。