Ai
1 Star 0 Fork 0

phy0292/cheat-engine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
d3dhookUnit.pas 49.23 KB
一键复制 编辑 原始数据 按行查看 历史
cheat-engine 提交于 2019-12-20 00:49 +08:00 . Fix registry issues
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826
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.
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/phy0292/cheat-engine.git
git@gitee.com:phy0292/cheat-engine.git
phy0292
cheat-engine
cheat-engine
master

搜索帮助