DLL的入口函数:
BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason,
LPVOID lpvReserved);
hinstance:该参数是当前DLL模块的句柄,即本动态连接库模块的实例句柄。
reason:该参数表示DllMain()函数被调用的原因。分别是:
值 | 作用 |
---|---|
DLL_PROCESS_ATTACH | 当DLL被某进程加载时,DllMain()函数被调用 |
DLL_PRO CESS_DETACH | 当DLL被某进程卸载时,DllMain()函数被调用 |
DLL_THREAD_ATTACH | 当进程中有线程被创建时,DllMain()函数被调用 |
DLL_THREAD_DETACH | 当进程中有线程结束时,DllMain()函数被调用 |
lpvReserved:保留参数,即不被程序员使用的参数。
添加导出函数:
extern "C" __declspec(dllexport) (函数返回类型)(函数名称)(参数...);
DLL的调用:
HMODULE hModule = loadLibrary("DLL文件名.dll");
函数指针 mFun = GetProcAddress(hModule, "DLL中所导出的函数名");
GetProcAddress(
HMODULE hModule, // DLL模块句柄
LPCSTR lpProcName // 函数名
);
返回值:
如果函数调用成功,返回值是DLL中的输出函数地址。
如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数GetLastError。
DLL远程注入:
先介绍几个函数:
HANDLE CreateRemoteThread(__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId);
/*
*/
hProcess : 线程所属进程的进程句柄.该句柄必须具有
PROCESS_CREATE_THREAD,
PROCESS_QUERY_INFORMATION,
PROCESS_VM_OPERATION,
PROCESS_VM_WRITE,
和PROCESS_VM_READ 访问权限.一般使用OpenProcess()获得。
lpThreadAttributes: 一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性.一般为NULL;
dwStackSize: 线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
lpStartAddress: 在远程进程的地址空间中,该线程的线程函数的起始地址.
lpParameter 传给线程函数的参数.
dwCreationFlags [in]:
线程的创建标志.
值 | 含义 |
---|---|
0 | 线程创建后立即运行 |
CREATE_SUSPENDED 0x00000004 | 线程创建后先将线程挂起,直到 ResumeThread 被调用 |
STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 | dwStackSize 参数指定为线程栈预订大小,如果STACK_SIZE_PARAM_IS_A_RESERVATION没有被指定,dwStackSize 参数指定为线程栈分配大小. |
lpThreadId [out]
指向所创建线程ID的指针,如果创建失败,该参数为NULL.
LPVOID VirtualAllocEX(HANDLE hProcess,LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect);//在目标进程申请内存
hProcess:
申请内存所在的进程句柄。
lpAddress:
保留页面的内存地址;一般用NULL自动分配 。
dwSize:
欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍
flAllocationType 可取下列值:
值 | 含义 |
---|---|
MEM_COMMIT | 为特定的页面区域分配内存中或磁盘的页面文件中的物理存储 |
MEM_PHYSICAL | 分配物理内存(仅用于地址窗口扩展内存) |
MEM_RESERVE | 保留进程的虚拟地址空间,而不分配任何物理存储。保留页面可通过继续调用VirtualAlloc()而被占用 |
MEM_RESET | 指明在内存中由参数lpAddress和dwSize指定的数据无效 |
MEM_TOP_DOWN | 在尽可能高的地址上分配内存(Windows 98忽略此标志) |
MEM_WRITE_WATCH | 必须与MEM_RESERVE一起指定,使系统跟踪那些被写入分配区域的页面(仅针对Windows 98) |
flProtect 可取下列值:
值 | 含义 |
---|---|
PAGE_READONLY: | 该区域为只读。如果应用程序试图访问区域中的页的时候,将会被拒绝访 |
PAGE_READWRITE | 区域可被应用程序读写 |
PAGE_EXECUTE | 区域包含可被系统执行的代码。试图读写该区域的操作将被拒绝。 |
PAGE_EXECUTE_READ | 区域包含可执行代码,应用程序可以读该区域。 |
PAGE_EXECUTE_READWRITE | 区域包含可执行代码,应用程序可以读写该区域。 |
PAGE_GUARD | 区域第一次被访问时进入一个STATUS_GUARD_PAGE异常,这个标志要和其他保护标志合并使用,表明区域被第一次访问的权限 |
PAGE_NOACCESS | 任何访问该区域的操作将被拒绝 |
PAGE_NOCACHE | RAM中的页映射到该区域时将不会被微处理器缓存(cached) |
返回值:
执行成功就返回分配内存的首地址,不成功就是NULL。
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesWritten
);//把lpBuffer中的内容写到进程句柄是hProcess进程的lpBaseAddress地址处,写入长度为nSize。
hProcess:该参数是指定进程的进程句柄。
lpBaseAddress:该参数是指定写入目标进程内存的起始地址。
lpBuffer:该参数是要写入目标进程内存的缓冲区起始地址。
nSize:该参数是指定写入目标内存中的缓冲区的长度。lpNumberOfBytesWritten:该参数用于接收实际写入内容的长度。