添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一、detours 的下载和编译

1、下载 Detours:​ ​GitHub - microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. - GitHub - microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. Windows 使用 Detours 进行 HOOK_github https://github.com/microsoft/Detours​

2、编译

cd Detours\vc
打开 Detours.sln 编译运行

如果编译失败,重定向一下解决方案

3、编译运行成功之后会生成 detours.lib

4、使用头文件和 detours.lib

二、使用 detours.lib 进行 Hook

这里我们进行 SendMessage 的 Hook,Hook 新定义的输出函数要和原函数参数是一样的

1、进行 API 的 Hook

主要函数

LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer,
_In_ PVOID pDetour);

第一个参数是原来的函数的地址,第二个参数是 Hook 之后的函数名称

void Hook() {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//这里可以连续多次调用DetourAttach,表明HOOK多个函数
DetourAttach(&(PVOID&)OldSendMessage, NewSendMessage);
DetourTransactionCommit();
}

2、取消 Hook

void UnHook() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK
DetourDetach(&(PVOID&)OldSendMessage, NewSendMessage);
DetourTransactionCommit();
}

3、具体代码

#include <Windows.h>
#include <iostream>
#include <thread>

#include "detours.h"

HWND hwnd;

static LRESULT(WINAPI* OldSendMessage)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = SendMessage;
LRESULT WINAPI NewSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
MessageBox(hwnd, TEXT("就不关闭!"), TEXT("关闭程序"), MB_OK | MB_ICONINFORMATION);
return 0;
}

void Hook() {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//这里可以连续多次调用DetourAttach,表明HOOK多个函数
DetourAttach(&(PVOID&)OldSendMessage, NewSendMessage);
DetourTransactionCommit();
}

void UnHook() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK
DetourDetach(&(PVOID&)OldSendMessage, NewSendMessage);
DetourTransactionCommit();
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
// MessageBox(hwnd, TEXT("关闭程序!"), TEXT("结束"), MB_OK | MB_ICONINFORMATION);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}

int main(void) {
Hook();
static TCHAR szAppName[] = TEXT("TextWindow");
MSG msg;
WNDCLASS wndclass;
// wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口样式
wndclass.lpszClassName = szAppName; //窗口类名
wndclass.lpszMenuName = NULL; //窗口菜单:无
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗口背景颜色
wndclass.lpfnWndProc = WndProc; //窗口处理函数
wndclass.cbWndExtra = 0; //窗口实例扩展:无
wndclass.cbClsExtra = 0; //窗口类扩展:无
wndclass.hInstance = GetModuleHandle(0); //窗口实例句柄
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //窗口最小化图标:使用缺省图标
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //窗口采用箭头光标
UnregisterClass(wndclass.lpszClassName, GetModuleHandle(0));
if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("窗口注册失败"), TEXT("错误"), MB_OK | MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName, TEXT("测试窗口"), WS_OVERLAPPEDWINDOW,
0, 0, 500, 400, NULL, NULL, GetModuleHandle(0), NULL);

ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
std::thread close_work = std::thread([&]() {
for (int i = 0; i < 5; ++i) {
std::cout << "close work: " << 5 - i << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
::SendMessage(hwnd, WM_CLOSE, 0, 0);
});
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (close_work.joinable()) {
close_work.join();
}
std::cout << "Finish" << std::endl;
UnHook();
getchar();
return 0;
}

4、运行结果

正常情况下如果不 Hook 的话,5s 过后窗口就退出了,使用 Hook 的话 5s 过后程序也不会退出

pytorch导入mnist数据集 pytorch加载mnist数据集

MNIST神经网络实现步骤1.加载必要的库2.定义超参数3.构建transforms,主要对图像进行变换4.下载、加载数据集5.构建网络模型6.定义优化器7.定义训练的函数8.定义测试方法9.调用方法总结 1.加载必要的库代码如下:import torch import torch.nn as nn # nn 作为一个代号 import torch.nn.functional as F