Why does a .NET program survive a corrupt stack? (when using the wrong calling convention)

前端 未结 2 677
天命终不由人
天命终不由人 2021-01-17 23:48

In VS2010, the managed debugging assistant will give you a pInvokeStackImbalance exception (pInvokeStackImbalance MDA) if you call a function using the wrong calling convent

2条回答
  •  北荒
    北荒 (楼主)
    2021-01-18 00:33

    It is because of the way the stack pointer is restored when the method exits. The standard prologue of a method, shown for the x86 jitter;

    00000000  push        ebp                 ; save old base pointer
    00000001  mov         ebp,esp             ; setup base pointer to point to activation frame
    00000003  sub         esp,34h             ; reserve space for local variables
    

    And the way it ends:

    0000014a  mov         esp,ebp             ; restore stack pointer
    0000014c  pop         ebp                 ; restore base pointer
    0000014d  ret 
    

    Getting the esp value unbalanced is not a problem here, it gets restored from the ebp register value. However, the jitter optimizer not infrequently optimizes this away when it can store local variables in cpu registers. You'll crash and burn when the RET instruction retrieves the wrong return address from the stack. Hopefully anyway, really nasty when it happens to land on a chunk of machine code by accident.

    This is liable to happen when you run the release build without a debugger, tough to troubleshoot if you didn't have the MDA to help you.

提交回复
热议问题