简体   繁体   English

通话未正确返回[X86_ASM]

[英]Call not returning properly [X86_ASM]

This is C++ using x86 inline assembly [Intel syntax] 这是使用x86内联汇编的C ++ [Intel语法]

Function: 功能:

     DWORD *Call ( size_t lArgs, ... ){

    DWORD *_ret = new DWORD[lArgs];

    __asm {
        xor edx, edx
        xor esi, esi
        xor edi, edi
        inc edx
start:
        cmp edx, lArgs
        je end
        push eax
        push edx
        push esi
        mov esi, 0x04
        imul esi, edx
        mov ecx, esi
        add ecx, _ret
        push ecx
        call dword ptr[ebp+esi] //Doesn't return to the next instruction, returns to the caller of the parent function.
        pop ecx
        mov [ecx], eax
        pop eax
        pop edx
        pop esi
        inc edx
        jmp start
end:
        mov eax, _ret
        ret
    }
}

The purpose of this function is to call multiple functions/addresses without calling them individually. 此功能的目的是调用多个功能/地址,而无需单独调用它们。

Why I'm having you debug it? 为什么我要调试它? I have to start school for the day, and I need to have it done by evening. 我白天必须上学,晚上需要上学。

Thanks alot, iDomo 非常感谢,iDomo

Thank you for a complete compile-able example, it makes solving problems much easier. 感谢您提供一个完整的可编译示例,它使解决问题变得更加容易。

According to your Call function signature, when the stack frame is set up, the lArgs is at ebp+8 , and the pointers start at ebp+C . 根据您的Call函数签名,当设置了堆栈帧时, lArgs位于ebp+8 ,并且指针开始于ebp+C And you have a few other issues. 还有其他一些问题。 Here's a corrected version with some push/pop optimizations and cleanup, tested on MSVC 2010 (16.00.40219.01) : 这是经过修正的版本,具有一些推送/弹出优化和清理功能,已在MSVC 2010(16.00.40219.01)上进行了测试:

DWORD *Call ( size_t lArgs, ... ) {

    DWORD *_ret = new DWORD[lArgs];

    __asm {
        xor edx, edx
        xor esi, esi
        xor edi, edi
        inc edx
        push esi
start:
        cmp edx, lArgs
        ; since you started counting at 1 instead of 0
        ; you need to stop *after* reaching lArgs
        ja end
        push edx
        ; you're trying to call [ebp+0xC+edx*4-4]
        ; a simpler way of expressing that - 4*edx + 8
        ; (4*edx is the same as edx << 2)
        mov esi, edx
        shl esi, 2
        add esi, 0x8
        call dword ptr[ebp+esi]
        ; and here you want to write the return value
        ; (which, btw, your printfs don't produce, so you'll get garbage)
        ; into _ret[edx*4-4] , which equals ret[esi - 0xC]
        add esi, _ret
        sub esi, 0xC
        mov [esi], eax
        pop edx
        inc edx
        jmp start
end:
        pop esi
        mov eax, _ret
        ; ret ; let the compiler clean up, because it created a stack frame and allocated space for the _ret pointer
    }
}

And don't forget to delete[] the memory returned from this function after you're done. 完成后,别忘了delete[]从此函数返回的内存。

I notice that, before calling, you push EAX, EDX, ESI, ECX (in order), but don't pop in the reverse order after returning. 我注意到,在调用之前,您按顺序按了EAX,EDX,ESI,ECX,但返回后不要以相反的顺序弹出。 If the first CALL returns properly, but subsequent ones don't, that could be the issue. 如果第一个CALL正确返回,但随后的CALL没有返回,则可能是问题所在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM