常用WindowsAPI

========================================

FindWindow 获取窗口句柄

SendMessage 发送消息给窗口

GetWindowThreadProcessId 获取进程ID(PID)

OpenProcess 打开进程,获取进程句柄

ReadProcessMemory 读取内存

CreateThread  创建线程

TerminateThread 终止线程

FreeLibraryAndExitThread 卸载dll并且结束线程

VirtualAllocEx  分配内存空间

WriteProcessMemory  写入内存

CreateRemoteThread  创建远程线程,执行远程函数

WaitForSingleObject   等待目标对象执行结束

VirtualFreeEx   释放内存空间

GetCurrentDirectory  获取当前目录

SetWindowsHookExA  功能之一主线程调用


SetWindowsHookExA 功能之一主线程调用

UINT myMsg = RegisterWindowMessageA("myMsg");//注册一个消息
HWND game_wnd_handle;
HHOOK hhook;

LRESULT CALLBACK GameWndProc(
	_In_ int    nCode,      //消息代码
	_In_ WPARAM wParam, //指定消息是否由当前线程发送,如果是,则它是非零的,不是则为0
	_In_ LPARAM lParam  //指向CWPSTRUCT结构的指针
)
{
	//如果nCode==HC_ACTION,那么为主程序调用,也就是进程的消息

	CWPSTRUCT   *wpstruct = (CWPSTRUCT*)lParam;
	//typedef struct tagCWPSTRUCT {
	//	LPARAM lParam;       //接收的消息
	//	WPARAM wParam;
	//	UINT   message;   // 注册的消息值,一般用于分类
	//	HWND   hwnd;   //窗口的句柄,用于接收消息
	//} 

	if (nCode== HC_ACTION)
	{
		//判断是不是我们的窗口,并且是我们指定的消息
		if (wpstruct->hwnd == game_wnd_handle && wpstruct->message == myMsg)
		{
			Debug_Print("消息收到了!");
			switch (wpstruct->wParam)  //wParam接受我们送过来的msg
			{
			case MSG_Use_Goods:
				BackPack back1;
				back1.use_goods_for_name((char*)wpstruct->lParam); return 1;
				break;
			default:
				break;
			}

			return 1;
		}
	}

	//如果nCode<0,那么窗口过程必须交给其他人处理

	return CallNextHookEx(hhook, nCode, wParam, lParam);
}


int HookMainThread()
{
	 game_wnd_handle=getGameWndHandle();
	DWORD threadId=GetWindowThreadProcessId(game_wnd_handle,NULL);
	if (threadId!=0)
	{
		hhook=SetWindowsHookExA(WH_CALLWNDPROC, GameWndProc,0,threadId);
		//1 钩子的类型,这里用WH_CALLWNDPROC 用于主程序调用
		//   系统将消息发送到目标窗口过程之前监视消息
		//2 回调函数的地址,指向钩子过程的指针
		//3 DLL的句柄,包含指向的钩子过程lpfn参数,暂且填0
		//4 线程ID,如果填写了这个,那么参数3便必须填0,暂且就这样记着
		//成功返回钩子句柄,失败返回0
		//您将安装一个钩子过程来监视系统中某些类型的事件
		//https://msdn.microsoft.com/zh-cn/ms644990

		return 0;
	}

	return -1;
}

int magUseGoodsForName(char *spname)
{
	//发送消息,我们在窗口过程给hook了,所以发送消息后,我们自己处理
	SendMessageA(game_wnd_handle, myMsg, MSG_Use_Goods, (LPARAM)spname);
	return 1;
}


int UnHook()
{
	UnhookWindowsHookEx(hhook);
	return 1;
}

GetCurrentDirectory  获取当前目录

	char pathName[256];
	GetCurrentDirectoryA(sizeof(pathName), pathName);
	//1 目标的路劲的大小
	//2 目标路劲名
	//如果我们在vs项目里运行,那么获取的是工作目录,也就是cpp所在的目录
	//但是如果我们直接点开exe程序,那么获取的就是我们exe所在的目录

VirtualFreeEx   释放内存空间

VirtualFreeEx(process_handle,path_address,256, MEM_COMMIT);
//1 进程句柄
//2 要释放的页面区域的地址
//3 释放的大小
//4 释放的类型,和VirtualAllocEx分配的类型一样即可 MEM_COMMIT

WaitForSingleObject   等待目标对象执行结束

WaitForSingleObject(thread_handle, (unsigned)-1);
//1 对象句柄
//2 等待时间
// 等待指定对象的状态,如果目标对象状态没有发生改变,那么本程序会暂时挂起本线程,
// 如果对象状态发送改变,那么会恢复本线程
// 这个函数就是确保CreateRemoteThread执行完成
//https://blog.csdn.net/zhanghuaichao/article/details/53444582

CreateRemoteThread  创建远程线程,执行远程函数

HANDLE thread_handle=CreateRemoteThread(process_handle,NULL,NULL,(LPTHREAD_START_ROUTINE)LoadLibraryA,path_address,NULL,NULL);
//1 进程的句柄
//2 指定新线程的安全描述符,一般为NULL,表示默认的安全描述符
//3 堆栈的大小,一般为NULL,由可执行文件自动分配
//4 函数指针,表示远程进程中线程的起始地址
//5 参数4函数的参数
//6 控制线程的标志,如果填0,表示立刻执行,如果4,需要手动唤醒线程
//7 用于接受线程ID的变量,null即可
//函数成功,则返回值是新线程的句柄,失败则为NULL

WriteProcessMemory  写入内存

WriteProcessMemory(process_handle, path_address, dll_path, strlen(dll_path) + 1, NULL);
	//1 进程句柄
	//2 要写的地址,就是写到哪个地方去
	//3 指向缓冲区的指针,缓冲区有我们需要写入的数据
	//4 要写入的字节数
	//5 指向变量的指针,该变量接收传输到指定进程的字节数,一般选NULL
//https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms681674(v=vs.85).aspx

VirtualAllocEx  分配内存空间

path_address=VirtualAllocEx(process_handle, NULL,256,MEM_COMMIT, PAGE_READWRITE);
//1 进程的句柄
//2 指定要分配的页面区域的所需起始地址,如果为NULL,则由函数自行确定起始地址
//3 要分配的内存区域的大小
//4 内存分配的类型  默认MEM_COMMIT即可
//5 分配的保护标志  PAGE_READWRITE 可读写
//如果函数成功,则返回值是分配的页面区域的地址,失败则返回值为NULL
//https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa366890(v=vs.85).aspx

FindWindow 获取窗口句柄

	HWND h_wnd= ::FindWindowW(L"扫雷", L"扫雷");
	//1 窗口类名 2 窗口标题
	//返回窗口句柄
	//https://msdn.microsoft.com/zh-CN/library/windows/desktop/ms633499(v=vs.85).aspx

SendMessage 发送消息给窗口

::SendMessageW(h_wnd, WM_COMMAND, 0x20A, 0); //SendMessage需要等待指定程序处理完,并返回,这个函数才返回,执行下面的代码
	//1 窗口句柄                                  //可以使用PostMessage,无须等待指定程序处理完
	//2 要发送的消息类型
	//3 附加消息值
	//4 附加消息值2
	//https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644950(v=vs.85).aspx

GetWindowThreadProcessId 获取进程ID(PID)

//获取进程标识符pid
	DWORD pid;
	::GetWindowThreadProcessId(h_wnd, &pid);
	//1 窗口句柄
	//2 用于存储pid的变量
	//返回pid,如果参数2填写NULL,那么可以用返回值接受pid
	//https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms633522(v=vs.85).aspx

OpenProcess 打开进程,获取进程句柄

//利用pid打开进程,获取进程句柄
  HANDLE  m_processHandle=::OpenProcess(PROCESS_ALL_ACCESS, false,pid);
	//1 访问权限,PROCESS_ALL_ACCESS 填写所有访问权限即可
	//2 继承句柄,填false即可
	//3 pid
	//https://docs.microsoft.com/zh-cn/windows/desktop/api/processthreadsapi/nf-processthreadsapi-openprocess

ReadProcessMemory 读取内存

//利用进程句柄远程读取数值
	ReadProcessMemory(m_processHandle,(void *)0x01005194,&m_saolei_value,4,NULL);
	//1 进程的句柄
	//2 要读取的指针(地址)
	//3 用于接受读取后的数值
	//4 读取几个字节数
	//5 实际读取了多少个字节数,用变量接受,可以忽略
	//当函数读取成功时返回1, 失败则返回0
	//https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms680553(v=vs.85).aspx

CreateThread  创建线程

	LPDWORD tip=NULL;
  thread_handle = CreateThread(NULL, 0, ThreadProc, 0, CREATE_SUSPENDED, tip);
	//参数1 暂且默认为NULL 用于确定返回的句柄是否可以被子进程继承
	//参数2  初始堆栈大小,暂且默认填写0,为可执行文件的默认大小
	//参数3  指向由线程执行的函数的指针
	//参数4  指向要传递给线程的参数
	//参数5  0表示创建后既运行,4表示创建后挂起
	//参数6  指向接收线程标识符的变量的指针。如果此参数为 NULL,则不返回线程标识符
 
 //CreateThread文档
 //https://docs.microsoft.com/zh-cn/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createthread

TerminateThread 终止线程

TerminateThread(thread_handle, 0);//参数2默认
	//TerminateThread文档
	//https ://docs.microsoft.com/zh-cn/windows/desktop/api/processthreadsapi/nf-processthreadsapi-terminatethread

FreeLibraryAndExitThread 卸载dll并且结束线程

	//卸载dll并且退出本线程
	FreeLibraryAndExitThread(theApp.m_hInstance, 1);
	//1 dll模块句柄,theApp.m_hInstance代表本dll的句柄,MFC里自己存起来的
	//2 退出线程的代码,填写1即可
	//https://msdn.microsoft.com/en-us/library/ms683153(v=vs.85).aspx






猜你喜欢

转载自blog.csdn.net/yzj17025693/article/details/80988384