Кто говорил, что 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 — уникальный язык в плане уровня вхождения и возможного уровня освоения. Лично мне очень жаль, что ему почти все.

Кто говорил, что Delphi прост?: 2 комментария

  1. Спасибо огромное за код. а то в нете мело доки про pdword;
    PS: это инлайн патч памяти во время выполнения некоторой процедуры циклически перебирающей данные.
    В каждом шаге производится замена одних байт на другие. Эмм все что выдернул из контекста. Так как это врапер над библиотекой, то скорее всего возвратом идет поток, который патчится на лету ))

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *