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注入终止函数释放数据。

 

原创粉丝点击