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