所以我正在编写一个代码洞,我基本上用跳转替换了对_memcpy的调用,然后我想保存源代码中的内容。原装配:
mov [esp+8], edx ; size
mov [esp+4], eax ; ptr to source
mov eax, [ebp+arg_4]
mov [esp], eax ; ptr to destination
call _memcpy
我正在为AT& T的语法挣扎,基本上我想在我自己的变量中存储[esp + 8],[esp + 4]和[esp]。我试着这样做:
void codecave_jump( void ) __attribute__ ( ( signal, naked ) );
void codecave_jump( void ){
void *destination, *source;
size_t size;
// push all registers onto the stack
__asm__("pushal\n\t");
// get size
__asm__ __volatile__(
"movl 8(%ecx), %0\n\t" : "=g" (size)
);
// get source
__asm__ __volatile__(
"movl 4(%ecx), %0\n\t" : "=g" (source)
);
// get destination
__asm__ __volatile__(
"movl %%eax, %0\n\t" : "=g" (destination)
);
// restore all of our registers
__asm__("popal\n\t");
// call memcpy
__asm__("call __memcpy\n\t");
// do the copy
memcpy(destination, source, size);
}
我收到以下错误: 错误:%-letter后缺少操作数 错误:%-letter
后缺少操作数基本上它对我大吼大叫: “movl 8(%ecx),%0 \ n \ t”:“= g”(大小)
有谁知道我应该如何在AT& T语法中正确地做到这一点?我真的很想念OS X上的Intel语法:/
答案 0 :(得分:1)
由于生成的AT& T代码使用百分号作为寄存器名称,因此当存在诸如size
之类的操作数时,您必须use double percent signs作为寄存器名称:
"movl 8(%%ecx), %0\n\t" : "=g" (size)
这与你有时需要printf
的双百分号相似。
似乎你在%%eax
进一步向下,我猜这条线编译得很好。
mov mem32, mem32
没有操作码。您首先需要将数据移动到寄存器,然后将其移动到内存位置(就像英特尔版本对destination
所做的那样)
// get size
__asm__ __volatile__(
"movl 8(%ecx), %eax\n\t"
);
__asm__ __volatile__(
"movl %%eax, %0\n\t" : "=g" (size)
);
为了记录:我还发现AT& T语法令人难以置信的混乱。 :)