Windows 코어 프로그래밍의 Dll 주입

다음은 레지스트리 편집기 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
"); break; case DLL_THREAD_ATTACH: printf("thread_attach
"); break; case DLL_THREAD_DETACH: printf("thread_detach
"); break; case DLL_PROCESS_DETACH: printf("process_detach
"); 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), "
%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 //////////////////////////////////

 

좋은 웹페이지 즐겨찾기