Dll的远程线程注入之关键代码描述总结

一、使用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);  // 打开进程
	   // 要注入的dll
	pLibNameRemote = 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 identifier
	TOKEN_PRIVILEGES tkp;   // 要设置的权限
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	// 获取访问令牌
	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);   // 获得调试权的luid
	tkp.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注入终止函数释放数据。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值