现在的位置: 首页 > 综合 > 正文

Windows 核心编程之Dll注入

2013年09月17日 ⁄ 综合 ⁄ 共 12871字 ⁄ 字号 评论关闭

下面写了一个是注册表编辑器DLL注入代码,读取的是右边SysListView 控件的例子

有什么不懂得可以提问,有时间一定解答

DLL 代码 对话框的资源,自己添加!

xx.h

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the DYNAMIC_DLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// DYNAMIC_DLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef DYNAMIC_DLL_EXPORTS
#define DYNAMIC_DLL_API __declspec(dllexport)
#else
#define DYNAMIC_DLL_API __declspec(dllimport)
#endif

// This class is exported from the dynamic_DLL.dll
class DYNAMIC_DLL_API Cdynamic_DLL {
public:
	Cdynamic_DLL(void);
	// TODO: add your methods here.
};

extern DYNAMIC_DLL_API int ndynamic_DLL;


DYNAMIC_DLL_API int fndynamic_DLL(void);

extern "C" DYNAMIC_DLL_API BOOL SetDIPSHook(DWORD dwThreadId);

xx.cpp

// dynamic_DLL.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "dynamic_DLL.h"
#include <stdio.h>
#include <winbase.h>
#include <Windows.h>
#include <WindowsX.h>
#include <assert.h>
#include "resource.h"
#include <atldef.h>
#include <CommCtrl.h>

#ifdef _MANAGED
#pragma managed(push, off)
#endif


#pragma data_seg("Shared")
HHOOK g_hHook = NULL;
DWORD g_dwThreadIdDIPS = 0;
#pragma data_seg()

// Instruct the linker to make the Shared section
// readable, writable, and shared.
#pragma comment(linker, "/section:Shared,rws")


HINSTANCE g_hInstDll = NULL;


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{

	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		g_hInstDll = hModule;
		printf("process_attach\n");
		break;
	case DLL_THREAD_ATTACH:
		printf("thread_attach\n");
		break;
	case DLL_THREAD_DETACH:
		printf("thread_detach\n");
		break;
	case DLL_PROCESS_DETACH:
		printf("process_detach\n");
		break;
	}
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

// This is an example of an exported variable
DYNAMIC_DLL_API int ndynamic_DLL=0;

// This is an example of an exported function.
DYNAMIC_DLL_API int fndynamic_DLL(void)
{
	return 42;
}

// This is the constructor of a class that has been exported.
// see dynamic_DLL.h for the class definition
Cdynamic_DLL::Cdynamic_DLL()
{
	return;
}

int MyAdd(int a,int b)
{
	
	return a + b;
}

int MyTest()
{
	return 10;
}
BOOL CALLBACK Dlg_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HWND hsysList =NULL;
	TCHAR buf[256]={0};
	HTREEITEM itemChild,Itemtwo,ItemThree;
	HTREEITEM itemRoot;
	TVITEMEX iteminfo;
	TCHAR temBuf[512];

	DWORD dwLen = 0;
	BOOL brs;

	switch(message)
	{
	case WM_APP:
		hsysList = (HWND)wParam;
		{
			DWORD dwMax = ListView_GetItemCount(hsysList);
			for (DWORD i=0; i < dwMax; ++i)
			{
				TCHAR Name[256] = {0};

				ListView_GetItemText(hsysList,i,0,Name,256);

				OutputDebugString(Name);
			}
		}
// 		itemRoot = TreeView_GetRoot(hwnd);
// 		brs = TreeView_Expand(hwnd, itemRoot,TVM_EXPAND);
// 		itemChild = TreeView_GetChild(hwnd,itemRoot);
// 		Itemtwo = TreeView_GetNextSibling(hwnd, itemChild);
// 		iteminfo.hItem = itemChild;
// 		iteminfo.mask = TVIF_TEXT;
// 		iteminfo.pszText = temBuf;
// 		iteminfo.cchTextMax = 512;
// 
// 		TreeView_GetItem(hwnd,&iteminfo);
// 
// 		iteminfo.hItem = Itemtwo;
// 
// 		TreeView_GetItem(hwnd,&iteminfo);

		
		return (TRUE);
	case WM_INITDIALOG:
        {
		//	MessageBox(NULL,L"1",L"1",MB_OK);
			ShowWindow(hDlg,SW_SHOWNORMAL);
        }
		return (TRUE);
	case WM_CLOSE:
        {
			DestroyWindow(hDlg);
        }
		return (TRUE);
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDCANCEL:
            {
                SendMessage(hDlg, WM_CLOSE, 0, 0);
            }
            return (TRUE);
		case IDOK:
            {
                
            }
			return (TRUE);
		}
		return (FALSE);
	}
	return (FALSE);
}
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {

	static BOOL bFirstTime = TRUE;

	if (bFirstTime) {
		// The DLL just got injected.
		bFirstTime = FALSE;

		// Uncomment the line below to invoke the debugger 
		// on the process that just got the injected DLL.
		// ForceDebugBreak();

		// Create the DIPS Server window to handle the client request.
		CreateDialog(g_hInstDll, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlg_Proc);

		// Tell the DIPS application that the server is up 
		// and ready to handle requests.
		PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0);
	}

	return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
}
DYNAMIC_DLL_API BOOL SetDIPSHook(DWORD dwThreadId)
{
	BOOL bOk = FALSE;

	if (dwThreadId != 0) {
		// Make sure that the hook is not already installed.
		assert(g_hHook == NULL);

		// Save our thread ID in a shared variable so that our GetMsgProc 
		// function can post a message back to the thread when the server 
		// window has been created.
		g_dwThreadIdDIPS = GetCurrentThreadId();

		// Install the hook on the specified thread
		g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, 
			dwThreadId);

		bOk = (g_hHook != NULL);
		if (bOk) {
			// The hook was installed successfully; force a benign message to 
			// the thread's queue so that the hook function gets called.
			bOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
		}
	} else {

		// Make sure that a hook has been installed.
		assert(g_hHook != NULL);
		bOk = UnhookWindowsHookEx(g_hHook);
		g_hHook = NULL;
	}

	return(bOk);
}

main.cpp

#include <stdio.h>
#include <windows.h>
#include <process.h>
#include "dynamic_DLL.h"
#include <assert.h>


int main(int argc, char* argv[])
{
	HWND hRegEdit_RegEdit = FindWindow(L"RegEdit_RegEdit",L"注册表编辑器");

	HWND hSysTreeView = GetDlgItem(hRegEdit_RegEdit,01);
	HWND hSysList = GetDlgItem(hRegEdit_RegEdit,02);

	
	BOOL b = SetDIPSHook(GetWindowThreadProcessId(hRegEdit_RegEdit,NULL));

	MSG msg;

	GetMessage(&msg,NULL,0,0);

	HWND hWndDIPS = FindWindow(NULL, TEXT("myTest"));

	SendMessage(hWndDIPS, WM_APP, (WPARAM)hSysList, 0);

	SendMessage(hWndDIPS, WM_CLOSE,0,0);

	assert(!IsWindow(hWndDIPS));

	SetDIPSHook(0);


	getchar();

	return 0;
}

 

下面的代码是在远端进程,创建一个线程,然后加载需要的DLL

/******************************************************************************
Module:  InjLib.cpp
Notices: Copyright (c) 2008 Jeffrey Richter & Christophe Nasarre
******************************************************************************/


#include "..\CommonFiles\CmnHdr.h"     /* See Appendix A. */
#include <windowsx.h>
#include <stdio.h>
#include <tchar.h>
#include <malloc.h>        // For alloca
#include <TlHelp32.h>
#include "Resource.h"
#include <StrSafe.h>



///////////////////////////////////////////////////////////////////////////////


#ifdef UNICODE
   #define InjectLib InjectLibW
   #define EjectLib  EjectLibW
#else
   #define InjectLib InjectLibA
   #define EjectLib  EjectLibA
#endif   // !UNICODE


///////////////////////////////////////////////////////////////////////////////


BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {

   BOOL bOk = FALSE; // Assume that the function fails
   HANDLE hProcess = NULL, hThread = NULL;
   PWSTR pszLibFileRemote = NULL;

   __try {
      // Get a handle for the target process.
      hProcess = OpenProcess(
         PROCESS_QUERY_INFORMATION |   // Required by Alpha
         PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
         PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
         PROCESS_VM_WRITE,             // For WriteProcessMemory
         FALSE, dwProcessId);
      if (hProcess == NULL) __leave;

      // Calculate the number of bytes needed for the DLL's pathname
      int cch = 1 + lstrlenW(pszLibFile);
      int cb  = cch * sizeof(wchar_t);

      // Allocate space in the remote process for the pathname
      pszLibFileRemote = (PWSTR) 
         VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
      if (pszLibFileRemote == NULL) __leave;

      // Copy the DLL's pathname to the remote process' address space
      if (!WriteProcessMemory(hProcess, pszLibFileRemote, 
         (PVOID) pszLibFile, cb, NULL)) __leave;

      // Get the real address of LoadLibraryW in Kernel32.dll
      PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
         GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
      if (pfnThreadRtn == NULL) __leave;

      // Create a remote thread that calls LoadLibraryW(DLLPathname)
      hThread = CreateRemoteThread(hProcess, NULL, 0, 
         pfnThreadRtn, pszLibFileRemote, 0, NULL);
      if (hThread == NULL) __leave;

      // Wait for the remote thread to terminate
      WaitForSingleObject(hThread, INFINITE);

      bOk = TRUE; // Everything executed successfully
   }
   __finally { // Now, we can clean everything up

      // Free the remote memory that contained the DLL's pathname
      if (pszLibFileRemote != NULL) 
         VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);

      if (hThread  != NULL) 
         CloseHandle(hThread);

      if (hProcess != NULL) 
         CloseHandle(hProcess);
   }

   return(bOk);
}


///////////////////////////////////////////////////////////////////////////////


BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {

   // Allocate a (stack) buffer for the Unicode version of the pathname
   SIZE_T cchSize = lstrlenA(pszLibFile) + 1;
   PWSTR pszLibFileW = (PWSTR) 
      _alloca(cchSize * sizeof(wchar_t));

   // Convert the ANSI pathname to its Unicode equivalent
   StringCchPrintfW(pszLibFileW, cchSize, L"%S", pszLibFile);

   // Call the Unicode version of the function to actually do the work.
   return(InjectLibW(dwProcessId, pszLibFileW));
}


///////////////////////////////////////////////////////////////////////////////


BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {

   BOOL bOk = FALSE; // Assume that the function fails
   HANDLE hthSnapshot = NULL;
   HANDLE hProcess = NULL, hThread = NULL;

   __try {
      // Grab a new snapshot of the process
      hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
      if (hthSnapshot == INVALID_HANDLE_VALUE) __leave;

      // Get the HMODULE of the desired library
      MODULEENTRY32W me = { sizeof(me) };
      BOOL bFound = FALSE;
      BOOL bMoreMods = Module32FirstW(hthSnapshot, &me);
      for (; bMoreMods; bMoreMods = Module32NextW(hthSnapshot, &me)) {
         bFound = (_wcsicmp(me.szModule,  pszLibFile) == 0) || 
                  (_wcsicmp(me.szExePath, pszLibFile) == 0);
         if (bFound) break;
      }
      if (!bFound) __leave;

      // Get a handle for the target process.
      hProcess = OpenProcess(
         PROCESS_QUERY_INFORMATION |   
         PROCESS_CREATE_THREAD     | 
         PROCESS_VM_OPERATION,  // For CreateRemoteThread
         FALSE, dwProcessId);
      if (hProcess == NULL) __leave;

      // Get the real address of FreeLibrary in Kernel32.dll
      PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
         GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");
      if (pfnThreadRtn == NULL) __leave;

      // Create a remote thread that calls FreeLibrary()
      hThread = CreateRemoteThread(hProcess, NULL, 0, 
         pfnThreadRtn, me.modBaseAddr, 0, NULL);
      if (hThread == NULL) __leave;

      // Wait for the remote thread to terminate
      WaitForSingleObject(hThread, INFINITE);

      bOk = TRUE; // Everything executed successfully
   }
   __finally { // Now we can clean everything up

      if (hthSnapshot != NULL) 
         CloseHandle(hthSnapshot);

      if (hThread     != NULL) 
         CloseHandle(hThread);

      if (hProcess    != NULL) 
         CloseHandle(hProcess);
   }

   return(bOk);
}


///////////////////////////////////////////////////////////////////////////////


BOOL WINAPI EjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {

   // Allocate a (stack) buffer for the Unicode version of the pathname
   SIZE_T cchSize = lstrlenA(pszLibFile) + 1;
   PWSTR pszLibFileW = (PWSTR) 
      _alloca(cchSize * sizeof(wchar_t));

   // Convert the ANSI pathname to its Unicode equivalent
      StringCchPrintfW(pszLibFileW, cchSize, L"%S", pszLibFile);

   // Call the Unicode version of the function to actually do the work.
   return(EjectLibW(dwProcessId, pszLibFileW));
}


///////////////////////////////////////////////////////////////////////////////


BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) {

   chSETDLGICONS(hWnd, IDI_INJLIB);
   return(TRUE);
}


///////////////////////////////////////////////////////////////////////////////


void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) {
   
   switch (id) {
      case IDCANCEL:
         EndDialog(hWnd, id);
         break;

      case IDC_INJECT:
         DWORD dwProcessId = GetDlgItemInt(hWnd, IDC_PROCESSID, NULL, FALSE);
         if (dwProcessId == 0) {
            // A process ID of 0 causes everything to take place in the 
            // local process; this makes things easier for debugging.
            dwProcessId = GetCurrentProcessId();
         }

         TCHAR szLibFile[MAX_PATH];
         GetModuleFileName(NULL, szLibFile, _countof(szLibFile));
         PTSTR pFilename = _tcsrchr(szLibFile, TEXT('\\')) + 1;
         _tcscpy_s(pFilename, _countof(szLibFile) - (pFilename - szLibFile),
             TEXT("22-ImgWalk.DLL"));
         if (InjectLib(dwProcessId, szLibFile)) {
            chVERIFY(EjectLib(dwProcessId, szLibFile));
            chMB("DLL Injection/Ejection successful.");
         } else {
            chMB("DLL Injection/Ejection failed.");
         }
         break;
   }
}


///////////////////////////////////////////////////////////////////////////////


INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

   switch (uMsg) {
      chHANDLE_DLGMSG(hWnd, WM_INITDIALOG, Dlg_OnInitDialog);
      chHANDLE_DLGMSG(hWnd, WM_COMMAND,    Dlg_OnCommand);
   }
   return(FALSE);
}


///////////////////////////////////////////////////////////////////////////////


int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int) {

   DialogBox(hInstExe, MAKEINTRESOURCE(IDD_INJLIB), NULL, Dlg_Proc);
   return(0);
}


//////////////////////////////// End of File //////////////////////////////////

 

/******************************************************************************
Module:  ImgWalk.cpp
Notices: Copyright (c) 2008 Jeffrey Richter & Christophe Nasarre
******************************************************************************/


#include "..\CommonFiles\CmnHdr.h"     /* See Appendix A. */
#include <tchar.h>


///////////////////////////////////////////////////////////////////////////////


BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, PVOID fImpLoad) {

   if (fdwReason == DLL_PROCESS_ATTACH) {
      char szBuf[MAX_PATH * 100] = { 0 };

      PBYTE pb = NULL;
      MEMORY_BASIC_INFORMATION mbi;
      while (VirtualQuery(pb, &mbi, sizeof(mbi)) == sizeof(mbi)) {

         int nLen;
         char szModName[MAX_PATH];

         if (mbi.State == MEM_FREE)
            mbi.AllocationBase = mbi.BaseAddress;

         if ((mbi.AllocationBase == hInstDll) ||
             (mbi.AllocationBase != mbi.BaseAddress) ||
             (mbi.AllocationBase == NULL)) {
            // Do not add the module name to the list
            // if any of the following is true:
            // 1. If this region contains this DLL
            // 2. If this block is NOT the beginning of a region
            // 3. If the address is NULL
            nLen = 0;
         } else {
            nLen = GetModuleFileNameA((HINSTANCE) mbi.AllocationBase, 
               szModName, _countof(szModName));
         }

         if (nLen > 0) {
            wsprintfA(strchr(szBuf, 0), "\n%p-%s", 
               mbi.AllocationBase, szModName);
         }

         pb += mbi.RegionSize;
      }

      // NOTE: Normally, you should not display a message box in DllMain
      // due to the loader lock described in Chapter 20. However, to keep
      // this sample application simple, I am violating this rule.
      chMB(&szBuf[1]);
   }

   return(TRUE);
}


//////////////////////////////// End of File //////////////////////////////////

 

 

抱歉!评论已关闭.