MemoryUtil.cpp 文件
//#include <windows.h> //#include <algorithm> //#include <string.h> //#include <iostream> //#include"tlhelp32.h" //#include <Psapi.h> //#include<ntstatus.h> //#include "xxxx.h" #include "pch.h" //==================================X64常用内存读写库========================== DWORD GetModuleSizeX64(DWORD Pid, const TCHAR* ModuleName)//获取模块大小,只能搞64位=64位,32位无法对64位操作 {/*初始化DLL列表*/ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Pid); if (hProcess == INVALID_HANDLE_VALUE || !hProcess)return NULL; DWORD dwBuffSize = 0; BOOL bRet = EnumProcessModulesEx(hProcess, NULL, 0, &dwBuffSize, LIST_MODULES_ALL); HMODULE * pModuleHandlerArr = (HMODULE*) new char[dwBuffSize]; bRet = EnumProcessModulesEx(hProcess, pModuleHandlerArr, dwBuffSize, &dwBuffSize, LIST_MODULES_ALL); // 模块名称 TCHAR szModuleName[MAX_PATH]; TCHAR szBaseName[MAX_PATH];//新建 // 保存模块信息 MODULEINFO stcModuleInfo = { 0 }; // 遍历模块列表 int nCount = dwBuffSize / sizeof(HMODULE); for (int i = 0; i < nCount; ++i) { // 根据进程句柄和模块句柄,获取模块信息 GetModuleInformation(hProcess, pModuleHandlerArr[i], &stcModuleInfo, sizeof(stcModuleInfo)); GetModuleBaseNameA(hProcess, pModuleHandlerArr[i], szBaseName, MAX_PATH); //printf(" %x ", (DWORD)stcModuleInfo.SizeOfImage); //模块内存大小 if (strcmp(szBaseName, ModuleName) == 0) { delete[] pModuleHandlerArr;// 释放数组 pModuleHandlerArr = nullptr; return stcModuleInfo.SizeOfImage; } } return NULL; } HMODULE GetModuleBaseX64(DWORD Pid, const TCHAR* ModuleName) {/*初始化DLL列表*/ // 这个程序不能删除,基础功能 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Pid); if (hProcess == INVALID_HANDLE_VALUE || !hProcess)return NULL; DWORD dwBuffSize = 0; BOOL bRet = EnumProcessModulesEx(hProcess, NULL, 0, &dwBuffSize, LIST_MODULES_ALL); HMODULE * pModuleHandlerArr = (HMODULE*) new char[dwBuffSize]; bRet = EnumProcessModulesEx(hProcess, pModuleHandlerArr, dwBuffSize, &dwBuffSize, LIST_MODULES_ALL); // 模块名称 TCHAR szModuleName[MAX_PATH]; TCHAR szBaseName[MAX_PATH];//新建 // 保存模块信息 MODULEINFO stcModuleInfo = { 0 }; // 遍历模块列表 int nCount = dwBuffSize / sizeof(HMODULE); for (int i = 0; i < nCount; ++i) { // 根据进程句柄和模块句柄,获取模块信息 GetModuleInformation(hProcess, pModuleHandlerArr[i], &stcModuleInfo, sizeof(stcModuleInfo)); // 根据进程句柄和模块句柄,获取模块的路径(包括模块名) //GetModuleFileNameEx(hProcess, pModuleHandlerArr[i], szModuleName, MAX_PATH); //获取模块的路径 GetModuleBaseNameA(hProcess, pModuleHandlerArr[i], szBaseName, MAX_PATH); printf(" %x ", (DWORD)stcModuleInfo.lpBaseOfDll); //获取模块基地址 printf(" %x ", (DWORD)stcModuleInfo.EntryPoint); //获取模块入口地址 printf(" %x ", (DWORD)stcModuleInfo.SizeOfImage); //模块内存大小 if (strcmp(szBaseName, ModuleName) == 0) { printf("基地址是:%s ", szBaseName); printf("基地址是:%X ", (DWORD)stcModuleInfo.lpBaseOfDll); delete[] pModuleHandlerArr;// 释放数组 pModuleHandlerArr = nullptr; return (HMODULE)stcModuleInfo.lpBaseOfDll; } // 基址 //CString szTemp; //szTemp.Format(L"%08X", stcModuleInfo.lpBaseOfDll); //// 入口点 //szTemp.Format(L"%08X", stcModuleInfo.EntryPoint); //// 内存大小 //szTemp.Format(L"%d", stcModuleInfo.SizeOfImage); //// 模块路径 //szModuleName; } return NULL; } HMODULE GetModuleBaseAddr(DWORD Pid, CONST TCHAR* moduleName)//获取进程模块入口地址 1.进程pid 2.模块的名称 xxx.exe 或者xxx.dll { MODULEENTRY32 moduleEntry; //模块信息的结构体 HANDLE handle = NULL; handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid); // 获取进程快照中包含在th32ProcessID中指定的进程的所有的模块 printf("handle %X ", (DWORD)handle); if (!handle) { //handle 类似指针,指向进程模块信息 CloseHandle(handle); return NULL; } ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32)); //清空 moduleEntry.dwSize = sizeof(MODULEENTRY32); if (!Module32First(handle, &moduleEntry)) { //结果传到 结构体指针moduleEntry CloseHandle(handle); return NULL; } do { if (strcmp(moduleEntry.szModule, moduleName) == 0) { //wcscmp宽字节比较 moduleEntry.szModule模块名字 //printf("基地址是 %X ", (DWORD)moduleEntry.hModule); return moduleEntry.hModule; //返回模块入口地址 } } while (Module32Next(handle, &moduleEntry)); CloseHandle(handle); return 0; } BOOL EnableSeDebugPrivilege(IN const CHAR* PriviledgeName, BOOL IsEnable) { // 打开权限令牌 HANDLE ProcessHandle = GetCurrentProcess(); HANDLE TokenHandle = NULL; TOKEN_PRIVILEGES TokenPrivileges = { 0 }; if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) { return FALSE; } LUID v1; if (!LookupPrivilegeValue(NULL, PriviledgeName, &v1)) // 通过权限名称查找uID { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } TokenPrivileges.PrivilegeCount = 1; // 要提升的权限个数 TokenPrivileges.Privileges[0].Attributes = IsEnable == TRUE ? SE_PRIVILEGE_ENABLED : 0; // 动态数组,数组大小根据Count的数目 TokenPrivileges.Privileges[0].Luid = v1; if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } CloseHandle(TokenHandle); TokenHandle = NULL; return TRUE; } //==============================================x86x64内存读写wow64函数指针获取===================================================== LPFN_NTWOW64READVIRTUALMEMORY64 __NtWow64ReadVirtualMemory64; LPFN_NTWOW64WRITEVIRTUALMEMORY64 __NtWow64WriteVirtualMemory64; BOOL GetNTWOW64MemoryProcAddress() { HMODULE NtdllModuleBase = NULL; NtdllModuleBase = GetModuleHandle("Ntdll.dll"); if (NtdllModuleBase == NULL) { return FALSE; } __NtWow64ReadVirtualMemory64 = (LPFN_NTWOW64READVIRTUALMEMORY64)GetProcAddress(NtdllModuleBase, "NtWow64ReadVirtualMemory64"); printf("__NtWow64ReadVirtualMemory64 %lx ", __NtWow64ReadVirtualMemory64); __NtWow64WriteVirtualMemory64 = (LPFN_NTWOW64WRITEVIRTUALMEMORY64)GetProcAddress(NtdllModuleBase, "NtWow64WriteVirtualMemory64"); return TRUE; } char* UTF8ToUnicode(char* szUTF8)//编码转换,已经修复delet释放bug { int wcscLen = MultiByteToWideChar(CP_UTF8, NULL, szUTF8, strlen(szUTF8), NULL, 0);//得到所需空间的大小 wchar_t wszcString[1024] = { 0 };//这个大小的转换我这里是为了写辅助的。溢出数据自己修改 MultiByteToWideChar(CP_UTF8, NULL, szUTF8, strlen(szUTF8), wszcString, wcscLen); //转换 wszcString[wcscLen] = ''; int len = WideCharToMultiByte(CP_ACP, 0, wszcString, wcslen(wszcString), NULL, 0, NULL, NULL); char m_char[1024] = { 0 };//这个大小的转换我这里是为了写辅助的。 WideCharToMultiByte(CP_ACP, 0, wszcString, wcslen(wszcString), m_char, len, NULL, NULL); m_char[len] = ''; return m_char; } char* UnicodeToUTF8(wchar_t* wszcString)//编码转换,已经修复 注意内存delet释放bug { int utf8Len = ::WideCharToMultiByte(CP_UTF8, NULL, wszcString, wcslen(wszcString), NULL, 0, NULL, NULL); //得到所需空间的大小 char szUTF8[1024] = { 0 };//这个大小的转换我这里是为了写辅助的。 WideCharToMultiByte(CP_UTF8, NULL, wszcString, wcslen(wszcString), szUTF8, utf8Len, NULL, NULL); //转换 szUTF8[utf8Len] = ''; return szUTF8; } int Wow64ReadInt(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 BufferData = NULL;//===================== ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("8字节数据是:%lld ", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } char * Wow64ReadAscii(ULONG ProcessID, ULONG64 BaseAddress, DWORD Len) //写入ASCII 参数三是长度 { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; char BufferData[4096] = { 0 };//===================== ULONG64 ReturnLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, Len, &ReturnLen); printf("字符串是:%s ", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } wchar_t * Wow64ReadUnicode(ULONG ProcessID, ULONG64 BaseAddress, DWORD Len) //写入ASCII 参数三是长度 { setlocale(LC_ALL, "chs"); // unicode 必加 只有添加这一句下面的打印1,2与调试打印成功 BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; wchar_t BufferData[4096] = { 0 };//===================== ULONG64 ReturnLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, Len * 5, &ReturnLen); //unicode编码要乘以2 //printf("字符串是:%s ", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } float Wow64ReadFloat(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; FLOAT BufferData = NULL;//===================== ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("单精度数据是:%f ", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } double Wow64ReadDouble(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; DOUBLE BufferData = NULL;//===================== ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("浮点数数据是:%lf ", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } LONG64 Wow64ReadInt64(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 BufferData = NULL;//===================== ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("8字节数据是:%lld ", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } BOOL Wow64WriteInt(ULONG ProcessID, ULONG64 BaseAddress, INT Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteFloat(ULONG ProcessID, ULONG64 BaseAddress, FLOAT Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteDouble(ULONG ProcessID, ULONG64 BaseAddress, DOUBLE Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteInt64(ULONG ProcessID, ULONG64 BaseAddress, INT64 Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteAscii(ULONG ProcessID, ULONG64 BaseAddress, const char* Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = NULL;//默认 ULONG64 BufferLen = strlen(Value);//获取字符串长度 printf("BufferLen %d ", BufferLen); if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, (PVOID64)Value, BufferLen, &ReturnLen);//32位和64位区别 } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteUTF8(ULONG ProcessID, ULONG64 BaseAddress, const wchar_t * GBK_Str)//为了兼容,写入的是unicode,函数内部会进行转换操作的。 { BOOL IsWow64 = FALSE; //64位程序备用 HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = NULL;//默认 char strUTF8[4096] = { 0 }; char *unGunG = UnicodeToUTF8((wchar_t*)GBK_Str); ULONG64 BufferLen = strlen(unGunG);//获取字符串长度 宽字符用 wcslen RtlMoveMemory(strUTF8, unGunG, BufferLen); printf("BufferLen %d ", BufferLen); if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &strUTF8, BufferLen, &ReturnLen);//32位和64位区别 } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteUnicode(ULONG ProcessID, ULONG64 BaseAddress, const wchar_t * Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = NULL;//默认 ULONG64 BufferLen = wcslen(Value) * 2;//获取字符串长度 宽字符用 wcslen printf("BufferLen %d ", BufferLen); if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, (PVOID64)Value, BufferLen, &ReturnLen);//32位和64位区别 } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常 "); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } //===============================x86 r3层普通API 内存读写================================================= BOOL WriteInt64(DWORD ProcessID, DWORD Addr, __int64 Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 8, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteInt(DWORD ProcessID, DWORD Addr, int Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 4, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteShort(DWORD ProcessID, DWORD Addr, short Value) //2字节整数 { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { //printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 2, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteByte(DWORD ProcessID, DWORD Addr, byte Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { //printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 2, NULL); CloseHandle(Process_handle); return ret; } // BOOL WriteFloat(DWORD ProcessID, DWORD Addr, float Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { //printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 4, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteDouble(DWORD ProcessID, DWORD Addr, double Value) { //printf("打印输出进程pid :%x ", game_pid); HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 8, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteAcsii(DWORD ProcessID, DWORD Addr, const char * str) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, strlen(str), NULL);//strlen字符长度 CloseHandle(Process_handle); return ret; } BOOL WriteUnicode(DWORD ProcessID, DWORD Addr, const wchar_t * str) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, wcslen(str) * 2 + 2, NULL);//wcslen宽字符长度+2 printf("iiiiiiiiiii %d ", wcslen(str)); CloseHandle(Process_handle); return ret; } BOOL WriteUnicode(DWORD ProcessID, DWORD Addr, wchar_t * str) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败 "); } else { printf("获取进程句柄成功 "); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, wcslen(str) * 2 + 2, NULL);//wcslen宽字符长度+2 printf("iiiiiiiiiii %d ", sizeof(str)); CloseHandle(Process_handle); return ret; } DWORD GetPidByHwnd(HWND hwnd) { DWORD Pid = NULL; GetWindowThreadProcessId(hwnd, &Pid); //lpdword指针类型 return Pid; } DWORD FloatToDword(float value)//单浮点数转整数 { DWORD val = NULL; memcpy(&val, &value, 4); return val; } QWORD DoubleToDword(double value)//双浮点数转整数 { QWORD val = NULL; memcpy(&val, &value, 8); return val; } int Int64To32(__int64 value)//部分接口 { DWORD val = NULL; memcpy(&val, &value, 4); return val; } int DwordToInt(DWORD value)//无符号转有符号 { int val = NULL; memcpy(&val, &value, 4); return val; } DWORD IntToDword(int value)//无符号转有符号 { DWORD val = NULL; memcpy(&val, &value, 4); return val; } BOOL WriteIntEx(DWORD ProcessID, DWORD Addr, __int64 Value, int NumByte) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) printf("获取进程句柄失败 "); else printf("获取进程句柄成功 "); BOOL ret = NULL; if (NumByte == 4) { int real_val = (int)Value; ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &real_val, 4, NULL); } else if (NumByte == 2) { short real_val = (short)Value; ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &real_val, 2, NULL); } else if (NumByte == 1) { short real_val = (short)Value; ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &real_val, 1, NULL); } else if (NumByte == 8) { ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 8, NULL); } CloseHandle(Process_handle); return ret; } byte ReadByte(DWORD ProcessID, DWORD addr) //写入4字节整数 { byte Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 1, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } short ReadShort(DWORD ProcessID, DWORD addr) //写入4字节整数 { short Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 2, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } int ReadInt(DWORD ProcessID, DWORD addr) //写入4字节整数 { int Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 4, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } DWORD ReadDword(DWORD ProcessID, DWORD addr) //写入4字节整数 { DWORD Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 4, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } __int64 ReadInt64(DWORD ProcessID, DWORD addr) //写入8字节整数,地址还是4字节 { __int64 Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 8, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } void * ReadAscii(DWORD ProcessID, DWORD addr, DWORD Len) //写入8字节整数,地址还是4字节 { char Value[1024] = { 0 }; char ByteBuffer = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); for (size_t i = 0; i < 1024; i++)//遍历长度,上限1024 { ReadProcessMemory(Hprocess, (LPCVOID)(addr + i), &ByteBuffer, 1, NULL);//注意参数 4字节 //printf("遍历I数值! %d ", i); if (ByteBuffer == 0) { if (Len == 0)//如果是0自动长度 { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &Value, i + 1, NULL); // 字节 break; } else { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &Value, Len, NULL); // 字节 break; } } } } CloseHandle(Hprocess);//关闭进程句柄 return Value; } wchar_t * ReadUnicode(DWORD ProcessID, DWORD addr, DWORD Len) //控制台程序不支持unicode打印输出 { wchar_t StrValue[1024] = { 0 }; wchar_t ShortBuffer = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败! "); else { printf("打开进程成功! "); for (size_t i = 0; i < 1024; i = i + 2)//遍历长度,上限1024 { ReadProcessMemory(Hprocess, (LPCVOID)(addr + i), &ShortBuffer, 2, NULL);//注意参数 4字节 if (ShortBuffer == '') { if (Len == 0)//如果是0自动长度 { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &StrValue, i + 2, NULL); // 字节 printf("打印 %s ", StrValue); //printf("打印i : %d ", i); break; } else { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &StrValue, Len, NULL); // 字节 break; } } } } CloseHandle(Hprocess);//关闭进程句柄 return StrValue; } int ReadIntEx(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { int Value = NULL; HANDLE Hprocess = NULL; DWORD nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &Value, 4, NULL);//注意参数 4字节 for (size_t i = 0; i < Num; i++)//word占2字节 { ReadProcessMemory(Hprocess, (LPVOID)(Value + OffsetArray[i]), &Value, 4, NULL);//注意参数 4字节 } } else printf("打开进程失败! "); CloseHandle(Hprocess);//关闭进程句柄 return Value; } float ReadFloatEx(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { DWORD Value = NULL; HANDLE Hprocess = NULL; DWORD nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &Value, 4, NULL);//注意参数 4字节 for (size_t i = 0; i < Num; i++)//word占2字节 { printf("str %d ", Value); ReadProcessMemory(Hprocess, (LPVOID)(Value + OffsetArray[i]), &Value, 4, NULL);//注意参数 4字节 } } else printf("打开进程失败! "); CloseHandle(Hprocess);//关闭进程句柄 return (float)Value; } double ReadDoubleEx(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { double ValueDouble = NULL; HANDLE Hprocess = NULL; DWORD nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &nBuffer, 4, NULL);//注意参数 4字节 int i = NULL; for (i = 0; i < Num - 1; i++)//word占2字节 { ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &nBuffer, 4, NULL);//注意参数 4字节 /* printf("double %x ", OffsetArray[i]);*/ } ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &ValueDouble, 8, NULL);//Value64最终结果 } else printf("打开进程失败! "); CloseHandle(Hprocess);//关闭进程句柄 return ValueDouble; } __int64 ReadIntEx64(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { __int64 value64 = NULL; HANDLE Hprocess = NULL; DWORD nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &nBuffer, 4, NULL);//注意参数 4字节 int i = NULL; for (i = 0; i < Num - 1; i++)//word占2字节 { ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &nBuffer, 4, NULL);//注意参数 4字节 /* printf("double %x ", OffsetArray[i]);*/ } ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &value64, 8, NULL);//Value64最终结果 } else printf("打开进程失败! "); CloseHandle(Hprocess);//关闭进程句柄 return value64; } int EnableDebugPriv(const char *name) { HANDLE hToken; //进程令牌句柄 TOKEN_PRIVILEGES tp; //TOKEN_PRIVILEGES结构体,其中包含一个【类型+操作】的权限数组 LUID luid; //上述结构体中的类型值 //打开进程令牌环 //GetCurrentProcess()获取当前进程的伪句柄,只会指向当前进程或者线程句柄,随时变化 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { fprintf(stderr, "OpenProcessToken error "); return -1; } //获得本地进程name所代表的权限类型的局部唯一ID if (!LookupPrivilegeValue(NULL, name, &luid)) { fprintf(stderr, "LookupPrivilegeValue error "); } tp.PrivilegeCount = 1; //权限数组中只有一个“元素” tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //权限操作 tp.Privileges[0].Luid = luid; //权限类型 //调整进程权限 if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { fprintf(stderr, "AdjustTokenPrivileges error! "); return -1; } return 0; } DWORD GetPidByName(const char * ProcessName) //根据进程名字获取进程ID { HANDLE ProcessAll = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); PROCESSENTRY32 processInfo = { 0 }; processInfo.dwSize = sizeof(PROCESSENTRY32); do { if (strcmp(ProcessName, processInfo.szExeFile) == 0) { return processInfo.th32ProcessID; } } while (Process32Next(ProcessAll, &processInfo)); return NULL; } //======================================注入========================== VOID InjectDll(const CHAR pathStr[0x1000], const CHAR ProcessName[256]) { //CHAR pathStr[0x1000] = { "K:\我的文档\visual studio 2012\Projects\InjectChat\Debug\WeChatDll.dll" }; DWORD PID = GetPidByName((CHAR*)ProcessName); if (PID == 0) { MessageBox(NULL, "没有找到微信进程或者微信没有启动", "错误", 0); return; } HANDLE hProcsee = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); if (hProcsee == NULL) { MessageBox(NULL, "没有找到微信进程", "错误", 0); return; } LPVOID dllAdd = VirtualAllocEx(hProcsee, NULL, strlen(pathStr), MEM_COMMIT, PAGE_READWRITE); if (dllAdd == NULL) { MessageBox(NULL, "内存写入", "错误", 0); } if (WriteProcessMemory(hProcsee, dllAdd, pathStr, strlen(pathStr), NULL) == 0) { MessageBox(NULL, "内存写入", "错误", 0); return; } HMODULE K32 = GetModuleHandle("Kernel32.dll"); LPVOID LoadAdd = GetProcAddress(K32, "LoadLibraryA"); HANDLE exec = CreateRemoteThread(hProcsee, NULL, 0, (LPTHREAD_START_ROUTINE)LoadAdd, dllAdd, 0, NULL); if (NULL == exec) { MessageBox(NULL, "远程注入失败", "错误", 0); return; } WaitForSingleObject(exec, INFINITE); CloseHandle(hProcsee); } BOOL InjectRemoteFunc(DWORD dwProcId, LPVOID mFunc, LPVOID pRemoteParam, DWORD ParamSize) { HANDLE hProcess; LPVOID ThreadAdd; LPVOID ParamAdd = NULL; HANDLE hThread = NULL; DWORD lpNumberOfBytes; BOOL BO; ThreadAdd = mFunc; EnableDebugPriv();//提权 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);// 打开被注入的进程 ThreadAdd = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); BO = WriteProcessMemory(hProcess, ThreadAdd, mFunc, 4096, &lpNumberOfBytes); //写入函数地址 if (ParamSize != 0) { ParamAdd = VirtualAllocEx(hProcess, NULL, ParamSize, MEM_COMMIT, PAGE_READWRITE); BO = WriteProcessMemory(hProcess, ParamAdd, pRemoteParam, ParamSize, &lpNumberOfBytes); //写入参数地址 } hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ThreadAdd, ParamAdd, 0, &lpNumberOfBytes); //创建远程线程 WaitForSingleObject(hThread, INFINITE);// 等待线程结束 VirtualFreeEx(hProcess, ThreadAdd, 4096, MEM_RELEASE); if (ParamSize != 0) { VirtualFreeEx(hProcess, ParamAdd, ParamSize, MEM_RELEASE); //释放申请的地址 } CloseHandle(hThread); CloseHandle(hProcess); return TRUE; } VOID InjectSellCode(HWND hwnd, BYTE SellCode[]) { EnableDebugPriv(SE_DEBUG_NAME); //CHAR pathStr[0x1000] = { "K:\我的文档\visual studio 2012\Projects\InjectChat\Debug\WeChatDll.dll" }; DWORD processid = NULL; GetWindowThreadProcessId(hwnd, &processid);//获取进程id if (processid == 0) { MessageBox(NULL, "没有找到微信进程或者微信没有启动", "错误", 0); return; } HANDLE hProcsee = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processid); if (hProcsee == NULL) { MessageBox(NULL, "没有找到微信进程", "错误", 0); return; } //LPVOID dllAdd = VirtualAllocEx(hProcsee, NULL, 1024, MEM_COMMIT| MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);//64位申请空间的时候可能会有bug LPVOID dllAdd = VirtualAllocEx(hProcsee, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//64位申请空间的时候可能会有bug if (dllAdd == NULL) { MessageBox(NULL, "内存申请失败", "0", 0); } if (WriteProcessMemory(hProcsee, dllAdd, SellCode, 1023, NULL) == 0) { //可能这里的问题 MessageBox(NULL, "内存写入", "错误", 0); return; } printf("申请的内存空间是 %llx ", dllAdd); HANDLE exec = CreateRemoteThread(hProcsee, NULL, 0, (LPTHREAD_START_ROUTINE)dllAdd, NULL, 0, NULL); //有一个参数的 if (NULL == exec) { MessageBox(NULL, "远程注入失败", "错误", 0); return; } //WaitForSingleObject(exec, INFINITE); CloseHandle(hProcsee); } BOOL UnloadDll(DWORD dwPid, CHAR strDllName[256]) { //获取宿主进程的句柄,注意那几个参数,不然会出错 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (hProcess == NULL) { ::MessageBox(NULL, "无法获取进程句柄", "错误", MB_OK | MB_ICONERROR); return FALSE; } DWORD dwSize = 0; DWORD dwWritten = 0; DWORD dwHandle = 0; dwSize = sizeof(strDllName)+1;//dll的全路径名的长度,待会分配内存要用到的 //向宿主进程分配内存,返回一个指针 LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); //如果在宿主进程空间写失败就直接报错闪人 if (!WriteProcessMemory(hProcess, lpBuf, strDllName, dwSize, (SIZE_T*)&dwWritten)) { VirtualFreeEx(hProcess, lpBuf, dwSize, MEM_DECOMMIT); CloseHandle(hProcess); MessageBox(NULL, "在目标进程中写入失败", "错误", MB_OK | MB_ICONERROR); return FALSE; } //获取GetModuleHandleA函数地址 LPVOID pFun = GetProcAddress(GetModuleHandle("Kernel32"), "GetModuleHandleA"); //在宿主进程中创建一个远程线程,线程函数为上面导出的GetModuleHandleA,参数为lpBuf指针,还 //记得我们获取的dll全路径不 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFun, lpBuf, 0, NULL); //如果创建线程失败,直接报错闪人 if (hThread == NULL) { CloseHandle(hProcess); ::MessageBox(NULL, "在目标进程创建远程线程失败", "错误", MB_OK | MB_ICONERROR); return FALSE; } // 等待GetModuleHandle运行完毕 WaitForSingleObject(hThread, INFINITE); // 获得GetModuleHandle的返回值 GetExitCodeThread(hThread, &dwHandle); // 释放目标进程中申请的空间 VirtualFreeEx(hProcess, lpBuf, dwSize, MEM_DECOMMIT); CloseHandle(hThread); // 使目标进程调用FreeLibraryAndExit,卸载DLL,实际也可以用FreeLibrary,但是我发现前者好一点 pFun = GetProcAddress(GetModuleHandle("Kernel32"), "FreeLibraryAndExitThread"); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFun, (LPVOID)dwHandle, 0, NULL); // 等待FreeLibraryAndExitThread执行完毕 WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; //操作成功 } //提升进程访问权限 bool enableDebugPriv() { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) { return false; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) { CloseHandle(hToken); return false; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) { CloseHandle(hToken); return false; } return true; } //======================================结尾部分 HANDLE GetModule() { HANDLE hProcess; //进程句柄 HANDLE hModule; //模块句柄 BOOL bProcess = FALSE; //获取进程信息的函数返回值 BOOL bModule = FALSE; //获取模块信息的函数返回值 PROCESSENTRY32 pe32; //保存进程信息 MODULEENTRY32 me32; //保存模块信息 int i = 0; int j = 0; //获取进程调试权限,如果失败,则提示获取权限失败,失败的话,有的进程信息就会获取不到 if (EnableDebugPriv(SE_DEBUG_NAME)) { fprintf(stderr, "Add Privilege error "); } hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获取进程快照 if (hProcess == INVALID_HANDLE_VALUE) { printf("获取进程快照失败 "); exit(1); } bProcess = Process32First(hProcess, &pe32); //获取第一个进程信息 while (bProcess) //循环获取其余进程信息 { printf("%d : Father's PID(%d) PID(%d) %s ", i, pe32.th32ParentProcessID, pe32.th32ProcessID, pe32.szExeFile); i++; j = 0; if (0 != pe32.th32ParentProcessID) //获取进程PID不为0的模块信息 { hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe32.th32ProcessID); //获取模块快照 if (hModule != INVALID_HANDLE_VALUE) { bModule = Module32First(hModule, &me32); //获取第一个模块信息,即进程相应可执行文件的信息 while (bModule) { printf("模块: %d %s ", j, me32.szExePath); j++; bModule = Module32Next(hModule, &me32); //获取其他模块信息 } CloseHandle(hModule); } } bProcess = Process32Next(hProcess, &pe32); //继续获取其他进程信息 printf(" "); getchar(); } CloseHandle(hProcess); return 0; } PVOID GetRemoteProcAddress32(HANDLE hProc, HMODULE hModule, LPCSTR lpProcName)//这个函数只支持32位的 { PVOID pAddress = NULL; SIZE_T OptSize; IMAGE_DOS_HEADER DosHeader; SIZE_T ProcNameLength = lstrlenA(lpProcName) + sizeof(CHAR);//'' //读DOS头 if (ReadProcessMemory(hProc, hModule, &DosHeader, sizeof(DosHeader), &OptSize)) { IMAGE_NT_HEADERS NtHeader; //读NT头 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + DosHeader.e_lfanew), &NtHeader, sizeof(NtHeader), &OptSize)) { IMAGE_EXPORT_DIRECTORY ExpDir; SIZE_T ExportVirtualAddress = NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; //读输出表 if (ExportVirtualAddress && ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExportVirtualAddress), &ExpDir, sizeof(ExpDir), &OptSize)) { if (ExpDir.NumberOfFunctions) { //x64待定:地址数组存放RVA的数据类型是4字节还是8字节??? SIZE_T *pProcAddressTable = (SIZE_T *)GlobalAlloc(GPTR, ExpDir.NumberOfFunctions * sizeof(SIZE_T)); //读函数地址表 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfFunctions), pProcAddressTable, ExpDir.NumberOfFunctions * sizeof(PVOID), &OptSize)) { //x64待定:名称数组存放RVA的数据类型是4字节还是8字节??? SIZE_T *pProcNamesTable = (SIZE_T *)GlobalAlloc(GPTR, ExpDir.NumberOfNames * sizeof(SIZE_T)); //读函数名称表 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNames), pProcNamesTable, ExpDir.NumberOfNames * sizeof(PVOID), &OptSize)) { CHAR *pProcName = (CHAR *)GlobalAlloc(GPTR, ProcNameLength); //遍历函数名称 for (DWORD i = 0; i < ExpDir.NumberOfNames; i++) { if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + pProcNamesTable[i]), pProcName, ProcNameLength, &OptSize)) { if (RtlEqualMemory(lpProcName, pProcName, ProcNameLength)) { //x64待定:函数在地址数组索引的数据类型是2字节还是??? WORD NameOrdinal; //获取函数在地址表的索引 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNameOrdinals + sizeof(NameOrdinal)* i), &NameOrdinal, sizeof(NameOrdinal), &OptSize)) { pAddress = (PVOID)((SIZE_T)hModule + pProcAddressTable[NameOrdinal]); } break;//for } } } GlobalFree(pProcName); } GlobalFree(pProcNamesTable); } GlobalFree(pProcAddressTable); } } } } return pAddress; }
MemoryUtil.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
HMODULE GetModuleBaseAddr(DWORD Pid, CONST TCHAR* moduleName);//获取进程模块入口地址 int ReadInt(DWORD ProcessID, DWORD addr); DWORD GetPidByHwnd(HWND hwnd); VOID InjectSellCode(HWND hwnd, BYTE SellCode[]); VOID InjectDll(const CHAR pathStr[0x1000], const CHAR ProcessName[256]); bool enableDebugPriv(); int EnableDebugPriv(const char *name); PVOID GetRemoteProcAddress32(HANDLE hProc, HMODULE hModule, LPCSTR lpProcName);//获取x64模块基地址,目前只支持32位基地址 DWORD GetModuleSizeX64(DWORD Pid, const TCHAR* ModuleName);//获取模块大小,只能搞64位=64位,32位无法对64位操作 HMODULE GetModuleBaseX64(DWORD Pid, const TCHAR* ModuleName);//获取x64程序模块基地址 DWORD GetPidByName(const char * ProcessName); //================提升程序的权限====================== BOOL EnableSeDebugPrivilege(IN const CHAR * PriviledgeName, BOOL IsEnable); typedef NTSTATUS(NTAPI *LPFN_NTWOW64READVIRTUALMEMORY64)( IN HANDLE ProcessHandle, IN ULONG64 BaseAddress, OUT PVOID BufferData, IN ULONG64 BufferLength, OUT PULONG64 ReturnLength OPTIONAL); typedef NTSTATUS(NTAPI *LPFN_NTWOW64WRITEVIRTUALMEMORY64)( IN HANDLE ProcessHandle, IN ULONG64 BaseAddress, OUT PVOID BufferData, IN ULONG64 BufferLength, OUT PULONG64 ReturnLength OPTIONAL); extern LPFN_NTWOW64READVIRTUALMEMORY64 __NtWow64ReadVirtualMemory64; //全局变量 extern LPFN_NTWOW64WRITEVIRTUALMEMORY64 __NtWow64WriteVirtualMemory64; //全局变量 #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) //==============================================x86x64内存读写===================================================== BOOL GetNTWOW64MemoryProcAddress();//wow64函数指针获取 char* UTF8ToUnicode(char* szUTF8);//编码转换 char* UnicodeToUTF8(wchar_t* wszcString);//编码转换 int Wow64ReadInt(ULONG ProcessID, ULONG64 BaseAddress);//驱动读取4字节整数 char * Wow64ReadAscii(ULONG ProcessID, ULONG64 BaseAddress, DWORD Len); //驱动读取ANSI编码 wchar_t * Wow64ReadUnicode(ULONG ProcessID, ULONG64 BaseAddress, DWORD Len); // 驱动读取unicode编码 float Wow64ReadFloat(ULONG ProcessID, ULONG64 BaseAddress);//驱动读取浮点数 double Wow64ReadDouble(ULONG ProcessID, ULONG64 BaseAddress);//驱动读取双精度浮点数 LONG64 Wow64ReadInt64(ULONG ProcessID, ULONG64 BaseAddress); //驱动读取8字节整数 BOOL Wow64WriteInt(ULONG ProcessID, ULONG64 BaseAddress, INT Value); //驱动写入整数 BOOL Wow64WriteFloat(ULONG ProcessID, ULONG64 BaseAddress, FLOAT Value); //驱动写入浮点数 BOOL Wow64WriteDouble(ULONG ProcessID, ULONG64 BaseAddress, DOUBLE Value); //驱动写入双精度浮点数 BOOL Wow64WriteInt64(ULONG ProcessID, ULONG64 BaseAddress, INT64 Value); //驱动写入8字节整数 BOOL Wow64WriteAscii(ULONG ProcessID, ULONG64 BaseAddress, const char* Value);//驱动写入ansi编码 BOOL Wow64WriteUTF8(ULONG ProcessID, ULONG64 BaseAddress, const wchar_t * GBK_Str); //驱动写入utf8编码 BOOL Wow64WriteUnicode(ULONG ProcessID, ULONG64 BaseAddress, const wchar_t * Value); //驱动写入unicode编码 //===============================x86 r3层普通API 内存读写================================================= BOOL WriteInt64(DWORD ProcessID, DWORD Addr, __int64 Value); BOOL WriteInt(DWORD ProcessID, DWORD Addr, int Value); BOOL WriteShort(DWORD ProcessID, DWORD Addr, short Value); BOOL WriteByte(DWORD ProcessID, DWORD Addr, byte Value); // BOOL WriteFloat(DWORD ProcessID, DWORD Addr, float Value); BOOL WriteDouble(DWORD ProcessID, DWORD Addr, double Value); BOOL WriteAcsii(DWORD ProcessID, DWORD Addr, const char * str); BOOL WriteUnicode(DWORD ProcessID, DWORD Addr, const wchar_t * str); BOOL WriteUnicode(DWORD ProcessID, DWORD Addr, wchar_t * str); DWORD GetPidByHwnd(HWND hwnd); DWORD FloatToDword(float value); QWORD DoubleToDword(double value); int Int64To32(__int64 value); int DwordToInt(DWORD value); DWORD IntToDword(int value); BOOL WriteIntEx(DWORD ProcessID, DWORD Addr, __int64 Value, int NumByte); byte ReadByte(DWORD ProcessID, DWORD addr); short ReadShort(DWORD ProcessID, DWORD addr); int ReadInt(DWORD ProcessID, DWORD addr); DWORD ReadDword(DWORD ProcessID, DWORD addr); __int64 ReadInt64(DWORD ProcessID, DWORD addr); void * ReadAscii(DWORD ProcessID, DWORD addr, DWORD Len); wchar_t * ReadUnicode(DWORD ProcessID, DWORD addr, DWORD Len); int ReadIntEx(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num); float ReadFloatEx(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num); double ReadDoubleEx(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num); __int64 ReadIntEx64(DWORD ProcessID, DWORD BaseAddr, DWORD OffsetArray[], DWORD Num); //======================================注入============================ VOID InjectDll(const CHAR pathStr[0x1000], const CHAR ProcessName[256]); VOID InjectSellCode(HWND hwnd, BYTE SellCode[]); BOOL UnloadDll(DWORD dwPid, CHAR strDllName[256]); //参数 1. 进程 ID //参数 2. 被注入函数指针 <函数名 > //参数 3. 参数 //参数 4. 参数长度 BOOL InjectRemoteFunc(DWORD dwProcId, LPVOID mFunc, LPVOID pRemoteParam, DWORD ParamSize); //==========================测试专用=========================== //提升进程访问权限 int EnableDebugPriv(const char *name); bool enableDebugPriv(); HANDLE GetModule(); PVOID GetRemoteProcAddress32(HANDLE hProc, HMODULE hModule, LPCSTR lpProcName);