Dll的远程线程注入之关键代码描述总结
来源:互联网 发布:8口网络交换机怎么连接 编辑:程序博客网 时间:2024/05/09 14:31
一、使用BCB实现关键代码的调用(我这里为了使dll注入时程序不至于卡主,所以重新创建了一个线程DllThreadTest)
(1)声明全局变量
HWND hWnd;DWORD pid;HANDLE hThread;HANDLE hProcess;void* pLibNameRemote;HMODULE hKernel32;DWORD hLibModule;
(2)Dll注入之前初始化
void DllThreadTest::InitDll(){//hWnd = FindWindow(NULL, "DLL注入测试窗口"); // 查找目标进程hWnd = FindWindow(NULL, "DLL注入测试窗口"); // 查找目标进程pid;hThread; //GetWindowThreadProcessId(hWnd, &pid); //EnableDebugPriv(); // 获得进程的调试权hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); // 打开进程 // 要注入的dllpLibNameRemote = VirtualAllocEx(hProcess, NULL, PATHNAME_LENGTH, MEM_COMMIT, PAGE_READWRITE);// 在目标进程的地址空间分配内存WriteProcessMemory(hProcess, pLibNameRemote, szLibName, PATHNAME_LENGTH, NULL); // 写入dll路径hKernel32 = GetModuleHandle("Kernel32"); // 获得kernel32.dll的句柄FARPROC fp = GetProcAddress(hKernel32, "LoadLibraryA"); // 获得loadibrary的便宜地址hThread = CreateRemoteThread(hProcess, NULL, 0, // 启动远程线程(LPTHREAD_START_ROUTINE)fp, // --要注入的代码写在dll的DllMain里pLibNameRemote, 0, NULL); //WaitForSingleObject(hThread, INFINITE); // 等待线程结束,也就是dllmain结束DWORD hLibModule;GetExitCodeThread(hThread, &hLibModule); // 返回注入的dll的句柄CloseHandle(hThread);}
(3)DIll注入调用
void DllThreadTest::StartDllThread(){InitDll();HMODULE hPrint = LoadLibrary("D://BCBPJ//BCBPJ//HookTest//vc//DllInjectTest//Debug//DllInjectTest.dll");PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)GetProcAddress(hPrint, "StartDllThread");
HANDLE hRemoteThread;if(pfnStartAddr == NULL){ ShowMessage("函数调用失败"); return;}if((hRemoteThread=CreateRemoteThread(hProcess,NULL,0,pfnStartAddr,pLibNameRemote,0,NULL))==NULL){ShowMessage("创建线程失败!");return;}WaitForSingleObject(hRemoteThread, INFINITE); // 等待线程结束,也就是dllmain结束DWORD hLibModule1;GetExitCodeThread(hRemoteThread, &hLibModule1); // 返回注入的dll的句柄CloseHandle(hRemoteThread);//FreeLibrary(hPrint);EndDll();ShowMessage("aaaaa");}
(4)DIll注入终止
void DllThreadTest::EndDll(){ VirtualFreeEx(hProcess, pLibNameRemote, PATHNAME_LENGTH, MEM_RELEASE);hThread = CreateRemoteThread(hProcess, NULL, 0, // 释放注入的dll(LPTHREAD_START_ROUTINE)::GetProcAddress(hKernel32, "FreeLibrary"),(void*)hLibModule, 0, NULL );WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);CloseHandle(hProcess);}
(5)提高当前执行线程的执行权限
void DllThreadTest::EnableDebugPriv(){ HANDLE hToken; // 进程访问令牌的句柄LUID luid; // 用于存储调试权对应的局local unique identifierTOKEN_PRIVILEGES tkp; // 要设置的权限 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);// 获取访问令牌LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); // 获得调试权的luidtkp.PrivilegeCount = 1; // 设置调试权tkp.Privileges[0].Luid = luid;tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL); // 使进程拥有调试权CloseHandle(hToken);}
(6)远程调用dll里面的其他输出函数停止dll里面的消息循环
void DllThreadTest::StopDllThread(){ HMODULE hPrint = LoadLibrary("D://BCBPJ//BCBPJ//HookTest//vc//DllInjectTest//Debug//DllInjectTest.dll");PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)GetProcAddress(hPrint, "SetDllThread");HANDLE hRemoteThread;if(pfnStartAddr == NULL){ ShowMessage("函数调用失败"); return;}else{}if((hRemoteThread=CreateRemoteThread(hProcess,NULL,0,pfnStartAddr,pLibNameRemote,0,NULL))==NULL){ShowMessage("创建线程失败!");return;}WaitForSingleObject(hRemoteThread, INFINITE); // 等待线程结束,也就是dllmain结束DWORD hLibModule1;GetExitCodeThread(hRemoteThread, &hLibModule1); // 返回注入的dll的句柄CloseHandle(hRemoteThread);FreeLibrary(hPrint);}
二、DllInjectTest.dll的实现
(1)DllInjectTest.h的实现
#ifndef DLL_INJECT_TEST#define DLL_INJECT_TEST#include <windows.h>#include <stdlib.h>#include <stdio.h>#include <process.h>DWORD WINAPI WindowCallBackProc(LPVOID *param);static LRESULT CALLBACK DllTestProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam);// 声明要导出的函数extern "C" _declspec(dllexport) void SetDllThread();extern "C" _declspec(dllexport) void StartDllThread();#endif
(2)DllInjectTest.cpp的实现
#include "DllInjectTest.h"HANDLE hThread=NULL;DWORD dwThread=0;HWND hwnd,btnHwnd;DWORD pid;DWORD g_OldButtonProc;#pragma data_seg("MySec")BOOL StopThread=false;#pragma data_seg()BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID pReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: //MessageBoxA(NULL,"DLL_PROCESS_ATTACH!","fuck",0); break; case DLL_THREAD_ATTACH: //MessageBoxA(NULL,"我操!","fuck",0); break; case DLL_THREAD_DETACH: //MessageBoxA(NULL,"DLL_THREAD_DETACH!","fuck",0); break; case DLL_PROCESS_DETACH: //MessageBoxA(NULL,"DLL_PROCESS_DETACH!","fuck",0); break; } //MessageBoxA(NULL,"DLL_PROCESS_DETACH!","fuck",0);//_beginthread(WindowCallBackProc,0,NULL);return TRUE;} // 线程回调函数DWORD WINAPI WindowCallBackProc(LPVOID *param){ MessageBoxA(NULL,"进入进程!","fuck",0); hwnd=::FindWindow(NULL,"DLL注入测试窗口"); //hwnd=::FindWindow(NULL,"添加好友"); if(hwnd) { EnumChildWindows(hwnd,(WNDENUMPROC)EnumChildProc, 0);//列举子窗口 } while (!StopThread) { } return 0;}void SetDllThread(){StopThread=true;}void StartDllThread(){hThread = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WindowCallBackProc,NULL,0,&dwThread); if(hThread){ MessageBoxA(NULL,"cao ni ma ge B!","fuck",0); WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);}}LRESULT CALLBACK DllTestProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp){/*switch(wp){ case EN_CHANGE: MessageBoxA(NULL,"EN_CHANGE!","fuck",0); break;}*/switch(msg){ case WM_SETTEXT:MessageBoxA(NULL,"设置文本!","fuck",0); ::CallWindowProc((WNDPROC)g_OldButtonProc,hwnd, msg, wp, lp); break;}return ::CallWindowProc((WNDPROC)g_OldButtonProc,hwnd, msg, wp, lp);}BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam){WCHAR lpWinTitle[256],lpClassName[256];::GetWindowTextW(hwndChild,lpWinTitle,256-1); //获得窗口caption::GetClassNameW(hwndChild,lpClassName,256-1); //获得窗口类名::SendMessageW(hwndChild,WM_GETTEXT,100,(long)strTest);if(_wcsicmp(lpClassName,L"TEdit")==0){ //修改窗口的执行函数 g_OldButtonProc=::SetWindowLong(hwndChild,GWL_WNDPROC,(LPARAM)(WNDPROC)DllTestProc); char strTest[100]="这是一个测试程序"; SendMessage(hwndChild,WM_SETTEXT,0,(LPARAM)strTest);}/*if(_wcsicmp(lpClassName,L"")!=0)) EnumChildWindows(hwndChild,(WNDENUMPROC)EnumChildProc, 0);*/return true;}
二、问题总结与分析
(1)在Dll的注入初始化时会调用Dll里面的DllMain函数,此时必须有返回值。
(2)针对第一种情况,我在Dll里面新建了一个处理消息循环的可以创建线程的输出函数SetDllThread,这样做是为了可以在Dll里面做各种消息过滤和Hook等应用做准备。
(3)针对第二种情况,当需要停止Dll里面的消息循环时,可以通过远程调用Dll里面的SetDllThread函数,当退出消息循环时就会执行Dll注入终止函数释放数据。
- Dll的远程线程注入之关键代码描述总结
- 远程线程注入技术(1)之DLL的注入
- Dll注入技术之远程线程注入
- Dll注入技术之远程线程注入
- DLL注入之远程线程注入
- Dll注入技术之远程线程注入
- Dll注入技术之远程线程注入
- 奇技淫巧之调试被远程线程注入的DLL
- 远程线程dll注入
- 远程线程DLL注入
- 远程线程注入dll
- DLL 远程线程注入
- 远程注入DLL(简单描述)
- 远程注入DLL(简单描述)
- 远程注入DLL(简单描述)
- 利用远程线程实现dll的注入
- 利用远程线程进行DLL的注入
- dll的注入 (远程线程方式)
- UVA11992----线段树的成段更新
- 为Python安装MySQLdb库
- iBATIS一对多/多对多N+1问题解决方案
- GlassFish下手动部署JSF程序
- rails环境下安装extjs4
- Dll的远程线程注入之关键代码描述总结
- 《C++ Primer》习题12.38——12.40
- 设计模式之-迭代器模式
- 安装SharePoint报错:系统从以前的安装重新启动,或更新正在等待错误(原)
- Java反射机制及应用(一)
- 铁路现代化技术系统整理(一)之TDCS
- Android实现局部图片滑动指引效果
- 《算法导论》学习笔记 第四章&&第五章
- rqnoj-643