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

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

перехват


Страницы:   1 2 3 4 5 6 7 8

Powerland ©   (2004-08-26 00:35:00) 

необходимо было реализовать перехват вызова некоторых системных функции. в процесс внедряется dll, а затем из неё производится замена адреса перехода на нужную фунцию. но это почему-то не работает. кто-нить встречался с этой проблемой?


noname   (2004-08-31 13:57:00) [121]

Я заметил =)


Digitman   (2004-08-31 13:06:00) [122]


> Хотя я согласен, что правка EAT надёжнее


не то слово

как раз это в вышеприведенном коде и реализовано - IAT + EAT


noname   (2004-08-31 09:37:00) [123]

А в чём проблема - правим в IAT адрес GetProcAddress.
Хотя я согласен, что правка EAT надёжнее =) Есть один способ загрузки не через LoadLib+GetProcAddr. То есть через PEB+EAT.


Digitman   (2004-08-31 09:14:00) [124]


> noname ©   (30.08.04 20:11) [23]


> 2. Перехват изменением IAT


еще раз повторюсь - изменения только одной IAT недостаточно, в частном случае это будет работать, в общем же случае - далеко не всегда

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


kaZaNoVa   (2004-08-30 23:47:00) [125]

[23] noname ©   (30.08.04 20:11)
ОГРОМНОЕ спасибо, СУПЕР модуль, как раз искал такой , ещё раз спасибо !


noname   (2004-08-30 20:11:00) [126]

Скачай HideModule:
http://dragonteam.nm.ru/Docs/F_HideModule.htm
Там в HideTypes я объявил (чуть-чуть по-другому) все необходимые мне типы. Также есть 2 Demo по перехвату API
1. Перехват модифицированнием первых байтов функции
2. Перехват изменением IAT


kaZaNoVa   (2004-08-30 18:57:00) [127]

осталась проблема с PImageImportDescriptor,PImageThunkData и SIZE_OF_NT_SIGNATURE, будьте добры, помогите :)
please !

и что-нить "дополнительное" нужно в uses  ?


kaZaNoVa   (2004-08-30 18:39:00) [128]

[20] Digitman ©   (30.08.04 15:09)
спасибо, сейчас попробую ;)

> разбежался !
> там несколько тысяч строк, многие из которых не имеют отношения
> к сабжу ...

Извините, я не хотел Вас оскорбить, НО, "неполное знание несовершенно" (как сказал классик (*не помню кто*)), если Вы даёте полностью рабочий код, то, пожалуйста, будьте добры его дать в том виде, чтобы он работал (с необходимыми обьявлениями типов и т.д.)
По поводу моей просьбы о полном коде модуля - я извиняюсь, я не знал, что он такой большой и что там много того, что не имеет отношения к рассматриваемой задаче, просто поймите, иногда так бывает обидно, когда вот так найдёшь код, который когдато был так нужен,  а он оказывается неполон, и , следовательно, не работает ... :(

про > Коберниченко
не слыхал, спасибо, поищу ...

P.S. Вы не первый раз давали это пример кода перехвата, и, каждый раз "кусочками", для понимания сложности и принципов перехвата этого может и достаточно, но для реальной работы с ним конечно же нет :)

P.P.S. я давно интересуюсь возможностими перехвата АПИ - функций, но пока у меня ничего "путного" не получалось, возможно из-за моей не очень большой квалификации . :(


Digitman   (2004-08-30 15:09:00) [129]

PClientId = ^TClientId;
 TClientId = record
   UniqueProcess: THandle; // Process ID
   UniqueThread: THandle;  // Thread ID
 end;
 CLIENT_ID = TClientId;

TPEB_LDR_DATA = packed record
  Length           : Cardinal;
  Initialized      : Byte;
  AlignmentBytes   : array[1..3] of Byte;
  SsHandle         : THandle;
  { ?????? ????????? TLDR_DATA_TABLE_ENTRY }
  InLoadOrderModuleList : PLIST_ENTRY;
  InMemoryOrderModuleList : PLIST_ENTRY;
  InInitializationOrderModuleList : PLIST_ENTRY;
  EntryInProgress  : Pointer;
end;
PPEB_LDR_DATA = ^TPEB_LDR_DATA;

 PTeb = ^TTeb;
 TTeb = packed record
   Tib               : TNtTib;
   Environment       : PWideChar;
   ClientId          : TClientId;
   RpcHandle         : THandle;
   ThreadLocalStorage: Pointer;  // PPointer
   Peb               : PPeb;
   LastErrorValue    : DWORD;
 end;
 _TEB = TTeb;

 PNtTib = ^TNtTib;
 _NT_TIB = record
   ExceptionList       : Pointer;  // ^_EXCEPTION_REGISTRATION_RECORD
   StackBase           : Pointer;
   StackLimit          : Pointer;
   SubSystemTib        : Pointer;
   case Integer of
     0: (FiberData     : Pointer);
     1: (Version       : ULONG;
 { end; }
   ArbitraryUserPointer: Pointer;
   Self                : PNtTib);
 end;
 TNtTib = _NT_TIB;


> дайте _полный_ код модуля со всеми определениями


разбежался !
там несколько тысяч строк, многие из которых не имеют отношения к сабжу ...

MSDN + Коберниченко в зубы - и вперед !! ... До полного просветления !!


kaZaNoVa   (2004-08-30 15:05:00) [130]

нехватает определения PPEB_LDR_DATA;
RtlEnterCriticalSection(PEB.LoaderLock);
компилятор ругается на
function GetCurrentPEB: PPEB;
asm
mov   eax, fs:[TTeb.Peb]
end;

Уважаемый  Digitman, пожалуйста, дайте _полный_ код модуля со всеми определениями, + что дополнительно прописывать в uses ;)
- мне это крайне важно !


Digitman   (2004-08-29 11:56:00) [131]

TUNICODE_STRING = packed record
   Length: Word;
   MaximumLength: Word;
   Buffer: PWideChar;
 end;
 TNtUnicodeString = TUNICODE_STRING;
 PNtUnicodeString = ^TNtUnicodeString;

PLIST_ENTRY = ^TLIST_ENTRY;
TLIST_ENTRY = packed record
  Flink            : PLIST_ENTRY;
  Blink            : PLIST_ENTRY;
end;
PPLIST_ENTRY = ^PLIST_ENTRY;
TListEntry = TLIST_ENTRY;
PListEntry = ^TListEntry;
PPListEntry = PPLIST_ENTRY;

TModuleInfo = packed record
  DllBase          : Pointer;
  EntryPoint       : Pointer;
  SizeOfImage      : Cardinal;
  FullDllName      : TUNICODE_STRING;
  BaseDllName      : TUNICODE_STRING;
  Flags            : Cardinal;
  LoadCount        : Word;
  TlsIndex         : Word;
  HashLinks        : TLIST_ENTRY;
  SectionPointer   : Pointer;
  CheckSum         : Cardinal;
  TimeDateStamp    : Cardinal;
  LoadedImports    : Pointer;
  EntryPointActivationContext : Pointer;
end;
PModuleInfo = ^TModuleInfo;

TLDR_DATA_TABLE_ENTRY = packed record
  InLoadOrderLinks : TLIST_ENTRY;
  InMemoryOrderLinks : TLIST_ENTRY;
  InInitializationOrderLinks : TLIST_ENTRY;
  ModuleInfoData: TModuleInfo;
end;

PLDR_DATA_TABLE_ENTRY = ^TLDR_DATA_TABLE_ENTRY;
TModuleEntry = TLDR_DATA_TABLE_ENTRY;
PModuleEntry = ^TModuleEntry;

TPEB = packed record
{000}   InheritedAddressSpace : ByteBool;
{001}   ReadImageFileExecOptions : ByteBool;
{002}   BeingDebugged    : ByteBool;
{003}   SpareBool        : ByteBool;
{004}   Mutant           : Pointer;
{008}   ImageBaseAddress : Pointer;
{00C}   LdrData          : Pointer; //PPEB_LDR_DATA; { Modules list }
{010}   ProcessParameters : Pointer; //PRTL_USER_PROCESS_PARAMETERS; { _RTL_USER_PROCESS_PARAMETERS }
{014}   SubSystemData    : Pointer;
{018}   ProcessHeap      : Pointer;
{01C}   FastPebLock      : PRTLCriticalSection;
{020}   FastPebLockRoutine : Pointer;
{024}   FastPebUnlockRoutine : Pointer;
{028}   EnvironmentUpdateCount : Cardinal;
{02C}   KernelCallbackTable : Pointer;
{030}   SystemReserved   : Cardinal;
{034}   ExecuteOptions   : Cardinal; {Pos 0, 2 Bits, SpareBits  : Pos 2, 30 Bits }
{038}   FreeList         : Pointer; { _PEB_FREE_BLOCK }
{03C}   TlsExpansionCounter : Cardinal;
{040}   TlsBitmap        : Pointer;
{044}   TlsBitmapBits    : array[0..1] of Cardinal;
{04C}   ReadOnlySharedMemoryBase : Pointer;
{050}   ReadOnlySharedMemoryHeap : Pointer;
{054}   ReadOnlyStaticServerData : Pointer;
{058}   AnsiCodePageData : Pointer;
{05C}   OemCodePageData  : Pointer;
{060}   UnicodeCaseTableData : Pointer;
{064}   NumberOfProcessors : Cardinal;
{068}   NtGlobalFlag     : Cardinal;
{06C}   Reserved0        : DWord;
{070}   CriticalSectionTimeout : TLARGEINTEGER;
{078}   HeapSegmentReserve : Cardinal;
{07C}   HeapSegmentCommit : Cardinal;
{080}   HeapDeCommitTotalFreeThreshold : Cardinal;
{084}   HeapDeCommitFreeBlockThreshold : Cardinal;
{088}   NumberOfHeaps    : Cardinal;
{08C}   MaximumNumberOfHeaps : Cardinal;
{090}   ProcessHeaps     : Pointer;
{094}   GdiSharedHandleTable : Pointer;
{098}   ProcessStarterHelper : Pointer;
{09C}   GdiDCAttributeList : Cardinal;
{0A0}   LoaderLock       : PRTLCriticalSection;
{0A4}   OSMajorVersion   : Cardinal;
{0A8}   OSMinorVersion   : Cardinal;
{0AC}   OSBuildNumber    : Word;
{0AE}   OSCSDVersion     : Word;
{0B0}   OSPlatformId     : Cardinal;
{0B4}   ImageSubsystem   : Cardinal;
{0B8}   ImageSubsystemMajorVersion : Cardinal;
{0BC}   ImageSubsystemMinorVersion : Cardinal;
{0C0}   ImageProcessAffinityMask : Cardinal;
{0C4}   Reserved2        : array[0..34] of DWord;
{150}   Reserved3        : DWord;
{154}   Reserved4        : array[0..31] of DWord;
{1D4}   Win32WindowStation : THandle;
{1D8}   Reserved5        : DWord;
{1DC}   Reserved6        : DWord;
{1E0}   CSDVersion       : PWord;
{1E4}   Reserved7        : DWord;
{1E8}
 end;

PPEB = ^TPEB;

function GetCurrentPEB: PPEB;
asm
 mov   eax, fs:[TTeb.Peb]
end;

procedure LockLoader(PEB: PPEB);
begin
 RtlEnterCriticalSection(PEB.LoaderLock);
end;

procedure UnlockLoader(PEB: PPEB);
begin
 RtlLeaveCriticalSection(PEB.LoaderLock);
end;

function FindModuleInfo(hModule: THandle): PModuleInfo;
var
 Peb: PPeb;
 pLdrData : PPEB_LDR_DATA;
 pLoadOrderList : PPLIST_ENTRY;
 pInLoadModuleEntry: PModuleEntry;
begin
 Result := nil;
 if hModule = 0 then Exit;
 Peb := GetCurrentPeb;
 LockLoader(Peb);
 try
   pLdrData := Peb^.LdrData;
   pLoadOrderList := @pLdrData.InLoadOrderModuleList;
   pInLoadModuleEntry := PModuleEntry(pLoadOrderList^);
   while PPListEntry(pInLoadModuleEntry) <> pLoadOrderList do
     begin
       Result := @pInLoadModuleEntry.ModuleInfoData;
       if Result^.DllBase = Pointer(hModule) then
         Exit;
       pInLoadModuleEntry := PModuleEntry(pInLoadModuleEntry.InLoadOrderLinks.Flink);
     end;
   Result := nil;
 finally
   UnLockLoader(Peb);
 end;
end;

function GetModuleInfo(lpModule: PChar; out ModuleInfo: TModuleInfo): Boolean;
var
 peb: PPeb;
 hModule: THandle;
 pLdrData : PPEB_LDR_DATA;
 pLoadOrderList : PPLIST_ENTRY;
 pInLoadModuleEntry: PModuleEntry;
 pModuleNfo: PModuleInfo;
begin
 Result := False;
 if not Assigned(lpModule) then Exit;
 peb := GetCurrentPeb;
 LockLoader(Peb);
 try
   hModule := FindHInstance(lpModule);
   if hModule = 0 then Exit;
   if hModule <> THandle(lpModule) then
     hModule := GetModuleHandle(lpModule);
   if hModule = 0 then Exit;
   pLdrData := peb^.LdrData;
   pLoadOrderList := @pLdrData.InLoadOrderModuleList;
   pInLoadModuleEntry := PModuleEntry(pLoadOrderList^);
   while PPListEntry(pInLoadModuleEntry) <> pLoadOrderList do
     begin
       pModuleNfo := @pInLoadModuleEntry.ModuleInfoData;
       if pModuleNfo^.DllBase = Pointer(hModule) then
         begin
           if Assigned(@ModuleInfo) then
             ModuleInfo := pModuleNfo^;
           Result := True;
           Break;
         end;
       pInLoadModuleEntry := PModuleEntry(pInLoadModuleEntry.InLoadOrderLinks.Flink);
     end;
 finally
   UnLockLoader(Peb);
 end;
end;


N_O   (2004-08-29 10:20:00) [132]

уважаемый Digitman. посмотрев вам код [11]  япопробовал его использовать. при компиляции было найдено много ошибок. неизвестные типы и функции.

[Error] Lib.dpr(30): Undeclared identifier: 'PPeb'
[Error] Lib.dpr(41): Undeclared identifier: 'PPEB_LDR_DATA'
[Error] Lib.dpr(42): Undeclared identifier: 'PPLIST_ENTRY'
[Error] Lib.dpr(43): Undeclared identifier: 'PModuleEntry'
[Error] Lib.dpr(44): Undeclared identifier: 'PModuleInfo'
[Error] Lib.dpr(51): Undeclared identifier: 'GetCurrentPEB'
[Error] Lib.dpr(52): Undeclared identifier: 'LockLoader'
[Error] Lib.dpr(54): Undeclared identifier: 'FindModuleInfo'
и много других ошибок. объясните незнающему человеку что это за типы и функции...


Powerland   (2004-08-26 11:01:00) [133]

ну а м.б. какие-то ссылки есть? может ещё чего полезного узнаю.


Powerland   (2004-08-26 10:52:00) [134]

> [12]


Digitman   (2004-08-26 10:52:00) [135]


> Powerland ©   (26.08.04 10:49) [12]
> откуда этот код? хочется узнать
> больше относительно этой темы...


код мой.
ориентирован только на НТ-совместимые системы


Powerland   (2004-08-26 10:49:00) [136]

спасибо. а можно узнать откуда этот код? хочется узнать больше относительно этой темы...


Digitman   (2004-08-26 10:49:00) [137]

function SetApiHook(hModule: THandle; ProcName: PChar; ProcAddr: Pointer): Pointer;
begin
 Result := GetProcAddress(hModule, ProcName);
 if Assigned(Result) and not SetProcAddress(hModule, ProcName, ProcAddr) then Result := nil;
end;

..
//установка

pOldMessageBoxA := SetApiHook(GetModuleHandle('USER32.DLL'), 'MessageBoxA', @MyMessageBox);

//снятие

SetApiHook(GetModuleHandle('USER32.DLL'), 'MessageBoxA', pOldMessageBoxA);


Digitman   (2004-08-26 10:43:00) [138]


> Powerland ©   (26.08.04 10:31) [10]


function SetProcAddress(hModule: THandle; lpProcName: PChar; pProcAddr: Pointer): Boolean;
var
 Peb: PPeb;
 hProcess, hImporter: THandle;
 pOptHdr: PImageOptionalHeader;
 pImpDir: PImageImportDescriptor;
 pExpDir: PImageExportDirectory;
 pIATEntry: PImageThunkData;
 pOldProcAddr: Pointer;
 pdwNamePtr, pdwEntryPoint: PDWord;
 pName: PChar;
 pwOrdinalPtr: PWord;
 i, nOrdinal, dwNewProcAddrRVA, dwProtect: DWord;
 pLdrData : PPEB_LDR_DATA;
 pLoadOrderList : PPLIST_ENTRY;
 pInLoadModuleEntry: PModuleEntry;
 pModuleNfo: PModuleInfo;
 pImpModuleNfo: PModuleInfo;
 sModuleName: String;
 dwDirSize: DWord;
begin
 Result := False;
 if (hModule = 0) or (lpProcName = nil) then Exit;
 peb := GetCurrentPEB;
 LockLoader(Peb);
 try
   pModuleNfo := FindModuleInfo(hModule);
   if not Assigned(pModuleNfo) then Exit;
   sModuleName := WideCharToString(pModuleNfo^.BaseDllName.Buffer);
   pOptHdr := PImageOptionalHeader(hModule + PImageDosHeader(hModule)._lfanew + SIZE_OF_NT_SIGNATURE + IMAGE_SIZEOF_FILE_HEADER);
   dwDirSize := pOptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
   if (pOptHdr^.NumberOfRvaAndSizes < 16) or (dwDirSize = 0) then Exit;
   pExpDir := PImageExportDirectory(hModule + pOptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
   pdwEntryPoint := nil;
   pwOrdinalPtr := PWord(hModule +  DWord(pExpDir^.AddressOfNameOrdinals));
  if HiWord(DWord(lpProcName)) = 0 then
     begin
       nOrdinal :=  LoWord(DWord(lpProcName)) - pExpDir^.Base;
       if (nOrdinal < pExpDir^.NumberOfFunctions) then
         pdwEntryPoint := PDWord(hModule + DWord(pExpDir^.AddressOfFunctions) + nOrdinal * SizeOf(PDWord));
     end
   else
     begin
       pdwNamePtr := PDWord(hModule + DWord(pExpDir^.AddressOfNames));
       for i := 0 to pExpDir^.NumberOfNames - 1 do
         begin
        pName := PChar(PDWord(hModule  + PDword(pdwNamePtr)^));
        if lstrcmp(pName,lpProcName) = 0 then
             begin
           nOrdinal := pwOrdinalPtr^;
               pdwEntryPoint := PDWord(hModule + DWord(pExpDir^.AddressOfFunctions) + nOrdinal * SizeOf(PDWord));
               Inc(nOrdinal, pExpDir^.Base);
           Break;
          end
           else
             begin
               Inc(pdwNamePtr);
            Inc(pwOrdinalPtr);
             end
         end;
     end;
   if not Assigned(pdwEntryPoint) then Exit;
   pOldProcAddr := Pointer(hModule + pdwEntryPoint^);
   if pOldProcAddr = pProcAddr then
     Result := True
   else
     try
       dwNewProcAddrRVA := DWord(pProcAddr) - hModule;
       hProcess := OpenProcess(PROCESS_VM_OPERATION, False, GetCurrentProcessId);
       Win32Check(hProcess <> 0);
       try
         Win32Check(VirtualProtectEx(hProcess, pExpDir, dwDirSize, PAGE_WRITECOPY, dwProtect));
         try
           pdwEntryPoint^ := dwNewProcAddrRVA;
         finally
           VirtualProtectEx(hProcess, pExpDir, dwDirSize, dwProtect, dwProtect);
         end;
         pName := PChar(sModuleName);
         pLdrData := Peb^.LdrData;
         pLoadOrderList := @pLdrData.InLoadOrderModuleList;
         pInLoadModuleEntry := PModuleEntry(pLoadOrderList^);
         while PPListEntry(pInLoadModuleEntry) <> pLoadOrderList do
           begin
             pImpModuleNfo := @pInLoadModuleEntry.ModuleInfoData;
             if pImpModuleNfo <> pModuleNfo then
               begin
                 hImporter := THandle(pImpModuleNfo^.DllBase);
                 pOptHdr := PImageOptionalHeader(hImporter + PImageDosHeader(hImporter)._lfanew + SIZE_OF_NT_SIGNATURE + IMAGE_SIZEOF_FILE_HEADER);
                 if pOptHdr^.NumberOfRvaAndSizes = 16 then
                   begin
                     dwDirSize := pOptHdr^.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
                     if dwDirSize > 0 then
                       begin
                         pImpDir := PImageImportDescriptor(hImporter + pOptHdr^.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
                         while Assigned(PChar(pImpDir^.RVAImportModuleName)) do
                           begin
                             if lstrcmpi(PChar(hImporter + pImpDir^.RVAImportModuleName), pName) = 0 then
                               begin
                                 pIATEntry := PImageThunkData(hImporter + DWord(pImpDir^.RVAImportAddressTable));
                                 while Assigned(pIATEntry^.Func) do
                                   begin
                                     if pIATEntry^.Func = pOldProcAddr then
                                       begin
                                         Win32Check(VirtualProtectEx(hProcess, pIATEntry, SizeOf(pIATEntry), PAGE_WRITECOPY, dwProtect));
                                         try
                                           pIATEntry^.Func := pProcAddr;
                                         finally
                                           VirtualProtectEx(hProcess, pIATEntry, SizeOf(pIATEntry), dwProtect, dwProtect);
                                         end;
                                         Break;
                                       end;
                                     Inc(pIATEntry);
                                   end;
                               end;
                             Inc(pImpDir);
                           end;
                       end;
                   end;
               end;
             pInLoadModuleEntry := PModuleEntry(pInLoadModuleEntry.InLoadOrderLinks.Flink);
           end;
       finally
         CloseHandle(hProcess);
       end;
       Result := True;
     except
     end;
 finally
   UnLockLoader(Peb);
 end;
end;


Powerland   (2004-08-26 10:31:00) [139]

всё равно не работает. я раньше перехват делал другим способом. а сейчас нужно сделать именно так.


Digitman   (2004-08-26 10:23:00) [140]


> хэндл, который получаем через GetCurrentProcess();


так это же неверно !

передаваемым хэндлом д.б. хэндл того модуля, таблица импорта которого подвергается правке

например, GetModuleHandle(0)


Страницы:   1 2 3 4 5 6 7 8

Наверх

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