简体   繁体   中英

C++/Assembly pushing arguments onto the stack for function call

i have a special case where i need to push arguments onto the stack one at a time and then call a function which takes a callable as an argument and pass those arguments that were pushed to the stack to the callable/function. to solve this i created a few functions in assembly to push arguments onto the stack and call a function passing those arguments. however it seams to work but my code started breaking in weird places whenever i made calls to other functions inside the callable passed to CallFunction.

i need this function to take any callable. any help would be much appreciated.

please note that std::bind and other similar functions are not an option. each argument needs to be pushed onto the stack one at a time using a function call and i need to be able to call functions between calls to PushArg and CallFunction should return the return value of the function it executes.

What ive tried:

saving the stack pointer at the beginning of the call and restoring it before i return (current state)

creating my own stack in memory for storing arguments (too complex and messy and not as efficient as just using the registers and existing stack. would like to avoid if possible)

Code:

.data
FunctionPointer QWORD 0
ReturnPointer QWORD 0
StackPointer QWORD 0

.code
ALIGN 16

FT_StartCall PROC
    mov [StackPointer],rsp
    ret
FT_StartCall ENDP

FT_PushIntPointer PROC
    pop ReturnPointer
    push rcx
    push ReturnPointer
    ret
FT_PushIntPointer ENDP

FT_CallFunction PROC
    ;save return address in Memory
    pop ReturnPointer
    mov FunctionPointer,rcx
    pop rcx
    pop rdx
    pop r8
    pop r9
    push r9
    push r8
    push rdx
    push rcx
    call FunctionPointer
    mov rcx,0
    mov rdx,0
    mov r8,0
    mov r9,0
    mov rsp, [StackPointer]
    push ReturnPointer
    ret
FT_CallFunction ENDP

END

C++:

extern "C" void* __fastcall FT_CallFunction(void* Function);

extern "C" void __fastcall FT_PushIntPointer(void* ArgOrPointer);

extern "C" void __fastcall FT_StartCall();

int ADD(int first,int second){

return first+second;

}

int main(){

FT_StartCall();

FT_PushIntPointer(3);

FT_PushIntPointer(2);

int res = FT_CallFunction(ADD);

return res;

}

Output:


5

As everyone agrees, you are delving into UB territory with this code, but it does have some experimental value, I guess.

You should consider allocating your own private stack for something a bit more robust.

This bit of code:

pop rcx
pop rdx
pop r8
pop r9
push r9
push r8
push rdx
push rcx

Does nothing, besides scrambling rcd, rdx, r8 and r9. You should remove it.

The same goes for this pîece of code:

mov rcx,0
mov rdx,0
mov r8,0
mov r9,0

Did you try something like this?

FT_CallFunction PROC
    ; save return address in Memory
    pop [ReturnPointer]

    ; call and replace with our own return point.
    call [rcx]

    mov rsp,[StackPointer]

    ; return to caller
    push [ReturnPointer]
    ret
FT_CallFunction ENDP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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