PDA

View Full Version : سوال: چطوری با داشتن آدرس توی حافظه متغیرهای اون رو تغییر بدم؟



papa_toop
یک شنبه 06 مرداد 1387, 14:54 عصر
سلام به دوستان

من یه آدرس دارم توی حافظه مثل 000102BE که آدرس یه اینتجر 2 بایتی هست و مقدارش هم 10

حالا اگه من بخوام مقدار اون رو به 100 برسونم یا فریزش کنم باید چی کار کنم(برای ساخت ترینر می خوام)

مرسی

اَرژنگ
یک شنبه 06 مرداد 1387, 15:22 عصر
سلام به دوستان

من یه آدرس دارم توی حافظه مثل 000102BE که آدرس یه اینتجر 2 بایتی هست و مقدارش هم 10

حالا اگه من بخوام مقدار اون رو به 100 برسونم یا فریزش کنم باید چی کار کنم(برای ساخت ترینر می خوام)

مرسی
ترینر چیست؟

Behrouz_Rad
یک شنبه 06 مرداد 1387, 15:33 عصر
احتمالاً Trainer های بازی منظور دوستمونه که Cheat Code بازی محسوب میشن ;)

papa_toop
یک شنبه 06 مرداد 1387, 15:48 عصر
ترینر ها نرم افزارهایی هستند که به جای رمز در بازی استفاده می شن

مثلا به جای اینکه رمز رو بزنید از ترینر استفاده می کنید در ضمن از ترینر برای بازی هایی که اصلا رمز ندارن هم استفاده می شه

به این صورت که کسی ترینر رو نوشته آدرس اون متغیر رو توی حافظه پیدا می کنه و اون رو تغییر می ده

مثلا به جای 6 خط رمز شما یه F7 رو فشار می دی و رمز فعال می شه

DarkSoroush
یک شنبه 06 مرداد 1387, 20:05 عصر
شما باید از Api های WriteProcessMemory و ... استفاده کنید.
من خودم شخصا چون زیاد بازی میکنم زیادم ترینر میسازم به همین دلیل کلاسی در این باره مدتها قبل نوشته بودم که ازش استفاده میکنم. البته زبانش vb.net هست ولی با کمی تغییر میتونید به c# تبدیلش کنید. امیدوارم به کارتون بیاد:


Public Class c_MemoryAccess
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Int32, ByRef lpdwProcessId As Int32) As Int32
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Int32, ByVal bInheritHandle As Int32, ByVal dwProcessId As Int32) As Int32
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Int32, ByVal lpBaseAddress As Int32, ByRef lpBuffer As Int32, ByVal nSize As Int32, ByRef lpNumberOfBytesWritten As Int32) As Int32
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Int32, ByVal lpBaseAddress As Int32, ByRef lpBuffer As Byte, ByVal nSize As Int32, ByRef lpNumberOfBytesWritten As Int32) As Int32
Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Int32, ByVal lpBaseAddress As Int32, ByRef lpBuffer As Long, ByVal nSize As Int32, ByRef lpNumberOfBytesWritten As Int32) As Int32
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Int32) As Int32
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal Classname As String, ByVal WindowName As String) As Int32
Public Declare Function ReadProcessMem Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Int32, ByVal lpBaseAddress As Int32, ByRef lpBuffer As Int32, ByVal nSize As Int32, ByRef lpNumberOfBytesWritten As Int32) As Int32
Public Declare Function ReadProcessMem Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Int32, ByVal lpBaseAddress As Int32, ByRef lpBuffer As Byte, ByVal nSize As Int32, ByRef lpNumberOfBytesWritten As Int32) As Int32
Public Declare Function ReadProcessMem Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Int32, ByVal lpBaseAddress As Int32, ByRef lpBuffer As Long, ByVal nSize As Int32, ByRef lpNumberOfBytesWritten As Int32) As Int32
Public Const PROCESS_ALL_ACCESS As Int32 = &H1F0FFF
Dim f1holder As Short
Dim timer_pos As Int32
Dim hProcess As Object
Dim hwnd As Int32
Dim phandle As Int32
Public Sub New(ByVal WindowName As String)
Dim pid As Int32
hwnd = FindWindow(vbNullString, WindowName)
If (hwnd = 0) Then
Debug.Fail("Can't find window", "The aforementioned window is not exist or protected.")
Exit Sub
End If
GetWindowThreadProcessId(hwnd, pid)
phandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
If (phandle = 0) Then
Debug.Fail("Can't get process id", "The aforementioned window may closed or protected.")
Exit Sub
End If
End Sub
Public Sub New(ByVal ProcessId As Int32)
phandle = OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId)
If (phandle = 0) Then
Debug.Fail("Can't find process id", "The aforementioned process id is not exist or protected.")
Exit Sub
End If
End Sub
Public Function WriteByte(ByRef Address As Int32, ByRef Value As Byte) As Int32
Return WriteProcessMemory(phandle, Address, Value, 1, 0)
End Function
Public Function WriteInt(ByRef address As Int32, ByRef value As Int32) As Int32
Return WriteProcessMemory(phandle, address, value, 2, 0)
End Function
Public Function WriteLong(ByRef address As Int32, ByRef value As Long) As Int32
Return WriteProcessMemory(phandle, address, value, 4, 0)
End Function
Public Function ReadByte(ByRef address As Int32) As Byte
Dim valbuffer As Byte
ReadProcessMem(phandle, address, valbuffer, 1, 0)
Return valbuffer
End Function
Public Function ReadInt(ByRef address As Int32) As Int32
Dim valbuffer As Int32
ReadProcessMem(phandle, address, valbuffer, 2, 0)
Return valbuffer
End Function
Public Function ReadLong(ByRef address As Int32) As Long
Dim valbuffer As Long
ReadProcessMem(phandle, address, valbuffer, 4, 0)
Return valbuffer
End Function

Protected Overrides Sub Finalize()
CloseHandle(hProcess)
MyBase.Finalize()
End Sub
End Class

papa_toop
یک شنبه 06 مرداد 1387, 20:48 عصر
دست شما درد نکنه ولی می شه یه توضیح بدید

DarkSoroush
یک شنبه 06 مرداد 1387, 23:49 عصر
دست شما درد نکنه ولی می شه یه توضیح بدید
خب!! مثل هر ابجکت دیگری شما باید ابتدا یک انستنس از این ابجکت بسازید. این کلاسی که نوشتم تابع new اون به دو صورت قابل فراخوانی هست. با pid برنامه و یا با نام پنجره برنامه یا بازی:
با استفاده از نام پنجره:


Dim m_access as new c_MemoryAccess("Age of empire III")
و یا با استفاده از PID برنامه:


Dim m_access as new c_MemoryAccess(1066)

PID برنامه یا بازی رو اگر خودت با استفاده از کلاس PROCESS ران کرده باشی در همون کلاس وجود داره. PID در اصل همون خاصیت ID کلاس process است. البته فکر کنم کد اول بیشتر به کارت بیاد
بعد از ساخت ابجکت میتونی در ترینرت برای تغییر مقدار یک ادرس به صورت زیر عمل کنی:


m_acess.writebyte()
m_access.writeint()
m_access.writelong()

بایت تک بایت رو تغییر میده, اینت دو بایت و long چهار بایت.
و میتونید با متدهای Read هم مقادیر رو بخونید. دقت کنید که ادرس را اگر به مبنای شانزده دارید (اصولا برنامه هایی شبیه به cheat engine یا memsearcher یا برنامه های مشابه به ادرس را به مبنای شانزده به شما تحویل میدهند.) در ابتدای عدد &h بزارید البته در vb.net
و در غیر اینصورت اگر عددتون برمبنای 10 است میتونید به راحتی ادرس رو بنویسید.

برای فریز کردن یک ادرس هم میتونید از تایمر استفاده کنید. همه ترینر ها اصولا از تایمر استفاده میکنند یا دستور مربوطه به تغییر اون اینتیجر رو Nop میکنند. البته تعدادی هم بحث dll injection رو پیش میبرند و ... که یکم مربوط به مهندسی معکوس میشه.

به طور کلی کدی که شما لازم دارید شبیه به این میشه (یک فرم بسازید و یک کلید روی اون قرار بدید.) در vb.net:


Private WithEvents t_maintimer As New Timers.Timer(10)
Dim m_access As c_MemoryAccess
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
m_access = New c_MemoryAccess("Name of the game window")
End Sub
Private Sub t_maintimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles t_maintimer.Elapsed
If Not (m_access Is Nothing) Then m_access.WriteInt(&H102BE, 100)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
t_maintimer.Enabled = Not t_maintimer.Enabled
End Sub

البته نوشته Name of the game window را با نام پنجره بازی عوض کنید.


چون در مورد زبانش حرفی نزده بودید با vb.net نوشتم ولی شما میتونید با کمی تغییر کد رو به c# تغییر بدید.
موفق باشی
- سروش