# Native Code > برنامه نویسی در Delphi >  آموزش ساخت تراینر با دلفی

## Shahryar_Bmp

سلام
اگه کسی بلده لطفا آموزش بده که چطوری میشه با دلفی تراینر برای بازی ها ساخت و چطور میشه آدرس ها رو تو تراینر فریز کرد و ...
ممنون

----------


## Shahryar_Bmp

در ضمن من سرچ کردم و تاپیکی با این عنوان ندیدم 
از مدیران خواهش میکنم این تاپیکو نبندند

----------


## Shahryar_Bmp

خوب مثل اینکه خبری نیست , باید خودم شروع کنم :

procedure TForm1.Button1Click(Sender: TObject);
var
  WindowName : integer;
  ProcessId : integer;
  ThreadId : integer;
  buf : pchar;
  HandleWindow : Integer;
  write : cardinal;
const
  WindowTitle = 'Minesweeper';
begin
WindowName := FindWindow(nil,WindowTitle);
If WindowName = 0 then
begin
MessageDlg('Your game is not running!', mterror,[mbOK],0);
end;
ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId);
HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);
GetMem(buf,1);
buf^ := Chr($90);
WriteProcessMemory(HandleWindow,ptr($400000),buf,1  ,write);
FreeMem(buf);
CloseHandle(HandleWindow);
end;

تو این کدی که من دارم اول باید پنجره Minesweeper رو پیدا کنه که من می خوام توی پروسه ها بگرده و بازی رو پیدا کنه 
سوال بدیم هم اینه که مثلاً چطوری میتونم همین آدرس رو فریز کنم 
ممنون

----------


## Shahryar_Bmp

اگه این بحث براتون جالبه بگید تا ادامه بدم

----------


## علامت سوال

تراینر چی هست؟
توی تراینر فریز کردن یعنی چی؟

----------


## Shahryar_Bmp

تراینر مثلا در بازی های کامپیوتر مقدار ها رو فریز = ثابت نگه میداری و...که باید از تابع 
WriteProcessMemory برای اینکار استفاده کنید

----------


## علامت سوال

توضیح شما خیلی کوتاه و کم بود
لطفا بیشتر توضیح بدید
چرا باید مقدار ها رو ثابت نگه داریم؟

----------


## Shahryar_Bmp

دوست عزیز مثلا توی یک بازی ما یک آدرس هگزادسیمال برای کنترل تیر داریم که مقدار این آدرس در اول مثلا 15 است حالا اگه یک تیر شلیک کنیم میشه 14 ما باید اول پروسه رو پیدا کنیم و سپس با استفاده از تابع WriteProcessMemory مقدار رو در اون آدرس قرار بدیم حالا اگه این دستور رو در یک تایمر قرار بدیم و interval رو 1 قرار بدیم این مقدار در هر ثانیه 1000 بار اتفاق میفته و باعث میشه که ما در بازی احساس کنیم از تیرمون کم نمیشه

----------


## علامت سوال

این توضیح بهتر شد ولی هنوز خیلی ناقصه در مورد بازیت یه کم بگو
بازی سازی هم جالبه
چه جور بازی میخای بسازی؟
گرافیکش بالاست؟

----------


## Shahryar_Bmp

> این توضیح بهتر شد ولی هنوز خیلی ناقصه در مورد بازیت یه کم بگو
> بازی سازی هم جالبه
> چه جور بازی میخای بسازی؟
> گرافیکش بالاست؟


اصلا منظور منو متوجه نشدی 
شما تا بحال از کد های تقالب بازی ها استفاده کردید ؟؟
که مثلا پول یا جون رو در بازی بی نهایت میکنه ؟؟ 
ما همچین کاری می کنیم

----------


## علامت سوال

ناقلا Cheater
حالا کاملا متوجه شدم
چطوری میتونی بفهمی که کدوم Procedure یا تابع برای تیر زدن و تغییر مقدار Counter تیر استفاده میشه؟
احتمال زیاد موقع اجرای بازی اما چطوری؟با دیباگ؟  لطفا توضیح بدید

----------


## Shahryar_Bmp

باید از برنامه های سرچر بازی مثله Tsearch و ArtMoney و CheatEngine و اینا استفاده کنی 
و آدرس چیزی که دنبالشی مثلا جون رو پیدا کنی بعد با دلفی با استفاده از کدی که اول گزاشتم مقدار مورد نظر رو در آدرس جون بریزی

----------


## Shahryar_Bmp

آرت مونی : www.artmoney.ru
Tsearch : http://www.timsvault.com/cheattools/tsearch.zip

----------


## علامت سوال

مرسی از توضیحاتت
برای هربازی برنامه بخصوصی وجود داره یا برنامه های بالا برای همه بازی ها یکسان عمل میکنه!!!!!!!!!!!!!!!!!!!!!!!!
در ضمن سایتت هم برای من فیلتر شده ( www.GameLife.ir )

----------


## Shahryar_Bmp

این سایت قبلیم بود که خیلی وقته فیلتره 
سایته الانم اینه : www.HighDL.com
شما تمامی برنامه هایی که در اینکار استفاده میشه رومیتونید از این صفحه بگیرید : 
http://www.timsvault.com/cheattools/
شما با این برنامه ها آدرس رو پیدا میکنی 
برای اینکار هم به طور مثال در Tsearchاول باید پروسه بازی رو انتخاب کنید که برای این روی open process کلیک میکنید و پروسه بازیرو انتخاب میکنید حالا ما دنبال مقدار تیر هستیم که تفنگ ما 30 تا تیرداره  و مقدارش Integer پس روی Search کلیک میکنیم و رویعلامت ذره بین کلیکمیکنیم و Extract Value رو میزنیم و در فیلد مورد نظر عدد 30 رو میزنیم وok حالا یک سری آدرس پیدا کرد که تعدادش زیاده پس دوباره به بازی بر میگردیم و مثلا 3 تا تیر میزنیم تا تیرامون بشه 27تا حالا به برنامه برمیگردیم و روی علامت ذره بین سمت راست قبلی کلیک میکنیم و 27 رو میزنیم حالا اینکارو باید انقدر ادامه بدیم که آدرس هامون کم تر نشه بعد آدرس ها رو به طرف راست انتقال میدیم و سیو میگیریم حالا باید اون آدرس رو یاد داشت کنی و در برنامت استفاده کنی

----------


## Shahryar_Bmp

اگه بازم مشکلی بود بگو تا توضیح بدم

----------


## علامت سوال

در مورد فارسی کردن Video Game ها 
مثلا فارسی صحبت کردن کاراکترها یا فارسی شدن توضیحاتی که در حین بازی میاد چکار میشه کرد؟

----------


## Shahryar_Bmp

اونا از نرم افزار های خاصی استفاده می کنند ولی برای فارسی کردن بازی باید فایل های صدای بازی رو پیدا کنی و ویرایش کنید

----------


## Shahryar_Bmp

اینم یک کد دیگه برای بازی Need For Speed : carbon استفاده کردم که از این کد هم می تونید استفاده کنید
var
  Form1: TForm1;
  Fentr : integer;
  PrcID : integer;
  ProID : integer;
  Opnpr : integer;
  Wrtpr : cardinal;
  Buf   : pchar;
  NumberOfBytes : byte;
  PokeValue     : dword;
  PokeAddress   : dword;
begin
if (GetAsyncKeyState(VK_F1)<> 0) and (GetAsyncKeyState(VK_CONTROL) <> 0) then
begin
  PokeAddress   := $61383A8;      
  PokeValue     := 999999;
  NumberOfBytes := 4;
  Fentr := FindWindow(nil,'NFSC');                                     
  PrcID := GetWindowThreadProcessId(Fentr,@ProID);                    
  Opnpr := OpenProcess(PROCESS_ALL_ACCESS,False,ProID);
  GetMem(Buf,1);
  Buf^  := Chr(PokeValue);
  WriteProcessMemory(Opnpr, ptr(PokeAddress),Buf,NumberOfBytes,Wrtpr);
  FreeMem(Buf);
  closehandle(Opnpr);
end;
end;

----------


## arash_ebrahimi_nk

میتونی از کامپوننت های madcollection برای پیشبرد اهدافت استفاده کنی.
madshi.net

بویژه یونیت madkernel

----------


## علامت سوال

از همه دوستان ممنون
دوست من آقای Gamelife قرار بود اطلاعات بگیرن که تا حالا قسمت بود که بنده اطلاعات بگیرم :بامزه: 
بحث جالبه

----------


## Shahryar_Bmp

> میتونی از کامپوننت های madcollection برای پیشبرد اهدافت استفاده کنی.
> madshi.net
> 
> بویژه یونیت madkernel


اگه ممکنه بیشتر توضیح بدید 
راستی علامت سوال من اون موقع که پست اول رودادم زیاد نمی دونستم ولی الان فکر کنم بتونم به بقیه دوستان کمک کنم

----------


## arash_ebrahimi_nk

یونیت مذکور و دیگر یونیت های مجموعه فوق یکی از بهترین منابع سورس کدهای سیستمی برای دلفی هستند که به کار گرفتنشون خیلی آسونه و برای اهداف مورد نظر شما حداقل در مراحل ابتدایی میتونه راه انداز مناسبی باشه. لطفاً به Help سایت مذکور مراجعه کنید و ببینید که چه امکاناتی داره (اگه انگلیستون هم ضعیفه نگران نباشید وقتی صفحات رو ببینید همه چی دستگیرون میشه).

----------


## Hamid_PaK

> توضیح شما خیلی کوتاه و کم بود
> لطفا بیشتر توضیح بدید
> چرا باید مقدار ها رو ثابت نگه داریم؟


ببین دوست عزیز اکثر بازی ها از مقادیر برای نگهداری اطلاعات بازی ، امتیاز ها و ... استفاده می کنند این دوست ما جهت حفظ این داده با ذخیره مقادیر در حافظه بازی ( که یک برنامه هست ) شما را در پیروزی در آن بازی کمک خواهد کرد ...

یا حق ...

----------


## Hamid_PaK

> خوب مثل اینکه خبری نیست , باید خودم شروع کنم :
> 
> procedure TForm1.Button1Click(Sender: TObject);
> var
>   WindowName : integer;
>   ProcessId : integer;
>   ThreadId : integer;
>   buf : pchar;
>   HandleWindow : Integer;
> ...


هم می تونید از ترد (Thread) استفاده کنید و هم از تایمر (Timer).
راستی اصلا در Base آدرس 400000$ چه مقداری هست که شما آنرا با کاراکتر 90$ بازنویسی کرده اید ؟

یا حق ...

----------


## Shahryar_Bmp

آدرس 400000$ فرضیه و هم مقداریه که در این آدرس بازنویسی میکنیم و هگزادسیماله و معادلش بصورت دسیمال میشه 140

----------


## Shahryar_Bmp

از این هم میتونید استفاده کنید 
procedure PokeMem(Address: Cardinal; Bytes: Array Of Byte);
var
  NBW: Cardinal;
begin
  WinName:= FindWindow(nil, 'White');
  GetWindowThreadProcessId(WinName, @ProcId);
  Proc:= OpenProcess(Process_All_Access, False, ProcId);
  WriteProcessMemory(Proc, Ptr(Address), @Bytes[0], Length(Bytes), NBW);
  CloseHandle(Proc);
end;
 procedure PokeMemory;
 begin
  PokeMem($679D120,[$00,$60,$6A,$47]);
  PokeMem($5F71AF0, [$00,$00,$80,$3F]);
 end;
از این هم برای فراخانی پروسیجر و جای تایمر استفاده کنید :
SetTimer(0, 0, 10, @PokeMemory);

----------


## ali_mohamadi8928

سلام دوستان .

من از کد زیر استفاده میکنم برای دادن مقدار به متغییری در بازی Command & Conquer Generals که مربوط به نگهداری مقدار پول هست .

var
  Fentr : integer;
  PrcID : integer;
  ProID : integer;
  Opnpr : integer;
  Wrtpr : cardinal;
  Buf   : pchar;
  NumberOfBytes : byte;
  PokeValue     : dword;
  PokeAddress   : dword;
begin
  PokeAddress   := $03900A38;
  PokeValue     := 999999;
  NumberOfBytes := 4;
  Fentr := FindWindow(nil,'Command & Conquer Generals');
  PrcID := GetWindowThreadProcessId(Fentr,@ProID);
  Opnpr := OpenProcess(PROCESS_ALL_ACCESS,False,ProID);
  GetMem(Buf,1);
  Buf^  := Chr(PokeValue);
  WriteProcessMemory(Opnpr, ptr(PokeAddress),Buf,NumberOfBytes,Wrtpr);
  FreeMem(Buf);
  closehandle(Opnpr);

ولی به جای اینکه در بازی مقداری که بهش دادیم ( 999999 ) رو نشون بده مقدار 63 رو نشون میده !!!!

دلیلش چی میتونه باشه ؟؟؟ من همین کد رو در بازیهای دیگه با ادرسهای متغیرهای مربوط به پولهای اون بازی ها هم امتحان کردم ولی بازم همین مشکل رو داره . ؟؟؟؟

علتش چیه ؟؟؟

----------


## شهریار بهمن پور

احتمالا اون آدرستون اشتباهه و یا مقدار آدرس کد شده

----------


## ali_mohamadi8928

ادرس هیچ مشکلی نداره .
مقدار داده میشه ولی همون مقداری که من معین میکنم نیست .

من با نرم افزار Artmony به همین ادرس همون مقدار رو میدم درست کار میکنه ولی نمیدونم چرا اینجا کار نمیکنه . ؟؟؟

----------


## ali_mohamadi8928

متاسفانه بازم همون 63 رو میریزه توی متغییر . ( این کا رو خودم هم قبلا امتحان کرده بودم )

----------


## persianboy

به به ، سلام به دوستای خودم . جای من خالیه . بابا چرا ما رو صدا نکردید ؟
چه مناسبت دار ، اتفاقا من الان دارم یه برنامه مینویسم که ترینر بسازه ، دیگه آخراشه . آماده شد تقدیمتون میکنم . در ضمن زیاد به فکر تغییر دادن اینجوری مقادیر بازی ها نباشید ، چون اکثر بازی ها از DMA استفاده میکنند و دیگه کمتر پیش میاد از حافظه static استفاده کنند ، یعنی اینکه شما هر وقت از بازی خارج میشید و دوباره میایید توش آدرس حافظه مثلا تعداد تیر شما عوض شده . توی help برنامه های artmoney , tsearch دنبال کار با pointer ها بگردید . در ضمن برای درک بهتر گفته هام حتما با cheatengine 5.3 هم یه ور برید ، یه tutorial آموزنده داره ، ولی بهترین کار استفاده از code injection هستش ، میتونید دربارش توی قسمت easywrite برنامه tsearch بخونید . اگه زیاد چیزی دستگیرتون نشد بهم خبر بدید . 
در مورد مشکل شما هم جناب ...ali_moha باید بگم طبق تجرب بنده شرکت ...command and توی بازیهاش از حافظه استاتیک استفاده میکنه ، ولی من generals رو ندارم تا امتحان کنم ، شایدم مقدار کد شده باشه .

----------


## persianboy

trainer maker آماده شد . 
میتونید واسه امتحان کردنش تو قسمت game's window title ، ی minesweeper رو وارد کنید و تو قسمت poke ، این آیتم ها رو وارد کنید :
1005B98   4040010594510001E9CFD8
1005BA3   FFFF
100346E    E92527000090 
و تو قسمت unpoke ، این آیتم ها رو وارد کنید :
100346E    010594510001
وقتی که trainer تون آماده شد ، بازی minesweeper ویندوز رو (ویندوز من xp sp2 هستش ولی احتمالا با همشون کار کنه ، امتحان نکردم) باز کنید و راست کلیک کنید . خواهید دید که به جای اینکه از تعداد مینها کم بسه ، بهشون اضافه میشه .
اگه متوجه نشدید واستون یه عکس ضمیمه کردم ، اونو نگاه کنید .
فقط ، کسانی که از ترینر سر در نمیارن چیزی رو الکی وارد نکنن ، چون ممکنه به ویندوز و برنامه هاشون صدمه بزنن .
یه help مختصر هم تو برنامه هستش اگه کافی نبود بگید که بیشتر توضیح بدم .
اگه برنامه مشکلی داشت بگین تا برطرفش کنم .

----------


## persianboy

ببخشید ، برنامه قبلیه مشکل داشت ، اینو امتحان کنید .

----------


## Hamid_PaK

پرشین بوی عزیز شاید این برنامه ای که ساخته اید بدرستی کار کند، ولی ملاک استفاده آن چیست اکثر برنامه هایی که برای بازی ها وصله ایجاد می کنند، جستجوگر و ... ابزارهای متفاوتی برای یافتن مقادیر حافظه دارند ولی شما برای این امر چه راه حلی دارید.
برای یافتن عنوان پنجره برنامه نیز باید از EnumWindows استفاده کنید تا بدرستی عنوان پنجره را بدست بیاورید.

یا حق ...

----------


## persianboy

خیلی ممنون از سوالتون ، باید بگم که توی help مختصر برنامه توضیح دادم که با چه برنامه هایی میتونن آدرسهایی رو که باید patch بشن بدست بیارن ، معمولا برنامه های حافظه یاب و ترینر ساز جدا از هم هستن . مثلا tsearch ، برنامه حافظه یاب هستش و( Trainer Maker Kit(TMK برنامه ساخت ترینر (exe ساز) هستش و من به خاطر نمیارم برنامه ای دیده باشم که هردوی این کارها رو باهم بکنه . در ضمن مگه برنامه من توی ردیابی عنوان پنجره ها اشتباه میکنه ؟ شما اون مثالی رو که در مورد بازی Minesweeper در 3 پست قبل از زدم رو امتحان نکردید ؟ واسه من که درست کار میکرد ، در ضمن باید بگم که عنوان پنجره بازی رو کاربر وارد میکنه و برنامه از طریق اون به حافظه بازی دسترسی پیدا میکنه  . اگه باز باز مشکلی بود بگید تا توضیح بدم ، خیلی ممنون از توجهتون .
در ضمن ترینر مربوط به بازی minesweeper رو واسطون میذارم تا امتحانش کنید که اگر شما کارهایی که در 3 پست قبل رو که گفتم انجام بدید این فایل رو میسازه . همچنین باید بگم که این آدرسها رو بوسیله tsearch 1.6 بدست آوردم . همچنین برای بدست آوردن code cave -offset 01005B98 بازی از [sheep]'s array of sunshine1.3 استفاده کردم . برای این کار در قسمت easywrite این برنامه این ها رو بنویسید وبعد دکمه tmk و بعدش دکمه check رو بزنید :
در قسمت بالایی این کد :

offset 01005B98
inc eax
inc eax
add [0x1005194],eax
jmp 0x01003474
offset 0x0100346E
jmp 0x01005B98
nop

و در قسمت پایینی این کد را قرار دهید :

offset 0x0100346e
add [0x1005194],eax

که اگر مقداری اسمبلی بلد باشید ، براحتی معنی این کد ها رو میفهمید .

----------


## hamarasystem

من چندتا در خواست داشتم.
1_شما ترینر +19 بازی mafia:the city of lost heaven را دانلود کن ویکی یکی توضیح  بدید که اینها با دلفی چگونه ساخته میشوند.
2_بعضی از بازیها صفحه رمزگیر یا همون کنسول دارند مثل بازی بازگشت به قلعه ولفن اشتاین که بازدن دکمه ~ فعال میشه اما بعضی از بازیها کنسول ندارد حالا آیا میشه با دلفی کاری کرد که بجای ساخت ترینر برنامه ای با پسوند exe ساخت که با زدن آن دکمه کنسول بالا بیاد و رمزهارا در آن قسمت وارد کرد.

----------

