代码拉取完成,页面将自动刷新
unit d3dhookUnit;
{
This unit will inject the d3d hook dll into the target process and hook the
apropriate functions.
A shared object will be used for communicating states and data
}
{$mode delphi}
{$warn 5044 off}
interface
{$ifdef windows}
uses
windows, Classes, SysUtils, sharedMemory, forms, graphics, cefuncproc,
newkernelhandler, controls, Clipbrd, strutils, LuaHandler, RemoteMemoryManager,
math, syncobjs;
type
TCEMessage=packed record
uMsg: DWORD;
wParam: UINT64;
lParam: UINT64;
character: DWORD;
end;
TTextureEntry=packed record
AddressOfTexture: UINT64;
AddressOfFontmap: UINT64;
size: integer;
hasBeenUpdated: integer;
end;
TTextureEntryArray=Array [0..1000] of TTextureEntry;
PTextureEntryArray=^TTextureEntryArray;
type TRenderCommandEnum=(rcEndOfCommandlist=0, //Stop going through the list
rcIgnored=1, //Ignore (Being updated)
rcDrawSprite=2, //Render the sprite at the given position
rcDrawFont=3); //Render some text at the given coordinates. The string is located at "addressoftext"
TSpriteCommand=packed record
width: integer;
height: integer;
textureid: integer;
end;
TFontCommand=packed record
addressoftext: UINT64;
fontid: integer;
end;
TRenderCommand=packed record
command: integer;
x: single;
y: single;
alphablend: single;
centerX: single;
centerY: single;
rotation: single;
case TRenderCommandEnum of
rcDrawSprite: (Sprite: TSpriteCommand);
rcDrawFont: (Font: TFontCommand);
end;
PRenderCommand=^TRenderCommand;
TRenderCommandarray=array [0..100] of TRenderCommand;
PRenderCommandArray=^TRenderCommandArray;
TD3DHookShared=packed record
cheatenginedir: array [0..255] of char;
snapshotdir: array [0..255] of char;
dxgi_present: UINT64;
dxgi_resizebuffers: UINT64;
d3d9_present: UINT64;
d3d9_reset: UINT64;
d3d9_drawprimitive: UINT64;
d3d9_drawindexedprimitive: UINT64;
d3d9_drawprimitiveup: UINT64;
d3d9_drawindexedprimitiveup: UINT64;
d3d9_drawrectpatch: UINT64;
d3d9_drawtripatch: UINT64;
d3d10_drawindexed: UINT64;
d3d10_draw: UINT64;
d3d10_drawindexedinstanced: UINT64;
d3d10_drawinstanced: UINT64;
d3d10_drawauto: UINT64;
d3d11_drawindexed: UINT64;
d3d11_draw: UINT64;
d3d11_drawindexedinstanced: UINT64;
d3d11_drawinstanced: UINT64;
d3d11_drawauto: UINT64;
dxgi_newpresent: UINT64;
dxgi_newresizebuffers: UINT64;
d3d9_newpresent: UINT64;
d3d9_newreset: UINT64;
d3d9_newdrawprimitive: UINT64;
d3d9_newdrawindexedprimitive: UINT64;
d3d9_newdrawprimitiveup: UINT64;
d3d9_newdrawindexedprimitiveup: UINT64;
d3d9_newdrawrectpatch: UINT64;
d3d9_newdrawtripatch: UINT64;
d3d10_newdrawindexed: UINT64;
d3d10_newdraw: UINT64;
d3d10_newdrawindexedinstanced: UINT64;
d3d10_newdrawinstanced: UINT64;
d3d10_newdrawauto: UINT64;
d3d11_newdrawindexed: UINT64;
d3d11_newdraw: UINT64;
d3d11_newdrawindexedinstanced: UINT64;
d3d11_newdrawinstanced: UINT64;
d3d11_newdrawauto: UINT64;
dxgi_originalpresent: UINT64;
dxgi_originalresizebuffers: UINT64;
d3d9_originalpresent: UINT64;
d3d9_originalreset: UINT64;
d3d9_originaldrawprimitive: UINT64;
d3d9_originaldrawindexedprimitive: UINT64;
d3d9_originaldrawprimitiveup: UINT64;
d3d9_originaldrawindexedprimitiveup: UINT64;
d3d9_originaldrawrectpatch: UINT64;
d3d9_originaldrawtripatch: UINT64;
d3d10_originaldrawindexed: UINT64;
d3d10_originaldraw: UINT64;
d3d10_originaldrawindexedinstanced: UINT64;
d3d10_originaldrawinstanced: UINT64;
d3d10_originaldrawauto: UINT64;
d3d11_originaldrawindexed: UINT64;
d3d11_originaldraw: UINT64;
d3d11_originaldrawindexedinstanced: UINT64;
d3d11_originaldrawinstanced: UINT64;
d3d11_originaldrawauto: UINT64;
wireframe: integer;
disabledzbuffer: integer;
hookwnd: integer;
clipmouseinwindow: integer;
clickedoverlay: integer;
clickedx: integer;
clickedy: integer;
console: packed record
hasconsole: integer;
consolevisible: integer;
consolekey: dword;
overlayid: integer;
cursorid: integer;
lastmessage: TCEMessage;
end;
lastHwnd: DWORD;
texturelistHasUpdate: integer; //If 1 this means that CE might be waiting for the HasHandledTextureUpdate event (if it is a high priority update)
textureCount: integer;
texturelist: UINT64 ; //offset into texturelist based on the start of the shared object (once setup, this does not change)
TextureLock: UINT64 ; //target process handle
commandListLock: UINT64; //lockinforder: FIRST commandlist, THEN texturelist.
useCommandListLock: integer;
hasOnKey: integer;
snapshotKey: DWORD;
smallSnapshotKey: DWORD;
snapshotDone: UINT64; //Event to signal that a snapshot is done
snapshotImageFormat: integer;
snapshotcount: integer;
progressiveSnapshot: integer; //set to 1 if you do not wish the snapshot to clear the screen before each draw. (This makes it easier to see how a scene was build up)
alsoClearDepthBuffer: integer; //set to 1 if you also want the depth buffer to be cleared before each draw
savePNGSeperateAsWell: integer;
canDoSnapshot: integer;
initialized: DWORD;
//followed by the rendercommands
end;
PD3DHookShared=^TD3DHookShared;
type
TD3DHook_RenderObject=class;
TD3DClickEvent=procedure(renderobject: TObject; x,y: integer) of object;
TD3DKeyDownEvent=function(VirtualKey: dword; char: pchar): boolean of object;
TD3DHook=class;
TD3DHook_Texture=class;
TD3DHook_Sprite=class;
TD3DHook_Fontmap=class;
TD3DHook_TextContainer=class;
TD3DMessageHandler=class(tthread)
private
owner: TD3DHook;
rendercommandid, x,y: integer; //clicked overlay
lastmessage: TCEMessage;
console: record
log: Tstringlist;
cursorpos: integer;
backgroundtexture: TD3DHook_Texture;
background: TD3DHook_Sprite;
cursortexture: TD3DHook_Texture;
cursor: TD3DHook_sprite;
seperator: TD3dhook_sprite; //horizontal line splitting commandline from output
fontmap: TD3DHook_Fontmap;
output: TD3DHook_textcontainer; //history/output
commandline: TD3DHook_TextContainer; //commandline
end;
procedure setConsoleCursorPos;
procedure doclick;
procedure dokeyboard;
procedure handleSnapshot;
public
procedure execute; override;
end;
TD3DHook_Texture=class(TObject)
private
resource: ptruint; //address where the current resource is located
protected
id: integer;
owner: TD3DHook;
fheight: integer;
fwidth: integer;
public
function getID: integer;
{
procedure LoadTextureFromFile(filename: string);
constructor Create(filename: string); overload; }
procedure LoadTextureByPicture(picture: TPicture);
constructor Create(owner: TD3DHook; picture: TPicture);
constructor Create(owner: TD3DHook);
destructor destroy; override;
published
property Height: integer read fheight;
property Width: integer read fwidth;
end;
TD3DHook_FontMap=class(TD3DHook_Texture)
private
fontmapdata: ptruint;
localfontmapcopy: TMemorystream; //used by calculateFontwidth
public
function calculateFontWidth(s:string): integer;
procedure ChangeFont(font: TFont);
constructor Create(owner: TD3DHook; font: TFont);
destructor destroy; override;
end;
TD3DHook_RenderObject=class(TObject)
private
fx: single;
fy: single;
fcenterX: single;
fcenterY: single;
fRotation: single; //stored as deg here, internally uses rad
falphablend: single;
fvisible: boolean;
procedure setRotation(v: single);
procedure setCenterX(v: single);
procedure setCenterY(v: single);
procedure setX(v: single);
procedure setY(v: single);
procedure setAlphaBlend(v: single);
procedure setVisible(state: boolean);
procedure setZOrder(newpos: integer);
protected
owner: TD3DHook;
updatecount: integer;
public
function getIndex: integer;
procedure beginUpdate;
procedure endUpdate;
procedure UpdateRenderCommand; virtual; abstract;
destructor destroy; override;
constructor create(owner: TD3DHook);
published
property ZOrder: integer read getIndex write setZOrder;
property Alphablend: single read falphablend write setAlphablend;
property X: single read fx write setX;
property Y: single read fy write setY;
property CenterX: single read fcenterx write setCenterX;
property CenterY: single read fcentery write setCenterY;
property Rotation: single read frotation write setRotation;
property Visible: boolean read fVisible write setVisible;
end;
TD3Dhook_TextContainer=class(TD3DHook_RenderObject) //class for rendering text
private
maxTextLength: integer;
AddressOfText: QWORD;
fFontMap: TD3DHook_FontMap;
fText: string;
addressChangedThisUpdate: boolean;
oldAddressOfText: QWORD;
private
procedure setFontMap(fm: TD3DHook_FontMap);
procedure setText(s: string);
public
procedure UpdateRenderCommand; override;
destructor destroy; override;
constructor create(owner: TD3DHook; fontmap: TD3DHook_FontMap; x,y: single; text: string; minsize: integer=0);
published
property FontMap: TD3DHook_FontMap read fFontMap write setFontMap;
property Text: String read fText write setText;
end;
TD3DHook_Sprite=class(TD3DHook_RenderObject) //clas for rendering textures
private
ftexture: TD3DHook_Texture;
fwidth: integer;
fheight: integer;
procedure setTexture(s: TD3DHook_Texture);
procedure setWidth(v: integer);
procedure setHeight(v: integer);
public
procedure UpdateRenderCommand; override;
constructor create(owner: TD3DHook; texture: TD3DHook_Texture);
published
property Width: integer read fWidth write setWidth;
property Height: integer read fHeight write setHeight;
property Texture: TD3DHook_Texture read ftexture write setTexture;
end;
TD3DHook=class(TObject)
private
hooked: boolean;
fonKeyDown: TD3DKeyDownEvent;
fonclick: TD3DClickEvent;
sharename: string;
shared: PD3DHookShared; //local address of the D3DHookShared structure
tea: PTextureEntryArray;
fmhandle: THandle;
textures: TList;
commandlist: TList; //collection of pointer to objects used for lookup and id management. 1-on-1 relation to the renderCommands list
renderCommandList: PRenderCommandArray;
isupdating: integer; //update counter for the texture list
isupdatingCL: integer; //update counter for the command list
maxsize: integer;
fprocessid: dword;
hasclickevent: THandle;
hashandledclickevent: THandle;
haskeyboardevent: THandle; //todo: combine into one "HasMessage" event, but for now, to make sure I don't break anything, this method...
hashandledkeyboardevent: THandle;
SnapshotDone: THandle;
texturelock: THandle;
CommandListLock: THandle;
messagehandler: TD3DMessageHandler;
memman: TRemoteMemoryManager;
commandlistCS: TCriticalSection;
procedure setOnKeyDown(s: TD3DKeyDownEvent);
public
procedure beginTextureUpdate;
procedure endTextureUpdate;
procedure beginCommandListUpdate;
procedure endCommandListUpdate;
function createTexture(f: string): TD3DHook_Texture; overload;
function createTexture(p: TPicture): TD3DHook_Texture; overload;
function createSprite(texture: TD3DHook_Texture): TD3DHook_Sprite;
function createFontMap(f: TFont): TD3DHook_FontMap;
function createTextContainer(fontmap: TD3DHook_FontMap; x,y: single; text: string): TD3Dhook_TextContainer;
function getDisabledZBuffer: boolean;
procedure setDisabledZBuffer(state: boolean);
function getWireframeMode: boolean;
procedure setWireframeMode(state: boolean);
function getMouseClip: boolean;
procedure setMouseClip(state: boolean);
function getWidth: integer;
function getHeight: integer;
procedure setCommandListLockFeature(state: boolean);
procedure enableConsole(virtualkey: DWORD);
procedure setSnapshotOptions(path: string; full, small: dword; Progressive: boolean; cleardepthbuffer: boolean; savepng: boolean; pictureFormat: integer);
constructor create(size: integer; hookhwnd: boolean=true);
destructor destroy; override;
published
property Width: integer read getWidth;
property Height: integer read getHeight;
property DisabledZBuffer: boolean read GetDisabledZBuffer write setDisabledZBuffer;
property WireframeMode: boolean read GetWireframeMode write setWireframeMode;
property MouseClip: boolean read GetMouseclip write setMouseClip;
property Processid: dword read fprocessid;
property OnKeyDown: TD3DKeyDownEvent read fonKeyDown write setOnKeyDown;
property OnClick: TD3DClickEvent read fonclick write fonclick;
end;
var D3DHook: TD3DHook;
function safed3dhook(size: integer=16*1024*1024; hookwindow: boolean=true): TD3DHook;
procedure FixAlpha(aPNG: TPortableNetworkGraphic);
{$endif}
implementation
{$ifdef windows}
uses frmautoinjectunit, autoassembler, MainUnit, frmSaveSnapshotsUnit,
frmsnapshothandlerUnit, symbolhandler, ProcessHandlerUnit, Globals;
resourcestring
rsTheD3dhookObjectHasNotBeenCreatedYet = 'The d3dhook object has not been created yet';
rsD3DHookFailureToOpenTheSharedMemoryObject = 'D3DHook: Failure to open the shared memory object';
rsD3DHookFailureToMapTheSharedMemoryObject = 'D3DHook: Failure to map the shared memory object';
procedure TD3DMessageHandler.handleSnapshot;
begin
if frmSaveSnapshots=nil then
frmSaveSnapshots:=TfrmSaveSnapshots.create(application);
frmSaveSnapshots.btnCombinedSelect.visible:=owner.shared.progressiveSnapshot=0;
frmSaveSnapshots.initialize(owner.shared.snapshotdir, owner.shared.snapshotcount);
frmSaveSnapshots.showmodal;
owner.shared.canDoSnapshot:=1;
if frmSaveSnapshots.saved.Count>0 then
begin
if frmsnapshothandler=nil then
frmsnapshothandler:=TfrmSnapshotHandler.create(application);
frmsnapshothandler.show;
frmsnapshothandler.loadsnapshots(frmSaveSnapshots.saved);
end;
//exit the function and wait for a new event
end;
procedure TD3DMessageHandler.setConsoleCursorPos;
var s: string;
begin
if console.cursor<>nil then
begin
console.cursor.y:=console.commandline.y;
s:=copy(console.commandline.Text,1, console.cursorpos);
console.cursor.x:=console.fontmap.calculateFontWidth(s);
end;
end;
procedure TD3DMessageHandler.dokeyboard;
var virtualkey: dword;
scancode: dword;
c,c2: string;
s: pchar;
old: tstrings;
p: tpicture;
f: tfont;
maxlines: integer;
currentlines: integer;
i: integer;
l: string;
begin
//check the size of the window. If it's changed, reinitialize the consoleoverlay
owner.shared.console.lastmessage.uMsg:=0; //don't handle the keypress in the target process
if assigned(owner.onkeydown) then
begin
if owner.onkeydown(lastmessage.wParam, pchar(@lastmessage.character)) then
owner.shared.console.lastmessage.uMsg:=1; //if it returns true, let it go through
end;
if (owner.shared.console.hasconsole=0) or (owner.shared.console.consolevisible=0) then exit;
//just create or show the console
if console.background=nil then
begin
owner.beginTextureUpdate;
try
p:=tpicture.Create;
p.png.canvas.brush.color:=clBlack;
p.png.width:=1;
p.png.height:=1;
console.backgroundtexture:=TD3DHook_Texture.Create(owner, p);
p.free;
console.background:=TD3DHook_Sprite.create(owner, console.backgroundtexture);
console.background.width:=-1; //full width
console.background.height:=owner.getHeight div 2;
console.background.x:=0;
console.background.y:=owner.getHeight div 2;
console.background.alphaBlend:=0.80;
p:=tpicture.Create;
p.png.canvas.brush.color:=clWhite;
p.png.width:=1;
p.png.height:=1;
p.png.Canvas.Pixels[0,0]:=clWhite;
console.cursortexture:=TD3DHook_Texture.Create(owner, p);
p.free;
console.cursor:=TD3DHook_sprite.create(owner, console.cursortexture);
f:=tfont.create;
f.Assign(mainform.Font);
f.color:=clWhite;
f.Size:=f.size*2;
console.fontmap:=TD3DHook_FontMap.Create(owner, f);
console.commandline:=TD3Dhook_TextContainer.create(owner, console.fontmap, 0, owner.getHeight-console.fontmap.height,'',256);
console.seperator:=TD3DHook_sprite.create(owner, console.cursortexture); //same color
console.seperator.x:=0;
console.seperator.y:=owner.getHeight-console.fontmap.height;
console.seperator.height:=1;
console.seperator.width:=-1; //full width
console.output:=TD3Dhook_TextContainer.create(owner, console.fontmap, 0, owner.getHeight div 2,'',8192);
console.cursor.width:=3;
console.cursor.height:=console.fontmap.height;
//
finally
owner.endTextureUpdate;
end;
end;
setConsoleCursorPos;
if lastmessage.uMsg=$ffffffff then
begin
console.background.visible:=true;
console.seperator.visible:=true;
console.cursor.visible:=true;
console.output.visible:=true;
console.commandline.visible:=true;
exit; //nothing else to do
end;
if lastmessage.uMsg=$fffffffe then
begin
console.background.visible:=false;
console.seperator.visible:=false;
console.cursor.visible:=false;
console.output.visible:=false;
console.commandline.visible:=false;
exit;
end;
//handle the key
virtualkey:=lastmessage.wParam;
scancode:=(lastmessage.lparam shr 16) and $FF;
owner.beginTextureUpdate;
//handle keys like delete, backspace, etc...
case virtualkey of
VK_RETURN:
begin
//execute the command
console.log.add(console.commandline.Text);
old:=lua_oldprintoutput;
lua_setPrintOutput(console.log);
lua_dostring(LuaVM, pchar(console.commandline.Text));
lua_setPrintOutput(old);
//calculate the max number of lines
maxlines:=trunc((console.seperator.y-console.background.y) / console.output.FontMap.height);
currentlines:=0;
l:='';
for i:=max(0, console.log.Count-maxlines) to console.log.Count-1 do
begin
l:=l+console.log[i]+#13#10;
inc(currentlines);
if (currentlines>=maxlines) then break;
end;
console.output.y:=console.seperator.y-(currentlines*console.output.FontMap.height);
console.output.Text:=l;
console.commandline.Text:='';
console.cursorpos:=0;
end;
VK_LEFT:
begin
if console.cursorpos>0 then
dec(console.cursorpos);
end;
VK_RIGHT:
begin
if console.cursorpos<length(console.commandline.Text) then
inc(console.cursorpos);
end;
VK_BACK:
begin
//delete the character before the cursorpos
if console.cursorpos>0 then
begin
c:=copy(console.commandline.text, 1, console.cursorpos-1);
c2:=copy(console.commandline.text, console.cursorpos+1, length(console.commandline.Text));
console.commandline.text:=c+c2;
dec(console.cursorpos);
end;
end;
VK_DELETE:
begin
//delete the character after the current cursor
c:=copy(console.commandline.text, 1, console.cursorpos);
c2:=copy(console.commandline.text, console.cursorpos+2, length(console.commandline.text));
console.commandline.text:=c+c2;
end
else
begin
//not a control key, check if it's a character
if lastmessage.character<>0 then
begin
//it's a character
s:=@lastmessage.character;
c:=copy(console.commandline.text, 1, console.cursorpos);
c2:=copy(console.commandline.text, console.cursorpos+1, length(console.commandline.text));
console.commandline.text:=c+s+c2;
inc(console.cursorpos);
end;
end;
end;
setConsoleCursorPos;
owner.endTextureUpdate;
end;
procedure TD3DMessageHandler.doclick;
begin
if assigned(owner.onclick) then
owner.onclick(TD3DHook_RenderObject(owner.commandlist[rendercommandid]), x,y);
end;
procedure TD3DMessageHandler.execute;
var eventlist: array of THandle;
r: dword;
cursor: boolean;
cursorstart: dword;
begin
cursorstart:=gettickcount;
console.log:=tstringlist.create;
console.cursorpos:=0;
setlength(eventlist,3);
eventlist[0]:=owner.hasclickevent;
eventlist[1]:=owner.haskeyboardevent;
eventlist[2]:=owner.SnapshotDone;
while (not terminated) do
begin
r:=WaitForMultipleObjects(3, @eventlist[0], false, 100);
case r of
WAIT_OBJECT_0:
begin
//click event: quickly save the variables and tell the game to continue
x:=owner.shared.clickedx;
y:=owner.shared.clickedy;
rendercommandid:=owner.shared.clickedoverlay;
SetEvent(owner.hashandledclickevent);
Synchronize(doclick);
end;
WAIT_OBJECT_0+1:
begin
//keyboard event
lastmessage:=owner.shared.console.lastmessage;
Synchronize(dokeyboard);
SetEvent(owner.hashandledkeyboardevent);
cursorstart:=GetTickCount;
end;
WAIT_OBJECT_0+2:
begin
//snapshot event
synchronize(handlesnapshot);
end;
end;
if (owner.shared.console.consolevisible=1) and (console.cursor<>nil) then //toggle the cursor visible or invisible based on the current time and if a key was pressed (keep the cursor visible rigth after pressing a key, so reset the timerstart)
console.cursor.visible:=(((GetTickCount-cursorstart) mod 1000)<500);
end;
end;
//----------------------------D3DHook_RenderObject------------------------------
procedure TD3DHook_RenderObject.setRotation(v: single);
begin
if fRotation=v then exit;
beginUpdate;
fRotation:=v;
endUpdate;
end;
procedure TD3DHook_RenderObject.setCenterX(v: single);
begin
if fcenterX=v then exit;
beginUpdate;
fcenterX:=v;
endUpdate;
end;
procedure TD3DHook_RenderObject.setCenterY(v: single);
begin
if fcenterY=v then exit;
beginUpdate;
fcenterY:=v;
endUpdate;
end;
procedure TD3DHook_RenderObject.setAlphaBlend(v: single);
begin
if falphablend=v then exit;
BeginUpdate;
falphablend:=v;
endUpdate;
end;
procedure TD3DHook_RenderObject.setX(v: single);
begin
if fx=v then exit;
beginUpdate;
fx:=v;
endUpdate;
end;
procedure TD3DHook_RenderObject.setY(v: single);
begin
if fy=v then exit;
beginUpdate;
fy:=v;
endUpdate;
end;
procedure TD3DHook_RenderObject.setVisible(state: boolean);
begin
if fvisible=state then exit; //no change, no update
beginUpdate;
fvisible:=state;
endUpdate;
end;
procedure TD3DHook_RenderObject.setZOrder(newpos: integer);
var
mypos: integer;
replaced: TD3DHook_RenderObject;
begin
//change the order of the commandlist
mypos:=zorder;
if (newpos<>mypos) and (newpos<owner.commandlist.count) then
begin
replaced:=TD3DHook_RenderObject(owner.commandlist[newpos]);
owner.beginCommandListUpdate;
owner.renderCommandList^[newpos].command:=integer(rcIgnored); //in case the locking option is not used. Will cause some flickering in the worst case
owner.renderCommandList^[mypos].command:=integer(rcIgnored);
owner.commandlist[newpos]:=self;
owner.commandlist[mypos]:=replaced;
//now update mine and the replaced one's rendercommand entry
UpdateRenderCommand;
if replaced<>nil then
replaced.UpdateRenderCommand;
owner.endCommandListUpdate;
end;
end;
function TD3DHook_RenderObject.getIndex: integer;
begin
result:=owner.commandlist.IndexOf(self);
end;
procedure TD3DHook_RenderObject.beginUpdate;
begin
inc(updatecount);
end;
procedure TD3DHook_RenderObject.endUpdate;
begin
if updatecount>0 then
dec(updatecount);
if updatecount=0 then
UpdateRenderCommand;
end;
destructor TD3DHook_RenderObject.destroy;
var index: integer;
begin
index:=getindex;
owner.renderCommandList^[Index].command:=integer(rcIgnored);
owner.commandlist[index]:=nil;
inherited destroy;
end;
constructor TD3DHook_RenderObject.create(owner: TD3DHook);
begin
self.owner:=owner;
falphablend:=1;
fvisible:=true;
owner.commandlist.Add(self);
end;
//----------------------------D3DHook_TextContainer-----------------------------
procedure TD3Dhook_TextContainer.setText(s: string);
var
x: ptruint;
nul: byte;
begin
BeginUpdate;
fText:=s;
if length(s)+1>maxTextLength then //+1 for 0 terminator
begin
if AddressOfText<>0 then //free the old block
owner.memman.dealloc(AddressOfText);
maxTextLength:=length(s)+16;
AddressOfText:=owner.memman.alloc(maxTextLength);
end;
if s='' then
begin
nul:=0;
WriteProcessMemory(processhandle, pointer(AddressOfText), @nul, 1, x);
end
else
WriteProcessMemory(processhandle, pointer(AddressOfText), @s[1], length(s)+1, x); //just write
endUpdate;
end;
procedure TD3Dhook_TextContainer.setFontMap(fm: TD3DHook_FontMap);
begin
BeginUpdate;
fFontMap:=fm;
endUpdate;
end;
procedure TD3Dhook_TextContainer.UpdateRenderCommand;
var index: integer;
begin
index:=getindex;
owner.beginCommandListUpdate;
if (index<>-1) and (fFontmap<>nil) and (fVisible) then
begin
if owner.renderCommandList^[index].command<>integer(rcDrawFont) then //something completely new
owner.renderCommandList^[index].command:=integer(rcIgnored);
owner.renderCommandList^[index].x:=x;
owner.renderCommandList^[index].y:=y;
owner.renderCommandList^[index].rotation:=degtorad(Rotation);
owner.renderCommandList^[index].centerx:=centerx;
owner.renderCommandList^[index].centery:=centery;
owner.renderCommandList^[index].alphablend:=alphablend;
owner.renderCommandList^[index].Font.fontid:=fFontmap.getID;
owner.renderCommandList^[index].Font.addressoftext:=AddressOfText;
owner.renderCommandList^[index].command:=integer(rcDrawFont);
end
else
owner.renderCommandList^[index].command:=integer(rcIgnored);
owner.endCommandListUpdate;
end;
destructor TD3Dhook_TextContainer.destroy;
begin
if AddressOfText<>0 then
owner.memman.dealloc(addressoftext);
inherited destroy;
end;
constructor TD3Dhook_TextContainer.create(owner: TD3DHook; fontmap: TD3DHook_FontMap; x,y: single; text: string; minsize: integer=0);
begin
inherited create(owner);
beginupdate;
if minsize<>0 then
begin
maxTextLength:=minsize;
AddressOfText:=owner.memman.alloc(maxTextLength);
end;
self.x:=x;
self.y:=y;
self.FontMap:=fontmap;
self.text:=text;
endUpdate;
end;
//-------------------------------D3DHook_Sprite---------------------------------
procedure TD3DHook_Sprite.setWidth(v: integer);
begin
beginUpdate;
fwidth:=v;
endUpdate;
end;
procedure TD3DHook_Sprite.setHeight(v: integer);
begin
beginUpdate;
fheight:=v;
endUpdate;
end;
procedure TD3DHook_Sprite.setTexture(s: TD3DHook_Texture);
begin
BeginUpdate;
ftexture:=s;
width:=s.width;
height:=s.height;
EndUpdate;
end;
procedure TD3DHook_Sprite.UpdateRenderCommand;
var index: integer;
begin
index:=getindex;
owner.beginCommandListUpdate;
if (index<>-1) and (texture<>nil) and (fVisible) then
begin
if owner.renderCommandList^[index].command<>integer(rcDrawSprite) then //something completely new
owner.renderCommandList^[index].command:=integer(rcIgnored);
owner.renderCommandList^[index].x:=x;
owner.renderCommandList^[index].y:=y;
owner.renderCommandList^[index].rotation:=degtorad(rotation);
owner.renderCommandList^[index].centerX:=centerx;
owner.renderCommandList^[index].centerY:=centery;
owner.renderCommandList^[index].alphablend:=alphablend;
owner.renderCommandList^[index].Sprite.width:=width;
owner.renderCommandList^[index].Sprite.height:=height;
owner.renderCommandList^[index].Sprite.textureid:=texture.getID;
owner.renderCommandList^[index].command:=integer(rcDrawSprite);
end
else
owner.renderCommandList^[index].command:=integer(rcIgnored);
owner.endCommandListUpdate;
end;
constructor TD3DHook_Sprite.create(owner: TD3DHook; texture: TD3DHook_Texture);
begin
inherited create(owner);
beginupdate;
setTexture(texture);
endUpdate;
end;
//-------------------------------d3dhook_font-----------------------------------
function TD3DHook_FontMap.calculateFontWidth(s:string): integer;
var cwa: PWordarray;
i: integer;
c: byte;
begin
result:=0;
cwa:=localfontmapcopy.memory;
for i:=1 to length(s) do
begin
c:=ord(s[i]);
if c in [32..127] then
inc(result,cwa[c-32+1]);
end;
end;
procedure FixAlpha(aPNG: TPortableNetworkGraphic);
type
TColor32 = packed record
B, G, R, A: Byte;
end;
PColor32=^TColor32;
TColor32Array = array[0..0] of TColor32;
PColor32Array = ^TColor32Array;
var
x, y: Integer;
Line: PColor32Array;
R,G,B: Integer;
begin
R := aPng.TransparentColor and $ff;
G := (aPng.TransparentColor shr 8) and $ff;
B := (aPng.TransparentColor shr 16) and $ff;
aPNG.BeginUpdate;
for y := 0 to aPNG.Height - 1 do
begin
{$warn 5044 off}
Line := aPNG.ScanLine[y];
for x := 0 to aPNG.Width - 1 do
begin
if (Line^[x].R=R) and (Line^[x].G=G) and (Line^[x].B=B) then
Line^[x].A := 0 //100% see through
else
Line^[x].A := 255;
end;
{$warn 5044 on}
end;
aPNG.EndUpdate;
end;
procedure TD3DHook_FontMap.ChangeFont(font: TFont);
var s: string;
i: integer;
charpos: integer;
p: TPicture;
charwidth: word; //65535 if the max size of one character
newblock: pointer;
x: ptruint;
begin
p:=TPicture.Create;
p.PNG.PixelFormat:=pf32bit;
p.png.canvas.font:=font;
p.png.canvas.brush.color:=InvertColor(font.color);
p.png.Transparent:=true;
p.png.TransparentColor:=p.png.canvas.brush.color;
p.png.width:=100;
p.png.height:=100; //initial setup
//create a fontmap picture with this font and set that as the texture
//also fill in the fontmap layout
s:='';
for i:=32 to 127 do
s:=s+chr(i);
fheight:=p.png.canvas.GetTextHeight(s); //get the max height
//calculate the width based on a per character rendering. (perhaps the whole string might have been using a half pixel at some spots...)
fwidth:=0;
for i:=32 to 127 do
fwidth:=fwidth+p.png.canvas.GetTextWidth(chr(i));
//setup the image
p.png.Width:=fwidth;
p.png.height:=fheight;
if localfontmapcopy<>nil then
freeandnil(localfontmapcopy);
localfontmapcopy:=tmemorystream.create; //buffer to obtain the fontmap data
localfontmapcopy.WriteBuffer(fheight, sizeof(word)); //2 bytes for the height of all characters
//now fill it in
charpos:=0;
for i:=32 to 127 do
begin
p.PNG.canvas.TextOut(charpos, 0, chr(i));
charwidth:=p.png.Canvas.GetTextWidth(chr(i));
localfontmapcopy.WriteBuffer(charwidth,2);
charpos:=charpos+charwidth;
end;
//laz 1.6 makes 32bit png's 100% transparant
//so manually make it visible
FixAlpha(p.PNG);
newblock:=pointer(owner.memman.alloc(localfontmapcopy.size));
if newblock<>nil then
begin
if WriteProcessMemory(processhandle, newblock, localfontmapcopy.memory, localfontmapcopy.size, x) then
begin
owner.beginTextureUpdate;
//set the font state
owner.tea[id].AddressOfFontmap:=qword(newblock);
owner.tea[id].hasBeenUpdated:=1;
//free old block if possible
if (resource<>0) then
owner.memman.dealloc(fontmapdata);
LoadTextureByPicture(p);
owner.endTextureUpdate;
fontmapdata:=qword(newblock);
end;
end;
// p.SaveToFile('c:\bla.png');
end;
destructor TD3DHook_FontMap.destroy;
begin
if fontmapdata<>0 then
owner.memman.dealloc(fontmapdata);
inherited destroy;
end;
constructor TD3DHook_FontMap.Create(owner: TD3DHook; font: TFont);
begin
inherited create(owner);
ChangeFont(font);
end;
//-------------------------------d3dhook_texture--------------------------------
procedure TD3DHook_Texture.LoadTextureByPicture(picture: TPicture);
var m: tmemorystream;
newblock: pointer;
x: ptruint;
msp: pointer;
s: integer;
begin
m:=TMemoryStream.create;
picture.PNG.SaveToStream(m);
owner.beginTextureUpdate;
newblock:=pointer(owner.memman.alloc(m.size));
if newblock<>nil then
begin
msp:=m.Memory;
s:=m.size;
if WriteProcessMemory(processhandle, newblock, m.memory, m.size, x) then
begin
owner.tea[id].AddressOfTexture:=qword(newblock);
owner.tea[id].Size:=m.size;
owner.tea[id].hasBeenUpdated:=1;
//free old block if possible
if (resource<>0) then
owner.memman.dealloc(resource);
fheight:=picture.Height;
fwidth:=picture.Width;
end;
resource:=qword(newblock);
end;
m.free;
owner.endTextureUpdate;
end;
function TD3DHook_Texture.getID: integer;
begin
result:=id;
end;
destructor TD3DHook_Texture.destroy;
begin
owner.beginTextureUpdate;
owner.tea[id].AddressOfTexture:=0;
owner.tea[id].hasBeenUpdated:=1; //marks for deletion
if resource<>0 then
owner.memman.dealloc(resource);
owner.textures[id]:=nil;
owner.endTextureUpdate;
inherited destroy;
end;
constructor TD3DHook_Texture.Create(owner: TD3DHook);
var i: integer;
begin
self.owner:=owner;
id:=-1;
//find a empty slot, and if not found, add it instead
for i:=0 to owner.textures.count-1 do
if owner.textures[i]=nil then
begin
id:=i;
owner.textures[id]:=self;
break;
end;
if id=-1 then
id:=owner.textures.add(self);
end;
constructor TD3DHook_Texture.Create(owner: TD3DHook; picture: TPicture);
var m: TMemoryStream;
begin
create(owner);
LoadTextureByPicture(picture);
end;
//----------------------------------D3dhook-------------------------------------
procedure TD3DHook.setSnapshotOptions(path: string; full, small: dword; Progressive: boolean; cleardepthbuffer: boolean; savepng: boolean; pictureFormat: integer);
begin
shared.snapshotdir:=IncludeTrailingPathDelimiter(path);
shared.snapshotKey:=full;
if Progressive then
begin
shared.progressiveSnapshot:=1;
shared.smallSnapshotKey:=0;
end
else
begin
shared.progressiveSnapshot:=0;
shared.smallSnapshotKey:=small;
end;
shared.snapshotImageFormat:=pictureFormat;
if cleardepthbuffer then shared.alsoClearDepthBuffer:=1 else shared.alsoClearDepthBuffer:=0;
if savepng then shared.savePNGSeperateAsWell:=1 else shared.savePNGSeperateAsWell:=0;
end;
procedure TD3DHook.setOnKeyDown(s: TD3DKeyDownEvent);
begin
if assigned(s) then
begin
fonKeyDown:=s;
shared.hasOnKey:=1;
end
else
shared.hasOnKey:=0;
end;
procedure TD3DHook.enableConsole(virtualkey: DWORD);
begin
shared.console.hasconsole:=1;
shared.console.consolekey:=virtualkey;
end;
function TD3DHook.getDisabledZBuffer: boolean;
begin
result:=shared.disabledzbuffer=1;
end;
procedure TD3DHook.setDisabledZBuffer(state: boolean);
begin
if state then
shared.disabledzbuffer:=1
else
shared.disabledzbuffer:=0;
end;
function TD3DHook.getWireframeMode: boolean;
begin
result:=shared.wireframe=1;
end;
procedure TD3DHook.setWireframeMode(state: boolean);
begin
if state then
shared.wireframe:=1
else
shared.wireframe:=0;
end;
function TD3DHook.getMouseClip: boolean;
begin
result:=shared.clipmouseinwindow=1;
end;
procedure TD3DHook.setMouseClip(state: boolean);
begin
if state then
shared.clipmouseinwindow:=1
else
shared.clipmouseinwindow:=0;
end;
function TD3DHook.getWidth: integer;
var x: trect;
begin
if (shared<>nil) and (GetClientRect(shared.lastHwnd, x)) then
result:=x.Right-x.left
else
result:=0;
end;
function TD3DHook.getHeight: integer;
var x: trect;
begin
if (shared<>nil) and (GetClientRect(shared.lastHwnd, x)) then
result:=x.bottom-x.top
else
result:=0;
end;
procedure TD3DHook.setCommandListLockFeature(state: boolean);
begin
shared.useCommandListLock:=integer(state);
end;
procedure TD3DHook.beginCommandListUpdate;
begin
if self=nil then
raise exception.create(rsTheD3dhookObjectHasNotBeenCreatedYet);
commandlistCS.enter;
if isupdatingCL=0 then //start of an edit
WaitForSingleObject(CommandListLock, INFINITE); //obtain lock
inc(isupdatingCL);
end;
procedure TD3DHook.endCommandListUpdate;
begin
renderCommandList^[commandlist.count].command:=integer(rcEndOfCommandlist);
if isupdatingCL>0 then
begin
dec(isupdatingCL);
if isupdatingCL=0 then
SetEvent(CommandListLock); //release the lock
end;
commandlistCS.leave;
end;
procedure TD3DHook.beginTextureUpdate;
begin
if isupdating=0 then //start of an edit
begin
beginCommandListUpdate;
WaitForSingleObject(TextureLock, INFINITE); //obtain lock
end;
inc(isupdating);
end;
procedure TD3DHook.endTextureUpdate;
begin
if isupdating>0 then
begin
dec(isupdating);
if isupdating=0 then
begin
shared.textureCount:=textures.count;
shared.texturelistHasUpdate:=1;
SetEvent(TextureLock); //release the lock
endCommandListUpdate;
end;
end;
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++version 2
function TD3DHook.createFontMap(f: TFont): TD3DHook_FontMap;
begin
beginTextureUpdate;
result:=TD3DHook_FontMap.Create(self, f);
endTextureUpdate;
end;
function TD3DHook.createTextContainer(fontmap: TD3DHook_FontMap; x,y: single; text: string): TD3Dhook_TextContainer;
begin
beginCommandListUpdate;
try
result:=TD3Dhook_TextContainer.create(self, fontmap, x,y,text);
finally
endCommandListUpdate;
end;
end;
function TD3DHook.createTexture(f: string): TD3DHook_Texture; overload;
var p: TPicture;
begin
p:=tpicture.Create;
beginTextureUpdate;
try
p.LoadFromFile(f);
result:=TD3DHook_Texture.Create(self, p);
finally
p.free;
endTextureUpdate;
end;
end;
function TD3DHook.createTexture(p: TPicture): TD3DHook_Texture;
begin
beginTextureUpdate;
result:=TD3DHook_Texture.Create(self, p);
endTextureUpdate;
end;
function TD3DHook.createSprite(texture: TD3DHook_Texture): TD3DHook_Sprite;
begin
beginCommandListUpdate;
result:=TD3DHook_Sprite.create(self, texture);
endCommandListUpdate;
end;
destructor TD3DHook.Destroy;
var i: integer;
begin
if messagehandler<>nil then
begin
messagehandler.terminate;
messagehandler.Free;
end;
if hooked then
begin
beginCommandListUpdate;
for i:=0 to commandlist.Count-1 do
if commandlist[i]<>nil then
TD3DHook_RenderObject(commandlist[i]).free;
//make sure all commands are gone:
if commandlist.count>0 then
renderCommandList^[0].command:=integer(rcIgnored);
endCommandListUpdate;
beginTextureUpdate;
for i:=0 to textures.Count-1 do
if textures[i]<>nil then
TD3DHook_Texture(textures[i]).Free;
endTextureUpdate;
end;
UnmapViewOfFile(shared);
closehandle(fmhandle);
commandlist.free;
textures.free;
memman.free;
d3dhook:=nil;
inherited destroy;
end;
constructor TD3DHook.create(size: integer; hookhwnd: boolean=true);
var h: thandle;
s: TStringList;
alreadyhooked: boolean;
begin
memman:=TRemoteMemoryManager.create;
textures:=TList.create;
commandlist:=TList.create;
commandlistCS:=TCriticalSection.create;
sharename:='CED3D_'+inttostr(processhandler.ProcessID);
fprocessid:=processhandler.processid;
maxsize:=size;
createSharedMemory(sharename, sizeof(TD3DHookShared)+maxsize);
fmhandle:=OpenFileMapping(FILE_MAP_EXECUTE or FILE_MAP_READ or FILE_MAP_WRITE, false, pchar(sharename));
if fmhandle=0 then
raise exception.create(rsD3DHookFailureToOpenTheSharedMemoryObject);
shared:=MapViewOfFile(fmhandle,FILE_MAP_EXECUTE or FILE_MAP_READ or FILE_MAP_WRITE, 0,0,0 );
if shared=nil then
raise exception.create(rsD3DHookFailureToMapTheSharedMemoryObject);
alreadyhooked:=shared.initialized=$dbcedbce;
if not alreadyhooked then
begin
ZeroMemory(shared, sizeof(TD3DHookShared));
shared.texturelist:=sizeof(TD3DHookShared)+(maxsize div 2);
shared.cheatenginedir:=CheatEngineDir;
shared.useCommandListLock:=1;
end;
tea:=PTextureEntryArray(ptruint(shared)+shared.texturelist);
renderCommandList:=PRenderCommandArray(ptruint(shared)+sizeof(TD3dHookShared));
if alreadyhooked then
begin
DuplicateHandle(processhandle, shared.TextureLock, GetCurrentProcess, @TextureLock, 0, false,DUPLICATE_SAME_ACCESS);
DuplicateHandle(processhandle, shared.CommandListLock, GetCurrentProcess, @CommandListLock, 0, false,DUPLICATE_SAME_ACCESS);
DuplicateHandle(processhandle, shared.SnapshotDone, GetCurrentProcess, @SnapshotDone, 0, false,DUPLICATE_SAME_ACCESS);
beginTextureUpdate;
renderCommandList^[0].command:=integer(rcEndOfCommandlist); //clear the command list
shared.textureCount:=0;
endTextureUpdate;
end
else
begin
if hookhwnd then
shared.hookwnd:=1;
h:=CreateEventA(nil, true, false, pchar(sharename+'_READY') );
if (h<>0) then
begin
if hookhwnd then
begin
hasclickevent:=CreateEventA(nil, false, false, pchar(sharename+'_HASCLICK') );
hashandledclickevent:=CreateEventA(nil, false, true, pchar(sharename+'_HANDLEDCLICK') );
haskeyboardevent:=CreateEventA(nil, false, false, pchar(sharename+'_HASKEYBOARD') );
hashandledkeyboardevent:=CreateEventA(nil, false, true, pchar(sharename+'_HANDLEDKEYBOARD') );
messagehandler:=TD3DMessageHandler.Create(true);
messagehandler.owner:=self;
messagehandler.start;
end;
TextureLock:=CreateEventA(nil, false, true, nil);
DuplicateHandle(GetCurrentProcess, TextureLock, processhandle, @shared.TextureLock,0, false,DUPLICATE_SAME_ACCESS);
CommandListLock:=CreateEventA(nil, false, true, nil);
DuplicateHandle(GetCurrentProcess, CommandListLock, processhandle, @shared.CommandListLock,0, false,DUPLICATE_SAME_ACCESS);
SnapshotDone:=CreateEventA(nil, false, false, nil);
DuplicateHandle(GetCurrentProcess, SnapshotDone, processhandle, @shared.SnapshotDone,0, false,DUPLICATE_SAME_ACCESS);
shared.canDoSnapshot:=1;
//now inject the dll
symhandler.reinitialize;
symhandler.waitforsymbolsloaded(true, 'kernel32.dll');
if processhandler.is64Bit then
injectdll(cheatenginedir+'d3dhook64.dll')
else
injectdll(cheatenginedir+'d3dhook.dll');
//wait till the injection is done
WaitForSingleObject(h, INFINITE);
closehandle(h);
//and hook the functions
//(script: tstrings; address: string; addresstogoto: string; addresstostoreneworiginalfunction: string=''; nameextension:string='0');
s:=tstringlist.create;
try
if shared.d3d9_present<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_present,8), inttohex(shared.d3d9_newpresent,8), inttohex(shared.d3d9_originalpresent,8), '0');
if shared.d3d9_reset<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_reset,8), inttohex(shared.d3d9_newreset,8), inttohex(shared.d3d9_originalreset,8), '1');
if shared.dxgi_present<>0 then
generateAPIHookScript(s, inttohex(shared.dxgi_present,8), inttohex(shared.dxgi_newpresent,8), inttohex(shared.dxgi_originalpresent,8), '2');
if shared.d3d9_drawprimitive<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_drawprimitive,8), inttohex(shared.d3d9_newdrawprimitive,8), inttohex(shared.d3d9_originaldrawprimitive,8), '3');
if shared.d3d9_drawindexedprimitive<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_drawindexedprimitive,8), inttohex(shared.d3d9_newdrawindexedprimitive,8), inttohex(shared.d3d9_originaldrawindexedprimitive,8), '4');
if shared.d3d9_drawprimitiveup<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_drawprimitiveup,8), inttohex(shared.d3d9_newdrawprimitiveup,8), inttohex(shared.d3d9_originaldrawprimitiveup,8), '5');
if shared.d3d9_drawindexedprimitiveup<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_drawindexedprimitiveup,8), inttohex(shared.d3d9_newdrawindexedprimitiveup,8), inttohex(shared.d3d9_originaldrawindexedprimitiveup,8), '6');
if shared.d3d9_drawrectpatch<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_drawrectpatch,8), inttohex(shared.d3d9_newdrawrectpatch,8), inttohex(shared.d3d9_originaldrawrectpatch,8), '7');
if shared.d3d9_drawtripatch<>0 then
generateAPIHookScript(s, inttohex(shared.d3d9_drawtripatch,8), inttohex(shared.d3d9_newdrawtripatch,8), inttohex(shared.d3d9_originaldrawtripatch,8), '8');
if shared.d3d10_drawindexed<>0 then
generateAPIHookScript(s, inttohex(shared.d3d10_drawindexed,8), inttohex(shared.d3d10_newdrawindexed,8), inttohex(shared.d3d10_originaldrawindexed,8), '9');
if shared.d3d10_draw<>0 then
generateAPIHookScript(s, inttohex(shared.d3d10_draw,8), inttohex(shared.d3d10_newdraw,8), inttohex(shared.d3d10_originaldraw,8), '10');
if shared.d3d10_drawindexedinstanced<>0 then
generateAPIHookScript(s, inttohex(shared.d3d10_drawindexedinstanced,8), inttohex(shared.d3d10_newdrawindexedinstanced,8), inttohex(shared.d3d10_originaldrawindexedinstanced,8), '11');
if shared.d3d10_drawinstanced<>0 then
generateAPIHookScript(s, inttohex(shared.d3d10_drawinstanced,8), inttohex(shared.d3d10_newdrawinstanced,8), inttohex(shared.d3d10_originaldrawinstanced,8), '12');
if shared.d3d10_drawauto<>0 then
generateAPIHookScript(s, inttohex(shared.d3d10_drawauto,8), inttohex(shared.d3d10_newdrawauto,8), inttohex(shared.d3d10_originaldrawauto,8), '13');
if shared.d3d11_drawindexed<>0 then
generateAPIHookScript(s, inttohex(shared.d3d11_drawindexed,8), inttohex(shared.d3d11_newdrawindexed,8), inttohex(shared.d3d11_originaldrawindexed,8), '14');
if shared.d3d11_draw<>0 then
generateAPIHookScript(s, inttohex(shared.d3d11_draw,8), inttohex(shared.d3d11_newdraw,8), inttohex(shared.d3d11_originaldraw,8), '15');
if shared.d3d11_drawindexedinstanced<>0 then
generateAPIHookScript(s, inttohex(shared.d3d11_drawindexedinstanced,8), inttohex(shared.d3d11_newdrawindexedinstanced,8), inttohex(shared.d3d11_originaldrawindexedinstanced,8), '16');
if shared.d3d11_drawinstanced<>0 then
generateAPIHookScript(s, inttohex(shared.d3d11_drawinstanced,8), inttohex(shared.d3d11_newdrawinstanced,8), inttohex(shared.d3d11_originaldrawinstanced,8), '17');
if shared.d3d11_drawauto<>0 then
generateAPIHookScript(s, inttohex(shared.d3d11_drawauto,8), inttohex(shared.d3d11_newdrawauto,8), inttohex(shared.d3d11_originaldrawauto,8), '18');
if shared.dxgi_resizebuffers<>0 then
generateAPIHookScript(s, inttohex(shared.dxgi_resizebuffers,8), inttohex(shared.dxgi_newresizebuffers,8), inttohex(shared.dxgi_originalresizebuffers,8), '19');
// clipboard.AsText:=s.text;
//if there is a script execute it.
if (s.count>0) and (autoassemble(s,false)=false) then
begin
//on error write the script to the clipboard
clipboard.AsText:=s.text; //debug
end;
shared.initialized:=$dbcedbce;
finally
s.free;
end;
end;
end;
hooked:=true;
end;
function safed3dhook(size: integer=16*1024*1024; hookwindow: boolean=true): TD3DHook;
//Calls the d3dhook constructor but captures exceptions
var wr: DWORD;
begin
if d3dhook=nil then
begin
try
d3dhook:=TD3DHook.Create(size, hookwindow);
except
d3dhook:=nil;
end;
end
else
begin
if d3dhook.processid<>processid then //different process
begin
d3dhook.Free;
try
d3dhook:=TD3DHook.Create(size, hookwindow);
except
d3dhook:=nil;
end;
end
else
begin
//same process
wr:=WaitForSingleObject(processhandle, 0);
if wr<>WAIT_TIMEOUT then //not alive anymore
freeandnil(d3dhook);
end;
end;
result:=d3dhook;
end;
{$endif}
end.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。