Форум программистов, компьютерный форум, киберфорум
Pure Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.58/26: Рейтинг темы: голосов - 26, средняя оценка - 4.58
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131

Перехват Win API функции

17.05.2014, 03:48. Показов 5224. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
как перехватить АПИ функции , с помощью внедрения длл в процесс?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.05.2014, 03:48
Ответы с готовыми решениями:

Перехват API функции
Доброго времени суток всем! Уважаемые форумчене помогите решить задачу, я взял функцию MessageBox и перехватил её. Объясните нубу как...

Выполнить перехват API вызова методом сплайсинга функции
Общий! :D Как следует из названия темы, хочу выполнить перехват API вызова. Сделать это хочу методом сплайсинга функции. То есть...

Функции WIN API
Здравствуйте. Подскажите пожалуйста где можно посмотреть реализацию некоторых функций в WIN API, например таких как DefWindowProc и...

20
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
17.05.2014, 10:41
Открыть процесс, выделить в нем участок памяти с правами на выполнение,
записать туда свой код, а потом запустить его через CreateRemoteThread.
Из этого нового потока загрузить в процесс свою dll-ку и вызвать оттуда
нужную функцию. Из этой функции найти адрес WinAPI-функции, которую
требуется перехватить, и поставить на нее перехватчик с помощью метода,
называемого сплайсингом.

Перехват (википедия):
http://ru.wikipedia.org/wiki/%... 8%D0%B5%29

Другой способ основан на изменении таблиц в загружаемых exe/dll
на ранних этапах загрузки.
1
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
17.05.2014, 11:52
Лучший ответ Сообщение было отмечено MAGA как решение

Решение

Можно так же использовать proxy-dll. Принцип следующий: В импорте программы ищут одну из dll, из которой импортируется меньше всего функций (обычно это одна из библиотек с WinAPI функциями) и создают аналогичную с таким же набором функций. Помещают ее в папку с программой. Винда ее загрузит, т. е. наша dll получит доступ к процессу и внедрение как таковое не требуется. Это сделает винда.

Перехватывать API можно и без dll.
PureBasic
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
EnableExplicit
 
Structure IMAGE_IMPORT_DESCRIPTOR
   ; относительный виртуальный адрес на оригинальную таблицу импорта
   ; в этой таблице содержатся имена или номера функций которые должны быть
   ; проинициализированы адресами
   ; имеет значение 0 если это концевой дескриптор
   OriginalFirstThunk.l
   ; штамп времени биндинга библиотеки системным загрузчиком
   TimeDateStamp.l
   ; указывает наличие переадресации к другой библиотеки
   ForwarderChain.l
   ; относительный вирутальный адрес на имя библиотеки
   Name.l
   ; относительный виртуальный адрес на инициализированную таблицу импорта
   ; в этой таблице содержатся уже адреса функций записанных
   ; системным загрузчиком
   FirstThunk.l
EndStructure
 
Structure IMAGE_THUNK_DATA32
   ; адрес функции
   ; ( в оригинальной таблице указывает на структуру IMAGE_IMPORT_BY_NAME )
   ; имеет значение 0 если это концевой указатель
   Function.l
EndStructure
 
;
; поиск в модуле дескриптора таблицы импорта по заданному имени библиотеки
;
Procedure FindImportDescriptor( BaseAddress.l, LibraryNameAddress.l )
   ; базовый адрес указывает на устаревший DOS заголовок
   Protected *IDH.IMAGE_DOS_HEADER = BaseAddress
   ; смещаемся на новый NT заголовок
   Protected *INH.IMAGE_NT_HEADERS = *IDH + *IDH\e_lfanew
   ; смещаемся на таблицу импорта
   Protected *IID.IMAGE_IMPORT_DESCRIPTOR = *IDH + *INH\OptionalHeader\DataDirectory[ #IMAGE_DIRECTORY_ENTRY_IMPORT ]\VirtualAddress
   ; ищем нужный дескриптор пока не достигнем концевого
   While *IID\OriginalFirstThunk <> 0
      ; сравниваем имя библиотеки в дескрипторе с искомым
      ;
      ; конкретно для KERNEL32.DLL
      ; можно произвести сравнение оптимальнее
      ; если представить KERNEL32 как 64-битное целое, например так:
      ;
      ; Protected *Name.Quad = *IDH + *IID\Name
      ; If *Name\q = '23LENREK'
      ;     ProcedureReturn *IID
      ; EndIf
      ;
      If CompareMemoryString( *IDH + *IID\Name, LibraryNameAddress, #PB_String_NoCase ) = #PB_String_Equal
         ProcedureReturn *IID
      EndIf
      ; смещаемся на следующий дескриптор
      *IID + SizeOf( IMAGE_IMPORT_DESCRIPTOR )
   Wend
   ProcedureReturn 0
EndProcedure
 
;
; поиск в таблице импорта указателя на адрес по заданному адресу
;
Procedure FindThunkData( BaseAddress.l, *ImportDescriptor.IMAGE_IMPORT_DESCRIPTOR, TargetAddress.l )
   Protected *ThunkData.IMAGE_THUNK_DATA32 = BaseAddress + *ImportDescriptor\FirstThunk
   ; ищем нужный указатель пока не достигнем концевого
   While *ThunkData\Function <> 0
      ; сравниваем адреса
      If *ThunkData\Function = TargetAddress
         ProcedureReturn *ThunkData
      EndIf
      ; смещаемся на следующий указатель
      *ThunkData + SizeOf( IMAGE_THUNK_DATA32 )
   Wend
   ProcedureReturn 0
EndProcedure
 
; прототипы оригинальных перехватываемых функций
 
Prototype WINAPICreateFile( *lpFileName, dwDesiredAccess.l, dwShareMode.l, *lpSecurityAttributes, dwCreationDistribution.l, dwFlagsAndAttributes.l, hTemplateFile.l )
Prototype WINAPIReadFile( hFile.l, *lpBuffer, nNumberOfBytesToRead.l, *lpNumberOfBytesRead, *lpOverlapped )
Prototype WINAPICloseHandle( hFile.l )
 
; адреса оригинальных перехватываемых функций
 
Global WINAPICreateFile.WINAPICreateFile
Global WINAPIReadFile.WINAPIReadFile
Global WINAPICloseHandle.WINAPICloseHandle
 
; свои функции которые будут заменять WINAPI функции
 
Procedure MyCreateFile( *lpFileName, dwDesiredAccess.l, dwShareMode.l, *lpSecurityAttributes, dwCreationDistribution.l, dwFlagsAndAttributes.l, hTemplateFile.l )
   
   ; здесь например по имени файла из указателя *lpFileName определяем
   ; что нужно сделать - найти файл в архиве или вызвать оригинальную функцию
   ; ( вызывать CreateFile нельзя, т.к. адрес в таблице указывает на эту же функцию
   ;   и произойдет рекурсивный вызов, поэтому вызывать нужно именно WINAPICreateFile )
   
   MessageRequester( "", "Hello from MyCreateFile!" )
   
EndProcedure
 
Procedure MyReadFile( hFile.l, *lpBuffer, nNumberOfBytesToRead.l, *lpNumberOfBytesRead, *lpOverlapped )
   
   ; здесь по переданому хендлу hFile
   ; определяем что это за файл, архивный или нет
   ; и соответственно читаем буфер из архива
   ; или же вызываем оригинальную функцию WINAPIReadFile
   
   MessageRequester( "", "Hello from MyReadFile!" )
   
EndProcedure
 
Procedure MyCloseHandle( hFile.l )
   
   ; здесь по переданому хендлу hFile
   ; определяем что это за файл, архивный или нет
   ; и соответственно этому выполняем необходимые действия
   ; либо освобождаем ресурсы выделенные под архивный файл
   ; либо вызываем оригинальную функцию WINAPICloseHandle
   
   MessageRequester( "", "Hello from MyCloseHandle!" )
   
EndProcedure
 
; адрес библиотеки kernel32.dll
Define KERNEL32.l = GetModuleHandle_( @"KERNEL32.DLL" )
 
; адреса функций
Define CreateFileAddress.l = GetProcAddress_( KERNEL32, @"CreateFileA" )
Define ReadFileAddress.l = GetProcAddress_( KERNEL32, @"ReadFile" )
Define CloseHandleAddress.l = GetProcAddress_( KERNEL32, @"CloseHandle" )
 
; адрес этой программы
Define BaseAddress.l = GetModuleHandle_( 0 )
 
; дескриптор импорта библиотеки kernel32.dll
Define *ImportDescriptor.IMAGE_IMPORT_DESCRIPTOR = FindImportDescriptor( BaseAddress, @"KERNEL32.DLL" )
 
; указатели на адреса импортированых функций
Define *CreateFileThunkData.IMAGE_THUNK_DATA32 = FindThunkData( BaseAddress, *ImportDescriptor, CreateFileAddress )
Define *ReadFileThunkData.IMAGE_THUNK_DATA32 = FindThunkData( BaseAddress, *ImportDescriptor, ReadFileAddress )
Define *CloseHandleThunkData.IMAGE_THUNK_DATA32 = FindThunkData( BaseAddress, *ImportDescriptor, CloseHandleAddress )
 
; переписываем адреса функций на свои
*CreateFileThunkData\Function = @MyCreateFile()
*ReadFileThunkData\Function = @MyReadFile()
*CloseHandleThunkData\Function = @MyCloseHandle()
 
; проверяем подмену вызвав оригинальные функции
Define File.l, Temp.l
File = CreateFile_( @"PureBasic.chm", #GENERIC_READ, 0, 0, #OPEN_EXISTING, 0, 0 )
ReadFile_( File, Temp, SizeOf( Temp ), @Temp, 0 )
CloseHandle_( File )
 
; восстанавливаем оригинальные адреса функций
*CreateFileThunkData\Function = CreateFileAddress
*ReadFileThunkData\Function = ReadFileAddress
*CloseHandleThunkData\Function = CloseHandleAddress
 
; проверяем еще раз чтобы убедится что адреса восстановлены успешно
File = CreateFile_( @"PureBasic.chm", #GENERIC_READ, 0, 0, #OPEN_EXISTING, 0, 0 )
ReadFile_( File, Temp, SizeOf( Temp ), @Temp, 0 )
CloseHandle_( File )
 
End
Пример внедрения DLL в сапера (для остановки времени игры).
Программа внедрения.
PureBasic
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#MessageTitle = "Внедрялка"      ; Заголовок сообщений 
#DLLName      = "dll.DLL"        ; Имя инжектируемой библиотеки 
#ProcessName  = "winmine.exe"    ; Искомый процесс 
 
#SE_DEBUG_PRIVILEGE = 20 
 
Procedure LastError() 
  ErrorText.s = Space(255) 
  FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError_(),#LANG_NEUTRAL,ErrorText,256,0) 
  MessageRequester(#MessageTitle, ErrorText, #MB_ICONERROR) 
EndProcedure 
 
Procedure InjectDll(Process.l, ModulePath.s); Внедрение Dll в процесс 
  
  Structure _Inject;: packed record 
    PushCommand.b 
    PushArgument.l 
    CallCommand.w 
    CallAddr.l 
    PushExitThread.b 
    ExitThreadArg.l 
    CallExitThread.w 
    CallExitThreadAddr.l 
    AddrLoadLibrary.l 
    AddrExitThread.l 
    LibraryName.s{255} 
  EndStructure
  
  Inject._Inject 
  
  *Memory = VirtualAllocEx_(Process, #Null, SizeOf(_Inject),#MEM_COMMIT, #PAGE_EXECUTE_READWRITE) 
  If *Memory = #Null 
    ProcedureReturn 0 
  EndIf 
  
  Code.l = *Memory 
  ;//инициализация внедряемого кода: 
  Inject\PushCommand    = $68 
  inject\PushArgument   = Code + $1E 
  inject\CallCommand    = $15FF 
  inject\CallAddr       = Code + $16 
  inject\PushExitThread = $68 
  inject\ExitThreadArg  = 0 
  inject\CallExitThread = $15FF 
  inject\CallExitThreadAddr = Code + $1A 
  hKernel32.l = GetModuleHandle_("kernel32.dll") 
  inject\AddrLoadLibrary = GetProcAddress_(hKernel32, "LoadLibraryA") 
  inject\AddrExitThread  = GetProcAddress_(hKernel32, "ExitThread") 
  inject\LibraryName = ModulePath 
  ;//записать машинный код по зарезервированному адресу 
  WriteProcessMemory_(Process, *Memory, inject, SizeOf(_inject), @BytesWritten) 
  ;//выполнить машинный код 
  hThread.l = CreateRemoteThread_(Process, #Null, 0, *Memory, #Null, 0, @ThreadId) 
  If hThread = 0 
    ProcedureReturn 0 
  EndIf 
  CloseHandle_(hThread) 
  ProcedureReturn 1 
EndProcedure 
 
pe32.PROCESSENTRY32 
pe32\dwSize = SizeOf(PROCESSENTRY32) 
 
hthSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS,0) 
Process32First_(hthSnapshot,@pe32) 
 
While Process32Next_(hthSnapshot,@pe32) 
  If PeekS(@pe32\szExeFile) = #ProcessName 
    
    CurrentDir.s = GetCurrentDirectory() 
    If Right(CurrentDir,1) <> "" : CurrentDir + "" : EndIf 
    RtlAdjustPrivilege_(#SE_DEBUG_PRIVILEGE, #True, #False, @OldPrivilege) 
    hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, #False, pe32\th32ProcessID) 
    If hProcess 
      If Not InjectDll(hProcess, CurrentDir + #DLLName) 
        LastError() 
      EndIf 
    Else 
      LastError() 
    EndIf 
    End 
  EndIf 
  
Wend 
 
MessageRequester(#MessageTitle,"Процесс " + Chr(34) + #ProcessName + Chr(34) + " не найден.",#MB_ICONERROR)
Код dll.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Declare Thread(x)
 
CreateThread(@Thread(), 0)
 
Procedure Thread(x)
  *baseaddress = $100579C 
  Repeat
    Timer=PeekA(*baseaddress) 
    If Timer>2 
      PokeA(*baseaddress, 2)  ; записываем 2 но через 1 сек. задержки  будет 3 
    EndIf 
    Beep_(1000,100) ; Пикалка, показывающая что код работает.
    
    Delay(1000) 
  ForEver
EndProcedure
Кликните здесь для просмотра всего текста
Ссылка на другой форум удалена


Добавлено через 18 минут
Перехват API во всех процессах.
Программа установки хука.
PureBasic
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
Global hHookDll
 
Procedure.s CharToOem(String.s) 
  CharToOem_(@String, @String) 
  ProcedureReturn String 
EndProcedure 
 
Procedure.s SetHook(bSet) 
  If(bSet) ; Если устанавливаем 
    If(hHookDll) ; Если загружена библиотека      
      hpHookProc = GetProcAddress_(hHookDll, "MessageProc"); ; Получим адрес хук-функции      
      If(hpHookProc) ; Если успешно получен адрес ф-ции,               
        hHook = SetWindowsHookEx_(#WH_CALLWNDPROC,  hpHookProc, hHookDll, #Null)        
        If(hHook = #Null) ; Если хук не установился, вернем ошибку          
          ProcedureReturn "Хук не установлен" 
        Else
          ProcedureReturn "хук установлен"
        EndIf        
      Else        
        ProcedureReturn "Функцию HookProc не удалось загрузить из нашей библиотеки"        
      EndIf      
    Else      
      ProcedureReturn "Нашу библиотеку не удалось загрузить"     
    EndIf    
  Else     
    UnhookWindowsHookEx_(hHook)
    ProcedureReturn "хук снят"
  EndIf 
EndProcedure
 
hHookDll = LoadLibrary_("Hook.dll")
 
OpenConsole()
 
PrintN(CharToOem(SetHook(#True)))
Repeat
  
  If GetKeyState_(#VK_CONTROL) = 1 
    PrintN(CharToOem(SetHook(#False)))
    Event=#PB_Event_CloseWindow
    Input()
  EndIf
  
Until Event=#PB_Event_CloseWindow
 
CloseConsole()
Код файла Hook.dll.
PureBasic
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
58
59
60
61
62
63
Structure jmp_far 
  LongJump.b 
  LongJumpAdr.l 
EndStructure 
 
Global JmpW.jmp_far, JmpA.jmp_far 
Global OldW.jmp_far, OldA.jmp_far
 
Prototype pMessageBoxExW(hWnd, lpText,lpCaption,uType,wLanguageId)
Prototype pMessageBoxExA(hWnd, lpText,lpCaption,uType,wLanguageId)
 
Global MbwAdr, MbaAdr
 
Procedure NewMessageBoxExW(hWnd, lpText,lpCaption,uType,wLanguageId)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @OldW, SizeOf(OldW), @written)
  winMessageBoxExW.pMessageBoxExW = MbwAdr
  Result = winMessageBoxExW(hWnd, @"fdgfdgfdg2",lpCaption,uType,wLanguageId)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @JmpW, SizeOf(JmpW), @written) 
  ProcedureReturn Result
EndProcedure
 
Procedure NewMessageBoxExA(hWnd, lpText,lpCaption,uType,wLanguageId)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @OldA, SizeOf(OldA), @written)
  winMessageBoxExA.pMessageBoxExA = MbaAdr
  Result = winMessageBoxExA(hWnd, @"fdgfdgfdg1",lpCaption,uType,wLanguageId)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @JmpA, SizeOf(JmpA), @written) 
  ProcedureReturn Result
EndProcedure
 
Procedure SetHook()
  hUser32.l = GetModuleHandle_("user32.dll")
  MbwAdr  = GetProcAddress_(hUser32, "MessageBoxExW")
  MbaAdr  = GetProcAddress_(hUser32, "MessageBoxExA")
  
  ReadProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr,  @OldW, SizeOf(OldW), @written) 
  ReadProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr,  @OldA, SizeOf(OldA), @written) 
  
  JmpW\LongJump = $E9
  JmpW\LongJumpAdr = (@NewMessageBoxExW()-MbwAdr)-5
  
  JmpA\LongJump = $E9
  JmpA\LongJumpAdr = (@NewMessageBoxExA()-MbaAdr)-5
  
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @JmpW, SizeOf(JmpW), @written) 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @JmpA, SizeOf(JmpA), @written) 
EndProcedure
 
Procedure Unhook() 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @OldW, SizeOf(OldW), @written) 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @OldA, SizeOf(OldA), @written) 
EndProcedure
 
ProcedureDLL MessageProc(nCode,wParam,lParam)  
  ProcedureReturn CallNextHookEx_(#Null, nCode,wParam,lParam)
EndProcedure
 
ProcedureDLL AttachProcess(Instance)
  SetHook() 
EndProcedure
 
ProcedureDLL DetachProcess(Instance)   
  UnHook()
EndProcedure
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
17.05.2014, 13:00  [ТС]
а можно по подробнее про хук во всех процессах. как перехватить несколько апи функции с помощью одной hook.dll ? как после выполнения обработчика вызвать оригинал функции?
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
17.05.2014, 13:24
Лучший ответ Сообщение было отмечено MAGA как решение

Решение

В примере перехватываются две функции MessageBoxExA и MessageBoxExW. Остальные аналогично.
Адреса оригинальных функций находятся в экземплярах OldA и OldW структуры jmp_far.
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
17.05.2014, 21:37  [ТС]
а как узнать ид процесса, которая вызывает перехвачеваемую функцию?
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
17.05.2014, 21:57
Попробуйте использовать функцию GetCurrentProcessId_().
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
18.05.2014, 04:30  [ТС]
а как можно исключить некоторые процессы из перехвата функции?
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
18.05.2014, 22:01
Исключить можно по PID. Если PID такой как у исключаемого процесса, то для него не нужно вызывать SetHook() и UnHook().
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
18.05.2014, 23:17  [ТС]
а можете показать пример, если не трудно? да, и еще, как в purebasic узнать PID самой программы?

Добавлено через 1 минуту
пожалуйста, извините за то , что трачу ваше время своей навязчивостью.
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
19.05.2014, 11:53
Цитата Сообщение от MAGA Посмотреть сообщение
как в purebasic узнать PID самой программы?
Та же функция GetCurrentProcessId_().
Она возвращает ID процесса из которого вызвана.
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
20.05.2014, 15:49  [ТС]
возникла одна проблема, я вот делаю перехват CopyFileExW, хочу узнать путь к копироваемой файле, проверяю переменную в которой она должна была быть , а там какие цифры. вот собственно и код: HOOk.dll:
PureBasic
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Structure jmp_far 
  LongJump.b 
  LongJumpAdr.l 
EndStructure 
 
Global JmpW.jmp_far, JmpA.jmp_far 
Global OldW.jmp_far, OldA.jmp_far
CreateFile(1,"E:\aa.txt")
 
Prototype pMessageBoxExW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, pbCancel, dwCopyFlags)
Prototype pMessageBoxExA(hWnd, lpText,lpCaption,uType,wLanguageId)
 
Global MbwAdr, MbaAdr
Global Name$
Global myID
OpenLibrary(110, "psapi.dll")
 
 
Procedure.s GetProcessFile_Name(PID) ;get the full Filename of the process 
If PID
  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, PID) 
  If hProcess 
    Name$ = Space(1024) 
    CallFunction(110,"GetModuleFileNameExA",hProcess, BaseModule, @Name$, Len(Name$)) 
    CloseHandle_(hProcess) 
    ProcedureReturn Name$ 
  EndIf 
EndIf
EndProcedure 
 
 
 
Procedure NewMessageBoxExW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, pbCancel, dwCopyFlags)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @OldW, SizeOf(OldW), @written)
  winMessageBoxExW.pMessageBoxExW = MbwAdr
    IDproc = GetCurrentProcessId_()
    Path.s = GetProcessFile_Name(IDproc)
    Resul = CallFunctionFast(lpExistingFileName)
    Result = FileSize(Str(resul))
    MessageRequester(Str(Result), Path.s) 
    CallFunction(111,"zaga", @IDproc, @Path.s)
   Result = winMessageBoxExW(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, pbCancel, dwCopyFlags)
   If IDproc <> myID
     WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @JmpW, SizeOf(JmpW), @written)
     EndIf
EndProcedure
OpenLibrary(111, "E:\tests\IDsearch.dll")
 
Procedure SetHook()
  hUser32.l = GetModuleHandle_("Kernel32.dll")
  MbwAdr  = GetProcAddress_(hUser32, "CopyFileExW")
  
  ReadProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr,  @OldW, SizeOf(OldW), @written) 
  
  JmpW\LongJump = $E9
  JmpW\LongJumpAdr = (@NewMessageBoxExW()-MbwAdr)-5
  
  
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @JmpW, SizeOf(JmpW), @written) 
 
EndProcedure
Procedure Unhook() 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @OldW, SizeOf(OldW), @written) 
EndProcedure
 
ProcedureDLL MessageProc(nCode,wParam,lParam)  
  ProcedureReturn CallNextHookEx_(#Null, nCode,wParam,lParam)
EndProcedure
 
ProcedureDLL AttachProcess(Instance)
  IDproc = GetCurrentProcessId_()
  nohookP.s = GetProcessFile_Name(IDproc)
  origno.s = ProgramFilename()
  If nohookP.s <> origno.s
    SetHook() 
    EndIf
EndProcedure
 
ProcedureDLL DetachProcess(Instance)  
  IDproc = GetCurrentProcessId_()
  nohookP.s = GetProcessFile_Name(IDproc)
  origno.s = ProgramFilename()
  If nohookP.s <> origno.s
    UnHook() 
    EndIf
  EndProcedure
программа установки хука:
PureBasic
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
Global hHookDll
 
Procedure.s CharToOem(String.s) 
  CharToOem_(@String, @String) 
  ProcedureReturn String 
EndProcedure 
 
Procedure.s SetHook(bSet) 
  If(bSet) ; Если устанавливаем 
    If(hHookDll) ; Если загружена библиотека      
      hpHookProc = GetProcAddress_(hHookDll, "MessageProc"); ; Получим адрес хук-функции      
      If(hpHookProc) ; Если успешно получен адрес ф-ции,               
        hHook = SetWindowsHookEx_(#WH_CALLWNDPROC,  hpHookProc, hHookDll, #Null)        
        If(hHook = #Null) ; Если хук не установился, вернем ошибку          
          ProcedureReturn "Хук не установлен" 
        Else
          ProcedureReturn "хук установлен"
        EndIf        
      Else        
        ProcedureReturn "Функцию HookProc не удалось загрузить из нашей библиотеки"        
      EndIf      
    Else      
      ProcedureReturn "Нашу библиотеку не удалось загрузить"     
    EndIf    
  Else     
    UnhookWindowsHookEx_(hHook)
    ProcedureReturn "хук снят"
  EndIf 
EndProcedure
 
hHookDll = LoadLibrary_("apiperdll2.dll")
 
OpenConsole()
 
PrintN(CharToOem(SetHook(#True)))
Repeat
  
  If GetKeyState_(#VK_CONTROL) = 1 
    PrintN(CharToOem(SetHook(#False)))
    Event=#PB_Event_CloseWindow
    Input()
  EndIf
  
Until Event=#PB_Event_CloseWindow
 
CloseConsole()
программа для теста:
PureBasic
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
#PROGRESS_CONTINUE        = 0 
#PROGRESS_CANCEL          = 1 
Enumeration 
 #CopyProgressBar 
 #CopyProgressText
 #ProgressWnd 
EndEnumeration 
 
Global Flag_CopyState = #PROGRESS_CONTINUE 
 
Procedure.l CopyProgressCallback(TotalFileSize , TotalBytesTransferred , StreamSize , StreamBytesTransferred , dwStreamNumber.l , dwCallbackReason.l , hSourceFile.l)
    TotalFileSize_ = (TotalFileSize>>16) &$FFFFFFFF 
    StreamSize_    = 100 * (StreamSize>>16) &$FFFFFFFF 
    If TotalFileSize_ > 0 And StreamSize_ > 0 
      Prozent = 100 * (StreamSize>>16) &$FFFFFFFF / (TotalFileSize>>16) &$FFFFFFFF 
    Else 
      Prozent = 100 
    EndIf 
    SetGadgetState(#CopyProgressBar  , Prozent ) 
    SetGadgetText (#CopyProgressText , "Orginal: " + Str(TotalFileSize)+ " Bytes     " + Str(StreamSize)+" Bytes transfered" ) 
    If Prozent = 100 : SetGadgetText (#CopyProgressText , "Orginal: " + Str(TotalFileSize)+ " Bytes     " + Str(StreamSize)+" Bytes  finished!" ) : EndIf 
  ProcedureReturn Flag_CopyState 
EndProcedure 
; Копирование файла выполняется в отдельном потоке. 
Procedure CopyFile_Thread(*x) 
  If CopyFileEx_( @"C:\install.log", @"D:\install.log4", @CopyProgressCallback(), 0, Flag, 0) 
    MessageRequester("", "copy yes") 
  Else 
    ErrorCode=GetLastError_() 
    ErrorBuffer$ = Space(1024) 
    FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, ErrorCode, 0, @ErrorBuffer$, Len(ErrorBuffer$), 0) 
    MessageRequester("Error", "CopyFileEx_() ошибка:"+Chr(10)+Chr(10)+ErrorBuffer$, 0) 
    SetGadgetState(#CopyProgressBar  , 0) 
  EndIf 
EndProcedure 
 
If OpenWindow(#ProgressWnd, 216, 0, 320, 120, " Filecopy Progress ", #PB_Window_SystemMenu | #PB_Window_SizeGadget) 
  ProgressBar = ProgressBarGadget(#CopyProgressBar , 10 , 15 , 300 , 20 , 0 , 100 , #PB_ProgressBar_Smooth) 
  TextGadget(#CopyProgressText , 11 , 54 , 280 , 20, "") 
        ButtonGadget(100, 200, 80,80, 20, "Отмена" )
        ButtonGadget(110, 110, 80,80, 20, "Старт" )
  Repeat 
    Event = WaitWindowEvent() 
    If Event = #PB_Event_Gadget 
      If EventGadget() = 100 
        Flag_CopyState = #PROGRESS_CANCEL 
      ElseIf EventGadget() = 110
        CreateThread(@CopyFile_Thread(), 0)  
      EndIf 
    EndIf 
  Until Event = #PB_Event_CloseWindow 
EndIf
перехват выполняется, но в переменной "lpExistingFileName" (в HOOk.dll), находится не путь к файлу а какой то дескриптор. пожалуйста, помоги
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
20.05.2014, 17:24
Цитата Сообщение от MAGA Посмотреть сообщение
но в переменной "lpExistingFileName" (в HOOk.dll), находится не путь к файлу а какой то дескриптор.
Там указатель на строку. Получить строку можно используя функцию PeekS().
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
21.05.2014, 00:06  [ТС]
наверное это все. большое спасибо вам, от души благодарен!!!
0
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
24.05.2014, 21:01  [ТС]
доброго дня, друг. у меня опять проблема , пытаюсь сделать запись числа (с каждым разом прибавляя 1) в текстовый файл при вызове перехвачиваемой функции , и все это вроде бы я реализовал, но не знаю где ошибка, она пищит неправильно число. вот код: hook.dll:
PureBasic
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
OpenLibrary(110, "psapi.dll")
Structure jmp_far 
  LongJump.b 
  LongJumpAdr.l 
EndStructure 
 
OpenLibrary(24, "engt.dll")
 
Global JmpW.jmp_far, JmpA.jmp_far 
Global OldW.jmp_far, OldA.jmp_far
 
Prototype pMessageBoxExW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
Prototype pMessageBoxExA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
 
Global MbwAdr, MbaAdr
Global myID
Global myP.s
Global sd
Global decas
Global lists
Procedure.s GetProcessFile_Name(PID) ;get the full Filename of the process 
If PID
  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, PID) 
  If hProcess 
    Name$ = Space(1024) 
    CallFunction(110,"GetModuleFileNameExA",hProcess, BaseModule, @Name$, Len(Name$)) 
    CloseHandle_(hProcess) 
    ProcedureReturn Name$ 
  EndIf 
EndIf
EndProcedure 
Procedure NewMessageBoxExW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @OldW, SizeOf(OldW), @written)
  lists = lists + 1
  CallFunction(24, "count", lists)
  winMessageBoxExW.pMessageBoxExW = MbwAdr
  Result = winMessageBoxExW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @JmpW, SizeOf(JmpW), @written) 
  ProcedureReturn Result
EndProcedure
 
Procedure NewMessageBoxExA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @OldA, SizeOf(OldA), @written)
    lists = lists + 1
  CallFunction(24, "count", lists)
  winMessageBoxExA.pMessageBoxExA = MbaAdr
  Result = winMessageBoxExA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @JmpA, SizeOf(JmpA), @written) 
  ProcedureReturn Result
EndProcedure
 
Procedure SetHook()
  hUser32.l = GetModuleHandle_("Kernel32.dll")
  MbwAdr  = GetProcAddress_(hUser32, "CreateFileW")
  MbaAdr  = GetProcAddress_(hUser32, "CreateFileA")
  
  ReadProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr,  @OldW, SizeOf(OldW), @written) 
  ReadProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr,  @OldA, SizeOf(OldA), @written) 
  
  JmpW\LongJump = $E9
  JmpW\LongJumpAdr = (@NewMessageBoxExW()-MbwAdr)-5
  
  JmpA\LongJump = $E9
  JmpA\LongJumpAdr = (@NewMessageBoxExA()-MbaAdr)-5
  
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @JmpW, SizeOf(JmpW), @written) 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @JmpA, SizeOf(JmpA), @written) 
EndProcedure
 
Procedure Unhook() 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbwAdr, @OldW, SizeOf(OldW), @written) 
  WriteProcessMemory_(#INVALID_HANDLE_VALUE, MbaAdr, @OldA, SizeOf(OldA), @written) 
EndProcedure
 
ProcedureDLL MessageProc(nCode,wParam,lParam)  
  ProcedureReturn CallNextHookEx_(#Null, nCode,wParam,lParam)
EndProcedure
ProcedureDLL AttachProcess(Instance)
  IDproc = GetCurrentProcessId_()
  ineP.s = GetProcessFile_Name(IDproc)
  myP.s = ProgramFilename()
  If myP.s <> ineP.s
    If "\\Jerami-pc\E\tests\engt.dll" <> ineP.s
Sethook()
  EndIf
  EndIf
EndProcedure
 
ProcedureDLL DetachProcess(Instance)   
  IDproc = GetCurrentProcessId_()
  ineP.s = GetProcessFile_Name(IDproc)
  myP.s = ProgramFilename()
  If myP.s <> ineP.s
    If "\\Jerami-pc\E\tests\engt.dll" <> ineP.s
Unhook()
  EndIf
  EndIf
EndProcedure
установка хука:
PureBasic
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
Global hHookDll, hpHookProc2
 
Procedure.s CharToOem(String.s) 
  CharToOem_(@String, @String) 
  ProcedureReturn String 
EndProcedure 
 
Procedure.s SetHook(bSet) 
  If(bSet) ; Если устанавливаем 
    If(hHookDll) ; Если загружена библиотека      
      hpHookProc = GetProcAddress_(hHookDll, "MessageProc"); ; Получим адрес хук-функции 
      If(hpHookProc) ; Если успешно получен адрес ф-ции,               
        hHook = SetWindowsHookEx_(#WH_CALLWNDPROC,  hpHookProc, hHookDll, #Null)        
        If(hHook = #Null) ; Если хук не установился, вернем ошибку          
          ProcedureReturn "Хук не установлен" 
        Else
          ProcedureReturn "хук установлен"
        EndIf        
      Else        
        ProcedureReturn "Функцию HookProc не удалось загрузить из нашей библиотеки"        
      EndIf      
    Else      
      ProcedureReturn "Нашу библиотеку не удалось загрузить"     
    EndIf    
  Else     
    UnhookWindowsHookEx_(hHook)
    ProcedureReturn "хук снят"
  EndIf 
EndProcedure
 
hHookDll = LoadLibrary_("apiperdll3.dll")
OpenConsole()
 
PrintN(CharToOem(SetHook(#True)))
Repeat
  
  If GetKeyState_(#VK_CONTROL) = 1 
    PrintN(CharToOem(SetHook(#False)))
    Event=#PB_Event_CloseWindow
    Input()
  EndIf
  Delay(20000)
Until Event=#PB_Event_CloseWindow
CloseConsole()
библиотека из которой вызывается функция записи:
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Global lis
ProcedureDLL count(lists)
lis = lis + 1
EndProcedure
Procedure zapis(va)
  While 1 <> 2
  OpenFile(234, "list2.txt")
  lists2.l = lis
       WriteString(234, Str(lists2.l),#PB_UTF8)
       CloseFile(234)
       Delay(5000)
       Wend
 EndProcedure
 CreateThread(@zapis(), 1)
вместо прибавления числа, пишет в файл то больше, то меньше.
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
24.05.2014, 21:18
Что пишет в файл?

В процедуре count() не используется аргумент lists. Может дело в этом?
1
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
25.05.2014, 23:32  [ТС]
пишет разные числа, с начало вверх 1-2-3-4 и.тд, потом вниз 2 и.тд, хотя должна была писать только прибавляя

Добавлено через 2 минуты
нет, в библиотеке записи неиспользуется lists, хотя она находится в параметрах
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
26.05.2014, 09:21
Возможно дело в том, что у каждого процесса своя область памяти для переменных dll. Они изолированы между собой чтобы не влияли друг на друга и не искажали результат. Но в данном случае, похоже что нужна общая память.
0
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
26.05.2014, 17:16  [ТС]
ну тогда мн
сбадо создать область памяти в библиотеке хука , и передавать указатель на нее?

Добавлено через 1 минуту
мне надо т.е
0
23 / 23 / 0
Регистрация: 15.05.2014
Сообщений: 131
30.05.2014, 15:39  [ТС]
?
друг
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.05.2014, 15:39
Помогаю со студенческими работами здесь

функции Win API
Помогите разобраться с функциями GetExceptionCode и GetStartUpInfo в Delphi. Сгодится любая помощь! Синтаксис использования, описание и...

Простые функции в win api
никак не могу с этим окном разобраться, нигде нет объяснения, максимум готовый код. помогите разобраться, пожалуйста. я попытался...

Функции изображений и текста в win api
Здравствуйте, не могли бы вы назвать функции из Win API, выводящие в окно текст и изображения? И ещё вопрос, есть ли в Win API функции,...

описание функции shellExecute WIN API!
Что нужно написать, что-бы при нажатии на кнопку запускалась определённая .ехе программа или открывался архив Winrar?????

Функции Win API для работы с процессорами
Здравствуйте, ток начал изучать API функции есть, интересует в данную минуту распараллеливание потоков по процессорам на n ядерной...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru