Пытаюсь сделать типа этого PersInfo через это Универсальный загрузчик плагинов
... для начала просто вывести текст
Проблема текст не остаётся на экране(в окне) либо мерцает все вместе с задним фоном(окна)
Код:
library Project1;
uses
Windows, SysUtils, Classes, Direct3D8, D3DX8;
var
FD3D: IDirect3D8;
FD3DDevice: IDirect3DDevice8;
FD3DText: ID3DXFont;
Wnd: HWND;
{$R *.res}
function KeyPressed(Key: Byte): Boolean;
begin
KeyPressed := (GetAsyncKeyState(Key) and (1 shl 16) <> 0)
end;
function SetupCamera: HResult;
var
ViewMatrix: TD3DMatrix;
ProjectionMatrix: TD3DMatrix;
Eye: TD3DVector;
At: TD3DVector;
Up: TD3DVector;
begin
// Вектор, определяющий положение глаз наблюдателя
Eye.x := 0; Eye.y := 0; Eye.z := -8;
// Направление камеры
At.x := 0; At.y := 0; At.z := 0;
// Вектор, определяющий направление верха мировых координат.
// Обычно имеет значение (0, 1, 0).
Up.x := 0; Up.y := 1; Up.z := 0;
// Строим левостороннюю матрицу вида
D3DXMatrixLookAtLH(ViewMatrix, Eye, At, Up);
// Устанавливаем матрицу вида
FD3DDevice.SetTransform(D3DTS_VIEW, ViewMatrix);
// Строим левостороннюю матрицу проекции
D3DXMatrixPerspectiveFovLH(ProjectionMatrix, D3DX_PI / 4, 1, 1, 100);
// Устанавливаем матрицу проекции
Result := FD3DDevice.SetTransform(D3DTS_PROJECTION, ProjectionMatrix);
end;
function InitD3D: HResult;
var
d3dDisplayInfo: TD3DDisplayMode;
d3dParams: TD3DPresentParameters;
d3dVector: TD3DVector;
d3dLight: TD3DLight8;
begin
Result := E_FAIL; // Создаем объект с интерфейсом IDirect3D9
FD3D := Direct3DCreate8(D3D_SDK_VERSION);
// Завершаем работу процедуры при ошибке
if FD3D = nil then EXIT;
// Получаем установки текущего режима адаптера
Result := FD3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, d3dDisplayInfo);
// Завершаем аботу в случае сбоя
if FAILED(Result) then EXIT;
ZeroMemory(@d3dParams, SizeOf(d3dParams)); // обнуляем поля
with d3dParams do begin
Windowed := True; // используется оконный режим
SwapEffect := D3DSWAPEFFECT_DISCARD; // режим переключения буферов
BackBufferFormat := d3dDisplayInfo.Format; // формат заднего буфера
end;
// Сздаем объект устройства
Result := FD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dParams, FD3DDevice);
if FAILED(Result) then EXIT;
// Включаем режим отсечения
FD3DDevice.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// Отключаем освещение сцены
FD3DDevice.SetRenderState(D3DRS_LIGHTING, 0);
// Включаем поддержку Z-буфера устройством
FD3DDevice.SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
// Устанавливаем параметры просмотра сцены
SetupCamera;
// Задаем параметры источника света
ZeroMemory(@d3dLight, SizeOf(d3dLight));
d3dLight._Type := D3DLIGHT_DIRECTIONAL;
d3dLight.Diffuse.r := 1;
d3dLight.Diffuse.g := 1;
d3dLight.Diffuse.b := 1;
d3dLight.Range := 20;
// Направление источника
d3dVector.x := 0;
d3dVector.y := 0;
d3dVector.z := 5;
D3DXVec3Normalize(d3dLight.Direction, d3dVector);
// Устанавливаем параметры первого источника света сцены
FD3DDevice.SetLight(0, d3dLight);
// Включаем источник
FD3DDevice.LightEnable(0, TRUE);
// Включаем режим обработки освещения
FD3DDevice.SetRenderState(D3DRS_LIGHTING, 1);
// Задаем освещение окружающей среды
FD3DDevice.SetRenderState(D3DRS_AMBIENT, $00202020);
end;
procedure FreeD3D; //Освобождаем ресурсы
begin
FD3DText := nil;
FD3DDevice := nil;
FD3D := nil;
end;
procedure TextOut(S: string; R: TRect; TextColor: D3DColor);
begin
if (FD3DText <> nil) then
begin
FD3DText.DrawTextA(PChar(S), Length(S), R, DT_WORDBREAK, TextColor);
end;
end;
procedure DrawTextMessage;
var
rectMain,
rectName: TRect;
d3dViewport: TD3DViewport8;
begin
// Получаем параметры окна вывода
FD3DDevice.GetViewport(d3dViewport);
// Области надписей
rectMain := Rect(0, 0, 130, 90);
rectName := Rect(0, 0, 80, 95);
// Выводим текст
OffsetRect(rectMain, d3dViewport.Width - 120, 10);
TextOut(PChar('Текст'), rectMain, D3DCOLOR_XRGB(255, 0, 0));
OffsetRect(rectMain, 2, 2);
TextOut(PChar('Текст'), rectMain, D3DCOLOR_XRGB(50, 255, 50));
end;
function ClearDevice: HResult;
begin
// Результат по умолчанию
Result := E_FAIL;
// Если устройство не создано, то завершаем работу
if FD3DDevice = nil then EXIT;
// Чистим устройство
Result := FD3DDevice.Clear(0, nil, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0)
end;
function RenderScene: HResult;
begin
// Чистим устройство
Result := ClearDevice;
// Если произошла ошибка, то завершаем работу
if FAILED(Result) then EXIT;
// Начало сцены
FD3DDevice.BeginScene;
try
// Выводим текст
DrawTextMessage;
finally
// Завершаем сцену
FD3DDevice.EndScene;
end;
// Переключение буферов
FD3DDevice.Present(nil, nil, 0, nil);
end;
function CreateText: HResult;
var
DC: HDC;
begin
DC := GetDC(0);
try
Result := CreateFont(20, 6, 0, 0, FW_NORMAL, 0, 0, 0, 1, 0, 0, 0, DEFAULT_PITCH, 'Arial');
D3DXCreateFont(FD3DDevice, Result, FD3DText);
finally
ReleaseDC(0, DC);
end;
end;
function IsGameWindowActive: Boolean;
var
pId: DWORD;
begin
IsGameWindowActive := False;
Wnd := GetForegroundWindow;
if (Wnd = 0) then Exit;
GetWindowThreadProcessId(Wnd, pId);
IsGameWindowActive := (pId = GetCurrentProcessId)
end;
procedure CText;
begin
repeat
RenderScene;
until (KeyPressed(VK_F11));
end;
procedure Cheat;
begin
repeat
if (KeyPressed(VK_F12)) then begin
IsGameWindowActive;
if FAILED(InitD3D) then begin exit end;
CreateText;
//RenderScene;
CText;
end;
until false
end;
procedure DLLMain(Reason: DWORD);
var
UselessShit: DWORD;
begin
if (Reason = DLL_PROCESS_ATTACH) then
begin
CreateThread(nil, 0, @Cheat, nil, 0, UselessShit)
end
end;
begin
DLLProc := @DLLMain;
DLLProc(DLL_PROCESS_ATTACH)
end.
подскажите как правильно сделать
________________
если я не ошибаюсь, а могу и ошибаться ...
too many actual parameters
Для синхронизации вывода текста нужно поставить хук на вызов функции D3DX EndScene, чтобы после прорисовки всей сцены клиентом в каждом кадре вывести поверх свой текст. Вот похожая темка [Ссылки могут видеть только зарегистрированные пользователи. ]
Только PW работает на directx8, а там пример для 9
копипаст темы. на всякий случай, чтобы было. May 31, 07 by TracKer
Однажды я нашел такую программу как Fraps, она рисовала счетчик FPS в приложениях DirectX. Мне захотелось написать что-то подобное. И вот что у меня получилось…
Что нужно иметь для работы:
[Ссылки могут видеть только зарегистрированные пользователи. ] – Новые заголовки DirectX 9 для Delphi
[Ссылки могут видеть только зарегистрированные пользователи. ] – И обязательно прочитать эту статью чтобы именть какое-то представление о работе DirectX
И так, приступим.
Попробуем написать какой-то текст в чужем приложении. Для этого на нужно кстановить перехватчик (hook или хук) на вызовы трех функций, нужных нам для отрисовки нашего текста. Но сделать это не так просто. Для того чтобы выполнить наш програмный код в чужем приложении необходимо создать DLL с этим кодом и провести так называемую “DLL инъекцию” (DLL Injection). Для этого необходимо создать приостановленый процесс (запустьть наше DirectX приложение вызовом CreateProcessA с флагом CREATE_SUSPENDED), далее Инджектировать нашу DLL в процесс (вызов InjectLibraryA), и продолжить выполнение нашего процесса (вызов ResumeThread).
Код:
uses Direct3D9, madCodeHook;procedure TForm1.Button1Click(Sender: TObject);
var start: TStartupInfo; procInfo: TProcessInformation;
begin
ZeroMemory(@start, SizeOf(start));
start.cb:=SizeOf(Start);
if CreateProcessA(
'E:\Games\Lineage II\system\l2.exe',
'', nil, nil, True, CREATE_SUSPENDED, nil,
'E:\Games\Lineage II\system',
start, procInfo) then
begin
if not InjectLibraryA(
procInfo.hProcess, 'my_lib.dll') then
ShowMessage('failed');
ResumeThread(procInfo.hThread);
end;
end;
Теперь, что качается самой DLL. Первым делом нужно установить хук на вызов Direct3DCreate9 из d3d9.dll. Далее нужно установить хук на создание D3DDevice, потом на метод интерфейса IDirect3D9.CreateDevice (тут также необходимо произвести инициализацию шрифта которым мы будим писать текст), и наконец на метод интерфейса IDirect3DDevice9.EndScene (тут мы будим писать текст).
Код:
library my_lib;uses
SysUtils, Classes, madCodeHook,
Windows, Direct3D9, D3DX9;
var
D3DObj: IDirect3D9;
D3DDev: IDirect3DDevice9;
g_Font: ID3DXFont;
function GetInterfaceMethod(const intf; methodIndex: dword) : pointer;
begin
result := pointer(pointer(dword(pointer(intf)^) + methodIndex * 4)^);
end;
var EndScene9Next : function (self: pointer): HResult stdcall = nil;
var CreateDevice9Next : function (self: Pointer; Adapter: LongWord;
DeviceType: TD3DDevType; hFocusWindow: HWND; BehaviorFlags: DWord;
pPresentationParameters: PD3DPresentParameters;
out ppReturnedDeviceInterface: IDirect3DDevice9) : HRESULT stdcall = nil;
var Direct3DCreate9Next: function (SDKVersion: LongWord): DWORD stdcall = nil;
function EndScene9Callback(self: pointer): HResult; stdcall;
var
TextRect: TRect;
begin
TextRect := Rect(100,100,100,100);
g_Font.DrawTextA(
nil, PChar('Превед!!! :)'),
-1, @TextRect,
DT_LEFT or DT_NOCLIP,
D3DCOLOR_RGBA($00, $ff, $ff, $ff)
);
Result:=EndScene9Next(self);
end;
function CreateDevice9Callback(self: pointer; Adapter: LongWord; DeviceType: TD3DDevType;
hFocusWindow: HWND; BehaviorFlags: DWord; pPresentationParameters: PD3DPresentParameters;
out ppReturnedDeviceInterface: IDirect3DDevice9) : HRESULT; stdcall;
var
A: Integer;
begin
result := CreateDevice9Next(self, adapter, DeviceType, hFocusWindow, BehaviorFlags,
pPresentationParameters, ppReturnedDeviceInterface);
D3DDev := ppReturnedDeviceInterface;
if (result = 0) then
begin
A := D3DXCreateFont(
D3DDev, 100, 0, FW_BOLD, 1,
false, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
DEFAULT_PITCH or FF_DONTCARE,
PChar('Arial'),
g_Font
);
HookCode(GetInterfaceMethod(ppReturnedDeviceInterface{^}, 42),
@EndScene9Callback, @EndScene9Next);
end;
end;
function Direct3DCreate9Callback(SDKVersion: LongWord): DWORD; stdcall;
begin
Result:=Direct3DCreate9Next(SDKVersion);
D3DObj := IDirect3D9(Result);
if (Result <> 0) then
begin
if (@CreateDevice9Next = nil) then
UnhookCode(@CreateDevice9Next);
HookCode(GetInterfaceMethod(result, 16), @CreateDevice9Callback, @CreateDevice9Next);
end;
end;
begin
HookAPI('d3d9.dll', 'Direct3DCreate9', @Direct3DCreate9Callback, @Direct3DCreate9Next);
end.
Эта функция осущесвляет перехват функции Direct3DCreate9, находящейся в библиотеке d3d9.dll и заменяет ее на вызов функции Direct3DCreate9Callback (которая описана выше в коде). Подробнее об этой функции можно узнать тут: [Ссылки могут видеть только зарегистрированные пользователи. ]
После этого мы ждем когда главное приложение вызовет Direct3DCreate9 и сработает Direct3DCreate9Callback. В Direct3DCreate9Callback мы вызываем настоящую функцию, указатель на которую хранится в переменной Direct3DCreate9Next:
Код:
Result := Direct3DCreate9Next(SDKVersion);
В результате этого мы получаем указатель на интерфейс IDirect3D9, а именно объект D3DObj. Теперь нас интересует процесс создания IDirect3DDevice9, для этого мы ставим хук на метод IDirect3D9.CreateDevice:
В качестве медода мы пишем не его название, а его порядковый номер в объявлении, в данном случае 16. Ниже на рисунке показан пример с нумерацией.
[Ссылки могут видеть только зарегистрированные пользователи. ]
Теперь мы ждем вызова CreateDevice9Callback. Как только это происходит мы делаем вызов самой функции Direct3DCreate9Next, и получаем объект D3DDev, после этого создаем объект шрифта g_Font вызовом D3DXCreateFont. Паремтры этой функции более подробно можно узнать тут: [Ссылки могут видеть только зарегистрированные пользователи. ]
И тут же ставим хук на вызов метода IDirect3DDevice9.EndScene, он имеет номер 42.
Все приготовления завершены. Теперь мы ждем вызова EndScene9Callback. В этой функции мы осуществляем сам процесс рисования следующим вызовом:
Тоже происходил кик при загрузке. Помогло Sleep в самом начале на 3 секунды. Вариант загрузки был с помощью реестра. Если грузишь библиотеку при уже запущенной игре, и крашит, внимательно проверь цепочки оффсетов, чтобы не было чтения с 0 адреса.
________________
[Ссылки могут видеть только зарегистрированные пользователи. ]
Создавай отдельный поток а вызов DllMaim возвращай через return TRUE, чтобы библиотека осталась в памяти. В созданном потоке впадай в спячку, потом опрашивай адрес HostPlayer Struct через промежутки времени - если он равен 0, значит игра еще не загрузилась. Сам в делфи не волоку, так что подсказать на примере в коде не могу. Когда искал пример исхода для себя, натыкался на примеры, сделанные именно на делфи. Копипаст выше не помог?
Инжект в уже запущенную игру сделал на Autoit, скорость там не критична, поэтому вполне подошло. Еще, правда, до товарного вида не довел - на исход смотреть стыдно. Да и не тестировал еще как следует.
Гугли почаще, или жди, когда в тему зайдет кто нибудь пишущий на делфи ))
________________
[Ссылки могут видеть только зарегистрированные пользователи. ]
........
procedure DLLMain(Reason: DWORD);
var
UselessShit: DWORD;
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
HookProc('d3d8.dll', 'Direct3DCreate8', @Direct3DCreate8Callback, @Direct3DCreate8Next);
CreateThread(nil, 0, @Cheat, nil, 0, UselessShit);
end;
DLL_PROCESS_DETACH:
begin
end;
end;
end;
begin
DLLProc := @DLLMain;
DLLProc(DLL_PROCESS_ATTACH);
end.
то что зеленым вызывается то что красным нет
это часть advAPIhook.pas также в зеленых есть значения в красном нет
Код:
function HookProc(lpModuleName, lpProcName: PChar;
NewProc: pointer; var OldProc: pointer): boolean;
var
hModule: dword;
fnAdr: pointer;
begin
Result := false;
hModule := GetModuleHandle(lpModuleName);
if hModule = 0 then hModule := LoadLibrary(lpModuleName);
if hModule = 0 then Exit;
fnAdr := GetProcAddress(hModule, lpProcName);
if fnAdr = nil then Exit;
Result := HookCode(fnAdr, NewProc, OldProc);
end;
может из за того что var OldProc: pointer=nil отсутствует я и не могу перехватить
Direct3DCreate8 инжект идет после запуска игры
З.Ы. :Копипаст я видел до этого помощи с него никакой ( конкретной не получил
Добавлено через 22 часа 17 минут
тут ошибка
Цитата:
Сообщение от sumikot
begin if (@CreateDevice9Next = nil) then UnhookCode(@CreateDevice9Next); HookCode(GetInterfaceMethod(result, 16), @CreateDevice9Callback, @CreateDevice9Next); end;
Код:
begin
if (@CreateDevice9Next = nil) then
begin//отсутствовали
UnhookCode(@CreateDevice9Next);
HookCode(GetInterfaceMethod(result, 16), @CreateDevice9Callback, @CreateDevice9Next);
end;//отсутствовали
end;
из за этого не запускалось через BritishLoader
причем эта ошибка во всех статьях про внедрение таким способом(видимо с одного и того же сайта копировали))
также вместо madCodeHook(платная) возможно лучше использовать advAPIhook.pas + NativeAPI.pas(free)
........ загружается через BritishLoader
Код:
procedure DLLMain(Reason: DWORD);
var
UselessShit: DWORD;
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
CreateThread(nil, 0, @Cheat, nil, 0, UselessShit);
end;
DLL_PROCESS_DETACH:
begin
end;
end;
end;
begin
HookProc('d3d8.dll', 'Direct3DCreate8', @Direct3DCreate8Callback, @Direct3DCreate8Next);
DLLProc := @DLLMain;
DLLProc(DLL_PROCESS_ATTACH);
end.
... пока ни как не могу заставить грузится через инжетор в запущенную игру
________________
если я не ошибаюсь, а могу и ошибаться ...
too many actual parameters
Последний раз редактировалось zaparca; 22.04.2012 в 19:19.
Причина: Добавлено сообщение