IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]C++实现获取DOTA玩家名称(反汇编查找指针地址和跨进程读取war3内存)

    linger2012liu发表于 2016-12-29 23:29:16
    love 0

                   C++实现获取DOTA玩家名称(反汇编查找指针地址和跨进程读取war3内存)

       大学时做了一个类似11小秘书的工具,就是一键查看当前玩家的11天梯积分。其中,获取DOTA玩家名称是其中一个模块,这部分代码之前没公布,现在发出来共享给各位编程爱好者。

      其中的思路是,先用反汇编技术把DOTA玩家名称的内存地址找出来,然后用C++实现跨进程内存读取。记得当时,找内存地址找了很久,因为当时不懂反汇编,就瞎搞。主要思路是,一次次在DOTA游戏打开查看玩家名称那个窗口,这时候用CE跟踪WAR3的内存访问(窗口显示玩家名称,肯定访问了对应的地址),就这样一次次,跟踪了很久,终于被我找到了。这是当时的截图。
      


    这是当时打电脑的玩家名称的截图。

    找到内存地址就好办了,直接上代码。


    /*
    author:linger
    blog:linger.devhub.com
    */
    #include<windows.h>
    #include <iostream>
    #include<vector>
    using namespace std;
    void EnableDebugPriv(); 
    void coutName(DWORD id,HANDLE hProc);
    int main()
    {
       SetConsoleTitle("预言帝linger");
       DWORD PID = 0;
       puts("正在检验Warcraft 3是否已启动");
       HWND hw = FindWindowA("Warcraft III", NULL); 
       while(hw == NULL)
       {
        Sleep(1000); 
        puts("Warcraft 3未启动,请启动");
        hw = FindWindowA("Warcraft III", NULL);
       }
       puts("Warcraft 3已启动");
       LPDWORD lp = NULL;
       lp = &PID;
       GetWindowThreadProcessId(hw,lp);
       
       EnableDebugPriv(); 
       
       HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
       if(hProc)
       {
        puts("打开进程成功");
       }
       else 
       {
       puts("打开进程失败");
      
       } 
       int id[]={1,2,3,4,5,7,8,9,10,11};
       int i;
       for(i=0;i<10;i++)
       coutName(id[i],hProc);
    
        system("PAUSE");
        return 0;
    }
    void coutName(DWORD id,HANDLE hProc)
    {
         
       DWORD byread;
       
       LPCVOID pbase1=(LPCVOID)0x6facd44c; 
       DWORD base2;
       ReadProcessMemory(hProc,pbase1,&base2,4,&byread);
       //printf("第一次读取%d字节数据\n",byread);
    
       DWORD first =0x58;
       first = first + 4*id;
       LPCVOID pbase2=(LPCVOID)(base2+first);    
       DWORD base3;
       ReadProcessMemory(hProc,pbase2,&base3,4,&byread);
       //printf("第二次读取%d字节数据\n",byread);   
    
       LPCVOID pbase3=(LPCVOID)(base3+0x2c);     
       DWORD base4;
       ReadProcessMemory(hProc,pbase3,&base4,4,&byread);
       //printf("第三次读取%d字节数据\n",byread);   
        
       LPCVOID pbase4=(LPCVOID)(base4+0x1c);     
       DWORD base5;
       ReadProcessMemory(hProc,pbase4,&base5,4,&byread);
      // printf("第四次读取%d字节数据\n",byread);    
        
      // printf("最后的地址是%x\n",base5); 
       
       CHAR name[50]={0};
    
    
       LPCVOID pbase5 = (LPCVOID)base5;
       ReadProcessMemory(hProc,pbase5,name,50,&byread);
        //printf("第五次读取%d字节数据\n",byread);
    
       
    
        int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
        wchar_t unicode[50];
        MultiByteToWideChar(CP_UTF8, 0, name, -1, &unicode[0], 50);
        setlocale(LC_CTYPE, "");    
        //setlocale(LC_CTYPE, "chs");  
        //ut<<" "<<endl;
        printf("玩家%ld:",id); 
        wprintf(L"%ls\n",unicode);
        printf("字符个数:");
        cout<<wcslen(unicode)<<endl;//wcslen返回宽字符的个数
        //strlen返回ANSI字符的个数
    }
    // enable the privilege necessary to patch the process
    void EnableDebugPriv()
    {
    
      //puts("提高dubug权限");
    
      HANDLE hToken;
    
      LUID sedebugnameValue;
    
      TOKEN_PRIVILEGES tkp;
    
      if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
      puts("获取进程访问令牌失败!");
    
    
    
      if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
      {
        CloseHandle(hToken);
      }
    
      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 );
    
      }
    
    
    }
    

    本文作者:linger

    本文连接:http://blog.csdn.net/lingerlanlan/article/details/53933133




沪ICP备19023445号-2号
友情链接