// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <atlstr.h>
#pragma data_seg(".Share")
HWND g_hMainWnd=NULL;//主窗口句柄;
HANDLE gameHandle=NULL;//游戏进程句柄
HINSTANCE hInstDll=NULL;//本dll实例句柄;
DWORD g_dwHookPid=0;//要HOOK的进程的PID
BOOL g_bIsFirstLoad=TRUE;//判断是否是第一次加载本dll
FLOAT destCoordinate[3]={202,43,-374};//目的坐标 别弄错类型 double是八个字节 弄错类型 跑的地点是错误的
FLOAT destDirection[3] = {0,1,0};//方向可以随便写 主要是调用的第三个call 判断方向上有没有障碍物
DWORD ecxBaseAddr = 0x00ce1118;//第一个call的ecx隐性参数的基地址
DWORD ecxAddr = 0;//存放第一个call隐性参数ecx
#pragma data_seg()
#pragma comment(linker, "/section:.Share,rws")
BOOL OpenProc()
{
g_hMainWnd=::FindWindow(L"QElementClient Window",L"Element Client");
if(!g_hMainWnd)
{
MessageBox(0,L"找不到主窗口句柄 ",0,0);
return 0;
}
GetWindowThreadProcessId(g_hMainWnd,&g_dwHookPid); //获取进程ID
if(!g_dwHookPid)
{
MessageBox(0,L"找不到游戏id ",0,0);
return 0;
}
gameHandle=::OpenProcess(PROCESS_ALL_ACCESS,false,g_dwHookPid); //打开进程 失败的话 就要调用EnableDebugPrivilege 修改进程权限
if(!gameHandle){ //如果进程ID等于0 退出
CString str;
int err = GetLastError();
str.Format(L"找不到游戏句柄 错误原因%d",err);
MessageBox(0,str,0,0);
PostQuitMessage(0);
return 0;
}
return 1;
}
BOOL EnableDebugPrivilege()
{
HANDLE hToken;
BOOL fOk=FALSE;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))//获得进程的调试的令牌句柄,就是个类似于结构的对象,负责管理系统进程,安全进程等的权限,第二个参数是获得哪种类型的句柄 第三个是返回地址
{
TOKEN_PRIVILEGES tp;//AdjustTokenPrivileges必备参数
tp.PrivilegeCount=1;//第一个参数是数组成员数量 第二个参数书一个数组 里面每个都是一个结构 结构成员就是 luid(类似于uid 数字和对象之间的映射 通过数字可以找到对象 通过对象可以找到数字)和对应的操作类型
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);//只有调用他才能迅速找到操作类型的对应的luid,第一个参数是操作系统 null代表当前的系统 第二个是操作类型 第三个是返回地址
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;//吧数组成员的结构的第二个成员设置为puid对应的操作类型为调试类型
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);//第一个参数是令牌句柄 第二个是ture就会去除现有的的特权 第三个是要调整的tp 第四个是大小 第五个是保存之前的tp 第六个是返回的大小
fOk=(GetLastError()==ERROR_SUCCESS);
CloseHandle(hToken);
}
return fOk;
}
BOOL ReadProcess()
{
DWORD buf = 0;
ReadProcessMemory(gameHandle,(LPVOID)ecxBaseAddr,&buf,4,NULL); //第二个参数不能是&ecxBaseAddr
buf+=0x1c;
ReadProcessMemory(gameHandle,(LPVOID)buf,&buf,4,NULL);
buf+=0x28;
ReadProcessMemory(gameHandle,(LPVOID)buf,&buf,4,NULL);
buf+=0x1548;
ReadProcessMemory(gameHandle,(LPVOID)buf,&buf,4,NULL);
ecxAddr = buf;
if(!buf)
return 0;
return 1;
}
VOID ExcuteGameCall()
{
__asm
{
push 0x1;
mov ecx,ecxAddr;
mov edx,0x00493060;
call edx;//返回一个结构eax
mov esi,eax;
lea eax,destCoordinate;
push eax;
push 0x0;
mov ecx,esi;
mov edx,0x00497FB0;
call edx;//吧目的坐标存入eax
lea ecx,destDirection;
lea edx,destCoordinate;
push ecx;//方向数组
push edx;//坐标数组
mov ecx,esi;
mov edx,0x00498100;
call edx;//判断方向是否有障碍物 0或者1 写入eax
mov ecx,ecxAddr;
push 0x0;
push 0x1;
push esi;
push 0x1;
mov edx,0x00493550;//寻路
call edx;
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hInstDll=GetModuleHandle(0);//这行不能少
g_bIsFirstLoad = FALSE;
MessageBox(NULL,L"注入成功",L"信息",MB_ICONINFORMATION);
BOOL enable = EnableDebugPrivilege();
if(!enable)
{
MessageBox(0,L"不能改变权限 ",0,0);
return 0;
}
if(!OpenProc())
{
MessageBox(NULL,L"打开游戏失败",L"信息",MB_ICONINFORMATION);
break;
}
if(!ReadProcess())
{
MessageBox(NULL,L"读取游戏失败",L"信息",MB_ICONINFORMATION);
break;
}
ExcuteGameCall();
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
武林外传寻路call
最新推荐文章于 2022-02-25 08:40:14 发布