UserMode Hook

Тема в разделе "WASM.BEGINNERS", создана пользователем Igi, 13 ноя 2006.

  1. Igi

    Igi New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2005
    Сообщения:
    35
    Написал dll которая хуками внедряется во все GUI процессы. Делаю подмену в таблице импорта адресов перехватываемых функций. Все работает - получается и установить и снять хук. Но, хук не срабатывает например в программах запакованных UPX. В этом случае мне кажеться нужно перехватывать GetProcAdress и подсовывать нужные адреса. Но собственно вопрос: как снять такой хук? или придется держать dll в памяти процесса до тех пор пока он не закроется?
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Зависит от того как ты его ставить собираешься.

    Забей на импорт, лучьше похукай сами функции.
     
  3. Igi

    Igi New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2005
    Сообщения:
    35
    Так ведь вроде всезде пишут что именять сами функции жутко ненадежно и т.п. Если например приложении многопоточное. Да и замедляет работу такой перехват. А перехватывать мне нужно во всей системе (скрытие файлов под win9x)
     
  4. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Где пишут? Я не предлагаю каждый раз восстанавливать оригинальные байты, а спереть несколько команд.

    Ой-ой, сколько функциё перехватываем. Я пробовал перехватывать вообще всё что кем-либо экспортируется одновременно, и то работало. Хотя и притормаживало.

    P.S. Может я что-то не знаю т.к. под 9х только в игрушки играл.
     
  5. zxm

    zxm New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2006
    Сообщения:
    71
    Да это нужно делать. Могу дать длл на делфе, которая перехватывает подключение новых модулей,GetProccessAdr и др.

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

    Также нужно учитывать, что если процесс успел сохранить адреса настоящих функций до перехвата, то он может вызывать настоящие функции - это основная проблема перехвата методом правки таблиц импорта.
     
  6. zxm

    zxm New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2006
    Сообщения:
    71
    Раскопал я тот код. Тут установка и снятие, перехват функции RegisterHotKey. Думаю разберёшься.(пьяные маты в коментах вырезаны)
    Код (Text):
    1. unit Unit1;
    2.  
    3. interface
    4.  
    5. uses Windows,TlHelp32;
    6.  
    7. var
    8. hSnapShot: THandle;
    9. me32: MODULEENTRY32;
    10. adr_RegisterHotKey:pointer;
    11. adr_LoadLibraryA:pointer;
    12. adr_LoadLibraryW:pointer;
    13. adr_LoadLibraryExA:pointer;
    14. adr_LoadLibraryExW:pointer;
    15. adr_FreeLibrary:pointer;
    16. adr_FreeLibraryAndExitThread:pointer;
    17. adr_GetProcAddress:pointer;
    18. f:TextFile;
    19.  
    20. procedure ReplaceAllFuncInModule(Instance:HMODULE;Unhook:Boolean);
    21.  
    22.  
    23. function MyRegisterHotKey(hWnd:LongWord;id:integer;fsModifiers:Cardinal;vk:Cardinal):LongBool;stdcall;
    24. procedure MyFreeLibraryAndExitThread(hLibModule:Cardinal;dwExitCode:Cardinal);stdcall;
    25. function MyGetProcAddress(hModule:Cardinal;lpProcName:PAnsiChar):pointer;stdcall;
    26. function MyFreeLibrary(hLibModule:Cardinal):LongBool;stdcall;
    27. function MyLoadLibraryExW(lpLibFilename:PWideChar;hFile:Cardinal;dwFlags:Cardinal):Cardinal;stdcall;
    28. function MyLoadLibraryExA(lpLibFilename:PAnsiChar;hFile:Cardinal;dwFlags:Cardinal):Cardinal;stdcall;
    29. function MyLoadLibraryW(lpLibFilename:PWideChar):Cardinal;stdcall;
    30. function MyLoadLibraryA(lpLibFilename:PAnsiChar):Cardinal;stdcall;
    31.  
    32.  
    33. function ImageDirectoryEntryToData(Base: Pointer; MappedAsImage: ByteBool;DirectoryEntry: Word; var Size: ULONG): Pointer; stdcall; external 'ImageHlp.dll';
    34.  
    35. implementation
    36. ////////////////////////////////////////////////////////////////////////////////
    37. ////////////////////////////////////////////////////////////////////////////////
    38. function StrIComp(const Str1, Str2: PChar): Integer; assembler;
    39. asm
    40.         PUSH    EDI
    41.         PUSH    ESI
    42.         MOV     EDI,EDX
    43.         MOV     ESI,EAX
    44.         MOV     ECX,0FFFFFFFFH
    45.         XOR     EAX,EAX
    46.         REPNE   SCASB
    47.         NOT     ECX
    48.         MOV     EDI,EDX
    49.         XOR     EDX,EDX
    50. @@1:    REPE    CMPSB
    51.         JE      @@4
    52.         MOV     AL,[ESI-1]
    53.         CMP     AL,'a'
    54.         JB      @@2
    55.         CMP     AL,'z'
    56.         JA      @@2
    57.         SUB     AL,20H
    58. @@2:    MOV     DL,[EDI-1]
    59.         CMP     DL,'a'
    60.         JB      @@3
    61.         CMP     DL,'z'
    62.         JA      @@3
    63.         SUB     DL,20H
    64. @@3:    SUB     EAX,EDX
    65.         JE      @@1
    66. @@4:    POP     ESI
    67.         POP     EDI
    68. end;
    69.  
    70.  
    71. function ReplaceImportEntries(Instance:HMODULE;ModuleName:PChar;OldProc,NewProc:Pointer):Integer;
    72. type
    73.   TIMAGE_IMPORT_DESCRIPTOR=record
    74.     Union:DWORD;
    75.     TimeDateStamp:DWORD;
    76.     ForwarderChain:DWORD;
    77.     Name:DWORD;
    78.     FirstThunk:DWORD;
    79.   end;
    80. var
    81.   Size:DWORD;
    82.   ppfn:PPointer;
    83.   ImportDesc:^TIMAGE_IMPORT_DESCRIPTOR;
    84. begin
    85.   Result:=0;
    86.   if (OldProc=nil)or(Instance=0) then Exit;
    87.   ImportDesc:=ImageDirectoryEntryToData(Pointer(Instance),True,IMAGE_DIRECTORY_ENTRY_IMPORT,Size);
    88.   if ImportDesc=nil then Exit;
    89.   while ImportDesc.Name<>0 do begin
    90.     if (ModuleName=nil)or(StrIComp(ModuleName,PChar(Instance+ImportDesc.Name))=0) then begin
    91.       ppfn:=Pointer(Instance+ImportDesc.FirstThunk);
    92.       while ppfn^<>nil do begin
    93.         if (ppfn^=OldProc)and WriteProcessMemory(GetCurrentProcess,ppfn,@NewProc,SizeOf(NewProc),Size)and(Size=SizeOf(NewProc)) then
    94.           Inc(Result);
    95.         Inc(ppfn);
    96.       end;
    97.     end;
    98.     Inc(ImportDesc);
    99.   end;
    100. end;
    101.  
    102. procedure ReplaceAllFuncInModule(Instance:HMODULE;Unhook:Boolean);
    103. begin
    104. if not Unhook then
    105. begin
    106.  ReplaceImportEntries(Instance,'user32.dll',adr_RegisterHotKey,@MyRegisterHotKey);
    107.  ReplaceImportEntries(Instance,'kernel32.dll',adr_GetProcAddress,@MyGetProcAddress);
    108.  ReplaceImportEntries(Instance,'kernel32.dll',adr_FreeLibraryAndExitThread,@MyFreeLibraryAndExitThread);
    109.  ReplaceImportEntries(Instance,'kernel32.dll',adr_FreeLibrary,@MyFreeLibrary);
    110.  ReplaceImportEntries(Instance,'kernel32.dll',adr_LoadLibraryExW,@MyLoadLibraryExW);
    111.  ReplaceImportEntries(Instance,'kernel32.dll',adr_LoadLibraryExA,@MyLoadLibraryExA);
    112.  ReplaceImportEntries(Instance,'kernel32.dll',adr_LoadLibraryW,@MyLoadLibraryW);
    113.  ReplaceImportEntries(Instance,'kernel32.dll',adr_LoadLibraryA,@MyLoadLibraryA);
    114. end else
    115. begin
    116.  ReplaceImportEntries(Instance,'user32.dll',@MyRegisterHotKey,adr_RegisterHotKey);
    117.  ReplaceImportEntries(Instance,'kernel32.dll',@MyGetProcAddress,adr_GetProcAddress);
    118.  ReplaceImportEntries(Instance,'kernel32.dll',@MyFreeLibraryAndExitThread,adr_FreeLibraryAndExitThread);
    119.  ReplaceImportEntries(Instance,'kernel32.dll',@MyFreeLibrary,adr_FreeLibrary);
    120.  ReplaceImportEntries(Instance,'kernel32.dll',@MyLoadLibraryExW,adr_LoadLibraryExW);
    121.  ReplaceImportEntries(Instance,'kernel32.dll',@MyLoadLibraryExA,adr_LoadLibraryExA);
    122.  ReplaceImportEntries(Instance,'kernel32.dll',@MyLoadLibraryW,adr_LoadLibraryW);
    123.  ReplaceImportEntries(Instance,'kernel32.dll',@MyLoadLibraryA,adr_LoadLibraryA);
    124. end;
    125. end;
    126.  
    127.  
    128. ////////////////////////////////////////////////////////////////////////////////
    129. ////////////////////////////////////////////////////////////////////////////////
    130. function MyLoadLibraryA(lpLibFilename:PAnsiChar):Cardinal;stdcall;
    131. var
    132. RealLoadLibraryA:function(lpLibFilename:PAnsiChar):Cardinal;stdcall;
    133. begin
    134. @RealLoadLibraryA:=Adr_LoadLibraryA;
    135. result:=RealLoadLibraryA(lpLibFilename);
    136. if result<>0 then ReplaceAllFuncInModule(result,false);
    137. end;
    138.  
    139. function MyLoadLibraryW(lpLibFilename:PWideChar):Cardinal;stdcall;
    140. var
    141. RealLoadLibraryW:function(lpLibFilename:PWideChar):Cardinal;stdcall;
    142. begin
    143. @RealLoadLibraryW:=Adr_LoadLibraryW;
    144. result:=RealLoadLibraryW(lpLibFilename);
    145. if result<>0 then ReplaceAllFuncInModule(result,false);
    146. end;
    147.  
    148. function MyLoadLibraryExA(lpLibFilename:PAnsiChar;hFile:Cardinal;dwFlags:Cardinal):Cardinal;stdcall;
    149. var
    150. RealLoadLibraryExA:function(lpLibFilename:PAnsiChar;hFile:Cardinal;dwFlags:Cardinal):Cardinal;stdcall;
    151. begin
    152. @RealLoadLibraryExA:=Adr_LoadLibraryExA;
    153. result:=RealLoadLibraryExA(lpLibFilename,hFile,dwFlags);
    154. if result<>0 then ReplaceAllFuncInModule(result,false);
    155. end;
    156.  
    157. function MyLoadLibraryExW(lpLibFilename:PWideChar;hFile:Cardinal;dwFlags:Cardinal):Cardinal;stdcall;
    158. var
    159. RealLoadLibraryExW:function(lpLibFilename:PWideChar;hFile:Cardinal;dwFlags:Cardinal):Cardinal;stdcall;
    160. begin
    161. @RealLoadLibraryExW:=Adr_LoadLibraryExW;
    162. result:=RealLoadLibraryExW(lpLibFilename,hFile,dwFlags);
    163. if result<>0 then ReplaceAllFuncInModule(result,false);
    164. end;
    165.  
    166. function MyFreeLibrary(hLibModule:Cardinal):LongBool;stdcall;
    167. var
    168. RealFreeLibrary:function(hLibModule:Cardinal):LongBool;stdcall;
    169. begin
    170. @RealFreeLibrary:=adr_FreeLibrary;
    171. if hLibModule<>HInstance then
    172.  begin
    173.  ReplaceAllFuncInModule(hLibModule,true);
    174.  result:=RealFreeLibrary(hLibModule);
    175. end else result:=false;
    176. end;
    177.  
    178. procedure MyFreeLibraryAndExitThread(hLibModule:Cardinal;dwExitCode:Cardinal);stdcall;
    179. var
    180. RealFreeLibraryAndExitThread:procedure(hLibModule:Cardinal;dwExitCode:Cardinal);stdcall;
    181. begin
    182. @RealFreeLibraryAndExitThread:=adr_FreeLibraryAndExitThread;
    183. if hLibModule<>HInstance then
    184.  begin
    185.  ReplaceAllFuncInModule(hLibModule,true);
    186.  RealFreeLibraryAndExitThread(hLibModule,dwExitCode);
    187.  end else ExitThread(dwExitCode);
    188. end;
    189.  
    190. function MyGetProcAddress(hModule:Cardinal;lpProcName:PAnsiChar):pointer;stdcall;
    191. var
    192. RealGetProcAddress:function(hModule:Cardinal;lpProcName:PAnsiChar):pointer;stdcall;
    193. begin
    194. @RealGetProcAddress:=adr_GetProcAddress;
    195. if hModule=GetModuleHandle('user32.dll')then
    196.  begin
    197.    if lpProcName='RegisterHotKey' then
    198.     begin
    199.      result:=@MyRegisterHotKey;
    200.      exit;
    201.     end;
    202.  
    203.  end;
    204. if hModule=GetModuleHandle('kernel32.dll')then
    205.  begin
    206.    if lpProcName='LoadLibraryA' then
    207.     begin
    208.      result:=@MyLoadLibraryA;
    209.      exit;
    210.     end;
    211.    if lpProcName='LoadLibraryW' then
    212.     begin
    213.      result:=@MyLoadLibraryW;
    214.      exit;
    215.     end;
    216.    if lpProcName='LoadLibraryExA' then
    217.     begin
    218.      result:=@MyLoadLibraryExA;
    219.      exit;
    220.     end;
    221.    if lpProcName='LoadLibraryExW' then
    222.     begin
    223.      result:=@MyLoadLibraryExW;
    224.      exit;
    225.     end;
    226.    if lpProcName='FreeLibrary' then
    227.     begin
    228.      result:=@MyFreeLibrary;
    229.      exit;
    230.     end;
    231.    if lpProcName='FreeLibraryAndExitThread' then
    232.     begin
    233.      result:=@MyFreeLibraryAndExitThread;
    234.      exit;
    235.     end;
    236.    if lpProcName='GetProcAddress' then
    237.     begin
    238.      result:=@MyGetProcAddress;
    239.      exit;
    240.     end;
    241.  end;
    242. result:=RealGetProcAddress(hModule,lpProcName);
    243. end;
    244.  
    245.  
    246. ////////////////////////////////////////////////////////////////////////////////
    247. ////////////////////////////////////////////////////////////////////////////////
    248. function MyRegisterHotKey(hWnd:LongWord;id:integer;fsModifiers:Cardinal;vk:Cardinal):LongBool;stdcall;
    249. var
    250. RealRegisterHotKey:function(hWnd:LongWord;id:integer;fsModifiers:Cardinal;vk:Cardinal):LongBool;stdcall;
    251. begin
    252. @RealRegisterHotKey:=adr_RegisterHotKey;
    253. result:=RealRegisterHotKey(hWnd,id,fsModifiers,vk);
    254. end;
    255.  
    256.  
    257.  
    258. ////////////////////////////////////////////////////////////////////////////////
    259.  
    260. initialization
    261.  
    262. adr_SetSystemCursor:=GetProcAddress(GetModuleHandle('user32.dll'),'SetSystemCursor');
    263. adr_SetCursor:=GetProcAddress(GetModuleHandle('user32.dll'),'SetCursor');
    264. adr_RegisterHotKey:=GetProcAddress(GetModuleHandle('user32.dll'),'RegisterHotKey');
    265. adr_GetProcAddress:=GetProcAddress(GetModuleHandle('kernel32.dll'),'GetProcAddress');
    266. adr_FreeLibraryAndExitThread:=GetProcAddress(GetModuleHandle('kernel32.dll'),'FreeLibraryAndExitThread');
    267. adr_FreeLibrary:=GetProcAddress(GetModuleHandle('kernel32.dll'),'FreeLibrary');
    268. adr_LoadLibraryExW:=GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadLibraryExW');
    269. adr_LoadLibraryExA:=GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadLibraryExA');
    270. adr_LoadLibraryW:=GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadLibraryW');
    271. adr_LoadLibraryA:=GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadLibraryA');
    272. hSnapShot:=CreateToolHelp32SnapShot(TH32CS_SNAPMODULE, GetCurrentProcessId);
    273. if not(hSnapshot=INVALID_HANDLE_VALUE) then
    274.  begin
    275.   try
    276.    ZeroMemory(@me32,sizeof(MODULEENTRY32));
    277.    me32.dwSize:= sizeof(MODULEENTRY32);
    278.    Module32First(hSnapShot, me32);
    279.     repeat
    280.      ReplaceAllFuncInModule(me32.hModule,false);
    281.     until not Module32Next(hSnapShot, me32);
    282.   finally
    283.    CloseHandle(hSnapShot);
    284.   end;
    285.  end;
    286.  
    287. finalization
    288. hSnapShot:=CreateToolHelp32SnapShot(TH32CS_SNAPMODULE, GetCurrentProcessId);
    289. if not(hSnapshot=INVALID_HANDLE_VALUE) then
    290.  begin
    291.   try
    292.    ZeroMemory(@me32,sizeof(MODULEENTRY32));
    293.    me32.dwSize:= sizeof(MODULEENTRY32);
    294.    Module32First(hSnapShot, me32);
    295.     repeat
    296.      ReplaceAllFuncInModule(me32.hModule,true);
    297.     until not Module32Next(hSnapShot, me32);
    298.   finally
    299.    CloseHandle(hSnapShot);
    300.   end;
    301.  end;
    302.  
    303. end.
    А ну да забыл сказать зачем я всё это в юнит запихнул. - У меня были проблемы с DllProc и код, выполняющийся при выгрузке длл я решил написать в finalization юнита. Этот юнит нужно просто подключить к пустой дллке.
     
  7. Igi

    Igi New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2005
    Сообщения:
    35
    спасибо всем, буду разбираться

    2 asd
    В Рихтере написано что такой способ не будет работать в win9x:

    В Windows 98 основные системные DLL (KerneI32, AdvAPI32, User32 и GDI32)
    защищены так, что приложение не может что-либо изменить на их страницах
    кода. Это ограничение можно обойти, только написав специальный драйвер
    виртуального устройства (VxD).
     
  8. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    А кто действительно посоветует как перехватывать функции в программах пожатые UPX'ом ? Уже все избил, не могу найти причины... Во всех программах нормально работает, в тех же, перехватить получается только LoadLibrary и GetProcAddress, ессно из за чего, потому что UPX в своих бинарниках ничего другого не оставляет :dntknw:
     
  9. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Мдя, оказывается достаточно в приостановленом режиме загрузить программу, перехватывать хотя бы LoadLibrary и все ок. Все работает... А с хуками тогда как быть ? :dntknw:
    я имею ввиду когда внедряем длл при помощи SetHook...
     
  10. zxm

    zxm New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2006
    Сообщения:
    71
    И что? Хочешь для внедряемых модулей тож перехват сделать? ))
     
  11. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    нет
    я хочу чтобы если я внедряюсь в процессы при помощи хуков то же перехват нормально делался
     
  12. zxm

    zxm New Member

    Публикаций:
    0
    Регистрация:
    20 июл 2006
    Сообщения:
    71
    Чё-то я не понял, а что меняется то? Ну есть Dll которая совершает перехват, ну и внедряй её как хочешь. Хоть через SetWindowsHook, хоть через CreateRemoteThread, хоть через ключ реестра или какие-то ещё извраты.
     
  13. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Хмм, ( смайлик чешущий репу ) или я не правильно говорил или меня не правильно понимают ...

    по порядку если то
    1 Запускаю лоудером программу в CREATE_SUSPENDED
    2 Заражаю ее длл
    3 Длл делает грязные дела
    4 Отпускаю процесс

    Иначе не получается против UPX

    Может тебе показалось, что я потоки в процессе приостанавливаю ?