需要包含头文件:Windows.h & TlHelp32.h

获取模块基址:

uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
	uintptr_t modBaseAddr = 0;
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
	if (hSnap != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32W modEntry;
		modEntry.dwSize = sizeof(modEntry);
		if (Module32FirstW(hSnap, &modEntry))
		{
			do
			{
				if (!_wcsicmp(modEntry.szModule, modName))
				{
					modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
					break;
				}
			} while (Module32NextW(hSnap, &modEntry));
		}
	}
	CloseHandle(hSnap);
	return modBaseAddr;
}

通过进程名获取PID:

DWORD GetProcessIDByName(LPCWSTR szName)
{
    DWORD id = 0;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 获取系统进程列表
    if (Process32First(hSnapshot, &pe))
    {
        do
        {
            if (0 == _wcsicmp(pe.szExeFile, szName))
            {
                id = pe.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapshot, &pe));
    }
    CloseHandle(hSnapshot);
    return id;
}

获取模块的开始基址和结束基址:

void GetModulInfo(DWORD pid, const wchar_t* modulName, INT64& startAddress, INT64& endAddress)
{
    MODULEENTRY32W modulInfo;
    modulInfo.dwSize = sizeof(MODULEENTRY32W);
    HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
    if (INVALID_HANDLE_VALUE == handle)
        exit(1);

    BOOL ret = Module32FirstW(handle, &modulInfo);
    while (ret)
    {
        if (_wcsicmp(modulInfo.szModule, modulName) == 0)
        {
            startAddress = (INT64)modulInfo.modBaseAddr;
            endAddress = startAddress + modulInfo.modBaseSize;
            CloseHandle(handle);
            return;
        }
        ret = Module32NextW(handle, &modulInfo);
    }
    CloseHandle(handle);
}

特征码搜索:

BOOL CompareMarkCode(BYTE* arr1, BYTE* arr2, DWORD length)
{
    for (DWORD i = 0; i < length; ++i)
    {
        if (arr1[i] != arr2[i])
            return false;
    }
    return true;
}

INT64 ScanMarkCode(HANDLE handle, BYTE* markCode, DWORD markCodeLen, INT64 startAddress, INT64 endAddress, int shifting)
{
    BYTE tempMarkArr[MARK_ARR_LEN] = { 0 }; //临时特征数组
    DWORD lentemp;
    while (startAddress < endAddress)
    {
        ReadProcessMemory(handle, (LPCVOID)startAddress, tempMarkArr, MARK_ARR_LEN, NULL);
        for (DWORD i = 0; i < MARK_ARR_LEN; ++i)
        {
            if (CompareMarkCode(tempMarkArr + i, markCode, markCodeLen))
                return startAddress + i + shifting;
            lentemp = i - markCodeLen;
        }
        startAddress += lentemp;
    }
    return 0;
}

“但行好事,莫问前程”