开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 11290|回复: 16
收起左侧

[原创视频分享] C++ X64X86通用驱动读写API源码教程

[复制链接]
结帖率:33% (2/6)
发表于 2019-7-8 22:11:19 | 显示全部楼层 |阅读模式   广东省广州市

C++逆向安全课程10.R3层调用内核API之NT函数x64汇编基础教程第5节: x64程序函数调用约定x64汇编基础教程第3节:了解64位CPU寄存器x64汇编基础教程第4节:x64位汇编扩展指令分析课程已上传B站 喜欢的可以去观看  在线观看  地址:  https://space.bilibili.com/416493426?spm_id_from=333.788.b_765f7570696e666f.1

//#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;
}




评分

参与人数 1好评 +1 精币 +2 收起 理由
kevin0830 + 1 + 2 支持开源~!感谢分享

查看全部评分


发表于 2020-7-30 06:52:16 | 显示全部楼层   吉林省延边朝鲜族自治州
回复 支持 反对

使用道具 举报

结帖率:100% (5/5)
发表于 2020-3-18 18:26:13 | 显示全部楼层   山东省枣庄市
教程挺好,希望能把课程更新完毕
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)
发表于 2019-12-2 03:58:31 | 显示全部楼层   福建省莆田市
看的我头大
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 18 天

发表于 2019-9-3 10:08:58 | 显示全部楼层   河北省石家庄市
{:4_256:学习
回复 支持 反对

使用道具 举报

发表于 2019-8-4 16:02:12 | 显示全部楼层   广东省中山市
看起来很有实力的样子 哈哈
回复 支持 反对

使用道具 举报

签到天数: 4 天

发表于 2019-7-28 08:30:37 | 显示全部楼层   广西壮族自治区钦州市
这个哪里是 驱动读写啊 明明是R3的
回复 支持 反对

使用道具 举报

发表于 2019-7-27 16:34:52 | 显示全部楼层   北京市北京市
支持开源 感谢分享
回复 支持 反对

使用道具 举报

发表于 2019-7-26 10:06:01 | 显示全部楼层   吉林省长春市
学习学习,LZ辛苦
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)
发表于 2019-7-24 07:51:42 | 显示全部楼层   山东省烟台市
让你打败了
回复 支持 反对

使用道具 举报

发表于 2019-7-17 15:25:11 | 显示全部楼层   福建省龙岩市
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表