Текущий архив: 2003.02.06;
Скачать: CL | DM;
ВнизВнедрение Найти похожие ветки
← →
alex134 (2002-12-18 15:38) [0]Каким образом проще и надежнее внедрять библиотеку в чужое адресное пространство (win9x) ?
← →
Ihor Osov'yak (2002-12-18 15:47) [1]hook
← →
alex134 (2002-12-18 15:55) [2]После 1-го выполнения callback-функции в чужом АП образ моей библиотеки будет висеть там до тех пор хук не сниму ?
← →
Игорь Шевченко (2002-12-18 16:11) [3]Да
← →
paul_shmakov (2002-12-18 16:13) [4]2 alex134:
при первом выполнении callback-функции нужно вызвать из нее LoadLibrary и загрузить ту dll, которую нужно. а хук потом можно и снять.
а лучше внедрять с помощью CreateRemoteThread. то, что в win9x этой функции якобы нет, легко решается с помощью:
RT by EliCZ ( http://www.anticracking.sk/EliCZ/export/RT.ZIP)
или madRemote by Madshi ( http://help.madshi.net)
← →
alex134 (2002-12-18 16:34) [5]2 paul_shmakov ;
а ЧТО этот код делает? Я так понял показывается пример юзания функции xCreateRemoteThread из RT.dll, заменяющей CreateRemoteThread под 9x?
← →
alex134 (2002-12-18 18:44) [6]Используя замечание paul_shmakov, получилось внедрить свою библиотеку методом удаленных потоков под 98-ой. Деятельность моя направлена, конечно, на перехват вызовов API-функций. Рихтер пишет, что оптимальный метод перехвата API-вызовов - использовать раздел импорта. Так как я в этих делах "не очень", интересует Ваше мнение:
будет ли работать схема перехвата через таблицу импорта, если библиотека подключается динамически?
← →
paul_shmakov (2002-12-18 20:39) [7]это не "оптимальный" метод, а самый простой.
"будет ли работать схема перехвата через таблицу импорта, если библиотека подключается динамически?"
для того, чтобы работала, нужно перехватывать еще и LoadLibrary, и для каждой загружаемой dll править таблицу импорта.
← →
alex134 (2002-12-18 22:03) [8]Выяснил, что программа, которую я "ограничиваю", подключает библиотеки статически (проблема отпала). Но... у этой проги есть своя библиотека “x.dll”, в которой и вызывается "запретная функция". Как быть? Я так понимаю, мне надо работать с таблицей импорта библиотеки “X.dll”?
← →
Ihor Osov'yak (2002-12-18 23:31) [9]Что-то типа этого :
function FinalFunctionAddress(Code: Pointer): Pointer;
Var func: PImportCode;
begin
Result:=Code;
if Code=nil then exit;
try
func:=code;
if (func.JumpInstruction=$25FF) then begin
Result:=func.AddressOfPointerToFunction^;
end;
except
Result:=nil;
end;
end;
Function PatchAddress(OldFunc, NewFunc: Pointer): Integer;
Var BeenDone: TList;
Function PatchAddressInModule(hModule: THandle;
OldFunc, NewFunc:Pointer): Integer;
Var
Dos: PImageDosHeader;
NT: PImageNTHeaders;
ImportDesc: PImage_Import_Entry; rva: DWORD;
Func: PPointer; DLL: String;
f: Pointer;
written: DWORD;
i:integer;
begin
Result:=0;
Dos:=Pointer(hModule);
if BeenDone.IndexOf(Dos)>=0 then begin
dec(level);
exit;
end;
BeenDone.Add(Dos);
OldFunc:=FinalFunctionAddress(OldFunc);
if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then begin
dec(level);
exit;
end;
if Dos.e_magic<>IMAGE_DOS_SIGNATURE then begin
dec(level);
exit;
end;
NT :=Pointer(Integer(Dos) + dos._lfanew);
RVA:=NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if RVA=0 then exit;
ImportDesc := pointer(integer(Dos)+RVA);
While (ImportDesc^.Name<>0) do begin
DLL:=PChar(Integer(Dos)+ImportDesc^.Name);
PatchAddressInModule(GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);
Func:=Pointer(Integer(DOS)+ImportDesc.LookupTable);
While Func^<>nil do begin
f:=FinalFunctionAddress(Func^);
if f=OldFunc then begin
WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written);
If Written>0 then begin
Inc(Result);
end
else begin
end
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
dec(level);
end;
begin //PatchAddress
result := 0;
if NewFunc = nil then exit;
if OldFunc = nil then exit;
if NewFunc=OldFunc then exit;
BeenDone:=TList.Create;
try
Result:=PatchAddressInModule(GetModuleHandle(nil),OldFunc,NewFunc);
finally
BeenDone.Free;
end;
end; //PatchAddress
← →
alex134 (2002-12-19 00:15) [10]Спасибо за код, но
Можно код полностью или его источник ? Тут моменты не совсем понятны :(
1) Что делает FinalFunctionAddress ?
2) Тип PImportCode не определен (может модуль какой-то дополнительный надо ?)
← →
Ihor Osov'yak (2002-12-19 00:33) [11]unit PEStuff;
interface
uses Windows;
type
PImageDosHeader = ^TImageDosHeader;
_IMAGE_DOS_HEADER = packed record { DOS .EXE header }
e_magic: Word; { Magic umber }
e_cblp: Word; { Bytes on last page of file }
e_cp: Word; { Pages in file }
e_crlc: Word; { Relocations }
e_cparhdr: Word; { Size of header in paragraphs }
e_minalloc: Word; { Minimum extra paragraphs needed }
e_maxalloc: Word; { Maximum extra paragraphs needed }
e_ss: Word; { Initial (relative) SS value }
e_sp: Word; { Initial SP value }
e_csum: Word; { Checksum }
e_ip: Word; { Initial IP value }
e_cs: Word; { Initial (relative) CS value }
e_lfarlc: Word; { File address of relocation table }
e_ovno: Word; { Overlay number }
e_res: array [0..3] of Word; { Reserved words }
e_oemid: Word; { OEM identifier (for e_oeminfo) }
e_oeminfo: Word; { OEM information; e_oemid specific}
e_res2: array [0..9] of Word; { Reserved words }
_lfanew: LongInt; { File address of new exe header }
end;
TImageDosHeader = _IMAGE_DOS_HEADER;
PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;
IMAGE_FILE_HEADER = packed record
Machine : WORD;
NumberOfSections : WORD;
TimeDateStamp : DWORD;
PointerToSymbolTable : DWORD;
NumberOfSymbols : DWORD;
SizeOfOptionalHeader : WORD;
Characteristics : WORD;
end;
PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
IMAGE_DATA_DIRECTORY = packed record
VirtualAddress : DWORD;
Size : DWORD;
end;
PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
IMAGE_SECTION_HEADER = packed record
Name : packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of
Char;
VirtualSize : DWORD; // or VirtualSize (union);
VirtualAddress : DWORD;
SizeOfRawData : DWORD;
PointerToRawData : DWORD;
PointerToRelocations : DWORD;
PointerToLinenumbers : DWORD;
NumberOfRelocations : WORD;
NumberOfLinenumbers : WORD;
Characteristics : DWORD;
end;
PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;
IMAGE_OPTIONAL_HEADER = packed record
{ Standard fields. }
Magic : WORD;
MajorLinkerVersion : Byte;
MinorLinkerVersion : Byte;
SizeOfCode : DWORD;
SizeOfInitializedData : DWORD;
SizeOfUninitializedData : DWORD;
AddressOfEntryPoint : DWORD;
BaseOfCode : DWORD;
BaseOfData : DWORD;
{ NT additional fields. }
ImageBase : DWORD;
SectionAlignment : DWORD;
FileAlignment : DWORD;
MajorOperatingSystemVersion : WORD;
MinorOperatingSystemVersion : WORD;
MajorImageVersion : WORD;
MinorImageVersion : WORD;
MajorSubsystemVersion : WORD;
MinorSubsystemVersion : WORD;
Reserved1 : DWORD;
SizeOfImage : DWORD;
SizeOfHeaders : DWORD;
CheckSum : DWORD;
Subsystem : WORD;
DllCharacteristics : WORD;
SizeOfStackReserve : DWORD;
SizeOfStackCommit : DWORD;
SizeOfHeapReserve : DWORD;
SizeOfHeapCommit : DWORD;
LoaderFlags : DWORD;
NumberOfRvaAndSizes : DWORD;
DataDirectory : packed array
[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY;
Sections: packed array [0..9999] of IMAGE_SECTION_HEADER;
end;
прод. следует
← →
Ihor Osov'yak (2002-12-19 00:35) [12]продолжение
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
IMAGE_NT_HEADERS = packed record
Signature : DWORD;
FileHeader : IMAGE_FILE_HEADER;
OptionalHeader : IMAGE_OPTIONAL_HEADER;
end;
PImageNtHeaders = PIMAGE_NT_HEADERS;
TImageNtHeaders = IMAGE_NT_HEADERS;
PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
IMAGE_IMPORT_BY_NAME = record
Hint: Word;
Name: Array[0..0] of Char;
end;
PIMAGE_THUNK_DATA = ^IMAGE_THUNK_DATA;
IMAGE_THUNK_DATA = record
Whatever: DWORD;
end;
PImage_Import_Entry = ^Image_Import_Entry;
Image_Import_Entry = record
Characteristics: DWORD;
TimeDateStamp: DWORD;
MajorVersion: Word;
MinorVersion: Word;
Name: DWORD;
LookupTable: DWORD;
end;
const
IMAGE_DOS_SIGNATURE = $5A4D; // MZ
IMAGE_OS2_SIGNATURE = $454E; // NE
IMAGE_OS2_SIGNATURE_LE = $454C; // LE
IMAGE_VXD_SIGNATURE = $454C; // LE
IMAGE_NT_SIGNATURE = $00004550; // PE00
implementation
end.
← →
Ihor Osov'yak (2002-12-19 00:41) [13]> Что делает FinalFunctionAddress ?
в доп.
PPointer = ^Pointer;
TImportCode = packed record
JumpInstruction: Word; // should be $25FF
AddressOfPointerToFunction: PPointer;
end;
PImportCode = ^TImportCode;
Некоторые компиляторы вместо call генерят jmp на call..
Зы - а всего кода модуля патчинга низя... Обет неразглашения на год...
на unit PEStuff такого нет...
← →
alex134 (2002-12-19 09:23) [14]В функции PatchAddressInModule используется переменная level. Где она описана, задано начальное значение и какой ее тип? А так вроде все работает (по крайней мере, ошибок не выдает).
← →
alex134 (2002-12-19 17:56) [15]up
← →
Troll (2002-12-19 22:13) [16]down
← →
Ihor Osov'yak (2002-12-20 00:39) [17]Использовал при отладке. Уровень глубины рекурс. вхождения...
inc вырезал, dec - недосмотрел :-). А сама она глобальная статическая.. И нафиг (кроме отладочных целей) нужна...
В оригинале -
begin
inc(level);
Result:=0;
Dos:=Pointer(hModule);
С Вас кава (хорошая)...
PS кава = coffee
← →
alex134 (2002-12-20 08:51) [18]
> С Вас кава (хорошая)...
> PS кава = coffee
Давайте e-mail (у Вас в анкете не нашел его)
← →
Ihor Osov'yak (2002-12-20 10:39) [19]ihoro2002@yahoo.com
Неужто кава на мыло пойдет :-)
← →
Troll (2002-12-20 15:59) [20]1
← →
alex134 (2002-12-20 23:40) [21]Как я уже говорил, программа, которую я "ограничиваю", подключает ДИНАМИЧЕСКИ свою библиотеку “x.dll”, в которой и вызывается "запретная функция" shAppBarMessage.
Прога загружает библиотеки через функцию LoadLibraryA. Теперь я подменяю эту ф-ии на свою:
function h_LoadLibraryA(lpLibFileName: PAnsiChar): HMODULE; stdcall;
begin
LogStr("Загружена "+lpLibFileName); // ф-ия, которая ведет лог
Result:=???;
end;
Вот код из библиотеки, делающей патч:
OldA:=GetProcAddress(GetModuleHandle("KERNEL32.dll"), "LoadLibraryA");
if PatchAddress(OldA, @h_LoadLibraryA)=0 then
begin
LogStr("can""t patch address!");
ExitProcess(0);
end
Думаю, мне надо воспользоваться "OldA". Как это сделать ?
← →
alex134 (2002-12-21 16:35) [22]
^
up/|\
|
← →
alex134 (2002-12-22 00:27) [23]Короче, сделал так:
function h_LoadLibraryA(lpLibFileName: PChar): HMODULE; stdcall; {Ansi}
var
f : function (lpLibFileName1: PChar): HMODULE; stdcall;
begin
@f:=OldAddr;
result:=f(lpLibFileName);
LogStr(lpLibFileName+" called faked! "+"result="+IntToStr(result)+" addr="+inttostr(longword(OldAddr)));
end;
ГДЕЕЕ тут ошибка? Какого хрена "программа выполнила недопустимую операцию и будет закрыта" !!! Причем это сообщение возникает 4 раза, каждый раз я нажимаю "закрыть", а в итоге оно запускается и нормально работает. LogStr не при делах - пробовал, убирал ее. Где ???????? Нашла коса на камень :(
← →
alex134 (2002-12-23 00:08) [24]Тут нет ошибки. Она в другом ...
2 Ihor Osov"yak :
Можно вриант с level (со всеми инкрементами и декрементами) ?. Думаю, просто не надо выходить на второй уровень при отлове LoadLibraryA.
← →
Ihor Osov'yak (2002-12-23 01:26) [25]Как есть, с рабочего проекта ... level нипричем, он рудиментный, как и sb - это осколки отладочного вывода в лог, не полностью удаленные...
var level:integer;
Function PatchAddress(OldFunc, NewFunc: Pointer): Integer;
Var BeenDone: TList;
Function PatchAddressInModule(hModule: THandle;
OldFunc, NewFunc:Pointer): Integer;
Var
Dos: PImageDosHeader;
NT: PImageNTHeaders;
ImportDesc: PImage_Import_Entry; rva: DWORD;
Func: PPointer; DLL: String;
f: Pointer;
written: DWORD;
sb:string;
i:integer;
begin
inc(level);
sb:=" ";
for i:=1 to level*3 do sb:=sb+" ";
Result:=0;
Dos:=Pointer(hModule);
if BeenDone.IndexOf(Dos)>=0 then begin
dec(level);
exit;
end;
BeenDone.Add(Dos);
OldFunc:=FinalFunctionAddress(OldFunc);
if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then begin
dec(level);
exit;
end;
if Dos.e_magic<>IMAGE_DOS_SIGNATURE then begin
dec(level);
exit;
end;
NT :=Pointer(Integer(Dos) + dos._lfanew);
RVA:=NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if RVA=0 then exit;
ImportDesc := pointer(integer(Dos)+RVA);
While (ImportDesc^.Name<>0) do begin
DLL:=PChar(Integer(Dos)+ImportDesc^.Name);
PatchAddressInModule(GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);
Func:=Pointer(Integer(DOS)+ImportDesc.LookupTable);
While Func^<>nil do begin
f:=FinalFunctionAddress(Func^);
if f=OldFunc then begin
WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written);
If Written>0 then begin
Inc(Result);
end
else begin
end
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
dec(level);
end;
begin //PatchAddress
result := 0;
if NewFunc = nil then exit;
if OldFunc = nil then exit;
if NewFunc=OldFunc then exit;
BeenDone:=TList.Create;
try
Result:=PatchAddressInModule(GetModuleHandle(nil),OldFunc,NewFunc);
finally
BeenDone.Free;
end;
end; //PatchAddress
Страницы: 1 вся ветка
Текущий архив: 2003.02.06;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.011 c