Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

VirtualProtect [D7]


Страницы:   1 2

Rem ©   (2004-10-07 12:27:00) 

Добрый день, мастера! Начну с главного, мне необходимо перехватить winapi'шную функцию CreateFile из одной другой проги, послать эту же функцию, но с другими параметрами из своей, получить результат и вернуть его той другой проге. Я знаю, что надо использовать функцию VirtualProtect, но я не знаю как, в MSDN практически ниче не описано по этому поводу, помогите мне плз решить эту проблему.


Digitman   (2004-10-08 15:17:00) [21]


> у меня не получается


мы догадываться должны, что у тебя там "не получается" ? у тебя языка нет детально описать проблему ?


Rem   (2004-10-08 14:46:00) [22]

Продолжение предыдущего...

var InterceptDllCall : function(hLocalModule: HModule; c_szDllName: Pchar; c_szApiName: PChar;
                         pApiNew: Pointer; p_pApiOrg: PPointer; pApiToChange: Pointer): Boolean;

type TMyProc= function (lpFileName: PAnsiChar; dwDesiredAccess : Cardinal; dwShareMode : Cardinal;
                       lpSecurityAttributes : PSecurityAttributes; dwCreationDisposition : Cardinal;
                       dwFlagsAndAttributes : Cardinal; hTemplateFile : Cardinal): THandle; stdcall;
    PTMyProc=^TMyProc;

var OldCreateProc : PTMyProc=nil;

function MapRuleCreateFile(lpFileName: PAnsiChar; dwDesiredAccess : Cardinal; dwShareMode : Cardinal;
                          lpSecurityAttributes : PSecurityAttributes; dwCreationDisposition : Cardinal;
                          dwFlagsAndAttributes : Cardinal; hTemplateFile : Cardinal): THandle; stdcall;
begin
 Result:=CreatFile(PAnsiChar('c:\TMP.tmp'),1,2,nil,2,4,0);
end;

procedure Start;
begin
   CreateFile(PAnsiChar('c:\Before.TMP'),1,2,nil,2,4,0);
   InterceptDllCall(hInstance,'Kernel32.dll','CreateFileA', Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
   {Здесь через интерфейс вызываем функцию из дллки, в которой (дллке) должна вызываться функция CreateFile, но ничего не работает}
   
end;


Rem   (2004-10-08 14:39:00) [23]

Помогите плз, у меня не получается, вот код

type
 PImageDosHeader = ^TImageDosHeader;
 _IMAGE_DOS_HEADER = packed record
   e_magic: Word;
   e_cblp: Word;
   e_cp: Word;
   e_crlc: Word;
   e_cparhdr: Word;
   e_minalloc: Word;
   e_maxalloc: Word;
   e_ss: Word;
   e_sp: Word;
   e_csum: Word;
   e_ip: Word;
   e_cs: Word;
   e_lfarlc: Word;
   e_ovno: Word;
   e_res: array[0..3] of Word;
   e_oemid: Word;
   e_oeminfo: Word;
   e_res2: array[0..9] of Word;
   e_lfanew: LongInt;
 end;
 TImageDosHeader = _IMAGE_DOS_HEADER;
 IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;

 //***************************************
 PImageDataDirectory = ^TImageDataDirectory;
 _IMAGE_DATA_DIRECTORY = record
   VirtualAddress: DWORD;
   Size: DWORD;
 end;
 //
 TImageDataDirectory = _IMAGE_DATA_DIRECTORY;
 IMAGE_DATA_DIRECTORY = _IMAGE_DATA_DIRECTORY;
 //

 //*************
 PImageOptionalHeader = ^TImageOptionalHeader;
 _IMAGE_OPTIONAL_HEADER = packed record
   Magic: Word;
   MajorLinkerVersion: Byte;
   MinorLinkerVersion: Byte;
   SizeOfCode: DWORD;
   SizeOfInitializedData: DWORD;
   SizeOfUninitializedData: DWORD;
   AddressOfEntryPoint: DWORD;
   BaseOfCode: DWORD;
   BaseOfData: DWORD;
   ImageBase: DWORD;
   SectionAlignment: DWORD;
   FileAlignment: DWORD;
   MajorOperatingSystemVersion: Word;
   MinorOperatingSystemVersion: Word;
   MajorImageVersion: Word;
   MinorImageVersion: Word;
   MajorSubsystemVersion: Word;
   MinorSubsystemVersion: Word;
   Win32VersionValue: 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 TImageDataDirectory;
 end;
 TImageOptionalHeader = _IMAGE_OPTIONAL_HEADER;
 IMAGE_OPTIONAL_HEADER = _IMAGE_OPTIONAL_HEADER;

 PImageNtHeaders = ^TImageNtHeaders;
 _IMAGE_NT_HEADERS = packed record
   Signature: DWORD;
   FileHeader: TImageFileHeader;
   OptionalHeader: TImageOptionalHeader;
 end;
 TImageNtHeaders = _IMAGE_NT_HEADERS;
 IMAGE_NT_HEADERS = _IMAGE_NT_HEADERS;

 PImage_import_by_name = ^TImage_import_by_mame;
 _IMAGE_IMPORT_BY_NAME = packed record
   Hint: Word;
   Name: Byte;
 end;
 TImage_import_by_mame = _IMAGE_IMPORT_BY_NAME;

 _u1 = packed record
   case Integer of
     0: (ForwarderString: PByte);
     1: (Functionn: PDWORD);
     2: (Ordinal: DWORD);
     3: (AddressOfData: PImage_import_by_name);
 end;
 PImageThunkData = ^TImageThunkData;
 _IMAGE_THUNK_DATA = packed record
   u1: _u1;
 end;
 TImageThunkData = _IMAGE_THUNK_DATA;
 IMAGE_THUNK_DATA = _IMAGE_THUNK_DATA;
 _temp_charcteristics = record
   case Integer of
     0: (Characteristics: DWORD);
     1: (OriginalFirstThunk: PImageThunkData);
 end;

 PImageImportDescriptor = ^TImageImportDescriptor;
 _IMAGE_IMPORT_DESCRIPTOR = packed record

   t: _temp_charcteristics;
   TimeDateStamp: DWord;
   ForwarderChain: DWORD;
   Name: DWORD;
   FirstThunk: PImageThunkData;
 end;
 TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
 IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
 PPointer = ^Pointer;

function MakePtr(base: Dword; Offset: DWORD): Pointer;
begin
 Result := Pointer(Base + Offset);
end;

function InterceptDllCall(hLocalModule: HModule; c_szDllName: Pchar; c_szApiName: PChar;
                         pApiNew: Pointer; p_pApiOrg: PPointer; pApiToChange: Pointer): Boolean;
var
 pDosHeader: PImageDosHeader;
 pNtHeader: PImageNtHeaders;
 PImportDesc: PImageImportDescriptor;
 dwProtect: DWORD;
 dwNewProtect: DWORD;
 dwAddressToInterCept: DWORD;
 pThunk: PImageThunkData;
begin
 pDosHeader := PImageDosHeader(hLocalModule);
 Result := False;
 if (pApiToChange <> nil) then dwAddressToIntercept := DWORD(pApiToChange)
                          else dwAddressToIntercept := Dword(GetProcAddress(GetModuleHandle(c_szDllName), c_szApiName));
 if IsBadReadPtr(Pointer(hLocalModule), sizeof(PImageNtHeaders)) then Exit;
 if pDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then exit;
 pNtHeader := PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader.e_lfanew)));
 if pNTHeader.signature <> IMAGE_NT_SIGNATURE then exit;
 pImportDesc := PImageImportDescriptor(MakePtr(hLocalModule,pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Virtual Address));
 if (PImportDesc = PImageImportDescriptor(pNtHeader)) then exit;
 while (pImportDesc.Name > 0) do
   begin
     pThunk := PImageThunkData(MakePtr(DWord(hLocalModule), Dword(pImportDesc.FirstThunk)));
     while (pThunk.u1.Functionn <> nil) do
       begin
         if DWord(pThunk.u1.Functionn) = dwAddressToIntercept then
           begin
             if not IsBadWritePtr(Pointer(@pThunk.u1.Functionn), sizeof(DWORD)) then
               begin
                 if (p_pApiOrg <> nil) then p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
                 pThunk.u1.Functionn := pApiNew;
                 Result := True;
               end                                                              else
               begin
                 if VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),PAGE_EXECUTE_READWRITE, @dwProtect) then
                   begin
                     if (p_pApiOrg <> nil) then p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
                     pThunk.u1.Functionn := PDWORD(pApiNew);
                     Result := True;
                     dwNewProtect := dwProtect;
                     VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),dwNewProtect, @dwProtect);
                   end;
               end;
           end;
         Inc(PThunk);
       end;
     Inc(pImportDEsc);
   end;
end;


Digitman   (2004-10-08 13:24:00) [24]


> это актив искина


"актив искина" - это по сути обычная ДЛЛ .. а ДЛЛ грузится и исполняется в АП затребовавшего ее (тем или иным образом - неважно) процесса


Rem   (2004-10-08 13:04:00) [25]

Ага, спасибо, тут вообщем немного поменялась ситуация. Вообщем все сложно, есть дллка - это актив искина, в этой дллке есть класс, в нем объявлен метод, этот метод вызывает функцию CreateFile со своими параметрами, мне надо перехватить вызов этой функции, вызвать эту же функцию, но со своими параметрами. Как это можно сделать, в каком процессе загружена эта дллка? Вобщем решение такое, что я узнаю процесс, этот процесс загружает мою дллку, которая перехватывает вызов функции CreateFile. Основная проблема определить в каком процессе выполняется дллка-актив иксина. Я думал, что в explorer'e, внедрил туда свой код, кот. перехватывает вызов, но ничего не получилось. Может это так, тогда (если это так) подскажите мне где у меня ошибка.


Rem   (2004-10-08 13:00:00) [26]

Ага, спасибо, тут вообщем немного поменялась ситуация. Вообщем все сложно, есть дллка - это актив искина, в этой дллке есть класс, в нем объявлен метод, этот метод вызывает функцию CreateFile со своими параметрами, мне надо перехватить вызов этой функции, вызвать эту же функцию, но со своими параметрами. Как это можно сделать, в каком процессе загружена эта дллка? Вобщем решение такое, что я узнаю процесс, этот процесс загружает мою дллку, которая перехватывает вызов функции CreateFile. Основная проблема определить в каком процессе выполняется дллка-актив иксина. Я думал, что в explorer'e, внедрил туда свой код, кот. перехватывает вызов, но ничего не получилось. Может это так, тогда (если это так) подскажите мне где у меня ошибка.


Digitman   (2004-10-08 08:11:00) [27]


> Rem   (07.10.04 16:53) [7]


если GUI , то можно воспользоваться механизмом установки глоб.хука

в общем же случае (для НТ-систем) - внедрение в АП процесса своей ДЛЛ вызовом CreateRemoteThread

как только внедренная тем или иным методом библиотека получит управление (в ходе ее иниц-ции), в этот момен как раз и можно осуществить перехват, например, модификацией EAT и IAT


kaZaNoVa   (2004-10-07 22:25:00) [28]

http://www.delphimaster.ru/cgi-bin/forum.pl?id=1093466109&n=5
там есть ВСЁ - спасибо Digitman'у !!!


kaZaNoVa   (2004-10-07 22:22:00) [29]

Digitman ©   (07.10.04 12:55) [2]

> "послать" - это ассоциируется с тремя веселыми буквами
> ...

CAD  ?


Rem   (2004-10-07 16:57:00) [30]

Вообщем, я нашел один примерчик http://delphiworld.narod.ru/base/catch_dll_functions_calling.html, только вместо вызова MessageBoxA, я пишу CreateFileA, библиотеку kernel32.dll, ну и TMyProc с MyMessageBox'ом изменяю так, как нужно. Пробовал, но что-то не получается.


Rem   (2004-10-07 16:53:00) [31]

да, это GUI приложение


Digitman   (2004-10-07 16:32:00) [32]


> Rem


теперь понятно.

процесс А - это процесс GUI-приложения ?


Игорь Шевченко   (2004-10-07 14:26:00) [33]


> CreateFile возвращает Handle на созданный файл, я этот Handle,
> должен передать порцессу А.


Не получится.


Rem   (2004-10-07 13:17:00) [34]

Окей, задача такая, из одного процесса (назовем его А) вызывается функция CreateFile с определенными параметрами. Мой процесс (процесс В), должен перехватить вызов этой функции, проверить параметры, и если в параметрах функции, вызванной процессом А, имя файла совпадает с моим именем фала, используемой в моем приложении, то процесс В вызывает функцию CreateFile с теми параметрами, кот. мне нужны (а именно указываю свой файл). CreateFile возвращает Handle на созданный файл, я этот Handle, должен передать порцессу А. Т.е. проблема в том, что одна программа (процесс А) используют такую затычку, что если файл создан, то она не запускается, а если не создан, то запускается. Я хочу обмануть эту прогу, перехватить вызов функции, создать свой файл и вернуть Handle процессу А. Таким образом Процесс А будет думать, что файл создан и запустится.


Rem   (2004-10-07 13:06:00) [35]

Пример на VC у меня есть, но там очень мутно, может есть у кого-нть на дельфи примерчик


Digitman   (2004-10-07 12:55:00) [36]


> послать эту же функцию


"послать" - это ассоциируется с тремя веселыми буквами ... может все-таки, будешь точней ? кто, куда и по какому поводу "посылает" ? ... и оперируй понятиями не "прога", а хотя бы "трэд процесса" и "процесс" ... хоть что-то прояснится ..


Суслик   (2004-10-07 12:30:00) [37]

эээ, ты куда-то не туда роешь...

это перехват api вызовов.
информации море.

дла начала см. книгу Рихтера Windows для профи - там несколько способов рассмотрено. Есть пример на rsdn -  #1 с.г. или #2 с.г. (см. в статьсях)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо