-
-
Save xrombar/d8b5df0de6dab5c5ea01be6946e19d0d to your computer and use it in GitHub Desktop.
Revisions
-
namazso revised this gist
Jun 21, 2025 . 1 changed file with 4 additions and 25 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,35 +15,12 @@ DECLSPEC_NOINLINE void SuperReturn( CONTEXT LocalContext; if (!Context) { FramesToSkip += 1; // skip this frame LocalContext.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; RtlCaptureContext(&LocalContext); Context = &LocalContext; } #if defined(_M_X64) #define CTX_IP(Ctx) (Ctx->Rip) #define CTX_SP(Ctx) (Ctx->Rsp) @@ -52,6 +29,10 @@ DECLSPEC_NOINLINE void SuperReturn( #define CTX_IP(Ctx) (Ctx->Pc) #define CTX_SP(Ctx) (Ctx->Sp) #define CTX_RV(Ctx) (Ctx->X0) #elif defined(_M_IX86) #error Can't possibly work on x86: no way to restore nonvolatile registers. #else #error Unsupported architecture! #endif ULONG64 ControlPc = CTX_IP(Context); @@ -88,7 +69,5 @@ DECLSPEC_NOINLINE void SuperReturn( #undef CTX_SP #undef CTX_RV NtContinue(Context, FALSE); } -
namazso revised this gist
Jun 21, 2025 . 1 changed file with 25 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,12 +15,35 @@ DECLSPEC_NOINLINE void SuperReturn( CONTEXT LocalContext; if (!Context) { // I'm not sure why we don't need this on x86 and don't have the patience to figure it out #if !defined(_M_IX86) FramesToSkip += 1; // skip this frame #endif LocalContext.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; RtlCaptureContext(&LocalContext); Context = &LocalContext; } #if defined(_M_IX86) // Force frame ptr at least in this function so that we can reliably skip ourselves even if /Gy- is not used volatile ULONG_PTR OpaqueSize = sizeof(ULONG_PTR); volatile ULONG_PTR* volatile UselessAlloc = (PULONG_PTR)_alloca(OpaqueSize); *UselessAlloc = (ULONG_PTR)UselessAlloc; PULONG_PTR CurrentEbp = (PULONG_PTR)Context->Ebp; for (ULONG i = 0; i < FramesToSkip; i++) { Context->Esp = (ULONG_PTR)(CurrentEbp + 2); Context->Eip = CurrentEbp[1]; Context->Ebp = CurrentEbp[0]; CurrentEbp = (PULONG_PTR)(Context->Ebp); } Context->Eax = RetVal; #else #if defined(_M_X64) #define CTX_IP(Ctx) (Ctx->Rip) #define CTX_SP(Ctx) (Ctx->Rsp) @@ -65,5 +88,7 @@ DECLSPEC_NOINLINE void SuperReturn( #undef CTX_SP #undef CTX_RV #endif NtContinue(Context, FALSE); } -
namazso revised this gist
Jun 21, 2025 . 1 changed file with 22 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,24 +12,35 @@ DECLSPEC_NOINLINE void SuperReturn( _In_opt_ ULONG_PTR RetVal, _In_opt_ PCONTEXT Context ) { CONTEXT LocalContext; if (!Context) { FramesToSkip += 1; // skip this frame LocalContext.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; RtlCaptureContext(&LocalContext); Context = &LocalContext; } #if defined(_M_X64) #define CTX_IP(Ctx) (Ctx->Rip) #define CTX_SP(Ctx) (Ctx->Rsp) #define CTX_RV(Ctx) (Ctx->Rax) #elif defined(_M_ARM64) #define CTX_IP(Ctx) (Ctx->Pc) #define CTX_SP(Ctx) (Ctx->Sp) #define CTX_RV(Ctx) (Ctx->X0) #endif ULONG64 ControlPc = CTX_IP(Context); for (ULONG i = 0; i < FramesToSkip; i++) { ULONG_PTR ImageBase = 0; PRUNTIME_FUNCTION FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL); if (!FunctionEntry) { // leaf CTX_IP(Context) = *(ULONG64*)CTX_SP(Context); CTX_SP(Context) += sizeof(ULONG64); } else { PVOID HandlerData; ULONG64 EstablisherFrame; @@ -45,10 +56,14 @@ DECLSPEC_NOINLINE void SuperReturn( ); } ControlPc = CTX_IP(Context); } CTX_RV(Context) = RetVal; #undef CTX_IP #undef CTX_SP #undef CTX_RV NtContinue(Context, FALSE); } -
namazso revised this gist
Jun 21, 2025 . 1 changed file with 7 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,8 +9,8 @@ // @param Context Context to start from, in case you want to SuperReturn from somewhere deeper. DECLSPEC_NOINLINE void SuperReturn( _In_ ULONG FramesToSkip, _In_opt_ ULONG_PTR RetVal, _In_opt_ PCONTEXT Context ) { CONTEXT LocalContext; if (!Context) { @@ -20,11 +20,11 @@ DECLSPEC_NOINLINE void SuperReturn( Context = &LocalContext; } ULONG64 ControlPc = Context->Rip; for (ULONG i = 0; i < FramesToSkip; i++) { ULONG_PTR ImageBase = 0; PRUNTIME_FUNCTION FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL); if (!FunctionEntry) { // leaf @@ -41,7 +41,7 @@ DECLSPEC_NOINLINE void SuperReturn( Context, &HandlerData, &EstablisherFrame, NULL ); } @@ -51,4 +51,4 @@ DECLSPEC_NOINLINE void SuperReturn( Context->Rax = RetVal; NtContinue(Context, FALSE); } -
namazso created this gist
Jun 21, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,54 @@ // Return, but across multiple frames. // // This function unwinds the given number of frames, then sets the return value provided, emulating as if this number // of functions returned, with the last one returning the value provided in RetVal. Can be used to hook a callee when // you don't have a convenient way to hook it directly and actually just want to stub it out with a return value. // // @param FramesToSkip The number of frames to skip, starting from the current frame. // @param RetVal The value to return from the last frame. // @param Context Context to start from, in case you want to SuperReturn from somewhere deeper. DECLSPEC_NOINLINE void SuperReturn( _In_ ULONG FramesToSkip, _In_opt_ ULONG_PTR RetVal = 0, _In_opt_ PCONTEXT Context = nullptr ) { CONTEXT LocalContext; if (!Context) { FramesToSkip += 1; // skip this frame LocalContext.ContextFlags = CONTEXT_INTEGER; RtlCaptureContext(&LocalContext); Context = &LocalContext; } auto ControlPc = Context->Rip; for (ULONG i = 0; i < FramesToSkip; i++) { ULONG_PTR ImageBase{}; const auto FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, nullptr); if (!FunctionEntry) { // leaf Context->Rip = *(ULONG64*)Context->Rsp; Context->Rsp += sizeof(ULONG64); } else { PVOID HandlerData; ULONG64 EstablisherFrame; RtlVirtualUnwind( UNW_FLAG_NHANDLER, ImageBase, ControlPc, FunctionEntry, Context, &HandlerData, &EstablisherFrame, nullptr ); } ControlPc = Context->Rip; } Context->Rax = RetVal; NtContinue(Context, FALSE); }