后卫大师教你过程注入
起首提一下,因为文章美满是我手写,所以打不了太多,请包含,因为我已经供给了源代码,所以我在这里具体讲一下理论,至于想看代码的下载代码就可以了。代码中关于注入的项目组做了具体的注释。MFC界面项目组的注释没有写,(毕竟成果太肤浅了。)
好,言归正传。
所谓DLL注入,既把一个DLL文件放到目标过程中。
下面介绍2种注入体式格式:
1.长途线程注入。
2.哄骗hook注入。(可以过卡巴斯基)
因为本文篇幅限制,不写如何编写DLL。
一.起首讲一下长途线程注入的办法:
1.假设我们已经写好了一个DLL文件。
2.设置本过程权限为debug权限,既调试权限,可以打开其他过程。代码如下:
BOOL SetToken(void)
{
HANDLE hToken;
TOKEN_PRIVILEGES Privileges;
LUID luid;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ,&hToken);
Privileges.PrivilegeCount=1;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid);
Privileges.Privileges[0].Luid=luid;
Privileges.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,FALSE,&Privileges,NULL,NULL,NULL)!=0)
return FALSE;
CloseHandle(hToken);
return (GetLastError() == ERROR_SUCCESS);
}
3.获得目标过程的句柄。
OpenProcess(权限类型,是否可被持续,过程ID)功能:返回目标过程句柄.
4.在长途过程平分派内存,用来存储,我们要注入的dll的路径
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
//VirtualAllocEx()函数功能:为制订的过程分派虚拟地址
//参1:要分派的过程句柄
//参2:要分派的虚拟地址的地位,0默示,主动分派地位
//参3:分派的大小
//参4:MEM_COMMIT默示,分派物理内存或者页面内存,并且初始化内存为0
//参5:存储选项:PAGE_READWRITE默示可以在页面内存中 “读写”
//返回值:若是分派内存成功,则返回分派内存的地址,若是分派失败则返回NULL,调用GetLastError()查看错误原因
5.在长途过程中刚才分派的内存处,写入目标DLL路径:
WriteProcessMemory(hProcess, pszLibFileRemote,PVOID) pszLibFile, cb, NULL)
//WriteProcessMemory()函数功能:在制订过程中写入内存
//参1:写入过程的句柄
//参2:写入内存的肇端地址,必须是已经创建的地址,比如上方用VirtualAllocEx()在过程中创建的内存地址
//参3:写入内存中的数据内容的缓存
//参4:写入数据大小
//参5:一个选项,0默示忽视
//返回值: 非0值默示成功, 返回0则默示写入错误。调用GetLastError()查看错误原因
6.获取LoadLibrary()函数地址,因为要用他来动态加载DLL,该函数在kernel32.dll文件中
PROC AdrMyDllDir=(PROC)::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryW");//W代表UNICODE版本,说实话,A代表多字节字符集,本人喜好UNICODE版本
GetProcAddress()
FARPROC GetProcAddress(HMODULE hModule,LPCWSTR lpProcName);
//功能:返回指定的DLL输出函数的函数地址
//参数1:DLL模块句柄
//参数2:DLL输出函数的函数名
这个函数的返回值,就是LoadLibraryW的地址了
7.创建长途线程,既在目标过程中创建一个线程,这里的线程跟通俗的线程不合,通俗线程有线程处理惩罚函数ProcThread()
CreateRemoteThread()
HANDLE CreateRemoteThread(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
//函数功能:在制订过程中的虚拟地址中创建一个线程
//参数1:过程句柄,线程被创建在这个过程中
//参数2:安然等级,0默示默认安然等级
//参数3:创建线程的大小,0默示体系主动分派线程实际须要的大小
//参数4:线程肇端地址,应用LPTHREAD_START_ROUTINE 定义的线程,并且线程是在长途过程中已经存在。
//参数5: 给线程函数传递的参数
//参数6:创建标记,若是参数是0,则线程创建后立即运行
//参数7:线程ID,若是 ID给0 ,则不返回创建线程的ID
::CreateRemoteThread(hProcess,0,0,(LPTHREAD_START_ROUTINE)AdrMyDllDir,bufRemote,0,0);
这里的AdrMyDllDir存放LoadLibraryW ,也就是说把LoadLibraryW当做线程处理惩罚函数,传入的参数bufRemote存放的是目标DLL文件的地址。
二。下面讲解一下如何用hook既钩子注入DLL文件。
起首给不懂钩子的人简单介绍一下道理:所谓hook,既钩子。hook会在应用法度接到消息之前,阻碍应用法度的信息,比如鼠标键盘钩子会阻碍一个应用法度的鼠标键盘信息。要做盗号木马?用WH_KEYBOARD类型的hook
1.我们要跨过程应用钩子,要把hook函数写在DLL文件中,这是微软明白规定的。也有其他办法,这里不久不多论述
2.在DLL文件中 设置钩子.
这里须要调用线程ID,threadId,我们会鄙人面调用DLL的调用端中写入
hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
//参数1:钩子类型
//参数2:钩子处理惩罚函数
//参数3:钩子地点的模块
//参数4:钩子要阻碍的线程ID,若是要设置全局钩子,这里给0。
把这个SetWindowsHookEx()函数写在一个导出函数中,容许调用dll文件的法度调用
_declspec(dllexport) void SetHook(DWORD threadId)
{
hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
}
SetHook()就是本dll的导出函数
3.在钩子处理惩罚函数中写入功能,当钩子截取到WM_NULL消息的时辰,注入DLL文件。因为WM_NULL消息,是个没用的消息,应用法度一般不会收到这个消息,除非我们本身发送一个这个消息,所以我们在注入DLL的时辰,只要给要注入的应用法度发一个WM_NULL消息,当钩子截取到WM_NULL的时辰就注入钩子,就可以了。
LRESULT CALLBACK GetMessageHookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
MSG* pMsg=(MSG*)lParam;
if(WM_NULL==pMsg->message)
::LoadLibraryW(TEXT("D://MyDLL.dll"));
}
好了,编译DLL项目,产生DLL文件。
4.编写调用端,调用钩子
起首获取窗口句柄
HWND FindWindow( LPCTSTR lpClassName,
LPCTSTR lpWindowName
);
返回窗体句柄。hWnd.
hWnd=FindWindow(0,要注入dll的窗体的名称(例如:千千静听))
哄骗hWnd,查找窗体线程ID
threadId=GetWindowThreadProcessId(hWnd,0);
好了,我们有了线程ID了,可以调用钩子了。
SetHook(threadId);
这时钩子已经加载到目标线程中了。
向目标窗体发送WM_NULL消息
SendMessage(hWnd,WM_NULL,0,0);
钩子会在目标窗体受到消息前受到WM_NULL消息。因为钩子处理惩罚函数中做了断定,当受到WM_NULL消息时,加载DLL文件。所以DLL文件就注入到目标线程中了。
你可以把你的DLL文件中写入很多功能,并且DLL已经被目标法度加载了,也就是说,你的DLL法度已经打入到目标法度内部了,所以如今你可以随心所欲了
posted on 2012-12-09 22:42
寻步 阅读(2508)
评论(0) 编辑 收藏 引用 所属分类:
Hack