cheat-engine/Cheat Engine/Valuechange.pas
2016-06-22 12:12:11 +02:00

427 lines
12 KiB
ObjectPascal

unit Valuechange;
{$MODE Delphi}
interface
uses
windows, LCLIntf, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, LResources, commonTypeDefs,NewKernelHandler, CEFuncProc;
type
TValueChangeForm = class(TForm)
cbVarType: TComboBox;
Button1: TButton;
Button2: TButton;
ValueText: TEdit;
cbunicode: TCheckBox;
procedure Button2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure cbVarTypeChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
faddress: ptrUint;
fvartype: byte;
fvartype2: Tvariabletype;
procedure Updatevalue;
procedure setaddress(x: ptrUint);
procedure setvartype(x: byte);
procedure setvartype2(vt: TVariableType);
function getVartype: TVariabletype;
procedure setunicode(x:boolean);
function getunicode:boolean;
public
{ Public declarations }
slength: integer;
property Address: ptrUint read faddress write setaddress;
property vtype: byte read fvartype write setvartype;
property VarType: TVariableType read getVartype write setVartype2;
property unicode: boolean read getunicode write setunicode;
end;
var
ValueChangeForm: TValueChangeForm;
implementation
uses ProcessHandlerUnit, parsers;
resourcestring
rsChangeOffset = 'Change offset %s';
rsPartOfTheStringIsUnreadable = 'Part of the string is unreadable!';
function TValueChangeForm.getunicode:boolean;
begin
result:=cbunicode.checked;
end;
procedure TValueChangeForm.setunicode(x: boolean);
begin
cbunicode.checked:=x;
end;
procedure TValueChangeForm.setaddress(x: ptrUint);
begin
faddress:=x;
caption:=Format(rsChangeOffset, [inttohex(x, 8)]);
updatevalue;
end;
procedure TValuechangeForm.setvartype2(vt: TVariableType);
//9/23/2011: adding support for the 'new' type... (really old code here)
begin
case vt of
vtByte: cbVarType.itemindex:=0;
vtWord: cbVarType.itemindex:=1;
vtDword: cbVarType.itemindex:=2;
vtQword: cbVarType.itemindex:=3;
vtSingle: cbVarType.itemindex:=4;
vtDouble: cbVarType.itemindex:=5;
vtString,vtUnicodeString:
begin
cbVarType.itemindex:=6;
cbunicode.checked:=vt=vtUnicodeString;
end;
vtByteArray: cbVarType.itemindex:=7;
end;
updatevalue;
end;
function TValuechangeForm.getVartype: TVariabletype;
begin
result:=vtbyte;
case cbVarType.itemindex of
0: result:=vtByte;
1: result:=vtWord;
2: result:=vtDword;
3: result:=vtQword;
4: result:=vtSingle;
5: result:=vtDouble;
6: if cbunicode.checked then result:=vtUnicodeString else result:=vtString;
7: result:=vtByteArray;
end;
end;
procedure TValuechangeForm.setvartype(x: byte);
begin
fvartype:=x;
case x of
0: cbVarType.itemindex:=0; //byte
1: cbVarType.itemindex:=1; //word
2: cbVarType.itemindex:=2; //dword
6: cbVarType.itemindex:=3; //int64
4: cbVarType.itemindex:=4; //float
5: cbVarType.itemindex:=5; //double
7: cbVarType.itemindex:=6; //text
end;
updatevalue;
end;
procedure TValueChangeForm.UpdateValue;
var value1: Byte;
value2: word;
value3: dword;
value4: single;
value5: double;
value6: Int64;
read: ptruint;
s: pchar;
ws: pwchar;
begin
value4:=0;
value5:=0;
case cbVarType.itemindex of
0 : begin //byte
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value1),1,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value1),1,read);
{$endif}
valuetext.text:=IntToStr(value1);
cbunicode.visible:=false;
end;
1 : begin //word
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value2),2,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value2),2,read);
{$endif}
valuetext.text:=IntToStr(value2);
cbunicode.visible:=false;
end;
2 : begin //dword
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value3),4,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value3),4,read);
{$endif}
valuetext.text:=IntToStr(value3);
cbunicode.visible:=false;
end;
3 : begin //int64
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value6),8,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value6),8,read);
{$endif}
valuetext.text:=IntToStr(value6);
cbunicode.visible:=false;
end;
4 : begin //float
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value4),4,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value4),4,read);
{$endif}
valuetext.text:=FloatToStr(value4);
cbunicode.visible:=false;
end;
5 : begin //double
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value5),8,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value5),8,read);
{$endif}
valuetext.text:=floatToStr(value5);
cbunicode.visible:=false;
end;
6 : begin //text
if unicode then
begin
getmem(ws,slength*2+2);
{$ifdef net}
readprocessmemorynet(0,pointer(address),ws,slength*2,read);
{$else}
readprocessmemory(processhandle,pointer(address),ws,slength*2,read);
{$endif}
ws[slength]:=#0;
ValueText.text:=ws;
freemem(ws);
ws:=nil;
end
else
begin
getmem(s,slength+1);
{$ifdef net}
readprocessmemorynet(0,pointer(address),s,slength,read);
{$else}
readprocessmemory(processhandle,pointer(address),s,slength,read);
{$endif}
s[slength]:=#0;
ValueText.text:=s;
freemem(s);
s:=nil;
end;
cbunicode.visible:=true;
end;
7 : begin
{$ifdef net}
readprocessmemorynet(0,pointer(address),addr(value1),1,read);
{$else}
readprocessmemory(processhandle,pointer(address),addr(value1),1,read);
{$endif}
ValueText.text:=inttohex(value1,2);
cbunicode.visible:=false;
end;
end;
end;
procedure TValueChangeForm.Button2Click(Sender: TObject);
begin
modalresult:=mrcancel;
end;
procedure TValueChangeForm.FormShow(Sender: TObject);
begin
//cbVarType.ItemIndex:=0;
valuetext.SetFocus;
valuetext.SelectAll;
end;
procedure TValueChangeForm.Button1Click(Sender: TObject);
var write: ptruint;
newvalue1: byte;
newvalue2: word;
newvalue3: dword;
newvalue4: single;
newvalue5: double;
newvalue6: int64;
{$ifndef net}
newvalue7: Tbytes;
{$endif}
newstring: array of byte;
i: Integer;
newvaluest:string;
fs: TFormatSettings;
begin
val(valuetext.text,newvalue1,i);
val(valuetext.text,newvalue2,i);
val(valuetext.text,newvalue3,i);
val(valuetext.text,newvalue4,i);
val(valuetext.text,newvalue5,i);
val(valuetext.text,newvalue6,i);
write:=i;
newvaluest:=valuetext.text;
fs:=DefaultFormatSettings;
case cbVarType.itemindex of
{byte} 0 : writeprocessmemory(processhandle,pointer(address),addr(newvalue1),1,write);
{word} 1 : writeprocessmemory(processhandle,pointer(address),addr(newvalue2),2,write);
{dword} 2 : writeprocessmemory(processhandle,pointer(address),addr(newvalue3),4,write);
{int64} 3 : writeprocessmemory(processhandle,pointer(address),addr(newvalue6),8,write);
{float} 4 : begin
try
newvalue4:=StrToFloat(valuetext.text, fs);
except
if fs.DecimalSeparator='.' then
fs.DecimalSeparator:=','
else
fs.DecimalSeparator:='.';
try
newvalue4:=StrToFloat(valuetext.text, fs);
except
exit; //quit
end;
end;
writeprocessmemory(processhandle,pointer(address),addr(newvalue4),4,write);
end;
{double}5 : begin
try
newvalue5:=StrToFloat(valuetext.text, fs);
except
if fs.DecimalSeparator='.' then
fs.DecimalSeparator:=','
else
fs.DecimalSeparator:='.';
try
newvalue5:=StrToFloat(valuetext.text, fs);
except
exit; //quit
end;
end;
writeprocessmemory(processhandle,pointer(address),addr(newvalue5),8,write);
end;
{byte} 6 : begin
setlength(newstring,length(ValueText.text));
for i:=1 to length(ValueText.text) do
newstring[i-1]:=ord(ValueText.text[i]);
writeprocessmemory(processhandle,pointer(address),newstring,length(ValueText.text),write);
end;
{bytes} 7 : begin
//convert the string to bytes
ConvertStringToBytes(Valuetext.Text,true,newvalue7, true);
setlength(newstring,length(newvalue7));
for i:=0 to length(newvalue7)-1 do
begin
//if the bytesvalue is -1 then read that byte from the memory and leave it untouched
//if it is unreadable popup a message noptifying the user
if newvalue7[i]<0 then
begin
write:=0;
readprocessmemory(processhandle,pointer(address+i),addr(newstring[i]),1,write);
if write<>1 then raise exception.Create(rsPartOfTheStringIsUnreadable);
if newvalue7[i]<>-1 then
begin
//apply the nibble part
//example: 9* and newstring[i]=7c
//the wanted result will be 9c
//newvalue7[i]=$8000f090
//not (f0) = 0f
//0f and 9c = 0c
//0c or 90 = 9c
newstring[i]:=(((not (newvalue7[i] shr 8)) and $ff) and newstring[i]) or (newvalue7[i] and $ff);
end;
end
else
newstring[i]:=newvalue7[i];
//newstring now contains all the bytes we need so write them to the memory
end;
writeprocessmemory(processhandle,pointer(address),newstring,length(newstring),write);
end;
end;
modalresult:=mrok;
end;
procedure TValueChangeForm.cbVarTypeChange(Sender: TObject);
begin
updatevalue;
end;
procedure TValueChangeForm.FormCreate(Sender: TObject);
begin
//cbVarType.Items.Delete(cbVarType.Items.Count-1);
cbVarType.itemindex:=0;
end;
procedure TValueChangeForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Action:=caFree;
end;
initialization
{$i Valuechange.lrs}
end.