您的位置:首页 > 编程语言 > C语言/C++

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

2016-12-29 23:29 555 查看
               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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息