微遇 2023-12-06 02:07 采纳率: 23.5%
浏览 29
已结题

用C语言写的一个程序遇到了两个问题第一是偏移正确但读取不到坐标,第二个问题是自己定义的函数实现不了获取指定进程模块。

用C语言写的一个程序遇到了两个问题第一是偏移正确但读取不到坐标,第二个问题是自己定义的函数实现不了获取指定进程模块。


```c
#include <iostream>
#include <Windows.h>
#include <graphics.h>
#include<psapi.h>
#include <string>
struct 敌人 {
    float x, y, z;
}敌人_1;
int 窗口高度 = 0;
int 窗口宽度 = 0;
int 视角宽 = 0;
int 视角高 = 0;
DWORD 矩阵数据_1[4][4] = {{0x02C20100,0x02C20104,0x02C20108,0x02C2010C},
                          {0x02C20110,0x02C20114,0x02C20118,0x02C2011C},
                          {0x02C20120,0x02C20124,0x02C20128,0x02C2012C},
                          {0x02C20130,0x02C20134,0x02C20138,0x02C2013C}};
float 矩阵数据_2[4][4];
DWORD 敌人基址 = 0;
DWORD 矩阵地址 = 0x02C20100;
DWORD 游戏基地址_1 = 0x1400000;
DWORD 游戏基地址_2_偏移_1 = 0x182C5C4;
DWORD 敌人基址数值_1 = 0;
DWORD 敌人基址数值_2 = 0;
DWORD 敌人基地址_1_偏移_1 = 0x90;
DWORD 敌人基地址_1_偏移_1_数值 = 0;
DWORD 模块基址 = 0x20B60000;
HMODULE 获取模块(HANDLE hProcess,char 模块[]) {
    HMODULE hModule[300] = { 0 };
    DWORD dwRet = 0;
    int ret = 0;
    ret = K32EnumProcessModulesEx(hProcess, (HMODULE*)hModule, sizeof hModule, &dwRet, LIST_MODULES_ALL);
    int num = dwRet / sizeof HMODULE;
    std::cout << "目标进程总模块个数: " << num << std::endl;
    for (int i = 0; i < num; i++)
    {
        char ModuleName[300];
        K32GetModuleBaseNameA(hProcess, hModule[i], ModuleName, 100);
        std::cout << i << "    " << "模块名: " << ModuleName << " 基址:" << hModule[i] << std::endl;
        if (模块 == ModuleName) {
            return hModule[i];
        }
    }
    return 0;
}
void 世界坐标转换屏幕坐标(HANDLE hProcess) {
    double  相机Z = 0, 缩放比列 = 0, 相机X = 0, 相机Y = 0, 相机Y2 = 0, 方框高度 = 0, 方框宽度 = 0;
    int i;
    int i2;
    for (i=0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            ReadProcessMemory(hProcess, LPCVOID(矩阵数据_1[i][j]), LPVOID(&矩阵数据_2[i][j]), 64, NULL);
        }
    }
    i2 = 1;
    for(int i=1;i<20;i++){

        ReadProcessMemory(hProcess, LPCVOID(模块基址 + 0x97260), LPVOID(&敌人基址), sizeof(DWORD), NULL);
        printf("敌人基地址:%d\n", 敌人基址);
        ReadProcessMemory(hProcess, LPCVOID(敌人基址 + (i - 1) * 0x230), LPVOID(&敌人基址数值_1), sizeof(DWORD), NULL);
        printf("敌人基址数值_1:%d\n", 敌人基址数值_1);
        ReadProcessMemory(hProcess, LPCVOID(敌人基址数值_1 + 0x88), LPVOID(&敌人_1.x), sizeof(DWORD), NULL);
        printf("x:%f\n",敌人_1.x);
        ReadProcessMemory(hProcess, LPCVOID(敌人基址数值_1 + 0x8C), LPVOID(&敌人_1.y), sizeof(DWORD), NULL);
        printf("y:%f\n", 敌人_1.y);
        ReadProcessMemory(hProcess, LPCVOID(敌人基址数值_1 + 0x90), LPVOID(&敌人_1.z), sizeof(DWORD), NULL);
        printf("z:%f\n", 敌人_1.z);
        视角宽 = 窗口宽度 / 2;
        视角高 = 窗口高度 / 2;
        相机Z = 矩阵数据_2[0][2] * 敌人_1.x + 矩阵数据_2[1][2] * 敌人_1.y + 矩阵数据_2[2][2] * 敌人_1.z + 矩阵数据_2[3][2];
        if (相机Z < 0.01)
            continue;
        缩放比列 = 1 / 相机Z;
        相机X = 视角宽 + (矩阵数据_2[0][0] * 敌人_1.x + 矩阵数据_2[1][0] * 敌人_1.y + 矩阵数据_2[2][0] * 敌人_1.z + 矩阵数据_2[3][0]) * 缩放比列 * 视角宽;
        相机Y = 视角高 - (矩阵数据_2[0][1] * 敌人_1.x + 矩阵数据_2[1][1] * 敌人_1.y + 矩阵数据_2[2][1] * (敌人_1.z - 40) + 矩阵数据_2[3][1]) * 缩放比列 * 视角高;
        相机Y2 = 视角高 - (矩阵数据_2[0][1] * 敌人_1.x + 矩阵数据_2[1][1] * 敌人_1.y + 矩阵数据_2[2][1] * (敌人_1.z + 25) + 矩阵数据_2[3][1]) * 缩放比列 * 视角高;
        方框高度 = 相机Y2 - 相机Y;
        方框宽度 = 方框高度 * 0.45;
        setlinecolor(GREEN);
        line(视角宽, 0, 相机X, 相机Y);
        line(相机X - 方框宽度 / 2, 相机Y, 相机X + 方框宽度 / 2, 相机Y);
        line(相机X + 方框宽度 / 2, 相机Y, 相机X + 方框宽度 / 2, 相机Y + 方框高度);
        line(相机X + 方框宽度 / 2, 相机Y + 方框高度, 相机X - 方框宽度 / 2, 相机Y + 方框高度);
        line(相机X - 方框宽度 / 2, 相机Y + 方框高度, 相机X - 方框宽度 / 2, 相机Y);
        FlushBatchDraw();
        cleardevice();
    }
}
int main()
{
    
    HWND win = FindWindowA(NULL, "Counter-Strike");
    RECT rect;
    HMODULE 敌人基址 = 0;
    DWORD PID;
    char 模块[] = "amxmodx_mm.dll";
    GetWindowThreadProcessId(win, &PID);
    HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, PID);
    GetWindowRect(win, &rect);
    窗口宽度 = (rect.right - rect.left);
    窗口高度 = (rect.bottom - rect.top);
    HWND hwnd = initgraph(窗口宽度, 窗口高度, EX_NOCLOSE | EX_NOMINIMIZE | EX_SHOWCONSOLE);
    SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 窗口宽度, 窗口高度, SWP_SHOWWINDOW);
    SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & (~(WS_CAPTION | WS_SYSMENU | WS_SIZEBOX)));
    SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & (~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME)) | WS_EX_LAYERED | WS_EX_TOOLWINDOW);
    SetLayeredWindowAttributes(hwnd, 0x000000, 0, LWA_COLORKEY);
    
    while (1) {
        GetWindowRect(win, &rect);
        MoveWindow(hwnd, rect.left, rect.top, 窗口宽度, 窗口高度, 1);
        世界坐标转换屏幕坐标(hProcess);
    }
    //敌人基址 = 获取模块(hProcess,模块);
    //printf("%p", 敌人基址);
    return 0;
}



```

  • 写回答

12条回答 默认 最新

  • IT·陈寒 优质创作者: 编程框架技术领域 2023-12-06 15:48
    关注

    你提到的问题涉及到从其他进程中读取数据,需要确保你的程序有足够的权限来读取目标进程的内存。此外,使用 Windows API 函数时,应该确保函数调用成功,避免在获取数据失败时导致的问题。下面我对你的程序进行了一些修改,包括错误修正和一些改进:

    #include <iostream>
    #include <Windows.h>
    #include <graphics.h>
    #include <TlHelp32.h>
    #include <psapi.h>
    #include <string>
    
    using namespace std;
    
    struct 敌人 {
        float x, y, z;
    } 敌人_1;
    
    int 窗口高度 = 0;
    int 窗口宽度 = 0;
    int 视角宽 = 0;
    int 视角高 = 0;
    float 矩阵数据_2[4][4];
    
    DWORD 矩阵地址 = 0x02C20100;
    DWORD 敌人基址 = 0;
    DWORD 模块基址 = 0x20B60000;
    
    void 世界坐标转换屏幕坐标(HANDLE hProcess) {
        // ... 你的代码 ...
    }
    
    HMODULE 获取模块(HANDLE hProcess, const char* 模块) {
        HMODULE hModule[300] = { 0 };
        DWORD dwRet = 0;
        int ret = 0;
    
        ret = K32EnumProcessModulesEx(hProcess, (HMODULE*)hModule, sizeof hModule, &dwRet, LIST_MODULES_ALL);
        int num = dwRet / sizeof HMODULE;
        cout << "目标进程总模块个数: " << num << endl;
    
        for (int i = 0; i < num; i++) {
            char ModuleName[300];
            K32GetModuleBaseNameA(hProcess, hModule[i], ModuleName, 100);
            cout << i << "    " << "模块名: " << ModuleName << " 基址:" << hModule[i] << endl;
    
            if (strcmp(模块, ModuleName) == 0) {
                return hModule[i];
            }
        }
    
        return nullptr;
    }
    
    int main() {
        HWND win = FindWindowA(NULL, "Counter-Strike");
        RECT rect;
    
        DWORD PID;
        char 模块[] = "amxmodx_mm.dll";
        GetWindowThreadProcessId(win, &PID);
        HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, PID);
    
        if (hProcess == nullptr) {
            cerr << "无法打开进程,错误码: " << GetLastError() << endl;
            return 1;
        }
    
        HMODULE 敌人基址 = 获取模块(hProcess, 模块);
    
        if (敌人基址 == nullptr) {
            cerr << "未找到目标模块" << endl;
            CloseHandle(hProcess);
            return 1;
        }
    
        GetWindowRect(win, &rect);
        窗口宽度 = (rect.right - rect.left);
        窗口高度 = (rect.bottom - rect.top);
    
        HWND hwnd = initgraph(窗口宽度, 窗口高度, EX_NOCLOSE | EX_NOMINIMIZE | EX_SHOWCONSOLE);
    
        if (hwnd == 0) {
            cerr << "初始化图形窗口失败" << endl;
            CloseHandle(hProcess);
            return 1;
        }
    
        SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 窗口宽度, 窗口高度, SWP_SHOWWINDOW);
        SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & (~(WS_CAPTION | WS_SYSMENU | WS_SIZEBOX)));
        SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & (~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME)) | WS_EX_LAYERED | WS_EX_TOOLWINDOW);
        SetLayeredWindowAttributes(hwnd, 0x000000, 0, LWA_COLORKEY);
    
        while (true) {
            GetWindowRect(win, &rect);
            MoveWindow(hwnd, rect.left, rect.top, 窗口宽度, 窗口高度, 1);
            世界坐标转换屏幕坐标(hProcess);
        }
    
        CloseHandle(hProcess);
        return 0;
    }
    

    在这个修改中,我添加了一些错误处理和更改了部分函数的参数类型。请注意,我还增加了对 OpenProcess 的返回值的检查,以确保成功打开目标进程。在实际使用时,请确保你的程序有足够的权限来读取其他进程的内存。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(11条)

报告相同问题?

问题事件

  • 系统已结题 12月14日
  • 已采纳回答 12月6日
  • 创建了问题 12月6日