 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
GH*master Expert Cheater
Reputation: 8
Joined: 10 Jan 2008 Posts: 159
|
Posted: Wed Jul 13, 2011 3:55 am Post subject: Suggestion: to add new template AA-script; |
|
|
I suggest a new template AA-script on the Free Pascal:
| Code: | [ENABLE]
alloc(newmem,2048)
aobscan(address,E8xxxxxxxx8BxxxxxxxxxxA1xxxxxxxx8Bxx8BxxxxxxxxxxE8xxxxxxxxA1)
label(injectAddress)
registersymbol(injectAddress)
label(originalcode)
label(returnhere)
newmem:
originalcode:
call Test.exe+52B40
jmp returnhere
address: // "Test.exe"+556EF = 0x004556EF
injectAddress:
jmp newmem
returnhere:
[DISABLE]
injectAddress:
call Test.exe+52B40
dealloc(newmem) |
If you want generate this a template AA-script, you want to add a handler function in frmautoinjectunit.pas:
| Code: | procedure TfrmAutoInject.Codeinjection1Click(Sender: TObject);
function inttostr(i:int64):string;
begin
if i=0 then result:='' else result:=sysutils.IntToStr(i);
end;
function getbytes(adr:qword):string;
var i,j,len,count:byte; frwrdaddr:Qword; stlist:TstringList; s,s0,s1,intsr:string;
begin
stlist:=TstringList.create;
frwrdaddr:=adr;
repeat
stlist.Add(disassemble(frwrdaddr)); // заполнили список ассемблерных инструкций типа '0061c2d3 - e8 61 c0 ff ff - call 00618339'
// frwrdaddr:=previousopcode(frwrdaddr)-1;
until frwrdaddr>=adr+120;
//После этого берём первые байты, если их количество не меньше 3 на опкод, остальные помечаем как xx
for i := 0 to stlist.Count-1 do
begin
s:=stlist.Strings[i]; // строка дизассемблера
s0:=copy(s,1,pos(' - ',s)); // адрес
delete(s,1,pos(' - ',s)+2);
s1:=copy(s,1,pos(' - ',s)); // строка байт
delete(s,1,pos(' - ',s)+2);
intsr:=s; // инструкция
// Удалять пробел пока он найден
j:=pos(' ',s1);
while(j<>0) do
begin
delete(s1,j,1);
j:=pos(' ',s1);
end;
len:=length(s1);
count:=(len div 2); //количество байт в строке байт
s:='';
if (count>1)and(pos('push',intsr)=0) then // если кол-во больше нуля и нет инструкции push
begin
s1:=copy(s1,1,2); // копируем первый байт
for j := 2 to count
do s:=s+'xx'; // остальные байты затераем "хх хх хх хх "
s1:=s1+s; //s1:= "FAхххххххх"
end
else // если байт меньше трёх то заливаем всё как "хх "
begin
for j := 1 to count do
s:=s+'xx';
s1:=s; //s1: = "xxхххх"
end;
result:=result+s1;
end;
delete(result,32*2,length(result) - 32*2); //режем первые 32 байта
// Режим последние xx-ы
while 'xx'=copy(result,length(result)-1,2) do
delete(result,length(result)-1,2);
stlist.Destroy;
end;
var address: string;
originalcode: array of string;
originalbytes: array of byte;
codesize: integer;
a: ptrUint;
br: dword;
c: ptrUint;
x: string;
i,j,k: integer;
injectnr: integer;
enablepos: integer;
disablepos: integer;
enablecode: tstringlist;
disablecode: tstringlist;
mi: TModuleInfo;
simbol:boolean; //*
bofset:byte; //*
provbyte:string; //*
begin
{$ifndef standalonetrainerwithassembler}
CheatTablecompliantcodee1.Click; //* обрамление
simbol:=symhandler.showmodules; //* запоминаем "нужно ли показывать модули"
symhandler.showmodules:=true; //* в любом случае показываем модули в метках
a:=memorybrowser.disassemblerview.SelectedAddress;
if symhandler.getmodulebyaddress(a,mi) then
begin
address:='"'+mi.modulename+'"+'+inttohex(a-mi.baseaddress,1);
end
else
address:=inttohex(a,8);
if inputquery(rsCodeInjectTemplate, rsOnWhatAddressDoYouWantTheJump, address) then
begin
{
try
a:=StrToQWordEx('$'+address);
except
a:=symhandler.getaddressfromname(address);
end;
}
a:=symhandler.getaddressfromname(address);
c:=a;
injectnr:=0;
for i:=0 to assemblescreen.Lines.Count-1 do
begin
j:=pos('alloc(newmem',lowercase(assemblescreen.lines[i]));
if j<>0 then
begin
x:=copy(assemblescreen.Lines[i],j+12,length(assemblescreen.Lines[i]));
x:=copy(x,1,pos(',',x)-1);
try
k:=strtoint(x);
if injectnr<=k then
injectnr:=k+1;
except
inc(injectnr);
end;
end;
end;
//disassemble the old code
setlength(originalcode,0);
codesize:=0;
while codesize<5 do
begin
setlength(originalcode,length(originalcode)+1);
originalcode[length(originalcode)-1]:=disassemble(c,x);
i:=posex('-',originalcode[length(originalcode)-1]);
i:=posex('-',originalcode[length(originalcode)-1],i+1);
originalcode[length(originalcode)-1]:=copy(originalcode[length(originalcode)-1],i+2,length(originalcode[length(originalcode)-1]));
codesize:=c-a;
end;
setlength(originalbytes,codesize);
ReadProcessMemory(processhandle, pointer(a), @originalbytes[0], codesize, br);
enablecode:=tstringlist.Create;
disablecode:=tstringlist.Create;
try
with enablecode do
begin
provbyte:=getbytes(a);
add(' alloc(newmem'+inttostr(injectnr)+',2048)');
add(' aobscan(address,'+inttostr(injectnr)+provbyte+')');
add(' label(injectAddress'+inttostr(injectnr)+')');
add(' registersymbol(injectAddress'+inttostr(injectnr)+')');
add(' label(originalcode'+inttostr(injectnr)+')');
add(' label(returnhere'+inttostr(injectnr)+')');
add('');
add('newmem'+inttostr(injectnr)+':');
// add(' mov [],eax //mov eax,');
add(' ');
add('originalcode'+inttostr(injectnr)+':');
for i:=0 to length(originalcode)-1 do
add(' '+originalcode[i]);
add(' jmp returnhere'+inttostr(injectnr)+'');
add('');
add('address: // '+address+' = 0x'+ IntToHex(a,8));
add('injectAddress'+inttostr(injectnr)+':');
// add(symhandler.getnamefromaddress(strtoint('+address))+':');//прыжок после выделения памяти
// add(address+':');
add(' jmp newmem'+inttostr(injectnr)+'');
bofset:=5;
while codesize>5 do
begin
add(' nop');
dec(codesize);
inc(bofset); // для посторения проверочных байта отмены
end;
add('returnhere'+inttostr(injectnr)+':');
end;
delete(provbyte,1,bofset*2); // удаляем то чего не надо искать
dec(bofset,5);
for I := 1 to bofset do
provbyte:='90'+provbyte;
with disablecode do
begin
add('injectAddress'+inttostr(injectnr)+':');
for i:=0 to length(originalcode)-1 do
add(' '+originalcode[i]);
add('');
add(' dealloc(newmem'+inttostr(injectnr)+')');
end;
getenableanddisablepos(assemblescreen.lines,enablepos,disablepos);
//skip first comment(s)
if enablepos>=0 then
begin
while enablepos<assemblescreen.lines.Count-1 do
begin
if pos('//',trim(assemblescreen.Lines[enablepos+1]))=1 then inc(enablepos) else break;
end;
end;
for i:=enablecode.Count-1 downto 0 do
assemblescreen.Lines.Insert(enablepos+1,enablecode[i]);
getenableanddisablepos(assemblescreen.lines,enablepos,disablepos);
//skip first comment(s)
if disablepos>=0 then
begin
while disablepos<assemblescreen.lines.Count-1 do
begin
if pos('//',trim(assemblescreen.Lines[disablepos+1]))=1 then inc(enablepos) else break;
inc(disablepos);
end;
//only if there actually is a disable section place this code
for i:=disablecode.Count-1 downto 0 do
assemblescreen.Lines.Insert(disablepos+1,disablecode[i]);
end;
finally
enablecode.free;
disablecode.Free;
end;
symhandler.showmodules:=simbol;
end;
{$endif}
end; |
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25812 Location: The netherlands
|
Posted: Wed Jul 13, 2011 5:32 am Post subject: |
|
|
Not as a replacement, but perhaps as an extra template
aobscans can be slow and that is annoying on a game you know won't get patched while you're still experimenting.
Also, just to point out, the example you have given is exactly how you should not go about using aobscans : You're rewriting a call instruction which will most likely have a different address to call when the game has been patched
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
GH*master Expert Cheater
Reputation: 8
Joined: 10 Jan 2008 Posts: 159
|
Posted: Wed Jul 13, 2011 12:26 pm Post subject: |
|
|
| I know that sloooowly... But, I suggested and You think about it, ok? Make better, if you have time.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|