为了写 UPX dll类型脱壳代码,我参照 yoda AspackDie的代码 写了一个,它的原理大致上就是 hook system exception handler,所有你在代码中设的 INT3 中断,都能拦下,在NT下,这个handler就是NT.DLL中 的 KiUserExceptionDispatcher,通过hook这个函数你就能横扫千军,无人匹敌,但问题也就跟着就来了,虽然我可以准确地拦下代码,但在处理如何hook这个函数上,犯了难 --- 那就是从最后一次中断处返回后,想退出hook,恢复原来的KiUserExceptionDispatcher 函数,但我的程序随之也退出,这说明在退出hook之前的扫尾工作没有做好,让系统认为还是发生了exception,强行中止了程序运行。哪位朋友有这方面的进一步分析或者代码、文章或其他相关内容,先谢了,下面我贴出我改良的yoda代码(delphi),现在就是不能正常退出。
procedure HookExceptionHandlerOnNT; stdcall;
label
OriKUED;
var
ExcepRec: PExceptionRecord;
Context: PContext;
begin
asm
mov eax, [EBP + 8] //struct _CONTEXT*
mov Context, eax
mov eax, [EBP + 4] // struct EXCEPTION_RECORD*
MOV ExcepRec, eax
end;
if ExcepRec.ExceptionCode = EXCEPTION_BREAKPOINT then
begin
// 我在脱壳程序中分别设置了三个断点,都成功拦下,但从第三次返回后,进程被强迫中止,程序退出,问题就出在这里了
case BpCounter of
0: BP_HANLDER_FIRST_DLL(ExcepRec);
1: BP_HANLDER_SECOND_DLL(Context);
2:
begin
BP_HANLDER_THIRD_DLL(Context);
UnhookExceptionHandlerOnNT; // KiUserExceptionDispatcher
end;
end;
//Inc(Context.Eip); //这一句不加程序能正常运行,加了反而不成,为什么yoda的就可以
TNtContinue(_NtContinue)(Context, 0);
Exit;
end;
//正常情况下 下面的代码不应该执行吧?
OriKUED:
UnhookExceptionHandlerOnNT;
asm
// restore stack from procedure HookExceptionHandlerOnNT
pop ecx
pop ecx
pop ebp
// jmp to orignal entrypoint of KiUserExceptionDispatcher
jmp pOrgKiUserExctDisp
end;
end;
// 恢复 KiUserExceptionDispatcher 入口处的原始代码
procedure UnhookExceptionHandlerOnNT;
asm
// restore orginal byte of KiUserExceptionDispatcher
MOV EDI, pOrgKiUserExctDisp
MOV EAX, KUED_Entry1
MOV DWORD PTR [EDI], EAX
MOV EAX, KUED_Entry2
MOV WORD PTR [EDI + 4], AX
RET
end;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)