最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Is it possible to unwind the stack without using trapsinterruptsexceptions on Windows? - Stack Overflow

programmeradmin2浏览0评论

On Windows, is it possible to unwind the stack without using mechanisms like SEH that rely on interrupts?

I know the C standard itself has no concept of stack unwinding, but I'm aware of mechanisms like setjmp/longjmp on POSIX, but I want to do it so that I can unwind a specific number of frames (not including inline functions) without setting the jump point first (via setjmp), while also executing the instructions in the exception record (epilogues for manipulating the stack pointer, register pop instructions).

For example:

__declspec(noinline)  void f1()
{
    //unwind 2 frames
    unwind(2);
}

__declspec(noinline) void f2()
{
    f1();
}

int main()
{
    //the unwind() function will unwind to the beginning of this function, causing an infinite loop
    f2();    
}

On Windows, is it possible to unwind the stack without using mechanisms like SEH that rely on interrupts?

I know the C standard itself has no concept of stack unwinding, but I'm aware of mechanisms like setjmp/longjmp on POSIX, but I want to do it so that I can unwind a specific number of frames (not including inline functions) without setting the jump point first (via setjmp), while also executing the instructions in the exception record (epilogues for manipulating the stack pointer, register pop instructions).

For example:

__declspec(noinline)  void f1()
{
    //unwind 2 frames
    unwind(2);
}

__declspec(noinline) void f2()
{
    f1();
}

int main()
{
    //the unwind() function will unwind to the beginning of this function, causing an infinite loop
    f2();    
}
Share Improve this question edited Mar 19 at 18:53 Remy Lebeau 601k36 gold badges507 silver badges851 bronze badges asked Mar 19 at 11:16 BadasahogBadasahog 8714 silver badges20 bronze badges 20
  • 3 Given your requirements, you have to do it in assembler, not C. – Lundin Commented Mar 19 at 11:39
  • @Lundin I know it's possible because windows has a function called RtlUnwind which appears to do this, but no one seems to know how it works. I asked about this in a previous question – Badasahog Commented Mar 19 at 11:42
  • 2 @Badasahog WINE's not Windows. Either way that function is obviously just a top layer API. – Lundin Commented Mar 19 at 11:49
  • 1 Why can’t you use stump/longjmp? Note that x86-32 does not record unwind information for functions that do not use structured exception handling, so this is unsolvable on x86-32 as written. – Raymond Chen Commented Mar 19 at 19:08
  • 1 @BenVoigt x86-32 allows fpo so you don’t even know where the return address is – Raymond Chen Commented Mar 19 at 21:50
 |  Show 15 more comments

1 Answer 1

Reset to default 0

in case x64 we can use such code:

    CONTEXT ctx;
    RtlCaptureContext(&ctx);
    ULONG_PTR ImageBase;

    while (PRUNTIME_FUNCTION pRT = RtlLookupFunctionEntry(ctx.Rip, &ImageBase, 0))
    {
        PVOID HandlerData = 0;
        ULONG_PTR EstablisherFrame = 0;
        RtlVirtualUnwind(UNW_FLAG_NHANDLER, ImageBase, ctx.Rip, pRT, &ctx, &HandlerData, &EstablisherFrame, 0);

        DbgPrint("0x%p 0x%p\n", ctx.Rip, ctx.Rsp);
        
        if (ctx.Rip != ((ULONG_PTR*)ctx.Rsp)[-1])
        {
            __nop();
        }
    }

but this will be not work for x86. real question - for what this is really need

发布评论

评论列表(0)

  1. 暂无评论