码迷,mamicode.com
首页 > 其他好文 > 详细

劫持注入DLL

时间:2015-02-28 14:20:29      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

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);
}
///////////////

 

劫持注入DLL

标签:

原文地址:http://www.cnblogs.com/wumac/p/4305217.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!