DLL:
1:DLL(动态链接库)和常见的EXE是一样的,他们都是PE结构,DLL也是PE结构的,单是两者在使用上会有不同,DLL常为EXE的一个补充体,DLL的运行也需要内存,和EXE是一样的。在Windows,有部分的EXE也可以被加载,OCX(控件)等格式也是。
2:使用DLL有如下优点:
1:扩展了应用程序的特性
2:简化了项目管理:项目设计的时候,简化项目管理
3:节省内存:一份DLL只有一个,但是可以由多个程序使用,会将这个DLL映射到一个进程里面。
4:促进资源共享:共享给多个进程使用
5:促进本地化:软件并不需要下载很多东西,在本地是共有的,不用下载重复的。
6:解决版本间差异:解决各版本之间的差异,只要dll名字一样即可。
3:DLL和应用程序是共用一个进程空间的,DLL在系统中运行,它本身永远只有一份。
4:DLL分配的内存,一定要自己释放,EXE消亡的时候,内存会释放,但是DLL是不会做这个事的,直到应用程序消亡的时候才会释放。
5:在一下这四个时间点,DLL Main都会被调用。
6:DLL中最重要的是导出函数,导出了那些函数
BOOL APIENTRY DllMain( HMODULE hModule,//当前模块句柄
DWORD ul_reason_for_call,//当前被调用的原因,分为下面switch的四种情况
LPVOID lpReserved//
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH://被某个进程启动加载的时候,这里面一般做的是初始化
case DLL_THREAD_ATTACH://当应用程序中有新线程启动的时候,加载dll之前可能已经有一些线程,这些不用管
case DLL_THREAD_DETACH://某个现线程终止卸载的时候
case DLL_PROCESS_DETACH://被进程卸载的时候,这里面一般做反初始化的事
break;
}
return TRUE;
}
6:DLL中最重要的是导出函数,导出了那些函数
7:在DLL编写的时候需要注意,C++里面有个命名改编,在编写DLL的时候,一般需要加上extern "C",告诉其按C语言的方式编译,防止命名改编。如果导出的本身就是类或者带有C++特性的,就不用了。此外,还需要加上__declspec(dllexport),告诉编译器这是一个导出函数,否则就不会被导出了。
8:DLL为动态链接库,生成的LIB称为静态链接库,LIB有两种,一种是我们直接可以在程序里面包含使用的,另一种是为了方便我们使用动态链接库而存在的,我们编译生成的就是为了方便我们使用动态链接库的。它里面是没有代码的。
8:DLL为动态链接库,生成的LIB称为静态链接库,LIB有两种,一种是我们直接可以在程序里面包含使用的,另一种是为了方便我们使用动态链接库而存在的,我们编译生成的就是为了方便我们使用动态链接库的。它里面是没有代码的。
HOOK:
WindowsHook:
使用Hook可以改变程序流程,但是会使得程序执行变慢。
1:WindowsHook只是Hook的一类,是使用SetWindowsHookEx来实现的,这个钩子适用于获取Windows中的消息流。
2:SetWindowsHookEx:
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,//Hook的标志,指定Hook什么消息
_In_ HOOKPROC lpfn,//钩子处理的回调函数。
_In_ HINSTANCE hMod,//指定挂钩的模块。
_In_ DWORD dwThreadId//在哪个线程安装钩子,全局钩子指定为0
);
3:在我们的系统中,杀毒软件已经设置了很多的Hook了,全局的钩子通常用于处理一写全局的热键,在进行Windows函数处理的时候,每次回调函数调用完成都应该返回CallNextHook,看其他程序是否还有Hook这个API。
4:Hook的设置与卸载:
4:Hook的设置与卸载:
#include <stdio.h>
#include <windows.h>
#include "WindowsMsgHookDemo.h"
extern HMODULE g_Module;//DLL传递进来的模块
HHOOK g_Hook = nullptr;
LRESULT CALLBACK KeyboardProc(int Code, WPARAM wParam, LPARAM lParam)
{
if (Code < 0)
{
return CallNextHookEx(g_Hook, Code, wParam, lParam);
}
char tKey[MAXBYTE];
GetKeyNameTextA(lParam, tKey, MAXBYTE);
printf("Code: %d,虚拟代码:0x%x,按下的按键是:%s\r\n", Code, wParam, tKey);
return CallNextHookEx(g_Hook, Code, wParam, lParam);
}
bool OnHook()
{
if (g_Hook == nullptr)
{
g_Hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_Module, 0);//全局钩子
return true;
}
return false;
}
bool UnHook()
{
if (g_Hook != nullptr)
{
UnhookWindowsHookEx(g_Hook);
g_Hook = nullptr;
return true;
}
return false;
}