概述
想写个远程线程注入的东西......
问了下栋哥终于把机理给搞明白了。
参考的书本是《Windows API 开发详解 ---函数、接口、编程实例》和《windows核心编程》
首先我们从编写一个dll开始。
为了统一起见,下面的代码中所有函数全部使用宽字符版本。
首先把代码给贴出来:
/******************************
* msg.c动态链接库
*******************************/
#include <Windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
__declspec(dllexport) DWORD ExportExample(LPSTR sMsg, DWORD dwCode);
//dll main
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
TCHAR lpMainMoudleName[MAX_PATH];
TCHAR lpMessage[MAX_PATH + 64];
//获取PID和主模块名,将弹出消息框
DWORD dwPID = GetCurrentProcessId();
GetModuleBaseName(GetCurrentProcess(), NULL, lpMainMoudleName, MAX_PATH);
wsprintf(lpMessage, L"process name: %s, PID: %u ", lpMainMoudleName, dwPID);
MessageBox(NULL, lpMessage, L"msg.dll", MB_OK);
break;
}
case DLL_THREAD_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
//导出函数,显示消息
DWORD ExportExample(LPWSTR szMsg, DWORD dwCode)
{
LPVOID lpShowOut = HeapAlloc(GetProcessHeap(), NULL, lstrlen(szMsg) + 100);
wsprintf((LPWSTR)lpShowOut, L"%s,%d", szMsg, dwCode);
MessageBox(NULL, (LPWSTR)lpShowOut, L"由导出函数弹出的消息! ", MB_OK);
HeapFree(GetProcessHeap(), NULL, lpShowOut);
return 0;
}
然后我们来分析一下代码:
__declspec(dllexport) DWORD ExportExample(LPSTR sMsg, DWORD dwCode);
这是个导出函数的声明,声明了这个函数是从dll中导出的函数。
接下来是dll的主函数入口。跟main 和WinMain 差不多。它是DllMain
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
dwnReason可以是下面四个值:
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_DETACH:
break;
}
通俗的理解,分别是附加进程,附加线程,分离进程,分离线程的意思。
具体的理解,大家可以查看《windows核心编程》,下面的博客也分别摘录了核心编程里面的东西:
http://blog.csdn.net/ithzhang/article/details/7051558
本例子中的代码是这样的,在DLL_PROCESS_ATTACH的时候执行下面的代码:
case DLL_PROCESS_ATTACH:
{
TCHAR lpMainMoudleName[MAX_PATH];
TCHAR lpMessage[MAX_PATH + 64];
//获取PID和主模块名,将弹出消息框
DWORD dwPID = GetCurrentProcessId();
GetModuleBaseName(GetCurrentProcess(), NULL, lpMainMoudleName, MAX_PATH);
wsprintf(lpMessage, L"process name: %s, PID: %u ", lpMainMoudleName, dwPID);
MessageBox(NULL, lpMessage, L"msg.dll", MB_OK);
break;
}
代码很简单,获得进程ID并且用对话框的方式显示出来。
接下来我们看看导出函数:
//导出函数,显示消息
DWORD ExportExample(LPWSTR szMsg, DWORD dwCode)
{
LPVOID lpShowOut = HeapAlloc(GetProcessHeap(), NULL, lstrlen(szMsg) + 100);
wsprintf((LPWSTR)lpShowOut, L"%s,%d", szMsg, dwCode);
MessageBox(NULL, (LPWSTR)lpShowOut, L"由导出函数弹出的消息! ", MB_OK);
HeapFree(GetProcessHeap(), NULL, lpShowOut);
return 0;
}
导出函数也很简单,就是弹出一个对话框。这个没什么好说的。
加载了动态链接库之后我们就可以直接使用这个dll中的接口函数了。dll的方便性就体现在这里了。^_^
然后我们简单的重新写个代码测试一下这个dll的正确性:
#include <stdio.h>
#include <windows.h>
typedef DWORD (*MY_EXPORT_PROC)(LPWSTR, DWORD);
void main(void)
{
HINSTANCE hinstLib;
MY_EXPORT_PROC lpProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
//获得DLL模块句柄
hinstLib = LoadLibrary(TEXT("msg.dll"));
//是否加载成功
if (NULL != hinstLib)
{
//获得指定导出函数的地址
lpProcAdd = (MY_EXPORT_PROC)GetProcAddress(hinstLib, "ExportExample");
//判断是否成功
if (NULL != lpProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(lpProcAdd) (TEXT("hello"), 123);
}
//释放dll
fFreeResult = FreeLibrary(hinstLib);
}
if (!fRunTimeLinkSuccess)
printf("error; %un", GetLastError());
}
这里使用的一种比较麻烦的方法。跟#pragma comment(“xxx.lib”, lib)有点不一样的地方。
#pragma comment(“xxx.lib”, lib)这种方式会在程序的可执行文件中创建导入表,并在程序加载时进行函数的链接。
使用这种方法的话,有没有lib文件的必要了。因为他在LoadLibrary之后直接获得了导出函数的地址
//获得指定导出函数的地址
lpProcAdd = (MY_EXPORT_PROC)GetProcAddress(hinstLib, "ExportExample");
然后我们测试一下,发现成功弹出了dll中的两个对话框~~~!!
OK,第一步我们先到这里了,接下来就是伟大的远程线程注入了,哈哈。
最后
以上就是斯文小兔子为你收集整理的远程线程注入(一)编写动态链接库的全部内容,希望文章能够帮你解决远程线程注入(一)编写动态链接库所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复