劫持注入DLL

void CControlDlg::InjectionTheDll(PROCESS_INFORMATION pi)
{
    CString csDllPath = m_csDirPath + _T("client.dll");
    if (csDllPath.IsEmpty())
    {
        AfxMessageBox(_T("无法找到client.dll"));
        return;
    }

    HANDLE hFile = CreateFile( m_csMainPath.GetBuffer(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
    if( hFile == NULL )
    {
        AfxMessageBox(_T("打开目标文件失败")) ;
        return;
    }
    HANDLE hMapping = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
    CloseHandle( hFile );
    if( hMapping == NULL )
    {
        AfxMessageBox( _T("打开目标文件映射失败"));
        return;
    }
    LPVOID lpMapFile = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
    if( lpMapFile == NULL )
    {
        AfxMessageBox( _T("映射目标文件失败") );
        return;
    }
    CloseHandle( hMapping );

    //已经完成文件映射
    PIMAGE_DOS_HEADER lpstDosHeader = (PIMAGE_DOS_HEADER)lpMapFile;
    PIMAGE_NT_HEADERS lpstNtHeaders = (PIMAGE_NT_HEADERS)( (ULONG)lpMapFile + lpstDosHeader->e_lfanew );
    DWORD dwPeEntry = lpstNtHeaders->OptionalHeader.AddressOfEntryPoint+lpstNtHeaders->OptionalHeader.ImageBase;
    DWORD dwSizeOfImage = lpstNtHeaders->OptionalHeader.SizeOfImage;

    //1.查找第一个call地址
    BYTE bCode = 0, nFind = 0;
    DWORD dwReadAddr = dwPeEntry;
    while(TRUE)
    {
        bool bOk = ReadProcessMemory( pi.hProcess, (LPVOID)dwReadAddr, &bCode, 1, NULL );
        if (bCode == 0xe8)
        {
            break;
        }
        if( !bOk )
        {
            AfxMessageBox( _T("查找第一个call地址出错") );
            return;
        }
        dwReadAddr++;
    }

    //2.计算被替换函数的入口地址
    DWORD dwCallAddr  = 0;
    bool bOk = ReadProcessMemory( pi.hProcess, (LPVOID)(dwReadAddr+1), &dwCallAddr, 4, NULL );
    if( !bOk )
    {
        AfxMessageBox(_T("查找第一个call地址出错"));
        return;

    }
    DWORD dwOldFuncAddr = dwReadAddr+5+dwCallAddr;

    //3.编写shellcode
    //shellcode格式
    /*

    $ ==>    >  60              pushad
    $+1      >  9C              pushfd
    $+2      >  68 11111111     push    11111111    //加载的dll名称
    $+7      >  E8 444288A5     call    22222222    //LoadLibraryA地址
    $+C      >  9D              popfd
    $+D      >  61              popad
    $+13     >- E9 495399B6     jmp     33333333    //跳转到第一个call函数开始
    */
    char lpShellCode[] = {
        0x60,
        0x9c,
        0x68,0x90,0x90,0x90,0x90,
        0xe8,0x90,0x90,0x90,0x90,
        0x9d,
        0x61,
        0xe9,0x90,0x90,0x90,0x90};

        LPVOID lpDllPathAddr = VirtualAllocEx( pi.hProcess, NULL, csDllPath.GetLength()+1, MEM_COMMIT, PAGE_READWRITE );

        bOk = WriteProcessMemory( pi.hProcess, lpDllPathAddr, csDllPath.GetBuffer(), csDllPath.GetLength()*sizeof(TCHAR), NULL);
        int n = GetLastError();
        if( !bOk )
        {
            AfxMessageBox(_T("写目标进程空间dll路径失败"));

        }

        LPVOID lpLoadLibraryAddr = GetProcAddress( GetModuleHandle(_T("kernel32.dll")), "LoadLibraryW" );

        LPVOID lpShellCodeAddr = VirtualAllocEx( pi.hProcess, NULL, strlen(lpShellCode)+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
        if( lpShellCodeAddr == NULL )
        {
            AfxMessageBox(_T("申请目标进程空间shellcode失败"));
        }

        //组合shellcode
        memcpy( lpShellCode+3, (char*)&lpDllPathAddr, 4 );
        DWORD dwFuncAddr = (DWORD)lpLoadLibraryAddr - ((DWORD)lpShellCodeAddr+7)-5;
        memcpy( lpShellCode+8, (char*)&dwFuncAddr, 4 );
        DWORD dwJmpEnd = dwOldFuncAddr - ((DWORD)lpShellCodeAddr+14) -5;
        memcpy( lpShellCode+15, (char*)&dwJmpEnd, 4 );

        //4.写入shellcode,及改变原来函数入口
        bOk = WriteProcessMemory( pi.hProcess, lpShellCodeAddr, lpShellCode, 30, NULL );
        if( !bOk )
        {
            AfxMessageBox( _T("写目标进程shellcode失败" ));
        }
        //计算call的新地址
        DWORD dwNewCallAddr = (DWORD)lpShellCodeAddr - (dwReadAddr+5);
        BYTE byJmpCode = 0xE9;

        MEMORY_BASIC_INFORMATION  stMemBasicInfor = {0};
        VirtualQueryEx( pi.hProcess, (PVOID)dwReadAddr, &stMemBasicInfor, sizeof(MEMORY_BASIC_INFORMATION) );
        DWORD dwOldProtect = 0;
        VirtualProtectEx( pi.hProcess, stMemBasicInfor.BaseAddress, stMemBasicInfor.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect );
        //写入jmp指令
        //WriteProcessMemory( pi.hProcess, (PVOID)dwReadAddr, &byJmpCode, 1, NULL );
        //写入jmp的地址
        bOk = WriteProcessMemory( pi.hProcess, (PVOID)(dwReadAddr+1), &dwNewCallAddr, 4, NULL );
        VirtualProtectEx( pi.hProcess, stMemBasicInfor.BaseAddress, stMemBasicInfor.RegionSize, dwOldProtect, NULL );
        if( !bOk )
        {
            AfxMessageBox(_T("写目标进程第一个call地址失败"));
        }

        //处理多开,临时方法,以后应该完善
//         DWORD dwAddr = MULTI_INSTANCE;
//         DWORD dwRealSize = 0;
//         byte byNew = 0xEB;
//         WriteProcessMemory(pi.hProcess, (LPVOID)dwAddr, &byNew, 1, &dwRealSize);
        ResumeThread(pi.hThread);
}
///////////////
时间: 2024-10-08 15:00:27

劫持注入DLL的相关文章

N种内核注入DLL的思路及实现

内核注入,技术古老但很实用.现在部分RK趋向无进程,玩的是SYS+DLL,有的无文件,全部存在于内存中.可能有部分人会说:"都进内核了.什么不能干?".是啊,要是内核中可以做包括R3上所有能做的事,软件开发商们也没必要做应用程序了.有时,我们确实需要R3程序去干驱动做起来很困难或者没必要驱动中去做的事,进程 /  DLL是不错的选择,但进程目标太大,所以更多的同学趋向于注DLL.     若要开发安全软件.小型工具,可借鉴其思路,Anti Rootkits时,在某些极端情况下,可使用同

[转]N种内核注入DLL的思路及实现

内核注入,技术古老但很实用.现在部分RK趋向无进程,玩的是SYS+DLL,有的无文件,全部存在于内存中.可能有部分人会说:“都进内核了.什么不能干?”.是啊,要是内核中可以做包括R3上所有能做的事,软件开发商们也没必要做应用程序了.有时,我们确实需要R3程序去干驱动做起来很困难或者没必要驱动中去做的事,进程 /  DLL是不错的选择,但进程目标太大,所以更多的同学趋向于注DLL.     若要开发安全软件.小型工具,可借鉴其思路,Anti Rootkits时,在某些极端情况下,可使用同样的技术发

创建进程时注入DLL

#include "stdafx.h" #include <Windows.h> // 函数声明 typedef BOOL (WINAPI* Proc_CreateProcessW)(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInherit

注入 - 远线程注入DLL到目标进程

// // 函数 -- void InjectDLL(LPCTSTR) // // 功能 -- 注入DLL到指定窗口 // // @param -- 要注入的DLL全路径 // // 返回值 -- 无 // void InjectDLL(LPCTSTR lpDLLFullPath) { DWORD dwPID = 0; // 目标进程PID HANDLE hGameProcess = NULL; // 目标进程句柄 LPDWORD lpdwAddr = NULL; // 远程申请的内存空间地址

SetThreadContext注入DLL

注入DLL的方式有很多 R3就有远程线程CreateRemoteThread.SetWindowsHookEx.QueueUserApc.SetThreadContext R0可以参考sudami大神的思路 关于本文32位下参考 http://bbs.pediy.com/showthread.php?t=181174&highlight=setthreadContext+dll+%E6%B3%A8%E5%85%A5 言归正传 大体思路就是 我们先打开目标进程,枚举目标线程采用的是系统快照的方式,

Windows x86/ x64 Ring3层注入Dll总结

0x01.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线程.Apc等等,这里我对Ring3层的Dll注入学习做一个总结吧. 我把注入的方法分成六类,分别是:1.创建新线程.2.设置线程上下背景文,修改寄存器.3.插入Apc队列.4.修改注册表.5.挂钩窗口消息.6.远程手动实现LoadLibrary. 那么下面就开始学习之旅吧! 0x02.预备工作 在涉及到注入的程序中,提升程序的权限自然是必不可少的,这里我提供了两个封装的函数,都可以用于提权.第一个是通过权限令牌来调整权限

远程创建线程注入DLL

HANDLE WINAPI CreateRemoteThread(__in HANDLE hProcess,__in LPSECURITY_ATTRIBUTES lpThreadAttributes,__in SIZE_T dwStackSize,__in LPTHREAD_START_ROUTINE lpStartAddress,__in LPVOID lpParameter,__in DWORD dwCreationFlags,__out LPDWORD lpThreadId);hProce

【windows核心编程】使用远程线程注入DLL

前言 该技术是指通过在[目标进程]中创建一个[远程线程]来达到注入的目的. 创建的[远程线程]函数为LoadLibrary, 线程函数的参数为DLL名字, 想要做的工作在DLL中编写.  示意图如下:  相关API 1.创建远程线程 //该函数除了第一个参数为目标进程句柄外 //其他参数均和CreateThread一样 HANDLE hThread = CreateRemoteThread( __in HANDLE hProcess, //目标进程句柄 __in_opt LPSECURITY_A

远程线程注入dll

// CommonInject.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <WinUser.h> #include <WinDef.h> #include <iostream> #include <Tlhelp32.h> using namespa