1

所以我正在研究一个代码洞穴,我基本上用我的跳转替换了对 _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 语法:/

4

1 回答 1

1

由于生成的 AT&T 代码对寄存器名称使用百分号,因此当存在以下操作数时,您必须对寄存器名称使用双百分号size

"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 的语法令人难以置信的混乱。:)

于 2011-12-06T00:33:43.793 回答