• 使用DLL远程注入对记事本换肤


    源代码下载

       详细阐述了如何使用DLL远程注入技术对Windows 记事本进行换肤,讲解了DLL远程注入的概念和步骤。

    关键词DLL远程注入,换肤

    一、概述

          1. DLL远程注入原理

              DLL远程注入就是使用远程线程来插入DLL,就是要求目标进程中的线程调用LoadLibrary函数来加载必要的DLL。由于除了自己进程中的线程外,我们无法方便地控制其它进程中的线程,因此这种解决方案要求我们在目标进程中创建一个新线程。由于是自己创建这个线程,因此我们能够控制它执行什么代码。

    Windows提供了一个称为CreaeRemoteThread的函数,使我们能够非常容易地在另一个进程中创建线程:

    HANDLE CreateRemoteThread(HANDLE hProcess,PSECURITY_ARRTRIBUTES psa,DWORD dwStackSize,

                             PTHREAD_START_ROUTINE pfnStartAddr,PVOID pvParam,DWORD fdwCreate,PDOWRD pdwThreadId);

              如何才能让该线程加载我们的DLL呢?那就需要该线程调用LoadLibrary函数:

              HINSTANCE LoadLibraryA (LPCSTR pszLibFileName);                   //ANSI 版本

              HINSTANCE LoadLibraryW (LPCWSTR pszLibFileName);             //Unicode版本

             我们现在要做的事情是创建一个新线程,并使线程函数的地址成为LoadLibraryALoadLibraryW函数的地址。

             PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)

                       GetProcAddress(GetModuleHandle(TEXT(“kernel32”)),”LoadLibraryA”);

             HANDLE hThread = CreateRemoteThread(hProcessRemote,NULL,0,pfnThreadRtn,”C:""MyLib.dll”,0,NULL);

             细心的读者应该注意到一个问题:就是字符串”C:""MyLib.dll”是在调用进程的地址空间中,会导致远程进程的线程可能引发访问违规。所以我们必须将DLL的路径名字符串放入远程进程的地址空间中。

    // 向目标进程地址空间写入DLL名称
    DWORD dwSize, dwWritten;
    dwSize = lstrlenA( lpszDll ) + 1;
    LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
    WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten )

    HANDLE hThread = CreateRemoteThread(hProcessRemote,NULL,0,pfnThreadRtn, lpBuf, 0,NULL);

    // 等待LoadLibrary加载完毕,对字符串空间进行回收

    VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );

        这时,DLL已经被插入远程的地址空间中,同时DLLDllMain函数接收到一个DLL_PROCESS_ATTACH通知,并且能够执行需要的代码。

             需要提醒的是,这种插入DLL的方法存在唯一一个不足是,Windows98并不支持这样的函数。只能用在Window2000及以上版本。

     2. 对记事本换肤

             要对记事本换肤,需要解决2个问题:

    第一、找到能对程序进行换肤DLL文件,这里我们采用Skin++ (www.uipower.com)作为换肤DLL

    第二、能将DLL远程注入到记事本的方法,该方法我们在上面已经做了介绍。

            

    二、换肤的关键部分代码

             TCHAR szLibFileName[_MAX_PATH];

             GetModuleFileName(NULL, szLibFileName,_MAX_PATH);

             CString strLibFileName(szLibFileName);

             strLibFileName = strLibFileName.Left(strLibFileName.ReverseFind(_T('""')) + 1);

             strLibFileName += _T("SkinPlusPlus.dll");

             _tcscpy(szLibFileName,strLibFileName);

             HWND hNotepad = ::FindWindow(_T("Notepad"),NULL);

             if (hNotepad == NULL) return;

             DWORD dwRemoteProcessId;

             ::GetWindowThreadProcessId( hNotepad, (DWORD*)&dwRemoteProcessId );

             HANDLE hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |

    PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE,dwRemoteProcessId);

             //计算DLL路径名需要的内存空间

             int cb = (1 + _tcslen(szLibFileName)) * sizeof(TCHAR);

             //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区

             BYTE* pszLibFileRemote = (BYTE*) VirtualAllocEx( hRemoteProcess, NULL, cb,MEM_COMMIT, PAGE_EXECUTE_READWRITE);

             //使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间

             int iReturnCode = WriteProcessMemory(hRemoteProcess,pszLibFileRemote, (PVOID)szLibFileName,cb, NULL);

             //计算LoadLibraryW的入口地址

             PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");

             //启动远程线程LoadLibraryW,通过远程线程调用用户的DLL文件

             HANDLE hThread = CreateRemoteThread( hRemoteProcess, NULL, 0,pfnStartAddr, pszLibFileRemote, 0, NULL);

             WaitForSingleObject( hThread, INFINITE );

             DWORD dwHandle;

             GetExitCodeThread( hThread, &dwHandle );

             VirtualFreeEx( hRemoteProcess, pszLibFileRemote, cb, MEM_DECOMMIT );

             CloseHandle( hThread );

             ::SetForegroundWindow(hNotepad);

    三、结束语

             DLL的远程注入技术和软件换肤是目前Windows上非常流行的2项技术,您可以在很多场合同时看到这2者的身影,比如MSNShell。有兴趣的读者可以到http://www.msnshell.com/上下载使用。

  • 相关阅读:
    如何阅读修改代码
    C C++ TDD单元测试非常好的书
    应用代理 socket TCP协议 的资料
    闲聊桌面应用开发[Win16->Win32->ATL/WTL/MFC->WinForm->WPF/Silverlight/WinRT]
    MySQL sharding的几个参考地址
    ubuntu环境变量
    Angular JS | Closure | Google Web Toolkit | Dart | Polymer 概要汇集
    Linux下的应用程序性能分析 总结
    ubuntu处理中文时设置locale
    Tomcat https自制证书和浏览器配置
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/1229784.html
Copyright © 2020-2023  润新知