Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/21: Рейтинг темы: голосов - 21, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23

Вызов процедуры из инжектированной DLL

18.03.2016, 15:05. Показов 4551. Ответов 39
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую.
Имеется игра с именем MP.exe
Имеется DLL, написанная на Си.
Известно имя процедуры внутри DLL (Test)
Имеется рабочий код инжектора, который внедряет эту длл в игру.

Вопрос: как вызвать процедуру из внедренной DLL, используя код Delphi?

Код для инжектирования написан не мной. Это визуальная форма, предлагающая выбрать длл а также процесс для внедрения. Вот ее полный код:

Кликните здесь для просмотра всего текста
Delphi
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
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, TlHelp32, Buttons, StdCtrls, jpeg, ExtCtrls, sSkinManager,
  sEdit, sGauge, sButton, sLabel, ComCtrls, sTrackBar, sPanel, sSpeedButton,
  sStatusBar;
 
type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    sSkinManager1: TsSkinManager;
    sButton2: TsButton;
    sButton1: TsButton;
    Button1: TsButton;
    sEdit1: TsEdit;
    Edit1: TsEdit;
    Edit2: TsEdit;
    sStatusBar1: TsStatusBar;
    procedure sButton1Click(Sender: TObject);
    procedure sButton2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
 
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
function GetOSVersion: Cardinal;
var
  OSVersionInfo: TOSVersionInfo;
begin
  Result := 0;
  FillChar(OSVersionInfo, Sizeof(OSVersionInfo), 0);
  OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
  if GetVersionEx(OSVersionInfo) then
  begin
    if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
    begin
      if OSVersionInfo.dwMajorVersion = 5 then
      begin
        if OSVersionInfo.dwMinorVersion = 0 then
          Result := 50//Windows 2000
        else if OSVersionInfo.dwMinorVersion = 2 then
          Result := 52//Windows 2003
        else if OSVersionInfo.dwMinorVersion = 1 then
          Result := 51//Windows XP
      end;
      if OSVersionInfo.dwMajorVersion = 6 then
      begin
        if OSVersionInfo.dwMinorVersion = 0 then
          Result := 60//Windows Vista
        else if OSVersionInfo.dwMinorVersion = 1 then
          Result := 61;//Windows 7
      end;
    end;
  end;
end;
 
 
 
function ModulInjectByDen(ModulePath: PAnsiChar; ProcessID: DWORD): Boolean;
var
  hSnapshot: THandle;
  ModuleEntry32: TModuleEntry32;
begin
  Result := False;
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
  if (hSnapshot <> -1) then
  begin
    ModuleEntry32.dwSize := SizeOf(TModuleEntry32);
    if (Module32First(hSnapshot, ModuleEntry32)) then
      repeat
        if string(ModuleEntry32.szExePath) = string(ModulePath) then
        begin
          Result := True;
          Break;
        end;
      until
        not Module32Next(hSnapshot, ModuleEntry32);
    CloseHandle(hSnapshot);
  end;
end;
 
function InjectIDMetod(ModulePath: PAnsiChar; ProcessID: DWORD): Boolean;
type
  TNtCreateThreadEx = function(
  ThreadHandle: PHANDLE;
  DesiredAccess: ACCESS_MASK;
  ObjectAttributes: Pointer;
  ProcessHandle: THANDLE;
  lpStartAddress: Pointer;
  lpParameter: Pointer;
  CreateSuspended: BOOL;
  dwStackSize: DWORD;
  Unknown1: Pointer;
  Unknown2: Pointer;
  Unknown3: Pointer): HRESULT; stdcall;
var
  lpStartAddress, lpParameter: Pointer;
  dwSize: Integer;
  hProcess, hThread, lpThreadId, lpExitCode, lpBytesWritten: Cardinal;
  NtCreateThreadEx: TNtCreateThreadEx;
begin
  Result := False;
  if ModulInjectByDen(ModulePath, ProcessID) = True then
    Exit;
  hProcess := 0;
  hProcess := OpenProcess(MAXIMUM_ALLOWED, False, ProcessID);
  if hProcess = 0 then
    Exit;
  dwSize := StrLen(ModulePath) + 1;
  lpParameter := VirtualAllocEx(hProcess, nil, dwSize, MEM_COMMIT, PAGE_READWRITE);
  if (lpParameter = nil) then
  begin
    if hProcess <> 0 then
      CloseHandle(hProcess);
    Exit;
  end;
  if GetOSVersion >= 60 then
    NtCreateThreadEx := GetProcAddress(GetModuleHandleW('ntdll'), 'NtCreateThreadEx');
  lpStartAddress := GetProcAddress(GetModuleHandleW('kernel32'), 'LoadLibraryA');
  if (lpStartAddress = nil) then
    Exit;
  if GetOSVersion >= 60 then
    if (@NtCreateThreadEx = nil) then
      Exit;
  lpBytesWritten := 0;
  if (WriteProcessMemory(hProcess, lpParameter, ModulePath, dwSize, lpBytesWritten) = False) then
  begin
    VirtualFreeEx(hProcess, lpParameter, 0, MEM_RELEASE);
    if hProcess <> 0 then
      CloseHandle(hProcess);
    Exit;
  end;
  hThread := 0;
  lpThreadId := 0;
  if GetOSVersion >= 60 then
    NtCreateThreadEx(@hThread, MAXIMUM_ALLOWED, nil, hProcess, lpStartAddress, lpParameter, false, 0, 0, 0, 0)
  else
    hThread := CreateRemoteThread(hProcess, nil, 0, lpStartAddress, lpParameter, 0, lpThreadId);
  if (hThread = 0) then
  begin
    VirtualFreeEx(hProcess, lpParameter, 0, MEM_RELEASE);
    CloseHandle(hProcess);
    Exit;
  end;
  GetExitCodeThread(hThread, lpExitCode);
  if hProcess <> 0 then
    CloseHandle(hProcess);
  if hThread <> 0 then
    CloseHandle(hThread);
  Result := True;
end;
 
 
procedure TForm1.sButton2Click(Sender: TObject);
var
  hSnap:THandle;
  pe:TProcessEntry32;
begin
 pe.dwSize:=SizeOf(pe);
 hSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  If Process32First(hSnap,pe) then
    While Process32Next(hSnap,pe) do
      if ExtractFileName(pe.szExeFile)='MP.exe' then
     edit2.Text:=IntToStr(pe.th32ProcessID);
     end;
 
procedure TForm1.sButton1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    Edit1.Text:= OpenDialog1.FileName;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 
  InjectIDMetod(PAnsiChar(Edit1.Text), StrToInt(Edit2.Text));
end;
 
end.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.03.2016, 15:05
Ответы с готовыми решениями:

Вызов процедуры из dll
Здравствуйте опытные программисты у меня к вам такой вопрос я написал dll с парочкой процедур добавил эту dll в ресурсы программы вопрос...

Вызов процедуры из DLL
Господа, помогите!!! Имеется самописная DLL в которой есть некая функция 'A'. Необходимо вызвать эту функцию из exe-шника. Если не трудно...

Вызов процедуры c парметрами из dll
В dll файле прописана простая процедура, которая принимает указатель на блок памяти(строку) и пробует узнать ее длину(чисто для примера): ...

39
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 15:12
А собссно из какого процесса и зачем понадобилось вызывать эту процедуру ?
0
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23
18.03.2016, 15:30  [ТС]
dll внедряется в процесс mp.exe, оттуда же и нужно вызвать процедуру. Сама процедура выполняет отправку сообщения, написанного в игре в чат строку. (Внешний чат)
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 15:43
что-то логика какая-то через ж выстроенная)

либа успешно грузанулась в АП "жертвы", после чего наверняка способна отслеживать изменения в "чат строке" и иных контролах "жертвы" (иначе нафих ее нужно было туда внедрять ?)

как только она обнаружила интересующие изменения, она сама связывается с приложением-инициатором внедрения и сообщает ему что, мол, в таком-то контроле "жертвы" произошли такие-то конкретно изменения (например, геймер написал че-то там в чат-строке и жмакнул "Отправить"), после чего приложение-инициатор вольно самостоятельно отправить это самое "че-то там" хоть во внешний чат хоть на Луну

и нафих для этого изголяться вызывать ф-ции из либы-шпиона - совершенно не понятно)
0
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23
18.03.2016, 15:57  [ТС]
Не знаю, зачем вам такие подробности, мне всего-лишь нужно вызвать процедуру.

Основная программа извне открывает чат строку (закрывая при этом консоль и прочее) и вставляет текст из мемо, далее используется длл, закрывается чат строка, убирается визуальная часть текста после отправки (иначе залипнет на экране).
Для отправки сообщения в игре используется кнопка Enter.
Почему нужно использовать длл? Потому что игра ни в какую не хочет использовать сообщения о нажатии клавиши полученные извне (send, post и прочие), а "напечатанный" интер отправляется как символ.
0
232 / 135 / 19
Регистрация: 10.11.2015
Сообщений: 305
18.03.2016, 16:05
Sevirman, ну тогда CreateRemoteThread и в шелл-коде GetModuleHandle/GetProcAddress.

Добавлено через 1 минуту
или вызывать функцию напрямую (CreateRemoteThread, если у функции нет параметров)

Добавлено через 1 минуту
Sevirman, а код dll доступен?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 16:06
Цитата Сообщение от Sevirman Посмотреть сообщение
мне всего-лишь нужно вызвать процедуру
Да осознаешь ли ты что либа находится в чужом адресном пространстве, а непосредственный вызов процедуры априори подразумевает что она находится в своем ?

Чтобы вызвать ее косвенно в чужом, в простейшем случае придется городить тот же самый огород с CreateRemoteThread, что используется и при внедрении либы ?

Код внедрения писал не ты и потому не понимаешь (или не желаешь понять) в принципе как и почему это работает, поэтому какой смысл рассказывать тебе про CreateRemoteThread, если тот же он самый как раз и используется для вызова нужной ф-ции в нужной либе в чужом процессе ?)
0
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23
18.03.2016, 16:06  [ТС]
Буду благодарен, если предоставите модификацию приведенного в начале кода, мне будет проще разобраться, так как нет опыта по этой части.
Да, код длл доступен.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 16:16
ты в имеющемся сначала разберись)
0
232 / 135 / 19
Регистрация: 10.11.2015
Сообщений: 305
18.03.2016, 16:18
Цитата Сообщение от Sevirman Посмотреть сообщение
Почему нужно использовать длл? Потому что игра ни в какую не хочет использовать сообщения о нажатии клавиши полученные извне (send, post и прочие), а "напечатанный" интер отправляется как символ.
А может эмуляция нажатий клавиш подойдет? (keybd_event)
0
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23
18.03.2016, 16:20  [ТС]
mss, не строй из себя всезнайку, со всем, что мне нужно я уже разобрался, а что не знаю спросил. Либо отвечай нормально, либо вовсе не отвечай.

jupman, эмуляция нажатия клавиш точно не подойдет.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 16:28
Sevirman,
Я дал тебе вполне конкретную рекомендацию - разобраться в работе ф-ции CreateRemoteThread по уже имеющемуся у тебя исходнику.
Она делат именно то что ты возжелал - вызывает указанную функцию из указанной библиотеки.
А ты надул губки аки барышня кисейная)
Чего еще надо-то ?)
0
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23
18.03.2016, 16:52  [ТС]
mss, губонадувательством не занимаюсь.
Мне желателен пример использования CreateRemoteThread для вызова функции из длл
0
232 / 135 / 19
Регистрация: 10.11.2015
Сообщений: 305
18.03.2016, 16:59
Цитата Сообщение от jupman Посмотреть сообщение
или вызывать функцию напрямую (CreateRemoteThread, если у функции нет параметров)
Оу. Я тут ошибся. Напрямую (не через шелл) можно вызвать если параметров 0 или 1.
Цитата Сообщение от Sevirman Посмотреть сообщение
Мне желателен пример использования CreateRemoteThread для вызова функции из длл
Дак пример у вас есть уже. В первом посте.

Добавлено через 1 минуту
Цитата Сообщение от Sevirman Посмотреть сообщение
lpStartAddress := GetProcAddress(GetModuleHandleW('kernel3 2'), 'LoadLibraryA');
Цитата Сообщение от Sevirman Посмотреть сообщение
hThread := CreateRemoteThread(hProcess, nil, 0, lpStartAddress, lpParameter, 0, lpThreadId);
Только имя dll и функции свое.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 17:00
Цитата Сообщение от Sevirman Посмотреть сообщение
Мне желателен пример использования CreateRemoteThread для вызова функции из длл
Да перед носом же он у тебя, че ты какой бестолковый ?)

Конкретно в ф-ции InjectIDMetod средствами конкретно CreateRemoteThread вызывается конкретно ф-ция
LoadLibraryA из конкретно библиотеки kernel32.dll, находящейся в адресноим пространстве процесса-жертвы !
0
232 / 135 / 19
Регистрация: 10.11.2015
Сообщений: 305
18.03.2016, 17:12
Sevirman, в вашей этой процедуре (Test) сколько параметров?

Добавлено через 11 минут
Sevirman, тфу ты, что-то я гоню сегодня. Это у kernel32.dll база фиксированная в процессах. Потому можно сразу вычислить lpStartAddress для потока. У вас так не получится сделать.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 17:42
Фиолетово - либа уже а ап жертвы
0
232 / 135 / 19
Регистрация: 10.11.2015
Сообщений: 305
18.03.2016, 17:51
Цитата Сообщение от mss Посмотреть сообщение
Фиолетово - либа уже а ап жертвы
Это вы мне, ну да да, я и говорю что затупил. В общем что-бы получить адрес нужной функции алго такой:

1) узнаете базу по которой загрузилась либа (CreateToolhelp32Snapshot/Module32First/Module32Next)
2) грузите либу к себе тоже, но без инициализации (LoadLibraryEx(DONT_RESOLVE_DLL_REFERENC ES)), находите адрес функции (GetProcAddress)
3) вычитаете из адреса функции базу либы (загруженную в свой процесс) и прибавляете базу (полученную из чужого процесса п.1)
4) это и будет адрес функции для CreateRemoteThread

Как то так.
0
0 / 0 / 0
Регистрация: 01.10.2015
Сообщений: 23
18.03.2016, 18:45  [ТС]
Блин, ничего не выходит . Пожалуйста приведите готовый код, к примеру для button1, чтобы вызвать функцию. Мне так намного проще будет разобраться.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
18.03.2016, 20:27
Цитата Сообщение от jupman Посмотреть сообщение
Как то так
Именно так.
Ну или хотя бы так)

Цитата Сообщение от Sevirman Посмотреть сообщение
приведите готовый код
Он у тебя есть !

Добавлено через 15 минут
Цитата Сообщение от jupman Посмотреть сообщение
если параметров 0 или 1
да сколько угодно можно передать параметров)

главное подготовить блок памяти под них и записать их туда (VirtualAlloxEx + WriteProcessMemory)

параметром в CreateRemoteThread передается адрес блока, а уж нить разбирает его на отдельные параметры и готовит вызов
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.03.2016, 20:27
Помогаю со студенческими работами здесь

Вызов функции или процедуры главного приложения с dll C#
Добрый день !!! :)Есть программа которая подключает плагины к себе, в одном из плагинов реализовывается добавление контрола и подписывается...

Вызов функции из dll. Dll не определена в коде и подключается программно
Я написал простую функцию которая возвращает негатив bitmap'а Function Negative(ByVal Bmp As Bitmap) Dim Bmp2 As New...

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

Вызов процедуры из другой процедуры с параметрами
Не подскажете как вызвать процедуру StringGrid1KeyUp procedure TMainForm.StringGrid1KeyUp(Sender: TObject; var Key: Word; Shift:...

Вызов пользовательской процедуры из процедуры по указателю
Такая задача: Нужно вызвать функцию с параметрами и передать ей указатель на другую функцию чтобы она в цикле вызывала сама функцию и...


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

Или воспользуйтесь поиском по форуму:
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