Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2003.02.06;
Скачать: [xml.tar.bz2];

Вниз

Внедрение   Найти похожие ветки 

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2003.02.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.01 c
3-15452
Valeris
2003-01-17 19:36
2003.02.06
Что не так?


3-15490
SergeySh
2003-01-20 12:51
2003.02.06
Маленький опрос: Кто чем пользуется для доступа к MS SQL


3-15520
Ihtiandr
2003-01-21 12:08
2003.02.06
UpdateSQL


4-15989
Alpine
2002-12-22 15:45
2003.02.06
Как с помощью ShellExecute можно раскрыть медиа плейер на весь эк


6-15811
kalishenko stas
2002-12-11 17:54
2003.02.06
Проверка почты





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский