Delphi 5-使用RTLUnwind捕获所有异常

Delphi 5-使用RTLUnwind捕获所有异常,delphi,exception,delphi-5,Delphi,Exception,Delphi 5,我今天在这里是因为我在使用Delphi5和RTLUnwind捕捉程序的每个异常时遇到了一些麻烦 问题是它捕捉到一个错误,但它在。。。 当我尝试调试时,会出现访问冲突 以下是我的全部捕获代码: unit ExceptLog; interface implementation uses SysUtils, Windows, U_Test, Dialogs; type PCardinal = ^Cardinal; PtrUInt = cardinal; PPtrUInt = ^Pt

我今天在这里是因为我在使用Delphi5和RTLUnwind捕捉程序的每个异常时遇到了一些麻烦

问题是它捕捉到一个错误,但它在。。。 当我尝试调试时,会出现访问冲突

以下是我的全部捕获代码:

unit ExceptLog;

interface

implementation

uses SysUtils, Windows, U_Test, Dialogs;

type
  PCardinal = ^Cardinal;
  PtrUInt = cardinal;
  PPtrUInt = ^PtrUInt;
  PExceptionRecord = ^TExceptionRecord;
  TExceptionRecord =
  record
    ExceptionCode : LongWord;
    ExceptionFlags : LongWord;
    OuterException : PExceptionRecord;
    ExceptionAddress : Pointer;
    NumberParameters : Longint;
    case {IsOsException:} Boolean of
    True : (ExceptionInformation : array [0..14] of Longint);
    False : (ExceptAddr: Pointer; ExceptObject: Pointer);
  end;

var
  // Declaration for Delphi 5
  oldRTLUnwindProc: procedure; stdcall;
  RTLUnWindProc: pointer;

procedure MyRtlUnwind; stdcall;
var
  s : string;
  PER : PExceptionRecord;
  E: Exception;
begin
  asm
    mov eax, dword ptr [EBP+8+13*4]
    mov PER, eax
  end;

  if PER^.ExceptionFlags and 1=1 then
  begin
    try
      E := Exception(PER^.ExceptObject);
      if (E is Exception) then
      begin
        s:= 'Delphi exception, type : ' + E.ClassName + ', message: ' +     E.Message;
        OutputDebugString(PChar(s));

        _MessageDlg(s, mtInformation, [mbOk], 0);
      end;
    except
    end;
  end;

  asm
    mov esp, ebp
    pop ebp
    jmp oldRTLUnwindProc  // here come the access violation
  end;
end;

{--------------------------------------------------------------------------------------------------}

procedure PatchCodePtrUInt(Code: PPtrUInt; Value: PtrUInt);
var RestoreProtection, Ignore: DWORD;
begin
  if VirtualProtect(Code, SizeOf(Code^), PAGE_EXECUTE_READWRITE,     RestoreProtection) then
  begin
    Code^ := Value;
    VirtualProtect(Code, SizeOf(Code^), RestoreProtection, Ignore);
    FlushInstructionCache(GetCurrentProcess, Code, SizeOf(Code^));
  end;
end;

{--------------------------------------------------------------------------------------------------}

procedure Patch(P: PAnsiChar);
var
  i: Integer;
  addr: PAnsiChar;
begin
  for i:= 0 to 31 do
  begin
    if (PCardinal(P)^ = $6850006a) and (PWord(P+8)^ = $E852) then
    begin
      inc(P, 10);
      if PInteger(P)^<0 then
      begin
        addr := P+4+PInteger(P)^;
        if PWord(addr)^=$25FF then
        begin
          PatchCodePtrUInt(Pointer(addr+2),cardinal(@RTLUnwindProc));
          exit;
        end;
      end;
    end else
      inc(P);
  end;
end;

{--------------------------------------------------------------------------------------------------}

procedure PatchCallRtlUnWind;
asm
  mov eax,offset System.@HandleAnyException+200
  call Patch
end;

{--------------------------------------------------------------------------------------------------}

procedure InitExceptionLogging;
begin
  oldRTLUnWindProc := RTLUnwindProc;
  RTLUnwindProc := @MyRtlUnwind;
  PatchCallRtlUnWind;
end;

{--------------------------------------------------------------------------------------------------}

initialization
  InitExceptionLogging;
end.
unitexceptlog;
接口
实施
使用SysUtils、Windows、U_测试、对话框;
类型
PCardinal=^基数;
PtrUInt=基数;
PPtrUInt=^PtrUInt;
PExceptionRecord=^TExceptionRecord;
TExceptionRecord=
记录
例外代码:长单词;
例外标志:长单词;
OuterException:PExceptionRecord;
例外地址:指针;
数字参数:Longint;
案例{IsOsException:}的布尔值
True:(例外信息:Longint的数组[0..14];
False:(ExceptAddress:指针;ExceptObject:指针);
结束;
变量
//Delphi 5的声明
oldRTLUnwindProc:程序;stdcall;
RTLUnWindProc:指针;
桃金娘风;stdcall;
变量
s:字符串;
PER:PEExceptionRecord;
E:例外;
开始
asm
mov eax,dword ptr[EBP+8+13*4]
每分钟移动量
结束;
如果PER^.ExceptionFlags和1=1,则
开始
尝试
E:=异常(每个异常对象);
如果(E是例外),那么
开始
s:='Delphi异常,类型:'+E.ClassName+',消息:'+E.message;
OutputDebugString(PChar(s));
_MessageDlg(s,mtInformation,[mbOk],0);
结束;
除了
结束;
结束;
asm
电除尘器
流行ebp
jmp oldRTLUnwindProc//访问冲突来了
结束;
结束;
{--------------------------------------------------------------------------------------------------}
过程PATCHCODEPTRAINT(代码:PPtrUInt;值:ptraint);
var恢复保护,忽略:DWORD;
开始
如果是VirtualProtect(代码,SizeOf(代码^),PAGE\u EXECUTE\u READWRITE,RestoreProtection),那么
开始
代码^:=值;
虚拟保护(代码,SizeOf(代码^),恢复保护,忽略);
FlushInstructionCache(GetCurrentProcess,Code,SizeOf(Code^));
结束;
结束;
{--------------------------------------------------------------------------------------------------}
程序补片(P:PAnsiChar);
变量
i:整数;
地址:潘斯卡尔;
开始
对于i:=0到31 do
开始
如果(PCardinal(P)^=6850006a美元)和(PWord(P+8)^=E852美元),则
开始
公司(第10页);

如果PInteger(P)^更容易使用MadeExceptMadeExcept似乎很有趣,但对我来说有点太大了,如果我选择这样做,那就是限制第三方程序或大型实现。但如果我找不到任何回应,Madeexcept可能是一个解决方案。ThanksIt完全不需要花时间添加它,它被证明是有效的,它具有难以置信的能力,它的堆栈跟踪非常出色。你根本不可能想出任何有用的东西。这不是指个人。我知道除了疯狂,我不能做任何事情。不管怎样,祝你好运。你不是Delphi5的专家,你自己写的代码吗?我会听从大卫的建议,把它换成疯子。我并不惊讶你用一些魔法常数修补地址而得到AV。看起来它是从《幻影》中的莫莫特(mORMot)搬来的,@Lieven。原始代码更复杂;也许乔亚过于简单化了,不小心删除了一些重要的东西。Joja,原始代码编译和运行是否正确?在这附近可以看到那个图书馆的作者。MadeExceptMadeExcept看起来很有趣,但对我来说有点太大了,如果我选择这样做,那就是限制第三方程序或大型实现。但如果我找不到任何回应,Madeexcept可能是一个解决方案。ThanksIt完全不需要花时间添加它,它被证明是有效的,它具有难以置信的能力,它的堆栈跟踪非常出色。你根本不可能想出任何有用的东西。这不是指个人。我知道除了疯狂,我不能做任何事情。不管怎样,祝你好运。你不是Delphi5的专家,你自己写的代码吗?我会听从大卫的建议,把它换成疯子。我并不惊讶你用一些魔法常数修补地址而得到AV。看起来它是从《幻影》中的莫莫特(mORMot)搬来的,@Lieven。原始代码更复杂;也许乔亚过于简单化了,不小心删除了一些重要的东西。Joja,原始代码编译和运行是否正确?在这附近可以看到那个图书馆的作者。他也许能帮忙。