purebasic.info

PureBasic forum
Текущее время: Ср сен 19, 2018 4:33 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Безопасный перехват функций DLL
СообщениеДобавлено: Вт янв 10, 2017 8:56 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Сб сен 05, 2015 11:30 am
Сообщений: 32
Благодарил (а): 2 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Привет,
В интернете можно найти примеры перехвата функций в UserMode когда внедренная DLL использовала 2 способа, сначала расскажу о них.
1. Использовалась таблица импорта в которой менялся адрес функции. Недостаток был в том, что функцию можно было вызвать при помощи OpenLibrary и CallFunction напрямую, минуя хук.
2. Когда в начале самой функции записывалось 6 байт: $68 адрес $C3 что с машинного кода переводиться как call <адрес> ret. И был такой недостаток, так как чтобы получить доступ к функции мы восстанавливали 6 байт и вызывали функцию, а тем временем, к функции мог обратиться другой поток. Если другой поток застанет функцию с правильными 6 байтами, он просто получал доступ минуя перехват. Но запись 6 байтов это задача не на один такт процессора и поэтому могло быть и такое что пару байт были старыми, а пару новыми, и возникала ошибка, и приложение падало.

Я хочу предложить новую технологию хука (если её еще никто не предложил).
По крайней мере на других языках люди реализовывали это.

Смысл технологии такой.
Почти любая функция Windows DLL кроме ntdll.dll начинается с одного и того же кода
    mov edi,edi
    push ebp
    mov ebp,esp
если вы заметите, то первая инструкция смысла не имеет вообще. Инструкции занимают 5 байт. В эти 5 байт я кладу jmp near <адрес сдвига> на свой буффер, в котором я написал примерно следующее
Код:
1
2
3
4
5
6
7
8
call MyFunction
ret
OriginalFunction:
mov edi,edi
push ebp
mov ebp,esp
call originaladdress+5
 


В итоге мы выдернули из оригинальной функции первые три команды, и написали их у себя в буфере, и если функция нам понадобится, то мы вызовем OriginalFunction которая выполнит инструкции а затем прыгнет в оригинальную функцию на 5 байт (чтобы продолжить и не наткнутся на jmp near который мы поставили)
Вот пример реализующий это на функции socket из ws2_32.dll которая ответственна за открытие соединения и создания сервера
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 
 
IncludeFile "mem.pb"
 
Global ws=GetModuleHandle_(@"ws2_32.dll")
If ws=0
  ws=OpenLibrary(#PB_Any,"ws2_32.dll")
  ws=GetModuleHandle_(@"ws2_32.dll")
EndIf
Global func_socket=GetProcAddress_(ws,@"socket")
 
CompilerIf #PB_Compiler_Processor <> #PB_Processor_x86 Or #PB_Compiler_OS <> #PB_OS_Windows
  MessageRequester("","Processor version not x86 or OS Version don't 2000,XP,Vista,7"+Chr(10)+"It's only for this versions",#MB_ICONERROR)
CompilerEndIf
 
InitNetwork()
 
Structure wrst
  i1.a
  a1.i
EndStructure
Global write.wrst\i1 = $E9
 
Procedure Hook(adr, newfunc)
    If adr=0 Or newfunc=0
      MessageRequester("","Hook zero found :("+Chr(10)+Hex(adr)+" "+Hex(newfunc),#MB_ICONERROR)
    EndIf
  mem=AllocateMemory(25)
  Start(mem)
    PutA($68)
    PutL(newfunc)
    PutA($C3)
    original=putbuf
    PutL($8B55FF8B)
    PutA($EC)
    PutA($68)
    PutL(adr+5)
    PutA($C3)
  write\a1 = mem - adr - 5
  WriteProcessMemory_(-1, adr, write, 5, @w)
  ProcedureReturn original
EndProcedure
 
Global connect_original
Procedure socket(a,b,c)
  MessageRequester("","socket "+Str(a)+" "+Str(b)+" "+Str(c))
  ret=CallFunctionFast(connect_original,a,b,c)
  ProcedureReturn ret
EndProcedure
 
connect_original=Hook(func_socket, @socket())
 
 
Debug SOCKET_(2,1,0)
;Debug OpenNetworkConnection("vk.com",80)
 
 


и содержимое файла mem.pb
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
Global putbuf
Procedure Start(mem)
  putbuf=mem
EndProcedure
Procedure PutA(byte)
  PokeA(putbuf,byte):putbuf+1
EndProcedure
Procedure PutU(word)
  PokeU(putbuf,word):putbuf+2
EndProcedure
Procedure PutL(long)
  PokeL(putbuf,long):putbuf+4
EndProcedure
 
 



Недостаток моей технологии - ни все функции поддерживают это правильно. Не используйте это чтобы перехватывать функции ntdll.dll, там по другому начинаются функции.
Могу сказать что можете использовать это с функциями:
CreateProcess
OpenProcess
CreateFile
WriteFileEx
ReadFileEx
CloseHandle
socket
connect
bind
send
WSASend
recv
WSARecv
gethostname
gethostbyname
MessageBox
GetDriveType
GetLogicalDrivers
GetDiskFreeSpaceEx
CreateMutex
OpenMutex
UnlockFile и UnlockFileEx
RegOpenKey и RegOpenKeyEx
RegCreateKey и RegCreateKeyEx
RegSetValue
RegQueryValue и RegQueryValueEx
RegDeleteKey
RegEnumKey и RegEnumKeyEx
RegEnumValue
GetUserName


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Ср янв 11, 2017 2:10 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Объясни зачем это?
Код:
1
2
3
4
5
6
7
8
9
10
11
12
 
 Start(mem)
    PutA($68)
    PutL(newfunc)
    PutA($C3)
    original=putbuf
    PutL($8B55FF8B)
    PutA($EC)
    PutA($68)
    PutL(adr+5)
    PutA($C3)
 


если есть возможность писать на асме? :roll:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Ср янв 11, 2017 11:17 am 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Сб сен 05, 2015 11:30 am
Сообщений: 32
Благодарил (а): 2 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Цитата:
Объясни зачем это?

А как мы туда напишем адрес функции, которая передается из параметра? По мне так проще как раз таки машинный код написать быстренько.
================================

Еще по поводу ntdll.dll. Почти все функции в ней занимают 4 строчки. Это присвоение номера функции, адрес системного обработчика, вызов функции и возврат. Поэтому, конечно, проще перехватывать их драйвером, который подменивает в таблице номеров функцию. Тут были темы про драйвера.

Если про эти 4 строчки.
Каждая версия ОС имеет свой номер и свои номера функций. Номера функций для версий до Windows Vista можете узнать здесь http://hex.pp.ua/service-descriptor-table.php
От Windows 7 и дальше можете узнать сами взяв PE Explorer, скачав библиотеку нужной версии, открыв в нем, и посмотрев. Например функция NtCreateProcess в XP имеет вид
    mov eax,0000002Fh
    mov edx,7FFE0300h
    call [edx]
    retn 0020h
Значит номер функции будет 2F. У вас на форуме есть целый раздел посвященный программированию драйверов.

Если все же очень нужно перехватить ntdll через dll, то нужно скопировать эти 4 инструкции в свой буфер, а на место функции поставить переход jmp или call.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Ср янв 11, 2017 12:39 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11255
Благодарил (а): 4 раз.
Поблагодарили: 429 раз.
dirty.cheese писал(а):
Поэтому, конечно, проще перехватывать их драйвером, который подменивает в таблице номеров функцию.
Не все так просто https://habrahabr.ru/company/pt/blog/246841/
Кроме того драйвер должен иметь цифровую подпись (стоит денег и есть некоторые сложности с получением) и для его установки требуются права администратора.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Ср янв 11, 2017 12:40 pm 
Не в сети
профессор

Зарегистрирован: Пн янв 03, 2011 4:27 pm
Сообщений: 410
Благодарил (а): 5 раз.
Поблагодарили: 17 раз.
Пункты репутации: 0
dirty.cheese писал(а):
Я хочу предложить новую технологию хука (если её еще никто не предложил).
Поиск
http://purebasic.info/phpBB3ex/viewtopic.php?f=5&t=2004
http://purebasic.info/phpBB3ex/viewtopic.php?f=15&t=1209


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Ср янв 11, 2017 6:59 pm 
Не в сети
доцент
Аватар пользователя

Зарегистрирован: Сб сен 05, 2015 11:30 am
Сообщений: 32
Благодарил (а): 2 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
@ZOLO@ писал(а):
dirty.cheese писал(а):
Я хочу предложить новую технологию хука (если её еще никто не предложил).
Поиск
http://purebasic.info/phpBB3ex/viewtopic.php?f=5&t=2004
http://purebasic.info/phpBB3ex/viewtopic.php?f=15&t=1209


Все новое это хорошо забытое старое :)
Кстати сейчас сижу с драйверным Purebasic и простым Purebasic, и открыл только что для себя, что неубиваемый процесс можно убить если к номеру процесса добавить 1,2,3. Например если номер процесса 200, и он защищен, то его можно убить открыв процесс 201, и вызвав TerminateProcess. Кто-нибудь может что-нибудь сказать по этому поводу?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Ср янв 11, 2017 8:50 pm 
Не в сети
док

Зарегистрирован: Ср июн 18, 2014 6:34 pm
Сообщений: 104
Благодарил (а): 2 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Какой неубиваемый процесс?
Скиньте мне ссылку сюда на такой экзешник с неубиваемым процессом, я сделаю видео как его убить.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Безопасный перехват функций DLL
СообщениеДобавлено: Чт янв 12, 2017 12:37 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
dirty.cheese писал(а):
Цитата:
Объясни зачем это?

А как мы туда напишем адрес функции, которая передается из параметра? По мне так проще как раз таки машинный код написать быстренько.
================================
Не увидел чтобы очищалась выделенная память,а если она постоянна то вполне можно в блок данных на асме писать.
да и процедуры тут ненужны,макросы будут куда эффективней. :roll:


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB