Доделываем плагин для 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
|