//#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, &stcModuleInfo, sizeof(stcModuleInfo));
                GetModuleBaseNameA(hProcess, pModuleHandlerArr, szBaseName, MAX_PATH);
                //printf("\n%x\n", (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, &stcModuleInfo, sizeof(stcModuleInfo));

                // 根据进程句柄和模块句柄,获取模块的路径(包括模块名)
                //GetModuleFileNameEx(hProcess, pModuleHandlerArr, szModuleName, MAX_PATH); //获取模块的路径
                GetModuleBaseNameA(hProcess, pModuleHandlerArr, szBaseName, MAX_PATH);
                printf("\n%x\n", (DWORD)stcModuleInfo.lpBaseOfDll); //获取模块基地址
                printf("\n%x\n", (DWORD)stcModuleInfo.EntryPoint); //获取模块入口地址
                printf("\n%x\n", (DWORD)stcModuleInfo.SizeOfImage); //模块内存大小

                if (strcmp(szBaseName, ModuleName) == 0)
                {
                        printf("基地址是:%s\n\n", szBaseName);
                        printf("基地址是:%X\n\n", (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 \n", (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 \n", (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\n", __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] = '\0';
        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] = '\0';
        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] = '\0';
        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\r\n", BufferData);

        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                printf("异常\r\n");
                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 \n", BufferData);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                printf("异常\r\n");
                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 \n", BufferData);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                printf("异常\r\n");
                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 \n", BufferData);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                printf("异常\r\n");
                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 \n", BufferData);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                printf("异常\r\n");
                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\r\n", BufferData);

        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                printf("异常\r\n");
                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("异常\r\n");
                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("异常\r\n");
                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("异常\r\n");
                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("异常\r\n");
                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\n", 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("异常\r\n");
                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\n", 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("异常\r\n");
                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\n", 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("异常\r\n");
                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("获取进程句柄失败\n");
        }
        else
        {
                printf("获取进程句柄成功\n");
        }
        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("获取进程句柄失败\n");
        }
        else
        {
                printf("获取进程句柄成功\n");
        }

        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("获取进程句柄失败\n");
        }
        else
        {
                //printf("获取进程句柄成功\n");
        }
        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("获取进程句柄失败\n");
        }
        else
        {
                //printf("获取进程句柄成功\n");
        }
        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("获取进程句柄失败\n");
        }
        else
        {
                //printf("获取进程句柄成功\n");
        }
        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 \n", game_pid);
        HANDLE  Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局   
        if (Process_handle == NULL)
        {
                printf("获取进程句柄失败\n");
        }
        else
        {
                printf("获取进程句柄成功\n");
        }
        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("获取进程句柄失败\n");
        }
        else
        {
                printf("获取进程句柄成功\n");
        }
        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("获取进程句柄失败\n");
        }
        else
        {
                printf("获取进程句柄成功\n");
        }
        BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, wcslen(str) * 2 + 2, NULL);//wcslen宽字符长度+2
        printf("iiiiiiiiiii    %d\n", 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("获取进程句柄失败\n");
        }
        else
        {
                printf("获取进程句柄成功\n");
        }
        BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, wcslen(str) * 2 + 2, NULL);//wcslen宽字符长度+2
        printf("iiiiiiiiiii    %d\n", 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("获取进程句柄失败\n");
        else
                printf("获取进程句柄成功\n");
        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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");
                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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");
                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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");
                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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");
                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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");
                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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");

                for (size_t i = 0; i < 1024; i++)//遍历长度,上限1024
                {
                        ReadProcessMemory(Hprocess, (LPCVOID)(addr + i), &ByteBuffer, 1, NULL);//注意参数 4字节
                        //printf("遍历I数值!  %d  \n", i);
                        if (ByteBuffer == 0)
                        {
                                if (Len == 0)//如果是0自动长度
                                {
                                        ReadProcessMemory(Hprocess, (LPCVOID)(addr), &Value, i + 1, NULL); //   字节\0
                                        break;

                                }
                                else {
                                        ReadProcessMemory(Hprocess, (LPCVOID)(addr), &Value, Len, NULL); //   字节\0
                                        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("打开进程失败!\n");
        else
        {
                printf("打开进程成功!\n");

                for (size_t i = 0; i < 1024; i = i + 2)//遍历长度,上限1024
                {
                        ReadProcessMemory(Hprocess, (LPCVOID)(addr + i), &ShortBuffer, 2, NULL);//注意参数 4字节
                        if (ShortBuffer == '\0')
                        {
                                if (Len == 0)//如果是0自动长度
                                {
                                        ReadProcessMemory(Hprocess, (LPCVOID)(addr), &StrValue, i + 2, NULL); //   字节\0
                                        printf("打印    %s  \n", StrValue);
                                        //printf("打印i  :  %d  \n", i);
                                        break;
                                }
                                else {
                                        ReadProcessMemory(Hprocess, (LPCVOID)(addr), &StrValue, Len, NULL); //   字节\0
                                        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), &Value, 4, NULL);//注意参数 4字节
                }
        }
        else         printf("打开进程失败!\n");
        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\n", Value);
                        ReadProcessMemory(Hprocess, (LPVOID)(Value + OffsetArray), &Value, 4, NULL);//注意参数 4字节
                }
        }
        else         printf("打开进程失败!\n");
        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), &nBuffer, 4, NULL);//注意参数 4字节
        /*                printf("double       %x\n", OffsetArray);*/
                }
                ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray), &ValueDouble, 8, NULL);//Value64最终结果
        }
        else         printf("打开进程失败!\n");
        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), &nBuffer, 4, NULL);//注意参数 4字节
        /*                printf("double       %x\n", OffsetArray);*/
                }
                ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray), &value64, 8, NULL);//Value64最终结果
        }
        else         printf("打开进程失败!\n");
        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\n");
                return -1;
        }
        //获得本地进程name所代表的权限类型的局部唯一ID
        if (!LookupPrivilegeValue(NULL, name, &luid))
        {
                fprintf(stderr, "LookupPrivilegeValue error\n");
        }

        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!\n");
                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);
}

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\n", 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\n");
        }

        hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获取进程快照
        if (hProcess == INVALID_HANDLE_VALUE)
        {
                printf("获取进程快照失败\n");
                exit(1);
        }

        bProcess = Process32First(hProcess, &pe32);              //获取第一个进程信息
        while (bProcess)                                         //循环获取其余进程信息
        {
                printf("%d :\t Father's PID(%d)\tPID(%d)\t%s\n", 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("模块:\n%d\t%s\n", j, me32.szExePath);
                                        j++;
                                        bModule = Module32Next(hModule, &me32);  //获取其他模块信息
                                }
                                CloseHandle(hModule);
                        }
                }

                bProcess = Process32Next(hProcess, &pe32);           //继续获取其他进程信息
                printf("\n\n");
                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);//'\0'  

        //读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), 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;
}

https://blog.csdn.net/u013761036/article/category/6748673/2

https://bbs.pediy.com/thread-253379.htm

[转帖]大家分析分析C++ X64X86通用驱动读写API源码教程的更多相关文章

  1. Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装

    原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底 ...

  2. Spring源码分析之IOC的三种常见用法及源码实现(二)

    Spring源码分析之IOC的三种常见用法及源码实现(二) 回顾上文 我们研究的是 AnnotationConfigApplicationContext annotationConfigApplica ...

  3. Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)

    事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...

  4. [源码分析]Java1.8中StringJoiner的使用以及源码分析

    [源码分析]StringJoiner的使用以及源码分析 StringJoiner是Java里1.8新增的类, 或许有一部分人没有接触过. 所以本文将从使用例子入手, 分析StringJoiner的源码 ...

  5. 如何高效地分析Android_log中的问题?——查看Android源码

    在日常解bugs时,需要通过log日志来分析问题,例如查看crash发生时的堆栈信息时,就会有Android的源码的调用,这是就要去查看Android源码. 1.进入Android源码网址查看,例如  ...

  6. Spring源码分析之IOC的三种常见用法及源码实现(一)

    1.ioc核心功能bean的配置与获取api 有以下四种 (来自精通spring4.x的p175) 常用的是前三种 第一种方式 <?xml version="1.0" enc ...

  7. Spring源码分析之IOC的三种常见用法及源码实现(三)

    上篇文章我们分析了AnnotationConfigApplicationContext的构造器里refresh方法里的invokeBeanFactoryPostProcessors,了解了@Compo ...

  8. DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用

    CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()),  --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...

  9. Spring事务源码分析专题(一)JdbcTemplate使用及源码分析

    Spring中的数据访问,JdbcTemplate使用及源码分析 前言 本系列文章为事务专栏分析文章,整个事务分析专题将按下面这张图完成 对源码分析前,我希望先介绍一下Spring中数据访问的相关内容 ...

随机推荐

  1. Spark SQL中Not in Subquery为何低效以及如何规避

    首先看个Not in Subquery的SQL: // test_partition1 和 test_partition2为Hive外部分区表 select * from test_partition ...

  2. 在swoole中制作一款仿制laravel的框架

    首先需要确定一下思路:我希望基于swoole的扩展开发的代码在run起来的时候,在接收到ws或是tcp等消息时,自动路由到某个类上,同时类可以实现加载类的依赖注入功能.目前市面上占据主流的一款框架La ...

  3. 安装anaconda和第三方库tushare

    安装anaconda和第三方库tushare 血泪教训 下载32位的anaconda(同你Python版本,不然会碰到第三方库无法import的问题) 安装anaconda 安装到C盘会比较快,安装到 ...

  4. Hexagon HDU - 6862

    题目链接:https://vjudge.net/problem/HDU-6862 题意: 由六边形组成的圆形图案,要求不重复走遍历每一个小六边形. 思路:https://www.cnblogs.com ...

  5. 【PAT甲级】1119 Pre- and Post-order Traversals(前序后序转中序)

    [题目链接] [题意] 根据二叉树的前序和后序序列,如果中序序列唯一,输出Yes,如果不唯一输出No,并输出这个中序序列. [题解] 众所周知,二叉树是不能够根据前序和中序建立的,为什么呢?首先需要明 ...

  6. 【java框架】SpringBoot(3) -- SpringBoot集成Swagger2

    1.SpringBoot web项目集成Swagger2 1.1.认识Swagger2 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体 ...

  7. PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642 题目描述: People in Mars represent the c ...

  8. 【数据结构与算法笔记04】对图搜索策略的一些思考(包括DFS和BFS)

    图搜索策略 这里的"图搜索策略"应该怎么理解呢? 首先,是"图搜索",所谓图无非就是由节点和边组成的,那么图搜索也就是将这个图中所有的节点和边都访问一遍. 其次 ...

  9. java面试-JVM调优和参数配置,如何查看JVM系统参数默认值

    一.JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式(先编译后执行) -Xint  解释执行 -Xcomp 第一次使用就编译 ...

  10. Dynamics CRM与ADFS安装到同一台服务器后ADFS服务与Dynamics CRM沙盒服务冲突提示808端口占用问题

    当我们安装Dynamics CRM的产品时如果是单台服务器部署而且部署了IFD的情况会遇到一个问题就是ADFS服务的监听端口和Dynamics CRM沙盒服务的端口冲突了. 这样会导致两个服务中的一个 ...