Writing data to Delphi TStringGrid from an external application

I have an outdated application written in Delphi, and you need to create a mechanism for

  • reading and
  • record

from / to TStringGrid.

I do not have the source code of the application, there is no automation interface, and it is very unlikely that the supplier will provide it.

Therefore I created

  • C ++ dll that introduces
  • Delphi dll (written by me) in
  • The address space of the legacy application.

DLL 2 accesses the TStringGrid instance inside the legacy application, reads the cell values ​​and writes them to the debug log.

Reading works great. But when I try to write data to a grid cell using a call like

realGrid.Cells[1,1] := 'Test'; 

Access violation occurs.

Here is the code:

 procedure DllMain(reason: integer) ; type PForm = ^TForm; PClass = ^TClass; PStringGrid = ^TStringGrid; var [...] begin if reason = DLL_PROCESS_ATTACH then begin handle := FindWindow('TForm1', 'FORMSSSSS'); formPtr := PForm(GetVCLObjectAddr(handle) + 4); if (not Assigned(formPtr)) then begin OutputDebugString(PChar('Not assigned')); Exit; end; form := formPtr^; // Find the grid component and assign it to variable realGrid [...] // Iterate over all cells of the grid and write their values into the debug log for I := 0 to realGrid.RowCount - 1 do begin for J := 0 to realGrid.ColCount - 1 do begin OutputDebugString(PChar('Grid[' + IntToStr(I) + '][' + IntToStr(J) + ']=' + realGrid.Cells[J,I])); // This works fine end; end; // Now we'll try to write data into the grid realGrid.Cells[1,1] := 'Test'; // Crash - access violation end; end; (*DllMain*) 

How can I write data to TStringGrid without getting an access violation problem?

+4
source share
2 answers

This approach just won't work. There are two VCL instances in the target executable. One of them belongs to the target application, and the other belongs to the DLL. This one instance of VCL is too much. You may be able to avoid this if the exact same version of Delphi is used to create the target application and your DLL.

However, there are still two heap managers in the game. And your code passes a bunch of allocated memory between your different VCL instances. You will select one heap and release it in another. This does not work and will result in access violations.

You pass the string allocated in the DLL heap to the mesh object that uses the heap of the target application. It just can't work.

I think that access violation will occur at the moment when the DLL code tries to free the previous value Cells[i,j] , which was assigned by the heap manager of the target application.

Basically, what you are trying will not work. You can find out the implementation address of the target application TStringGrid.SetCell and fake a call. But you also need to find the target implementation of the GetMem application, FreeMem , etc. And make sure that all the dynamic memory that went from your DLL to the target application has been allocated and freed by the target heap of the target application. You will have the devil of work doing this work. Of course, if both the target application and the DLL use the shared memory manager, then you can just do this approach.

It would be much easier to fake keyboard input. I will personally consider using AutoHotKey.

+1
source

Everything related to using the heap is at a very serious risk. You can try Jedi CodeLib to combine object trees and provide the same heap in EXE and DLL, but that would be an extremely fragile solution.

Reliability of VMT calls is more or less safe and paranoid tries to prevent the compiler from freeing the line, the sketch will be like this:

 type TSGCracker = class(Grids.TStringGrid); // access to protected functions. .... var s: string; function dummy(s: string); // not-inline! pretend we need and use the value! begin Result := s + '2'; end; begin ... s := 'Test'; TSGCracker(realGrid).SetEditText(1,1, s); dummy( s+'1'); ... end; 

But this can cause TStringGrid.OnSetEditText if the EXE host uses it.

+1
source

Source: https://habr.com/ru/post/1434549/


All Articles