Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Доделываем плагин для Import REconstructor 1.3

Автор: EGOiST
WEB сайт: http://www.ego1st.cjb.net/

Как говорил Hex : бывают 2 типа джимпов : относительный и прямой. При прямом джампе (jmp xxxxxxxx) xxxxxxxx = адресу, на который ссылается джамп. При относительном джампе xxxxxxxx = адрес, на который ссылается джамп - текущий адрес байта - 5(длина джампа). Так вот. Плагин от Hex'а не находил ф-ии вида :


push ebp
mov xxx,xxx
push xxx
...
jmp xxxxxxxx

Плагин не находил ф-ию, потому что к xxxxxxxx прибавлялся g_pointer, а не текущий адрес байта - это первая ошибка.. Еще у ASProtect'a есть емуляция вызовов типа :


push ebp
push BFFxxxxx
push xxx
push BFFxxxxx
...
push xxxxxxxx
ret

Тут тоже плагин попадал на первый push BFFxxxxx и выдавал это в результат (нужно добавить проверку на ret) - это вторая ошибка.. Я это все поправил и привожу исходник :


{ASProtect plugin for Import REConstructor v1.3.
It helps to reconstruct import table of executables
protected by ASProtect 1.xx.
This plugin tested on ASProtect 1.2(asprotect.exe),
ASPack 2.11d(aspack.exe), Undisker 1.1(undisker.exe).
EGOiST[TSRh].[www.ego1st.cjb.net]}

library ASProtect12x;
uses
  windows;

var
  g_temp: array[0..MAX_PATH] of char;
  g_ftmp: array[0..MAX_PATH] of char;
  g_ftmp2: array[0..MAX_PATH] of char;
  g_time_out: DWORD;
  g_pointer: DWORD;

function Trace(param: DWORD): DWORD; cdecl;
var
  i: DWORD;
  hFile: DWORD;
  BytesRead: DWORD;
  to_trace: array[0..128] of BYTE;
  val: DWORD;
  BytesWritten: DWORD;
  adr: DWORD;
begin
  lstrcpy(g_ftmp, g_temp);
  lstrcat(g_ftmp, '\');
  i := lstrlen(g_ftmp);
  movememory(addr(g_ftmp[i]), addr(param), 4);
  g_ftmp[i + 4] := chr(0);
  lstrcpy(g_ftmp2, g_ftmp);
  lstrcat(g_ftmp, '.tmp');
  lstrcat(g_ftmp2, '_.tmp');

  hFile := CreateFile(g_ftmp, GENERIC_READ, 0, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if (hFile = INVALID_HANDLE_VALUE) then
  begin
    Trace := 201;
    exit;
  end;

  if not ReadFile(hFile, g_time_out, 4, BytesRead, nil)
    or (BytesRead <> 4) then
  begin
    CloseHandle(hFile);
    Trace := 203;
    exit;
  end;

  if not ReadFile(hFile, g_pointer, 4, BytesRead, nil)
    or (BytesRead <> 4) then
  begin
    CloseHandle(hFile);
    Trace := 203;
    exit;
  end;
  CloseHandle(hFile);

  if (IsBadReadPtr(pointer(g_pointer), 4)) then
  begin
    Trace := 205;
    exit;
  end;

  movememory(addr(to_trace), pointer(g_pointer), 129);
  for i := 0 to 128 do
  begin
    if (to_trace[i] = $E9) or (to_trace[i] = $68) then
    begin
      if (to_trace[i] = $68) and (to_trace[i + 5] <> $C3) then
        continue;
      val := to_trace[i + 4] shl 24 + to_trace[i + 3] shl 16 +
        to_trace[i + 2] shl 8 + to_trace[i + 1];
      if val < $400000 then
        continue;
      asm
mov adr, eax
      end;
      if IsBadReadPtr(pointer(val), 4) then
        val := val + adr + 5
      else
        val := val;
      break;
    end;
  end;

  if (IsBadReadPtr(pointer(val), 4)) then
  begin
    Trace := 205;
    exit;
  end;

  hFile := CreateFile(g_ftmp2, GENERIC_WRITE, 0,
    nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  if (hFile = INVALID_HANDLE_VALUE) then
  begin
    Trace := 207;
    exit;
  end;

  if (not WriteFile(hFile, val, 4, BytesWritten, nil)) then
  begin
    CloseHandle(hFile);
    Trace := 209;
    exit;
  end;
  CloseHandle(hFile);

  Trace := 200;
end;

exports Trace;

begin
  GetTempPath(MAX_PATH, g_temp);
end.

В массиве to_trace ищется байт E9h или 68h. Если нашли E9h, т.е. jmp, читаются 4 байта после E9h (в обратном порядке) и это выдается в результат. Если же нашли 68h, то дальше сравнивается 5 байт после 68h с С3h(ret). Если равно, то читаем 4 байта после 68h. Если нет, то продолжаем поиск...вот и все.

Все вопросы в мыло...
e-mail : egoist_tsrh@rbcmail.ru

writer : EGOiST[TSRh]
coder : EGOiST[TSRh]
web : http://www.ego1st.cjb.net/
: http://kickme.to/tsrh
e-mail : egoist_tsrh@rbcmail.ru
: tsrh@mail.ru

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay