![](/img/trans.png)
[英]How can I call this x86 ASM CALL in C++ with typedef or inline
[英]Call not returning properly [X86_ASM]
这是使用x86内联汇编的C ++ [Intel语法]
功能:
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
}
}
此功能的目的是调用多个功能/地址,而无需单独调用它们。
为什么我要调试它? 我白天必须上学,晚上需要上学。
非常感谢,iDomo
感谢您提供一个完整的可编译示例,它使解决问题变得更加容易。
根据您的Call
函数签名,当设置了堆栈帧时, lArgs
位于ebp+8
,并且指针开始于ebp+C
还有其他一些问题。 这是经过修正的版本,具有一些推送/弹出优化和清理功能,已在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
}
}
完成后,别忘了delete[]
从此函数返回的内存。
我注意到,在调用之前,您按顺序按了EAX,EDX,ESI,ECX,但返回后不要以相反的顺序弹出。 如果第一个CALL正确返回,但随后的CALL没有返回,则可能是问题所在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.