Also das ganze ist so.
Ich injiziere eine
DLL in die Anwendung die das Spiel startet. In der ersten
DLL hooke ich CreateProcessW. Wenn dies Aufgerufen wird, ändere ich den Flag zu SUSPEND, injiziere die
DLL in das Spiel und danach lasse ich den Thread weiter laufen.
Das ganze sieht so aus.
Delphi-Quellcode:
function CallbackCreateProcess( lpApplicationName: PWideChar; lpCommandLine: PWideChar;
lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW;
var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
if (Pos('vertices',ExtractFileName(lpCommandLine)) > 0) then
begin
Result := newCreateProcess(lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes,
bInheritHandles, CREATE_SUSPENDED,
lpEnvironment, lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
uAllHook.InjectLibrary(lpProcessInformation.dwProcessId, PChar(ExtractFilePath(GetModulePath) + 'd3dxhook.dll'));
ResumeThread(lpProcessInformation.dwThreadId);
end else
Result := newCreateProcess(lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags,
lpEnvironment, lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
end;
Meine d3dxhook.dll sieht so aus:
Delphi-Quellcode:
library d3dxhook;
{ 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,
SysUtils,
Direct3D8,
d3dx8,
uAllHook;
{$R *.res}
type
Direct3DCreate8 =
function( D3D_SDK_VERSION: cardinal ): IDirect3D8;
stdcall;
var
oldDirect3DCreate8 : Direct3DCreate8;
newDirect3DCreate8 : Direct3DCreate8;
pIDirect3D8 : IDirect3D8;
function callbackDirect3DCreate8( D3D_SDK_VERSION: cardinal ): IDirect3D8;
stdcall;
begin
Result := oldDirect3DCreate8(D3D_SDK_VERSION);
MessageBox(0, '
callbackDirect3DCreate8', '
Information', MB_ICONINFORMATION);
end;
procedure DllMain(dwReason: DWord);
begin
case dwReason
of
DLL_PROCESS_ATTACH:
begin
oldDirect3DCreate8 := GetProcAddress(GetModuleHandle('
d3d8.dll'), '
Direct3DCreate8');
if not(HookCode( @oldDirect3DCreate8, @callbackDirect3DCreate8, @newDirect3DCreate8))
then
MessageBox(0, '
Direct3DCreate8 hooking failed', '
Information', MB_ICONINFORMATION);
end;
end;
end;
begin
DllProc := @DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.
Direct3DCreate8 hooking failed bekomme ich als Message, danach startet das Game. Wenn ich nur das Spiele starte, und nicht das Programm nehme was dieses eigentlich starten soll wird der Hook gesetzt. Also ist wohl irgendwas bei dem erstellen des Prozesses schief gelaufen - aber was?
Es muss aber auch ohne dieses Suspend funktionieren. Xfire, und die BNet banlist, welche glaube ich von einem aus diesem Board entwickelt wurde, schaffen es beide, nachdem das Spiel gestartet ist, sich darein zu hooken.
Den Thread habe ich mir schon zu Gemühte geführt aber C++ Kentnisse gehen gegen
null.
Du derefernzierst p2 einmal und weißt die Adresse von i zu. Das heißt p2 (also der Zeiger auf einen Zeiger) zeigt auf den Zeiger p1 welchen du so auf i zeigen lässt.