Hỏi cách lấy Base Address của một Module
Mình không phải dân IT nên mấy thuật ngữ trên có dùng sai mọi người bỏ qua giùm nhé
Vấn đề là mình có debug game Minesweeper (game dò mìn có sẵn trên win) để lấy base address của số lượng bom trong game. Mà cái address sau cùng mình nhận được không phải dạng số mà là dạng chữ: “minesweeper.exe”+000AAA38.
Dạng số mình đã test thành công còn cái này có lên mạng search thì biết nó là Module gì đó. Viết code y như họ mà vẫn không đọc được address đó. Đây là code của mình, không biết sai chỗ nào mong cao nhân giúp đỡ
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
using namespace std;
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcID, TCHAR *szModuleName);
int main()
{
DWORD d_address;
DWORD d_offset[4] = { 0x000AAA38, 0x8, 0x1c8, 0x8 };
//DWORD d_baseOffset = 0x000AAA38;
DWORD d_temp;
DWORD d_BaseAddress;
int d_value;
DWORD pid = NULL;
HWND hwnd = FindWindow(NULL, TEXT("minesweeper"));
if (!hwnd)
{
cout << "Loi roi! Khong dung` dc ham FindWindow" << endl;
}
GetWindowThreadProcessId(hwnd, &pid);
HANDLE d_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!d_handle)
{
cout << "Loi roi! Khong dung dc ham OpenProcess" << endl;
}
d_address = dwGetModuleBaseAddress(pid, _T("minesweeper.exe"));
for (int n = 0; n < 5; n++)
{
if (n == 0)
{
ReadProcessMemory(d_handle, (LPCVOID*)d_address, &d_temp, sizeof(d_temp), 0);
}
else {
ReadProcessMemory(d_handle, (LPCVOID*)d_BaseAddress, &d_temp, sizeof(d_temp), 0);
}
d_BaseAddress = d_temp + d_offset[n];
}
ReadProcessMemory(d_handle, (void*)d_address, &d_value, sizeof(d_value), 0);
cout << d_value << endl;
system("pause");
return 0;
}
DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *lpszModuleName)
{
DWORD dwModuleBaseAddress = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessIdentifier);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32 = { 0 };
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
{
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
Theo như link này thì bạn phải build trong môi trường 64 bit (x64) thì mới thành công:
http://forum.cheatengine.org/viewtopic.php?t=557296&sid=b8a27a09465f8d07c31317e67de46709
Tuy nhiên nếu bạn muốn làm tiếp thì phải học khá nhiều đấy, vì cái này là lập trình Windows, process management in Windows, khó hơn lập trình bình thường nữa!
Bạn có thể tham khảo thêm link này https://stackoverflow.com/questions/26572459/c-get-module-base-address-for-64bit-application
Bạn chạy x64 OS thì compile bằng x64 compiler như anh Quân nói.
Nếu vùng bộ nhớ đó là static thì chắc cứ viết y chang con số offset lúc đó là được.
Thanks các bạn đã giúp đỡ. Mình mò một hồi cuối cùng cũng ra . Mình sai ở những chỗ sau:
Dưới đây là code đã chạy thành công cho bạn nào muốn thử:
Hai biến này mình thử giống bạn mà bị lỗi vì hàm dwGetModuleBaseAddress mình dùng kiểu dữ liệu DWORD
Mình nghĩ bạn nên wrap 1 template để get value sau mỗi offset.
Và riêng chỉ cần sử dụng
hwnd
là đủ để đọc memory rồi, không cần sử dụngdwGetModuleBaseAddress
, vì vốn dĩ pid và hwnd đã giữ hết thông tin về game rồi.Vì dụ:
Khi get chỉ cần:
Tham khảo: https://github.com/HadesD/AutoTLBB
FindWindow(NULL, TEXT("minesweeper"));
-> hàm này nên thay bằng::GetClassName
, dùng Spy++ của vs để lấy class name, như vậy sẽ lấy được hwnd thay vì search theo tên file.Lần trước thấy bài chìm xuống dưới tưởng nó kết thúc luôn rồi chứ, mình đọc bình luận của bạn lâu rồi mà chưa có thời gian trả lời :D.
Đầu tiên là cảm ơn bạn Dark.Hades trước, nhưng mà trình độ của mình còn hơi gà nên đọc code của bạn chưa hiểu được nhiều lắm :D. Giống như bạn Nguyễn Phạm Anh Quân đã nói, mình phải học thêm rất nhiều. Cái mình đang học bây giờ là tìm base adress của một biến trong chương trình rồi dùng được hàm read và writeprocessmemory là được.
Mình đang tìm hiểu assembly để phục vụ quá trình tìm base address mà chưa biết học thế nào cho hiệu quả. Mấy tài liệu trên mạng thấy mơ hồ quá.
Nếu bạn có tài liệu assembly nào phụ hợp với mục đích trên thì share giùm mình với, cảm ơn nhiều :D.