Форум программистов, компьютерный форум, киберфорум
The trick
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Внедрение в чужой процесс на VB6 (без DLL)

Запись от The trick размещена 26.01.2014 в 17:03
Показов 12114 Комментарии 7
Метки injection, multithreading, vb


Всем известна утилита SPYXX. С помощью нее можно делать много чего интересного. В числе ее возможностей - просмотр сообщений отправленных окну и результаты их обработки. Я решил сделать что-то подобное только на VB6 (не в качестве создания программы типа SPYXX, а в качестве демонстрации возможности внедрения кода из VB6, так что функционал проги очень маленький). Как известно SPYXX делает это с помощью глобальных хуков, но мне была интересна идея внедрения без DLL (c DLL все гораздо проще можно сделать, у Рихтера описано как можно несколькими функциями внедрится в чужой код с помощью DLL) и я решил сделать немного по другому. В моем примере код вместе с оконной процедурой непосредственно копируется в АП нужного процесса и там запускается (работает только с 32 разрядными приложениями). Там я размещаю код, который устанавливает новую процедуру обработки сообщений, для окна и усыпляю поток. В новой процедуре, я всего лиш передаю параметры, которые получило чужое окно, моему окну (frmSpy), далее вызывается оригинальная процедура окна. Скажу сразу - передача осуществляется не самым эффективным способом, можно было сделать гораздо эффективнее напрямую работая с FileMapping'ом, либо асинхронно передавать 2 сообщения подряд. Но я не стал заморачиваться лишним кодом, т.к. моя конечная цель не эффективность. Отмена инъекции осуществляеться пробуждением потока и завершению его естественным образом, после чего из своей программы я освобождаю ресурсы. Работу я проверял в отладчике все работает, как и задумывалось.
При работе в другом процессе, вообще не используется рантайм, хотя можно его загрузить и использовать (про инициализацию контекста потока отдельно) его функции, массивы строки и т.п. Также возникает проблема работы с переменными, т.к. глобальных переменных "не существует", и соответственно обращение к любым таким переменным может оказаться фатальным для всего процесса. Для вызова API я использую сплайсинг "псевдофункций API", заменяю вызов на безусловный переход к нужной функции. Работа с переменными осуществляеться в выделенной для этого области. Для того чтобы ее сохранить я использую SetProp, т.к. из WindowProc я могу что-то идентифицировать только через hWnd. Если надо добавить еще какие-либо глобальные переменные, то можно в этой области выделить место под строки и т.п. (например для вызова LoadLibrary с нужным параметром). Если бы в VB была непосредственная работа с указателями (без VarPtr, GetMem и т.п. функций), то было намного проще. Можно делать сразу ассемблерный переходник и в нем можно узнать значения переменных переданных в поток без SetProp и CopyMemory, но это детали, кто захочет - тот сделает.

Модуль modInjection.mod:
Visual Basic
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
Option Explicit
 
' Модуль для внедрения в чужой процесс и подмены оконной процедуры, с целью получить все сообщения пересылемые окну
' © Кривоус Анатолий Анатольевич (The trick), 2014
 
 
' ******                  ******* **                                         *            **
'  *    *                 *  *  *  *                        *                              *
'  *    *                    *     *                        *                              *
'  *    * *** ***            *     * **    *****           ****   *** **   ***     *****   *  **
'  *****   *   *             *     **  *  *     *           *       **  *    *    *     *  *  *
'  *    *  *   *             *     *   *  *******           *       *        *    *        * *
'  *    *   * *              *     *   *  *                 *       *        *    *        ***
'  *    *   * *              *     *   *  *     *           *  *    *        *    *     *  *  *
' ******     *              ***   *** ***  *****             **   *****    *****   *****  **   **
'            *
'          **
 
Private Type MessageInfo                    ' Эту структуру передаем в качестве параметра нашему окну
    Msg As Long
    wParam As Long
    lParam As Long
End Type
Private Type TrickThreadData
    SrcWnd As Long                          ' Хендл сабклассируемого окна
    DesthWnd As Long                        ' Хендл окна frmSpy
    EventHandle As Long                     ' Хендл события, отвечающего за завершение потока
    AddrWindowProc As Long                  ' Адрес функции WindowProc в чужом процессе
    AddrStructure As Long                   ' Адрес этой структуры
    Msg As MessageInfo                      ' Для передачи указателя COPYDATASTRUCT
End Type
Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type
 
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32.dll" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32.dll" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CreateRemoteThread Lib "kernel32" (ByVal hProcess As Long, lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (src As Any, dst As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As Any, ByVal bManualReset As Long, ByVal bInitialState As Long, lpName As Any) As Long
Private Declare Function PulseEvent Lib "kernel32" (ByVal hEvent As Long) As Long
Private Declare Function DuplicateHandle Lib "kernel32" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As Any) As Long
 
Private Const WM_COPYDATA = &H4A
Private Const GWL_WNDPROC = (-4)
Private Const DUPLICATE_SAME_ACCESS = &H2
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Const MEM_COMMIT = &H1000&
Private Const MEM_RESERVE = &H2000&
Private Const MEM_RELEASE = &H8000&
Private Const PAGE_EXECUTE_READWRITE = &H40&
Private Const INFINITE = -1&
 
Private Const Prop As String = "pInject"                    ' 7 символов + \0, итого 8 байт, вполне помещается в переменную типа Currency
Private Const PropCur As Currency = 3276038452689.5472@     ' Строка Prop в виде Currecy числа
 
Public hProcess As Long                                     ' Хендл процесса, в который внедряемся
Public hThread As Long                                      ' Хендл потока, который мы создадим в чужом процессе
Public TID As Long                                          ' Идентификатор этого потока
Public lpProc As Long                                       ' Адрес функции InjectionProc
Public Size As Long                                         ' Размер данных и кода, внедряемого в процесс
Public hEvent As Long                                       ' Описатель события в нашем процессе
 
Dim lpPrevWndProc As Long                                   ' Адрес оконной процедуры frmSpy (изначальный)
 
' Функция внедряет код в чужой процесс
Public Function Hook(hwnd As Long) As Boolean
    Dim Buf() As Byte, ret As Long, PID As Long, DupHandle As Long, nearWndProc As Long, _
        FuncOf() As Long, FuncAddr() As Long, hMod As Long, lpFunc As Long, i As Long, lpData As Long
        
    If hProcess Then Clear                   ' Если перехват был, то убираем
    GetWindowThreadProcessId hwnd, PID
    
    ' Инициализация словаря
    If modListView.Dic Is Nothing Then modListView.DicInit
    
    If PID Then hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, PID) Else Exit Function
 
    ' Создаем событие для управления потоком
    hEvent = CreateEvent(ByVal 0, 1, 0, ByVal 0)
 
    If hEvent = 0 Then Clear: Exit Function
    ' Создаем дубликат описателя события для процесса
    If DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, DupHandle, 0, False, DUPLICATE_SAME_ACCESS) = 0 Then Clear: Exit Function
 
    ' Определяем размер для внедренного кода
    lpData = AddrOf(AddressOf AddrOf) - AddrOf(AddressOf InjectionProc)
    ' Определяем относительное смещение функции WindowProc от данных
    nearWndProc = AddrOf(AddressOf AddrOf) - AddrOf(AddressOf WindowProc)
    ' Определяем размер данных и кода
    Size = lpData + 32
 
    ' Выделяем память в чужом процессе
    lpProc = VirtualAllocEx(hProcess, ByVal 0, Size, MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
    If lpProc = 0 Then MsgBox "Error allocate memory", vbCritical: Clear: Exit Function
 
    ' Определяем смещения для псевдофункций API относительно начала данных
    ReDim FuncOf(9)
    FuncOf(0) = AddrOf(AddressOf myCopyMemory) - AddrOf(AddressOf InjectionProc)
    FuncOf(1) = AddrOf(AddressOf myCopyMemory2) - AddrOf(AddressOf InjectionProc)
    FuncOf(2) = AddrOf(AddressOf myCloseHandle) - AddrOf(AddressOf InjectionProc)
    FuncOf(3) = AddrOf(AddressOf myWaitForSingleObject) - AddrOf(AddressOf InjectionProc)
    FuncOf(4) = AddrOf(AddressOf mySetProp) - AddrOf(AddressOf InjectionProc)
    FuncOf(5) = AddrOf(AddressOf myGetProp) - AddrOf(AddressOf InjectionProc)
    FuncOf(6) = AddrOf(AddressOf myRemoveProp) - AddrOf(AddressOf InjectionProc)
    FuncOf(7) = AddrOf(AddressOf mySetWindowLong) - AddrOf(AddressOf InjectionProc)
    FuncOf(8) = AddrOf(AddressOf mySendMessage) - AddrOf(AddressOf InjectionProc)
    FuncOf(9) = AddrOf(AddressOf myCallWindowProc) - AddrOf(AddressOf InjectionProc)
 
    ' Определяем адреса API функций, для системных библиотек их образы спроецированы по одному и томуже адресу что и у нас
    ReDim FuncAddr(9)
    hMod = GetModuleHandle("kernel32")
    FuncAddr(0) = GetProcAddress(hMod, "RtlMoveMemory")
    FuncAddr(1) = FuncAddr(0)
    FuncAddr(2) = GetProcAddress(hMod, "CloseHandle")
    FuncAddr(3) = GetProcAddress(hMod, "WaitForSingleObject")
    hMod = GetModuleHandle("user32")
    FuncAddr(4) = GetProcAddress(hMod, "SetPropA")
    FuncAddr(5) = GetProcAddress(hMod, "GetPropA")
    FuncAddr(6) = GetProcAddress(hMod, "RemovePropA")
    FuncAddr(7) = GetProcAddress(hMod, "SetWindowLongA")
    FuncAddr(8) = GetProcAddress(hMod, "SendMessageA")
    FuncAddr(9) = GetProcAddress(hMod, "CallWindowProcA")
 
    ' Копируем код
    ReDim Buf(Size - 1)
    CopyMemory Buf(0), ByVal AddrOf(AddressOf InjectionProc), lpData
 
    ' Модифицируем код для вызова API вместо наших пустышек
    For i = 0 To UBound(FuncOf)
        Buf(FuncOf(i)) = &HE9                                                   ' JMP
        GetMem4 (FuncAddr(i) - FuncOf(i) - lpProc) - 5, Buf(FuncOf(i) + 1)      ' near (относительный прыжок на API функцию)
    Next
 
    ' Копируем данные
    GetMem4 hwnd, Buf(lpData)                                                   ' Хендл сабклассируемого окна
    GetMem4 frmSpy.hwnd, Buf(lpData + 4)                                        ' Хендл окна-приемника
    GetMem4 DupHandle, Buf(lpData + 8)                                          ' Хендл события
    GetMem4 lpProc + lpData - nearWndProc, Buf(lpData + 12)                     ' Адрес WindowProc в чужом процессе
    GetMem4 lpProc + lpData, Buf(lpData + 16)                                   ' Адрес этой структуры в чужом процессе
    
    ' Делаем инъекцию
    If WriteProcessMemory(hProcess, lpProc, Buf(0), Size, ret) Then
        If ret <> Size Then MsgBox "Error write process", vbCritical: Clear: Exit Function
        ' Запускаем код инъекции
        hThread = CreateRemoteThread(hProcess, ByVal 0, 0, lpProc, ByVal lpProc + Size - 32, 0, TID)
        If hThread = 0 Then MsgBox "Error create thread", vbCritical: Clear: Exit Function
    End If
    
    lpPrevWndProc = SetWindowLong(frmSpy.hwnd, GWL_WNDPROC, AddressOf SpyWindowProc)     ' Сабклассим наше окно
    
    Hook = True
End Function
 
' Удалить инъекцию
Public Sub Clear()
    If lpPrevWndProc Then
        SetWindowLong frmSpy.hwnd, GWL_WNDPROC, lpPrevWndProc       ' Убираем сабклассинг
        lpPrevWndProc = 0
    End If
    If hThread Then
        PulseEvent hEvent                                           ' Запускаем завершение потока
        WaitForSingleObject hThread, INFINITE                       ' Ждем завершения потока (замораживаемся)
        CloseHandle hThread                                         ' Закрываем описатель потока
        hThread = 0
    End If
    If lpProc Then
        Call VirtualFreeEx(hProcess, ByVal lpProc, 0, MEM_RELEASE)  ' Освобождаем выделенную память
    End If
    If hProcess Then
        CloseHandle hProcess                                        ' Закрываем описатель процесса
        hProcess = 0
    End If
    If hEvent Then
        CloseHandle hEvent                                          ' Закрываем описатель события (объект тоже удалится)
        hEvent = 0
    End If
End Sub
' Оконная процедура для отслеживания сообщений из нашего процесса
Private Function SpyWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim CDS As COPYDATASTRUCT, Info As MessageInfo
    
    If Msg = WM_COPYDATA Then
        ' Получили сообщение из того процесса!!!
        CopyMemory CDS, ByVal lParam, Len(CDS)
        CopyMemory Info, ByVal CDS.lpData, CDS.cbData
        ItemAdd modListView.GetMessageName(Info.Msg), Info.wParam, Info.lParam
    End If
    
    ' Обрабатываем как и раньше
    SpyWindowProc = CallWindowProc(lpPrevWndProc, hwnd, Msg, wParam, ByVal lParam)
End Function
 
' Данный код выполняется в АП чужого процесса, поэтому он не имеет понятия ни о каких глобальных или локальных переменных
' уровня этого модуля, единственная область памяти с которой он может работать передаеться ему указателем на структуру
' TrickThreadData, который в последствии сохраняется в свойстве окна 'pInject'. Вызов наших функций, ведет к перенапрвлению
' к соответствующим API функциям. Здесь выполняется код, который вообще не использует рантайм. Для использования функций
' рантайма (сейчас о функциях которые не требуют инициализацию контекста потока), нужно его предварительно загрузить, через
' LoadLibrary() и получить адреса функций через GetProcAddress(). Все символьные имена и переменные, нужно хранить в
' в выделенной для этого предварительно памяти. Так что обращение к любой глобальной переменной или константе
' (пример s$="VB6 best language") может вызвать ошибку доступа
 
' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
' Процедура, выполняемая в чужом процессе, передаем ей указатель на данные
Private Sub InjectionProc(Dat As TrickThreadData)
    Dim lpOldProc As Long
    ' Мы в чужом процессе ))
    mySetProp Dat.SrcWnd, PropCur, Dat.AddrStructure                         ' Устанавливаем окну свойство с указателем на данные
    lpOldProc = mySetWindowLong(Dat.SrcWnd, GWL_WNDPROC, Dat.AddrWindowProc) ' Устанавливаем окну новый оконный обработчик
    ' Вместо нового адреса процедуры пишем старое
    Dat.AddrWindowProc = lpOldProc
    ' Замораживаем поток
    myWaitForSingleObject Dat.EventHandle, INFINITE
    ' Поток разморожен, значит надо возвращать все на место
    mySetWindowLong Dat.SrcWnd, GWL_WNDPROC, Dat.AddrWindowProc
    myRemoveProp Dat.SrcWnd, PropCur
    ' Закрываем описатель события
    myCloseHandle Dat.EventHandle
    ' Все поток закончен, теперь Clear разморозится и очистит занимаемую память
End Sub
 
' Прцедуры вызова соответствующих API c помощью сплайсинга
Private Function myCopyMemory(dst As TrickThreadData, ByVal src As Long, ByVal Length As Long) As Long
    myCopyMemory = -1
End Function
Private Function myCopyMemory2(ByVal dst As Long, src As TrickThreadData, ByVal Length As Long) As Long
    myCopyMemory2 = -2
End Function
Private Function mySetProp(ByVal hwnd As Long, ByRef Name As Currency, ByVal Value As Long) As Long
    mySetProp = -3
End Function
Private Function myGetProp(ByVal hwnd As Long, ByRef Name As Currency) As Long
    myGetProp = -4
End Function
Private Function myRemoveProp(ByVal hwnd As Long, ByRef Name As Currency) As Long
    myRemoveProp = -5
End Function
Private Function mySetWindowLong(ByVal hwnd As Long, ByVal Index As Long, ByVal Data As Long) As Long
    mySetWindowLong = -6
End Function
Private Function myWaitForSingleObject(ByVal hEvent As Long, ByVal Millisecond As Long) As Long
    myWaitForSingleObject = -7
End Function
Private Function mySendMessage(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As COPYDATASTRUCT) As Long
    mySendMessage = -8
End Function
Private Function myCallWindowProc(ByVal addr As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    myCallWindowProc = -9
End Function
Private Function myCloseHandle(ByVal Handle As Long) As Long
    myCloseHandle = -10
End Function
' Оконная функция, которая будет работать в чужом процессе
Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim lpDat As Long, Dat As TrickThreadData, CDS As COPYDATASTRUCT
    
    lpDat = myGetProp(hwnd, PropCur)
 
    myCopyMemory Dat, lpDat, Len(Dat)                   ' Копируем параметры
    
    ' Устанавливаем параметры сообщения
    Dat.Msg.Msg = uMsg
    Dat.Msg.wParam = wParam
    Dat.Msg.lParam = lParam
    
    myCopyMemory2 lpDat, Dat, Len(Dat)                  ' Копируем параметры обратно
    
    CDS.cbData = Len(Dat.Msg)
    CDS.lpData = lpDat + 20                             ' Смещение структуры MessageInfo, относительно данных
    
    ' Отправляем нашему окну уведомление
    mySendMessage Dat.DesthWnd, WM_COPYDATA, hwnd, CDS
    
    ' Вызываем процедуру по умолчанию
    WindowProc = myCallWindowProc(Dat.AddrWindowProc, hwnd, uMsg, wParam, lParam)
End Function
' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
' Эта функция также служит маркером конца функции и в процесс не копируется
Private Function AddrOf(Value As Long) As Long
    AddrOf = Value
End Function
Модуль modEnumWindow.mod:
Visual Basic
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
Option Explicit
 
' Модуль для получения окна под курсором (с учетом Z-порядка)
' © Кривоус Анатолий Анатольевич (The trick), 2014
 
Private Type Point
    x As Long
    y As Long
End Type
 
Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Private Declare Function WindowFromPoint Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As Any) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal ptx As Long, ByVal pty As Long) As Long
Private Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
 
Private Const WS_EX_MDICHILD As Long = &H40&
Private Const WS_CHILD As Long = &H40000000
Private Const GWL_STYLE As Long = (-16)
Private Const GWL_EXSTYLE As Long = (-20)
Private Const GW_CHILD As Long = 5
Private Const GW_HWNDPREV As Long = 3
Private Const GW_HWNDLAST As Long = 1
 
' Получить хендл окна исходя из позиции курсора
Public Function GetWindowFromCursorPos() As Long
    Dim pt As Point, PID As Long, TID As Long, hwnd As Long, hWndParent As Long
    
    GetCursorPos pt
    hWndParent = WindowFromPoint(pt.x, pt.y)
 
    TID = GetWindowThreadProcessId(hWndParent, PID)
    If App.ThreadID = TID And GetCurrentProcessId() = PID Then Exit Function        ' Игнорируем окна нашего приложения
 
    hwnd = EnumWindowZOrder(hWndParent, pt, True)                                   ' Перебираем все дочерние окна
    
    Do While hWndParent <> hwnd And hwnd
        DoEvents
        hWndParent = EnumWindowZOrder(hwnd, pt, False)                              ' Перебераем все сестринские окна
        hwnd = EnumWindowZOrder(hWndParent, pt, True)                               ' Пока у него есть дети
    Loop
 
    If (GetWindowLong(hWndParent, GWL_STYLE) And WS_CHILD) Then                     ' Возвращаем если окно дочернее
        GetWindowFromCursorPos = hWndParent
    ElseIf (GetWindowLong(hWndParent, GWL_EXSTYLE) And WS_EX_MDICHILD) = 0 Then
        GetWindowFromCursorPos = hWndParent
    Else
        GetWindowFromCursorPos = EnumWindowZOrder(hWndParent, pt, False)
    End If
 
End Function
' Точка внутри окна
Private Function PtInWindow(hwnd As Long, x As Long, y As Long) As Boolean
    Dim RC As RECT
    GetWindowRect hwnd, RC
    PtInWindow = PtInRect(RC, x, y)
End Function
' Перечисление окон и возврат окна по координатам
Private Function EnumWindowZOrder(ByVal hwnd As Long, pt As Point, Optional IsParent As Boolean) As Long
    Dim hRgn As Long
    
    hRgn = CreateRectRgn(0, 0, 0, 0)
    
    If IsParent Then hwnd = GetWindow(hwnd, GW_CHILD)
 
    hwnd = GetWindow(hwnd, GW_HWNDLAST)
    
    Do While hwnd
        DoEvents
        If IsWindowVisible(hwnd) And PtInWindow(hwnd, pt.x, pt.y) Then
            If GetWindowRgn(hwnd, hRgn) = 0 Then Exit Do
            If PtInRegion(hRgn, pt.x, pt.y) Then Exit Do
        End If
        hwnd = GetWindow(hwnd, GW_HWNDPREV)
    Loop
    
    DeleteObject hRgn
    EnumWindowZOrder = hwnd
End Function
Модуль modListView.mod:
Visual Basic
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
166
167
168
169
170
Option Explicit
 
' Дополнительный модуль для работы с SysListView32
' © Кривоус Анатолий Анатольевич (The trick), 2014
 
' Стандартный ListViewWndClass перерисовывает всю клиентскую область при добавлении
' новой записи, либо при прокрутке из-за этого происходит неприятное мерцание, иногда
' даже полностью "белеет" фон. Для предотвращения такого поведения я решил использовать
' SysListView32, который ведет себя правильно при добавлении записей и прокрутке
' Также я использую в качестве идентификации сообщений коллекцию, с ключом - номером сообщения
' поэтому не поддерживаются одинаковые номера сообщений, т.к. я делал этот пример только
' ради демонстрации внедрения
 
Private Type LVITEM
    mask       As Long
    iItem      As Long
    iSubItem   As Long
    State      As Long
    stateMask  As Long
    pszText    As String
    cchTextMax As Long
    iImage     As Long
    lParam     As Long
    iIndent    As Long
End Type
Private Type LVCOLUMN
    mask As Long
    fmt As Long
    CX As Long
    pszText As String
    cchTextMax As Long
    iSubItem As Long
    iImage As Long
    iOrder As Long
End Type
Private Type tagInitCommonControlsEx
    dwSize As Long
    dwICC As Long
End Type
Private Declare Function InitCommonControlsEx Lib "comctl32" (ByRef TLPINITCOMMONCONTROLSEX As tagInitCommonControlsEx) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
 
Private Const ICC_WIN95_CLASSES = &HFF
Private Const WS_CHILD = &H40000000
Private Const WS_TABSTOP = &H10000
Private Const LVS_REPORT = &H1&
Private Const LVS_SINGLESEL = &H4&
Private Const WS_EX_CLIENTEDGE = &H200&
Private Const LVS_EX_FULLROWSELECT = &H20&
Private Const LVS_EX_GRIDLINES = &H1&
Private Const SW_SHOW = 5
 
Private Const LVM_FIRST = &H1000
Private Const LVM_INSERTCOLUMN = (LVM_FIRST + 27)
Private Const LVM_INSERTITEM = (LVM_FIRST + 7)
Private Const LVM_SETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 54)
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_ENSUREVISIBLE = (LVM_FIRST + 19)
Private Const LVM_SETITEMTEXTA = (LVM_FIRST + 46)
Private Const LVCF_WIDTH = &H2
Private Const LVCF_TEXT = &H4
Private Const LVIF_TEXT = &H1
 
Public hListView As Long                                                                        ' Хендл
Public Dic As Collection                                                                        ' Список сообщений
 
' Инициализация ListView
Public Sub InitListView()
    Dim ExStyle As Long
    Dim LVStyle As Long
    Dim Col As LVCOLUMN
    Dim CC As tagInitCommonControlsEx
    
    CC.dwSize = Len(CC)
    CC.dwICC = ICC_WIN95_CLASSES
    
    If InitCommonControlsEx(CC) = 0 Then MsgBox "Error InitCommonControlsEx": End
    
    ExStyle = WS_EX_CLIENTEDGE                                                                  ' Рамка у ListView
    LVStyle = WS_CHILD Or WS_TABSTOP Or LVS_REPORT Or LVS_SINGLESEL                             ' Стиль Report и единственный выбор
    
    hListView = CreateWindowEx(ExStyle, "SysListView32", vbNullString, LVStyle, 5, 5, 100, 100, frmSpy.hwnd, 0, App.hInstance, ByVal 0)
    
    If hListView = 0 Then MsgBox "Error creating ListView " & Err.LastDllError, vbCritical: End ' Если не удалось создать - нет смысла
                                                                                                ' продолжать работать
    
    SendMessage hListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, _
                ByVal LVS_EX_FULLROWSELECT Or LVS_EX_GRIDLINES                                  ' Установка расширеных стилей:
                                                                                                ' выбор всей строки и сетка
    ' Вставляем колонки в ListView
    Col.mask = LVCF_TEXT Or LVCF_WIDTH
    Col.pszText = "№": Col.cchTextMax = Len(Col.pszText): Col.CX = 64
    SendMessage hListView, LVM_INSERTCOLUMN, 0, Col
    
    Col.pszText = "Message": Col.cchTextMax = Len(Col.pszText): Col.CX = 200
    SendMessage hListView, LVM_INSERTCOLUMN, 1, Col
    
    Col.pszText = "wParam": Col.cchTextMax = Len(Col.pszText): Col.CX = 100
    SendMessage hListView, LVM_INSERTCOLUMN, 2, Col
    
    Col.pszText = "lParam": Col.cchTextMax = Len(Col.pszText): Col.CX = 100
    SendMessage hListView, LVM_INSERTCOLUMN, 3, Col
    
    Call ShowWindow(hListView, SW_SHOW)                                                         ' Показываем окно
End Sub
' Уничтожение ListView
Public Sub DestroyListView()
    DestroyWindow hListView                                                                     ' Уничтожаем окно
    hListView = 0
End Sub
' Инициализация словаря
Public Sub DicInit()
    Dim fNum As Integer, s As String, key As String
    
    On Error GoTo Errorlabel
    
    fNum = FreeFile
    
    Open App.Path & "\WMList.txt" For Input As fNum
    
    Set Dic = New Collection
    
    Do Until EOF(fNum)
        Line Input #fNum, s
        key = "_" & Left$(s, 4)
        Dic.Add Mid$(s, 5), key
    Loop
    
    Close fNum
    
    Exit Sub
Errorlabel:
    MsgBox "Windows messages list loading error", vbExclamation
    Err.Clear
End Sub
' Добавить строку (без мерцания)
Public Function ItemAdd(ByVal Message As String, ByVal wParam As String, ByVal lParam As String) As Boolean
    Dim LV As LVITEM, i As Long
    
    i = SendMessage(hListView, LVM_GETITEMCOUNT, 0, ByVal 0&)
    
    With LV
      .pszText = i
      .iItem = i
      .cchTextMax = Len(.pszText)
      .mask = LVIF_TEXT
    End With
    
    SendMessage hListView, LVM_INSERTITEM, 0, LV
    LV.pszText = Message: LV.iSubItem = 1
    SendMessage hListView, LVM_SETITEMTEXTA, i, LV
    LV.pszText = wParam: LV.iSubItem = 2
    SendMessage hListView, LVM_SETITEMTEXTA, i, LV
    LV.pszText = lParam: LV.iSubItem = 3
    SendMessage hListView, LVM_SETITEMTEXTA, i, LV
    
    SendMessage hListView, LVM_ENSUREVISIBLE, i, ByVal True
End Function
' Возвращает имя сообщения по номеру
Public Function GetMessageName(ByVal Number As Long) As String
    On Error Resume Next
    Dim h As String
    
    h = "0000": Mid$(h, 5 - Len(Hex(Number))) = Hex(Number)
    GetMessageName = Dic.Item("_" & h)
    If Err.Number Then GetMessageName = h: Err.Clear
End Function
Форма frmSpy.frm:
Visual Basic
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
Option Explicit
 
' Форма frmSpy.frm
' © Кривоус Анатолий Анатольевич (The trick), 2014
' Работает вместе с modEnumWindow.mod, modInjection.mod, modListView.mod
 
Private Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Private Declare Function SetROP2 Lib "gdi32" (ByVal hdc As Long, ByVal nDrawMode As Long) As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long
Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long) As Long
Private Declare Function IsZoomed Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
Private Declare Function FrameRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long, ByVal hBrush As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateHatchBrush Lib "gdi32" (ByVal nIndex As Long, ByVal crColor As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
 
Private Const COLOR_WINDOWFRAME As Long = 6
Private Const HS_DIAGCROSS As Long = 5
Private Const SM_CXBORDER As Long = 5
Private Const SM_CYBORDER As Long = 6
Private Const SM_CXFRAME = 32
Private Const SM_CYFRAME = 33
Private Const R2_NOT As Long = 6
Private Const PS_INSIDEFRAME As Long = 6
Private Const NULL_BRUSH As Long = 5
 
Private Const ControlSpacing As Long = 5                                                        ' Расстояние между контролами
 
Dim hWndprev As Long                                                                            ' Хендл "захваченного" окна
Dim Pn As Long, Br As Long                                                                      ' Перо и кисть
 
' Установка позиции и размеров контролов в зависимости от размеров формы
Private Sub SetMetrics()
    Dim CsPx As Long, l As Long, t As Long, w As Long, h As Long
 
    w = Me.ScaleWidth - ControlSpacing * 2
    h = Me.ScaleHeight - ControlSpacing * 3 - cmdPick.Height
    
    cmdPick.Move (Me.ScaleWidth - cmdPick.Width - cmdStop.Width - ControlSpacing) \ 2, _
                 ControlSpacing * 2 + h
    cmdStop.Move cmdPick.Left + cmdPick.Width, _
                      cmdPick.Top
                      
    MoveWindow modListView.hListView, ControlSpacing, _
                         ControlSpacing, _
                         w, h, True
End Sub
 
' Нажали на кнопку - начинаем поиск
Private Sub cmdPick_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    hWndprev = 0
    cmdPick.Caption = "Drop on window"
End Sub
' Перемещение кнопки над окнами
Private Sub cmdPick_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    If modInjection.hThread = 0 Then MarkWindow
End Sub
' Отпустили кнопку
Private Sub cmdPick_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    MarkWindow True
    cmdPick.Caption = "Drag on window"
    If hWndprev Then
        modInjection.Clear
        cmdPick.Enabled = Not modInjection.Hook(hWndprev)
    End If
End Sub
Private Sub cmdStop_Click()
    modInjection.Clear               ' Удаляем инъекцию
    hWndprev = 0
    cmdPick.Enabled = True
End Sub
Private Sub Form_Load()
    modListView.InitListView
    Pn = CreatePen(PS_INSIDEFRAME, GetSystemMetrics(SM_CXBORDER) * 3, vbBlack)
    Br = CreateHatchBrush(HS_DIAGCROSS, GetSysColor(COLOR_WINDOWFRAME))
End Sub
 
' Помечаем окно рамкой
Private Sub MarkWindow(Optional Cancel As Boolean)
    Dim hWndFp As Long, Buf As String, l As Long
 
    If Cancel And hWndprev Then DrawFrame hWndprev: Exit Sub    ' Это когда отпускаем кнопку, чтобы отменить изменения
    
    hWndFp = modEnumWindow.GetWindowFromCursorPos               ' Получаем окно под курсором
    
    If hWndFp <> hWndprev Then
        If hWndFp Then
            Buf = String(256, 0)
            l = GetClassName(hWndFp, Buf, 255)
            If l Then Buf = Left(Buf, l)
            Me.Caption = Hex(hWndFp) & " Class = '" & Buf & "' "
            DrawFrame hWndFp
        Else
            Me.Caption = "Message log by the trick"
        End If
        If hWndprev Then DrawFrame hWndprev
    End If
    
    hWndprev = hWndFp
End Sub
' Рисует рамку у окна
Private Sub DrawFrame(lhWnd As Long)
    Dim hDCWnd As Long, RC As RECT, oPn As Long, oBr As Long, _
        hRgn As Long, SzX As Long, SzY As Long
 
    hDCWnd = GetWindowDC(lhWnd)
    If hDCWnd = 0 Then Exit Sub
    SetROP2 hDCWnd, R2_NOT
    oPn = SelectObject(hDCWnd, Pn)
    oBr = SelectObject(hDCWnd, GetStockObject(NULL_BRUSH))
    
    hRgn = CreateRectRgn(0, 0, 0, 0)
    SzX = GetSystemMetrics(SM_CXBORDER) * 3
    SzY = GetSystemMetrics(SM_CYBORDER) * 3
    
    If GetWindowRgn(lhWnd, hRgn) Then
        FrameRgn hDCWnd, hRgn, oBr, SzX, SzY
    Else
        GetWindowRect lhWnd, RC
        If IsZoomed(lhWnd) Then
            RC.Left = GetSystemMetrics(SM_CXFRAME)
            RC.Top = GetSystemMetrics(SM_CYFRAME)
            RC.Right = RC.Right + RC.Left
            RC.Bottom = RC.Bottom + RC.Top
        End If
        Rectangle hDCWnd, 0, 0, RC.Right - RC.Left, RC.Bottom - RC.Top
    End If
    
    SelectObject hDCWnd, oBr
    SelectObject hDCWnd, oPn
    ReleaseDC lhWnd, hDCWnd
End Sub
Private Sub Form_Resize()
    If Me.ScaleHeight > (cmdPick.Height + ControlSpacing * 3) Then SetMetrics
End Sub
Private Sub Form_Unload(Cancel As Integer)
    Call cmdStop_Click
    DeleteObject Pn
    DeleteObject Br
    DestroyListView
End Sub
Работает все только в скомпилированном (native) виде.
Миниатюры
Нажмите на изображение для увеличения
Название: Безымянный.png
Просмотров: 820
Размер:	228.8 Кб
ID:	2032  
Вложения
Тип файла: rar MessageLog.rar (23.9 Кб, 561 просмотров)
Метки injection, multithreading, vb
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 7
Комментарии
  1. Старый комментарий
    Аватар для Pro_grammer

    Внедрение

    При запуске exe "Error creating ListView"
    В IDE запускается без ошибки. Что может быть?
    Запись от Pro_grammer размещена 26.01.2014 в 21:39 Pro_grammer вне форума
  2. Старый комментарий

    Внедрение

    Цитата Сообщение от Pro_grammer
    При запуске exe "Error creating ListView"
    В IDE запускается без ошибки. Что может быть?
    Ошибка в CreateWindowEx при создании ListView'а, не знаю почему, но она возвращает у тебя 0. Скомпилируй у себя со всеми 6 оптимизациями в Native, и попробуй запусти.
    Посмотри чему у тебя равно Err.LastDllError после вызова этой функции в скомпилированном виде
    Запись от The trick размещена 26.01.2014 в 22:04 The trick вне форума
  3. Старый комментарий
    Аватар для AzaKendler
    а как это можно применть в софте? ведь если незя - то фтопку
    Запись от AzaKendler размещена 26.01.2014 в 23:50 AzaKendler вне форума
  4. Старый комментарий
    Цитата Сообщение от AzaKendler
    а как это можно применть в софте? ведь если незя - то фтопку
    Можно перехватывать API, можно мониторить чужой процесс, ставить хуки в чужих программах без DLL, да можно массу привести примеров. Тут недавно тема была как отрисовать в DirectX окне чужого приложения, вот с помощью внедрения можно это осуществить. Используя File mapping обмениваться данными со своей прогой. Можно добавить еще одну пустышку и реализовать в ней возврат адреса переменной, будет намного больше возможностей.
    Запись от The trick размещена 26.01.2014 в 23:56 The trick вне форума
  5. Старый комментарий

    Внедрение

    Цитата Сообщение от The trick
    Ошибка в CreateWindowEx при создании ListView'а, не знаю почему, но она возвращает у тебя 0. Скомпилируй у себя со всеми 6 оптимизациями в Native, и попробуй запусти.
    Посмотри чему у тебя равно Err.LastDllError после вызова этой функции в скомпилированном виде
    Баг исправлен.
    Запись от The trick размещена 27.01.2014 в 17:59 The trick вне форума
  6. Старый комментарий
    Аватар для ISergey
    но мне была интересна идея внедрения без DLL
    Малварь уже давно что то похожее использует. Правда обычно в чужое адресное пространство полностью свое тело копирует и вместо CreateRemoteThread делает подмену контекста одного из потоков приложения.

    [IMG]http://i.**********/3jFuPnV.png[/IMG]
    [IMG]http://i.**********/MyUj91B.png[/IMG]
    Запись от ISergey размещена 05.03.2014 в 16:19 ISergey вне форума
  7. Старый комментарий
    Цитата Сообщение от ISergey
    делает подмену контекста одного из потоков приложения.
    Для этого придется потом восстанавливать контекст, по окончанию работы тела вируса, т.е. отслеживать когда, закончится выполнение кода вируса. Этот прием можно использовать для запуска EXE в памяти другого процесса.
    Запись от The trick размещена 05.03.2014 в 16:26 The trick вне форума
 
Новые блоги и статьи
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru