Hello what's up anh em :v
Như anh em đã biết hoặc chưa biết =)) C/C++ là một ngôn ngữ thao tác với memory rất tốt. Và do đó nó là một ngôn ngữ được nhiều anh em lựa chọn trong việc đọc ghi bộ nhớ một process cụ thể trong hệ thống, cụ thể ở đây anh em có thể dùng vào nhiều mục đích khác nhau. Nhưng ở bài viết này mình dùng vào mục đích Hacking
Ở bài viết này mình sẽ hướng dẫn anh em cách để đọc ghi bộ nhớ với C/C++ một cách đơn giản và dễ hiểu nhất.
Oke, vào thẳng vấn đề luôn, chúng ta có một con game huyền thoại mà chắc không anh em nào chưa từng chơi qua: Plant and zombie.
Để cho dễ hiểu thì mình sẽ lấy một ví dụ đơn giản nhất. Cái thứ anh em cần nhiều nhất ở con game này đó là số lượng mặt trời.
Anh em sẽ phải trồng cây để thu nhặt mặt trời vì số lượng mặt trời rơi tự nhiên rất ít :v
Mình là một thằng rất ghét chơi kiểuđó nêntựdưng trongđầu mình lóe raý tưởng thayđổi số mặt trờilên 9999 mà không cần ngồi nhặt từng cái
Trước hết chúng ta sẽ tìm địa chỉ của vùng nhớ chứa giá trị là số lượng mặt trời hiện tại bằng Cheat Engine
Mở process list và chọn thằng Plant and zombie:
Oke, Cheat Engine sẽ Open Process này và mở quyền scan vùng nhớ đối với vùng nhớ của process này.
Oke tiếp theo, xét theo số lượng mặt trời có thể có tối đa, đó là 9999 do đó mình dự đoán vùng nhớ được lưu giá trị này ở trong bộ nhớ có độ lớn là 4 bytes, do đó mình sẽ tìm những giá trị 4 bytes trong bộ nhớ có đúng giá trị mà nó đang giữ là 75
Oke, nhặt tiếp một mặt trời nữa để giá trị thay đổi, ta sẽ lặp lại bước này tới khi tìm được giá trị đúng:
Oke, tìm giá trị 100 và nhấn Next scan:
Như vậy là chúng ta đã có giá trị chính xác lưu giá trị số lượng mặt trời có trong bộ nhớ :v
Ta sẽ chỉ chú ý tới địa chỉ của nó trong bộ nhớ nhé: 0x188F7FA8
Như anh em có thể đã biết hoặc chưa biết, những giá trị như này trong game thường được khai báo dưới dạng địa chỉ static (sang bên bộ nhớ người ta hay gọi nó là pointer)
Chúng ta sẽ tiến hành tìm con trỏ (pointer) trỏ tới địa chỉ này ở trong vùng nhớ của game :v
Hehe. Chỗ này mình sẽ viết chi tiết ở bài viết sau. Các bạn chỉ cần dùng Pointer scan của Cheat Engine là xong :v
Mình tìm được pointer base là: 0x00329670
Các offsets là 0x320, 0x18, 0x0, 0x8, 0x5578
Oke như vậy là mình đã có địa chỉ con trỏ trỏ tới vùng nhớ của địa chỉ chứa số lượng mặt trời, việc còn lại là đọc ghi với thằng C++.
Mình sẽ tính chính xácđịa chỉ của thằng nàyđể mỗi lần chúng ta khởiđộng lại game, giá trị này vẫn linhđộng theo:
Trước hết chúng ta cần base address của main module của game này:
Tìm địa chỉ đó bằng hàm này:
Sau đó ta sẽ tính địa chỉ chính xác mà pointer trỏ tới:
Tiếp tục chúng ta cần attach vào process để lấy handle của nó bằng cách dùng OpenProcess
(OpenProcess return handle of the Process: anh em có thể tham khảo thêm tại đây:
Khi đã lấy được handle của nó thì mình làm mọe gì với nó cũng được, hấp diêm hoặc lấy nó làm vợ cũng được, oke chưa a e
Tiếp theo là hàm đọc ghi bộ nhớ trong C++
//Hàm ghi
//Hàmđọc
Ở đây mình dùng template để linh động trong việc ghi giá trị bộ nhớ, do các giá trị có kiểu dữ liệu rất đa dạng, do đó biến truyền vào kiểu dữ liệu nào thì mình ghi kiểu dữ liệu đó
Oke việc còn lại là mình sẽ gọi hàm wpm để thực hiện ghi 9999 vào bộ nhớ tại địa chỉmà mình tìmđược bằng pointer
Hàm main của chúng ta:
Oke chạy và nhận thành cmn quả:
Chúc anh em thành công không thành thụ :v
Source code chi tiết ở đây:
Như anh em đã biết hoặc chưa biết =)) C/C++ là một ngôn ngữ thao tác với memory rất tốt. Và do đó nó là một ngôn ngữ được nhiều anh em lựa chọn trong việc đọc ghi bộ nhớ một process cụ thể trong hệ thống, cụ thể ở đây anh em có thể dùng vào nhiều mục đích khác nhau. Nhưng ở bài viết này mình dùng vào mục đích Hacking
Ở bài viết này mình sẽ hướng dẫn anh em cách để đọc ghi bộ nhớ với C/C++ một cách đơn giản và dễ hiểu nhất.
Oke, vào thẳng vấn đề luôn, chúng ta có một con game huyền thoại mà chắc không anh em nào chưa từng chơi qua: Plant and zombie.
Để cho dễ hiểu thì mình sẽ lấy một ví dụ đơn giản nhất. Cái thứ anh em cần nhiều nhất ở con game này đó là số lượng mặt trời.
Anh em sẽ phải trồng cây để thu nhặt mặt trời vì số lượng mặt trời rơi tự nhiên rất ít :v
Mình là một thằng rất ghét chơi kiểuđó nêntựdưng trongđầu mình lóe raý tưởng thayđổi số mặt trờilên 9999 mà không cần ngồi nhặt từng cái
Trước hết chúng ta sẽ tìm địa chỉ của vùng nhớ chứa giá trị là số lượng mặt trời hiện tại bằng Cheat Engine
Mở process list và chọn thằng Plant and zombie:
Oke tiếp theo, xét theo số lượng mặt trời có thể có tối đa, đó là 9999 do đó mình dự đoán vùng nhớ được lưu giá trị này ở trong bộ nhớ có độ lớn là 4 bytes, do đó mình sẽ tìm những giá trị 4 bytes trong bộ nhớ có đúng giá trị mà nó đang giữ là 75
Oke, nhặt tiếp một mặt trời nữa để giá trị thay đổi, ta sẽ lặp lại bước này tới khi tìm được giá trị đúng:
Oke, tìm giá trị 100 và nhấn Next scan:
Ta sẽ chỉ chú ý tới địa chỉ của nó trong bộ nhớ nhé: 0x188F7FA8
Như anh em có thể đã biết hoặc chưa biết, những giá trị như này trong game thường được khai báo dưới dạng địa chỉ static (sang bên bộ nhớ người ta hay gọi nó là pointer)
Chúng ta sẽ tiến hành tìm con trỏ (pointer) trỏ tới địa chỉ này ở trong vùng nhớ của game :v
Hehe. Chỗ này mình sẽ viết chi tiết ở bài viết sau. Các bạn chỉ cần dùng Pointer scan của Cheat Engine là xong :v
Mình tìm được pointer base là: 0x00329670
Các offsets là 0x320, 0x18, 0x0, 0x8, 0x5578
Oke như vậy là mình đã có địa chỉ con trỏ trỏ tới vùng nhớ của địa chỉ chứa số lượng mặt trời, việc còn lại là đọc ghi với thằng C++.
Mình sẽ tính chính xácđịa chỉ của thằng nàyđể mỗi lần chúng ta khởiđộng lại game, giá trị này vẫn linhđộng theo:
Trước hết chúng ta cần base address của main module của game này:
Tìm địa chỉ đó bằng hàm này:
C++:
DWORD getModule(LPSTR moduleName)
{
hModuleSnap = INVALID_HANDLE_VALUE;
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID);
if (hModuleSnap == INVALID_HANDLE_VALUE)
{
cout << "Khong the snapshot module list cua process " << pID << endl;
CloseHandle(hModuleSnap);
return false;
}
modEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hModuleSnap, &modEntry32))
{
if (!strcmp(moduleName, modEntry32.szModule))
{
cout << "Tim thay module " << modEntry32.szModule << " voi base address la: " << hex << (DWORD)modEntry32.modBaseAddr << endl;
CloseHandle(hModuleSnap);
return (DWORD)modEntry32.modBaseAddr;
}
}
while (Module32Next(hModuleSnap, &modEntry32))
{
if (!strcmp(moduleName, modEntry32.szModule))
{
cout << "Tim thay module " << modEntry32.szModule << " voi base address la: " << hex << (DWORD)modEntry32.modBaseAddr << endl;
CloseHandle(hModuleSnap);
return (DWORD)modEntry32.modBaseAddr;
}
}
cout << "Khong the tim thay module " << moduleName << " trong process " << pID << endl;
CloseHandle(hModuleSnap);
return false;
}
Sau đó ta sẽ tính địa chỉ chính xác mà pointer trỏ tới:
C++:
DWORD getPointerAddress(DWORD gameBaseAddress, DWORD address, vector<DWORD> offsets)
{
DWORD offset_null = NULL;
ReadProcessMemory(hProc, (LPVOID*)(gameBaseAddress + address), &offset_null, sizeof(offset_null), 0);
DWORD pointerAddress = offset_null;
for (int i = 0; i < offsets.size() - 1; i++)
{
ReadProcessMemory(hProc, (LPVOID*)(pointerAddress + offsets.at(i)), &pointerAddress, sizeof(pointerAddress), 0);
}
return pointerAddress += offsets.at(offsets.size() - 1);
}
Tiếp tục chúng ta cần attach vào process để lấy handle của nó bằng cách dùng OpenProcess
(OpenProcess return handle of the Process: anh em có thể tham khảo thêm tại đây:
Ồ, bạn chưa phải thành viên của forum
Đăng nhập hoặc đăng ký ngay.
)
C++:
bool attachProc(char* procName)
{
procEntry32.dwSize = sizeof(PROCESSENTRY32);
hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcSnap == INVALID_HANDLE_VALUE)
{
cout << "Khong the snap cac process" << endl;
return false;
}
while (Process32Next(hProcSnap, &procEntry32))
{
if (!strcmp(procName, procEntry32.szExeFile))
{
cout << "Tim thay process " << procEntry32.szExeFile << " voi pID la " << procEntry32.th32ProcessID << endl;
pID = procEntry32.th32ProcessID;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procEntry32.th32ProcessID);
if (hProc == NULL)
{
cout << "Khong the tao handle cua process, exit." << endl;
return false;
}
CloseHandle(hProcSnap);
return true;
}
}
cout << "Khong the tim thay process " << procName << " trong list process, vui long thu lai sau." << endl;
CloseHandle(hProcSnap);
return false;
}
Khi đã lấy được handle của nó thì mình làm mọe gì với nó cũng được, hấp diêm hoặc lấy nó làm vợ cũng được, oke chưa a e
Tiếp theo là hàm đọc ghi bộ nhớ trong C++
//Hàm ghi
C++:
template <class dataType>
void wpm(dataType valToWrite, DWORD addressToWrite)
{
WriteProcessMemory(hProc, (PVOID)addressToWrite, &valToWrite, sizeof(dataType), 0);
}
C++:
template <class dataType>
void rpm(dataType valToRead, DWORD addressToRead)
{
dataType rpmBuffer;
ReadProcessMemory(hProc, (PVOID)addressToRead, &rpmBuffer, sizeof(dataType), 0);
return rpmBuffer;
}
Ở đây mình dùng template để linh động trong việc ghi giá trị bộ nhớ, do các giá trị có kiểu dữ liệu rất đa dạng, do đó biến truyền vào kiểu dữ liệu nào thì mình ghi kiểu dữ liệu đó
Oke việc còn lại là mình sẽ gọi hàm wpm để thực hiện ghi 9999 vào bộ nhớ tại địa chỉmà mình tìmđược bằng pointer
Hàm main của chúng ta:
C++:
int main()
{
DWORD moduleBaseAddr = NULL;
DWORD sunAddress = 0x00329670;
DWORD realAddress = NULL;
int val = 9999; // số lượng mặt trời muốn ghi vào bộ nhớ
vector<DWORD> offsets = { 0x320, 0x18, 0x0, 0x8, 0x5578 };
bool check = attachProc((char*)"popcapgame1.exe");
if (check)
{
cout << "Thanh cong attach vao process " << pID << endl;
moduleBaseAddr = getModule((LPSTR)"popcapgame1.exe");
if (moduleBaseAddr == NULL)
{
cout << "Khong tim duoc module base address" << endl;
return 0;
}
cout << "Base address: " << hex << moduleBaseAddr << endl;
realAddress = getPointerAddress(moduleBaseAddr, sunAddress, offsets);
if (realAddress == NULL)
{
cout << "Khong tim duoc realaddress cua " << hex << sunAddress << endl;
return 0;
}
cout << "Dia chi sunaddress: " << hex << realAddress << endl;
cout << "Nhap so luong mat troi: ";
cin >> val;
while (true)
{
wpm<int>(val, realAddress);
cout << "Da thuc hien ghi " << val << " SUN vao bo nho" << endl;
Sleep(1000);
}
}
else {
cout << "Khong the attach process, vui long thu lai";
return 0;
}
}
Oke chạy và nhận thành cmn quả:
Chúc anh em thành công không thành thụ :v
Video chi tiết hướng dẫn mình làm ở đây:
Source code chi tiết ở đây:
Ồ, bạn chưa phải thành viên của forum
Đăng nhập hoặc đăng ký ngay.