427 lines
12 KiB
ObjectPascal
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.
|