新手写代码的时候,遇到一点困难,没办法获取某个DLL模块的地址,不过自己到处复制粘贴还是弄出来了一个。
这个是函数,你丢任意地方都行,你就是单独创建一个.h文件夹,然后丢进去都行
#include <windows.h>
#include <iostream>
#include <tlhelp32.h>
// 获取进程ID
DWORD GetProcessIdByName(const wchar_t* processName) {
DWORD processId = 0;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot, &processEntry)) {
do {
if (_wcsicmp(processEntry.szExeFile, processName) == 0) {
processId = processEntry.th32ProcessID;
break;
}
} while (Process32Next(snapshot, &processEntry));
}
CloseHandle(snapshot);
}
return processId;
}
// 获取模块基址
uintptr_t GetModuleBaseAddress(DWORD processId, const wchar_t* moduleName) {
uintptr_t moduleBaseAddress = 0;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
if (snapshot != INVALID_HANDLE_VALUE) {
MODULEENTRY32 moduleEntry;
moduleEntry.dwSize = sizeof(MODULEENTRY32);
if (Module32First(snapshot, &moduleEntry)) {
do {
if (_wcsicmp(moduleEntry.szModule, moduleName) == 0) {
moduleBaseAddress = (uintptr_t)moduleEntry.modBaseAddr;
break;
}
} while (Module32Next(snapshot, &moduleEntry));
}
CloseHandle(snapshot);
}
return moduleBaseAddress;
}
// 读取DLL+偏移的数据
template<typename T>
bool ReadMemory(HANDLE processHandle, uintptr_t baseAddress, uintptr_t offset, T& value) {
uintptr_t targetAddress = baseAddress + offset;
return ReadProcessMemory(processHandle,
(LPCVOID)targetAddress,
&value,
sizeof(T),
NULL) != 0;
}
然后是在程序里面调用的写法。 如果真和我一样创建后写到了头文件里面,记得开头加上#include “你写的头文件.h”
// 获取进程ID和句柄
DWORD pid = GetProcessIdByName(L"target.exe");
//你可以通过任何方式获取进程的ID,手动赋值也行。
HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess)
{
// 获取DLL基址 dllBase存放的就是你dll模块的地址啦。
uintptr_t dllBase = GetModuleBaseAddress(pid, L"target.dll");
//归还权限,
CloseHandle(hProcess);
}
下面是我自己写的MFC程序,一个获取TIM程序的qq账户的工具。
按钮触发以后,获取TIM里面的dllI+偏移地址,读取4字节出来。至于为什么那么多的猫猫(二次元的问题劝你少管闲事)。
void CMFCApplication1Dlg::OnBnClickedButtonGet()
{
int MyQQID = 404;
int dwProcessId = 0;
CString strText;
HWND hwnd = FindWindowA(NULL, "TIM");
//获取窗口句柄
if (hwnd == NULL)
{
strText.Format(_T("猫猫未找到进程"));
//设置编辑框文本,Text是文本,int是整形变量
}
else
{
GetWindowThreadProcessId(hwnd, (LPDWORD)&dwProcessId);
//获取进程ID
//创建一个盒子装文本
strText.Format(_T("猫猫找到了 %d 进程哟~♡"), dwProcessId);
//把整数变量放进文本盒子里
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwProcessId);
//获取读写权限
if (hProcess == NULL)
{
strText.Format(_T("猫猫无法读取%d~♡"), GetLastError());
}
else
{
HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
// 获取DLL基址
uintptr_t dllBase = GetModuleBaseAddress(dwProcessId, L"AVSDK.dll");
strText.Format(_T("猫猫读取到地址 0x%p~♡"), (void*)dllBase);
//dllBase += 0x; // 偏移地址,需根据实际情况修改
ReadProcessMemory(hProcess, (LPCVOID)(dllBase + 0x00161E30), &MyQQID, 4, NULL);
strText.Format(_T("猫猫找到了账户%d~♡"), MyQQID);
CloseHandle(hProcess);
// 归还钥匙
}
}
SetDlgItemText(IDC_EDIT1_OUT,strText);
//设置编辑框文本,Text是文本,int是整形变量。可能之前测试有问题的时候加上的,你自己处理.
int ProcessID = 0;
SetDlgItemText(IDC_EDIT1_OUT, strText);
//输出结果到编辑框
}



没有回复内容