新手分享一段获取DLL模块地址的代码。

新手写代码的时候,遇到一点困难,没办法获取某个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);
	//输出结果到编辑框
}

 

请登录后发表评论