int APIENTRY _tWinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
TCHAR szCommandLine[] _T("目标进程");
TCHAR szCurPath[] = _T("当前目录");
WCHAR szTagetDLLName[256] = L"目标DLL";
PWSTR pszRemoteDLLName = NULL;
HANDLE hRemoteThread = NULL;
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PROCESS_INFORMATION ProcessInfo = { 0 };
PTHREAD_START_ROUTINE pfnLoadLibraryAddress = NULL;
HANDLE hTheFileMaping = NULL;
LPREMOTEDATA pTheRemoteData = NULL;
__try
{
//获得本地进程路径名称
GetModuleFileNameW(hInstance, szTagetDLLName, 256);
//获得目标DLL路径名称,假定目标DLL本地进程在同一个目录。
WCHAR * p = szTagetDLLName + lstrlenW(szTagetDLLName) - 1;
while( (*p != L'\\') && (p != szTagetDLLName) )
p --;
p ++;
*p = L'\0';
lstrcatW(szTagetDLLName, L"TagetDll.DLL");
//获取LoadLibraryW在Kernel32.DLL中的地址,用于作为远线程的入口地址。
pfnLoadLibraryAddress = ( PTHREAD_START_ROUTINE )
GetProcAddress( GetModuleHandle( _T("Kernel32") ), "LoadLibraryW" );
if( NULL == pfnLoadLibraryAddress )
__leave;
//创建内存文件映射,用于目标DLL注入后共享访问。
hTheFileMaping = CreateFileMapping( INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof( REMOTEDATA ),
_T("InsertDLLRemoteData") );
if( NULL == hTheFileMaping )
__leave;
//如果文件映射已经存在,表明另一个实例尚未运行完毕。
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
MessageBox( NULL, _T("另一个实例尚未加载完毕,请等待该实例加载完毕后再试。"), _T("错误"), MB_OK );
__leave;
}
pTheRemoteData = ( LPREMOTEDATA ) MapViewOfFile( hTheFileMaping,
FILE_MAP_WRITE,
0,
0,
0 );
if( NULL == pTheRemoteData )
__leave;
//创建目标进程并获得目标进程句柄。(若目标进程已经存在,则需打开目标进程以获得句柄)
if(! CreateProcess( NULL,
szCommandLine,
NULL,
NULL,
FALSE,
0,
NULL,
szCurPath,
&StartupInfo,
&ProcessInfo ))
__leave;
//为共享数据赋值,以供目标DLL加载后使用
pTheRemoteData->dwTagetThreadID = ProcessInfo.dwThreadId;
if( !InitRemoteData(pTheRemoteData, ProcessInfo.hProcess) )
{
MessageBox( NULL,_T("读取角色信息失败,请联系QQ:703252627"),_T("请升级"),MB_OK );
__leave;
}
//计算存放目标DLL路径和名字需要的空间尺寸。
SIZE_T cbSize = ( lstrlenW(szTagetDLLName)+1 ) * sizeof(WCHAR);
//在目标进程中远程申请空间,用于存放目标DLL的路径和名字。
pszRemoteDLLName = (PWSTR) VirtualAllocEx( ProcessInfo.hProcess,
NULL,
cbSize,
MEM_COMMIT,
PAGE_READWRITE);
if( NULL == pszRemoteDLLName )
__leave;
//将目标DLL的路径和名字写入到远进程地址空间中,用于作为LoadLibrary的参数。
if(! WriteProcessMemory( ProcessInfo.hProcess,
pszRemoteDLLName,
(LPVOID)szTagetDLLName,
cbSize,
NULL))
__leave;
//在目标进程中创建远线程并运行
hRemoteThread = CreateRemoteThread( ProcessInfo.hProcess,
NULL,
0,
pfnLoadLibraryAddress,
pszRemoteDLLName,
0,
NULL );
if( NULL == hRemoteThread )
__leave;
//等待远线程结束并获取其返回值
DWORD dwExitCode = 0;
WaitForSingleObject( hRemoteThread, INFINITE );
GetExitCodeThread( hRemoteThread, &dwExitCode );
//判断目标DLL是否被成功注入
if( 0 == dwExitCode )
{
//注入没有成功,可能是目标DLL不存在或者目标DLL的DllMain返回了FALSE。
MessageBox( NULL,_T("目标DLL注入失败!"), _T("错误"), MB_OK );
__leave;
}
else
{
//注入成功。dwExitCode事实上是目标DLL的模块句柄。
//MessageBox( NULL,_T("目标DLL注入成功!"), _T("成功"), MB_OK );
}
}
__finally
{
//释放资源
if( pTheRemoteData != NULL )
UnmapViewOfFile( pTheRemoteData );
if( hTheFileMaping != NULL )
CloseHandle( hTheFileMaping );
if( pszRemoteDLLName != NULL )
VirtualFreeEx( ProcessInfo.hProcess, pszRemoteDLLName, 0, MEM_RELEASE );
if( ProcessInfo.hThread != NULL )
CloseHandle( ProcessInfo.hThread );
if( ProcessInfo.hProcess != NULL )
CloseHandle( ProcessInfo.hProcess );
if( hRemoteThread != NULL )
CloseHandle( hRemoteThread );
}
return 0;
}
这段代码可以做一些修改,不要显示的创建一个进程,而是打开系统内常运行的进程,这样,别人就看不到你的进程了,但是它确实在工作。
另外,需要把你想干的事情放到一个DLL中,并在DllMain里面作一些处理即可。