Доделываем плагин для Import REconstructor 1.3

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: 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

{/codecitation}

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