I'm a new assembly programmer and I wonder if there is a way to completely clean the stack (from all the function parameters and the function pointer ) thanks in advance
emu8086 emulates real mode. There is no security; all code runs with full privileges to take over the whole machine. You have to trust your caller; your caller could have disassembled the machine code of your function and even modified it before calling.
But sure you can overwrite your args on the stack before returning. In most calling conventions, the stack args are "owned" by the callee so they can use them as local vars anyway.
However, no, it's impossible to jump somewhere without leaving the target address in memory or a register. pop cx
/ zero return address / jmp cx
would let you emulate ret
after overwriting the return address in memory, but then it would be in a register.
I guess maybe you could set TF
(the single-step mode trap flag) in FLAGS and use a debug interrupt handler to do something (like zero a return address) before disabling TF again. But the debug exception frame pushes the CS:IP which includes that return address, and returning from the debug exception with iret
will
But keep in mind: a return address is not valuable info. The code you're returning to could already find its own address with call +0
; pop ax
just calling one of its own functions.
On modern x86, there are ways to make protected enclaves. For example, SGX is designed for that, and SMM (System Management Mode) is also "outside" even a kernel.
Or in protected mode, you might have calls between different privilege domains. Usually user-space calling into a kernel. You avoid info leaks there by having the kernel use a separate private kernel stack. Necessary for security in a multi-threaded system, otherwise another user-space thread modifies stack memory while the kernel is using it, taking control of a kernel return address.
To avoid info leaks on a system call; preserve all registers except ones that contain return value(s) or get zeroed. That way you can't leave any kernel temporary data in registers. And since you aren't using the user-space stack at all, that's not a problem.