Архив метки: Delphi VMT

Кто говорил, что Delphi прост?

Есть хорошая библиотека IrrLicht Я ее использую в рабочем проекте. Кто то добрый написал под нее враппер для Delphi, который прекрасно работает, но ужасно «течет”. Пришлось руками править многое, чтобы убрать утечки. Вот один и примеров кода, с которым пришлось разбираться:

 

procedure PatchVMTbyVMT{_backup}(const vmt, VMCount: DWORD; const bToThisCall: Boolean; const pCustom: Pointer = nil);
const
//  t2s: array[0..3] of Byte = ($58, $51, $50, $E9);
  t2s: array[0..12] of Byte = ({ $CC,} $81, $3C, $24, $00, $00, $00, $10, $72, $03, $58, $51, $50, $E9);
  s2t: array[0..12] of Byte = ({ $CC,} $81, $3C, $24, $00, $00, $00, $10, $73, $03, $58, $59, $50, $E9);
var
  pcode: PDWORD;
  addr:  DWORD;
  vi:    PPointer;
  vp:    DWORD;
  i:     DWORD;
  pwrap: PDWORD;
  wsize: DWORD;
begin
  // unlock vmt
  if VirtualProtect(Pointer(vmt), 4 * VMCount, PAGE_READWRITE, vp) then begin
    // choose wrap
    if bToThisCall then begin
      pwrap := @t2s[0];
      wsize := SizeOf(t2s);
    end else begin
      pwrap := @s2t[0];
      wsize := SizeOf(s2t);
    end;
    // patch
    for i := 0 to VMCount - 1 do begin
      vi := Pointer(vmt + i * 4);
      if not Assigned(vi^) then
        Continue;
      // replace vmt
      if Assigned(pCustom) then
        vi^ := pCustom
      else begin
        // check alredy patched
        if (PDWORD(vi^)^ <> pwrap^) then begin
          // alloc mem for code
          GetMem(pcode, wsize + 4);
          VirtualProtect(pcode, wsize + 4, PAGE_EXECUTE_READWRITE, vp);
          // write wrapper
          CopyMemory(pcode, pwrap, wsize);
          // near jump
          addr := DWORD(pcode) - PDWORD(vi)^ + wsize + 4;
          // insert irr imagebase
          PDWORD(DWORD(pcode) + 3)^ := IRR_IMAGEBASE;
          // write jump to original vmt
          PDWORD(DWORD(pcode) + wsize)^ := -addr;
          // replace vmt
          vi^ := pcode;
        end;
      end;
    end;
  end;
end;

 

Кто разобрался, что код делает – тому печенька =) Потом напишу, как это понял я. В любом случае не стоит говорить, что Delphi для дебилов. Delphi — уникальный язык в плане уровня вхождения и возможного уровня освоения. Лично мне очень жаль, что ему почти все.