Hello all,
While I'm experimenting with DLLs generated by FreePascal, I made sure that every exported function has its own try..except construct so that no exception escapes from those functions. Instead, in the except part, I do something like that:
on E: TObject do
begin
SetLastExceptionDetails(E);
Result := False;
end;This works fine, but it has a cost both in writing and in execution time. To avoid this, I would like to hook into the raise keyword with my own code so that it does the following pseudo code:
Call SetLastExceptionDetails with the exception object Set the return value to False (asm mov eax, 0 end;) Resume execution at the end of the function located at the frontier between the DLL and the host process.
To achieve this, I thought about using RaiseProc at first, but using ExceptProc seems more promising. At least, I can do the first two steps, but I'm having a hard time doing the last one.
I know I have to walk the stack to find procedure pointers inside it and stop at the first valid one that is outside the DLL, but are there any code examples around for this?
To test for the frontier between DLL and host process, I can use this function:
function GetModuleBaseByAddr(Addr: Pointer): Pointer;
var
Tmm: TMemoryBasicInformation;
begin
if VirtualQuery(addr, @Tmm, SizeOf(Tmm)) SizeOf(Tmm) then
Result := nil
else
Result := Tmm.AllocationBase;
end;in such a test :
if GetModuleBaseByAddr(AddressInStack)
GetModuleBaseByAddr(@someLabelInTheDLL) then
set eax to zero
return to caller of previous address in stack (using leave asm instruction?)
However, I fear this would trash the stack and assume I would have to do some cleanup.
What do you all think about that? Does it sound feasible? Do you have any advices on how best to proceed?
Thanks in advance
OBones.
