Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.08.2015, 02:01   #1
Reimscher
Пользователь
 
Регистрация: 01.02.2011
Сообщений: 33
Восклицание Управление socket'ом чужого приложения, как в WPE PRO

Доброго времени суток!

Пытаюсь написать программу для отправки пакетов на сервер "от имени" игры (а точнее её socket'а).

Если вам интересно зачем мне это, то вот история в кратце: Есть одна старая MMO игра, на Flash. Бой в ней происходит "на отдельной от игрового мира карте". Т.е., грубо говоря, нажимаем на монстра и попадаем с ним в бой на существующей только во время боя локации. Однако, не всегда мы в бой попадём. Зачастую вылетит сообщение о том, что монстры тут "кончились". Но потыкав по их иконке ещё несколько раз, и закрыв пару тройку таких окошек, мы таки попадём в бой. Я хочу написать программу, которая будет имитировать эти нажатия до тех пор, пока не окажусь в бою, потому что это занимает жутко много времени (в игре стоит таймер на это событие, с очень большим интервалом, хотя пакеты приходят моментально). К тому же есть желание в будущем сделать alert-бота, через которого игроки смогут обращаться к другим игрокам, например, за помощью, а те, при желании, отвечать им. Да и давно хотел изучить эту нишу программирования, хотя бы для того, что бы иметь представление об уязвимостях в подобных местах. Но пока что решил остановиться на программе для инициации боя. Пришёл к выводу, что самый простой вариант — работать напрямую с трафиком.

Данный момент имею сниффер на Delphi, с возможностью фильтрации трафика (входящего/исходящего) по IP/Порту/Содержимому, иначе говоря, запросто имею весь "диалог" клиента игры и сервера.

Через WPE PRO вручную отправлял пакеты с данными, сервер с радостью их принимает, присылает ответ. Игру вполне устраивают подобные "телодвижения" со стороны сервера (т.е. пакет со стороны сервер ни с того ни с сего).

Что хочу сделать — каким-либо образом отправлять определённые данные на сервер через socket игры. Насколько я знаю, это можно сделать получив handle этого socket'а. Это в свою очередь можно сделать через инъекцию dll в игру.

Что хочу узнать/в чём требуется ваша помощь:
1. Можно ли узнать handle без инъекции, например, по pid? Насколько я понимаю, это можно отследить (имею ввиду dll инъекцию, хотя игра и древняя, но тем не менее), а следовательно и бан получить. Не хотелось бы такого расклада, очень уж давно я с ней знаком, и пока прощаться не хотелось бы.
2. Каким образом получить handle socket'а с помощью внедрённой dll? Игра имеет .ехе оболочку.
3. Что делать заимев handle? Просто сделать клон? Не будет ли проблем с seq? Или клон будет работать как указатель на оригинал?

Надеюсь тема не умрёт, и мне удастся решить все проблемы. Нашёл очень старую, схожую тему на другом форуме, и насколько понял, задача вполне решаема. К сожалению, там не было требуемой мне информации.
Reimscher вне форума Ответить с цитированием
Старый 03.08.2015, 09:35   #2
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

http://yandex.ru/yandsearch?text=%D1...0%B3%20winsock
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 03.08.2015, 13:38   #3
Reimscher
Пользователь
 
Регистрация: 01.02.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Slym Посмотреть сообщение
Насколько я понял, сплайсинг хорошо подходит для получения и замены данных. Но в данном случае требуется ведь отправить пакеты "от имени" клиента игры, когда ей это не нужно. Хотя, подменив send / recv мы получим указатель на socket? И тогда им можно будет свободно пользоваться?

Последний раз редактировалось Reimscher; 03.08.2015 в 13:41.
Reimscher вне форума Ответить с цитированием
Старый 03.08.2015, 16:22   #4
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Цитата:
Сообщение от Reimscher Посмотреть сообщение
Хотя, подменив send / recv мы получим указатель на socket? И тогда им можно будет свободно пользоваться?
Возможно проще будет подменить connect. А использовать socket можно будет, но скорее всего, только в границах процесса, где он был создан.

Еще нужно учитывать то, что игра может при нажатии на монстра выполнять еще какие-то действия, кроме как отправить пакет. И если просто отправить пакет, то игра может начать что-то некорректно отображать или вообще повиснуть.

А подмена функций не считается взломом случайно?
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Krasiosoft вне форума Ответить с цитированием
Старый 03.08.2015, 17:42   #5
Reimscher
Пользователь
 
Регистрация: 01.02.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
Возможно проще будет подменить connect. А использовать socket можно будет, но скорее всего, только в границах процесса, где он был создан.

Еще нужно учитывать то, что игра может при нажатии на монстра выполнять еще какие-то действия, кроме как отправить пакет. И если просто отправить пакет, то игра может начать что-то некорректно отображать или вообще повиснуть.

А подмена функций не считается взломом случайно?
Касательно последнего вопроса — всё относительно. Да и давно была мечта "похакерствовать", а тут вполне себе безобидная возможность.

Я представлял следующую подмену: есть оригинальный send и мой (набор аргументов у них идентичен), разница лишь в том, что мой передаёт мне всю информацию о socket, а затем вызывает настоящий send (только, наверное, придётся использовать оригинальный send внутри, опять же, dll). Ну, а получив данные о socket, им можно было бы уже манипулировать.

Насчёт подмены connect, как мне кажется, не лучший выход. Это ведь уже эмулятор игры придётся писать, т.к. там ведь игра постоянно с сервером "общается", а в случае разъединения происходит выброс и полная переинициализация данных. А мне всего-то хочется сделать свою кнопку инициации боя. А даже если socket будет доступен только внутри игры, то можно как-нибудь попытаться управлять им с помощью инъекцированной dll.

Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
Еще нужно учитывать то, что игра может при нажатии на монстра выполнять еще какие-то действия, кроме как отправить пакет. И если просто отправить пакет, то игра может начать что-то некорректно отображать или вообще повиснуть.
Касательно этого — проверял через WPE PRO, игра вполне приемлет сообщение от сервера о том, что надо начать вывод данных боя, даже если оно пришло "ни с того ни с сего".

Последний раз редактировалось Reimscher; 03.08.2015 в 17:52.
Reimscher вне форума Ответить с цитированием
Старый 03.08.2015, 18:11   #6
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Цитата:
Сообщение от Reimscher Посмотреть сообщение
Насчёт подмены connect, как мне кажется, не лучший выход.
С функции connect можно будет узнать socket и отправлять уже пакеты с помощью send. А если нужно еще отслеживать трафик, то тут нужно еще подменять send и recv.

Посмотрите как это делает WPE PRO, возможно, эта программа тоже встраивает свою dll в приложение.
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Krasiosoft вне форума Ответить с цитированием
Старый 03.08.2015, 18:18   #7
Reimscher
Пользователь
 
Регистрация: 01.02.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
С функции connect можно будет узнать socket и отправлять уже пакеты с помощью send. А если нужно еще отслеживать трафик, то тут нужно еще подменять send и recv.

Посмотрите как это делает WPE PRO, возможно, эта программа тоже встраивает свою dll в приложение.
Кажется только теперь до меня дошёл смысл подмены connect. Но, боюсь, этот вариант не подходит, т.к. я не знаю в какой момент он происходит, вероятнее всего в момент запуска игры. Слишком проблематично вылавливать этот момент. Доступ к трафику я уже и так имею, через WinPCap драйвер. Поэтому будут придерживаться пока что плана подмены send'а, к тому же, в случае успеха я откажусь от WinPCap'а, т.к. я там использую приложение от Magenta, в котором для меня очень много лишнего (точнее там вообще весь трафик идет, через написанный мною фильтр).
Reimscher вне форума Ответить с цитированием
Старый 03.08.2015, 21:39   #8
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Можно попробовать следующее,
простой способ добраться до чужого сокета, делаем проверку сокетов перебором номеров и находя нужный адрес находим и сам Handle сокета.

Код:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, WinSock,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  WSData: WSAData;

implementation

{$R *.dfm}

//процедура поиска Handle сокета
Function FindSoketHost(Host: string): integer;
var
addrIP: string;
Port: Dword;
HSock, fromLen: integer;
sin : sockaddr_in;
begin
result:= 0;
for HSock:= 1 to 5000 do
begin
  FillChar(sin, SizeOf(sin), 0);
  fromLen := SizeOf(sin);
  getpeername(HSock, sin, fromLen);
  addrIP:= inet_ntoa(sin.sin_addr);
  Port := htons(sin.sin_port);
 Application.ProcessMessages;

//для проверки что код находит сокеты с адресами
  if Port > 0 then
  showmessage(Inttostr(HSock) + #13#10 + Format('%s:%d', [addrIP, Port]));

if Host = Format('%s:%d', [addrIP, Port]) then
begin
result:= HSock;
break;
end;
end;
end;

//использование
procedure TForm1.Button1Click(Sender: TObject);
var
HSock: integer;
begin
//Ищем нужный хост
HSock:= FindSoketHost('127.0.0.1:2706');
if HSock > 0 then
WinSock.send(HSock, ваши данные для отправки, размер, 0);
end;


// Общий запуск WinSock иначе работать не будет
initialization
  WSAStartup(MAKEWORD(2, 2), WSData);

finalization
  WSACleanup;

end.
Можно конечно все это через поток сделать.
В этом примере поиск идет нормально, но вот отправка получиться ли не проверял.
Также теоретически можно закрывать ненужные сокеты используя closesocket(HSock).
Запускать я думаю нужно из под админа для отправки и закрытия.
В общем пробуйте код можно и без порта проверку сделать.

Последний раз редактировалось Aliens_wolfs; 03.08.2015 в 22:42.
Aliens_wolfs вне форума Ответить с цитированием
Старый 04.08.2015, 12:04   #9
Reimscher
Пользователь
 
Регистрация: 01.02.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Можно попробовать следующее,
простой способ добраться до чужого сокета, делаем проверку сокетов перебором номеров и находя нужный адрес находим и сам Handle сокета.

Можно конечно все это через поток сделать.
В этом примере поиск идет нормально, но вот отправка получиться ли не проверял.
Также теоретически можно закрывать ненужные сокеты используя closesocket(HSock).
Запускать я думаю нужно из под админа для отправки и закрытия.
В общем пробуйте код можно и без порта проверку сделать.
Каким образом тестировали код? Запускали версию приложения — Debug?
Потому что у меня находит только Embarcadero'вский socket, и только если запускаю Debug, в Release вообще пусто.
Однако, если код запихать в DLL и её инъецировать в клиент игры, то возможно, она найдёт все socket'ы.
Reimscher вне форума Ответить с цитированием
Старый 04.08.2015, 19:18   #10
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Код:
library ProjectFindSocket;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Controls,
  Forms,
  Dialogs,
  WinSock,
  StdCtrls;

var
   WSData: WSAData;
   HSock: integer;

{$R *.res}

Function FindSoketHost(Host: string): integer;
var
addrIP: string;
Port: Dword;
HSock, fromLen: integer;
sin : sockaddr_in;
begin
result:= 0;
for HSock:= 1 to 20000 do
begin
  FillChar(sin, SizeOf(sin), 0);
  fromLen := SizeOf(sin);
  getpeername(HSock, sin, fromLen);
  addrIP:= inet_ntoa(sin.sin_addr);
  Port := htons(sin.sin_port);
 Application.ProcessMessages;

// Диалоговое окно найденных подключений для примера работы этого кода
  if Port > 0 then
  showmessage(Inttostr(HSock) + #13#10 + Format('%s:%d', [addrIP, Port]));

if Host = Format('%s:%d', [addrIP, Port]) then
begin
result:= HSock;
break;
end;
end;
end;

begin
WSAStartup(MAKEWORD(2, 2), WSData);
HSock:= FindSoketHost('127.0.0.1:2706');

WSACleanup;
end.
У меня получилось получить хенделы сокетов определенной программы, для примера я взял Скайп и Оперу и внедрил в них эту DLL. Этот код показывает в диалоговом окне все сокеты программы в которую внедрили эту DLL.
Внедрять DLL умеете в чужую программу?

Последний раз редактировалось Aliens_wolfs; 04.08.2015 в 20:22.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как разрешить запуск второй копии чужого приложения s1s1s1 Общие вопросы Delphi 4 02.11.2011 01:47
как запретить сворачивание чужого приложения 856100 Общие вопросы Delphi 11 23.07.2010 01:36
Нужно найти или написать прогу, на подобие WPE Pro ZBEP Фриланс 4 22.03.2010 17:03
Как скопировать текст чужого приложения? Nikolay-niw32 Общие вопросы Delphi 17 12.03.2009 21:28
Как определить путь чужого приложения? VVM Win Api 3 02.12.2008 18:22