Yams
14-Oct-2008, 09:18 AM
Hello.
I have a DLL and a function that called from main app. Main app is build without EL and I have no source code.
DLL is my project, developed in D2007, EL 6.0.17 is enabled.
the func roughly is like that:
var Run: procedure;
procedure gg; stdcall;
begin
try
...
Run; // here: Run = nil => EAccessViolation here.
...
except
on E: Exception do
ShowLastExceptionData;
end;
end;
When I run this stuff EL show me 'unknown error' with 'unknown message'. Expected is 'EAccessViolation' with 'Access violation at ...'.
I have traced this issue to:
procedure Call_HookedRtlUnwind(TargetFrame, TargetIp: Pointer;
ExceptionRecord: PExceptionRecord);
...
begin
...
Obj := OldExceptObjProc(ExceptionRecord);
try
GoNotify(Obj, Addr, False, True); // here Obj saved to LastExceptionObject
finally
Obj.Free; // and now we free it???
end;
...
end;
Here obj = EAccessViolation object, Addr = nil.
GoNotify sets LastExceptionObject with SetLastException.
So Obj will be saved in LastExceptionObject.
When we return from GoNotify object will be freed. But pointer in LastExceptionObject remains untouched and now points to garbage.
When later I call ShowLastExceptionData then IsValidObject inside GetLastExceptionObject detects that LastExceptionObject is real object. It is not true. Well, shit happens :) EL starts to generate error log and eventually revrite area to which LastExceptionObject points. So, when you call IsValidObject in GetExceptionType it returns False, since memory already rewritten. And now we got "unknown error" message.
Sorry, no demo today ;)
I have a DLL and a function that called from main app. Main app is build without EL and I have no source code.
DLL is my project, developed in D2007, EL 6.0.17 is enabled.
the func roughly is like that:
var Run: procedure;
procedure gg; stdcall;
begin
try
...
Run; // here: Run = nil => EAccessViolation here.
...
except
on E: Exception do
ShowLastExceptionData;
end;
end;
When I run this stuff EL show me 'unknown error' with 'unknown message'. Expected is 'EAccessViolation' with 'Access violation at ...'.
I have traced this issue to:
procedure Call_HookedRtlUnwind(TargetFrame, TargetIp: Pointer;
ExceptionRecord: PExceptionRecord);
...
begin
...
Obj := OldExceptObjProc(ExceptionRecord);
try
GoNotify(Obj, Addr, False, True); // here Obj saved to LastExceptionObject
finally
Obj.Free; // and now we free it???
end;
...
end;
Here obj = EAccessViolation object, Addr = nil.
GoNotify sets LastExceptionObject with SetLastException.
So Obj will be saved in LastExceptionObject.
When we return from GoNotify object will be freed. But pointer in LastExceptionObject remains untouched and now points to garbage.
When later I call ShowLastExceptionData then IsValidObject inside GetLastExceptionObject detects that LastExceptionObject is real object. It is not true. Well, shit happens :) EL starts to generate error log and eventually revrite area to which LastExceptionObject points. So, when you call IsValidObject in GetExceptionType it returns False, since memory already rewritten. And now we got "unknown error" message.
Sorry, no demo today ;)