流程
DLL注入:
1.提升注入者权限(AddDebugPrivilege添加一个Debug权限)
2.打开被注入的目标进程获取句柄(OpenProcess传入目标进程ID)
3.在目标进程中分配内存(VirtualAllocEx传入句柄分配内存)
4.将DLL路径写入到目标内存中(WriteProcessMemory传入分配后返回的地址)
5.获取kernel32中LoadLibraryA地址,调用CreateRemoteThread在目标进程中加载DLL(GetProcAddress获取函数地址)
6.DLL中DLLMAIN执行,注入成功
7.释放内存
直接注入:
1.准备好一个注入函数(还要准备一个相邻的空函数用来计算注入函数大小)
2.提高注入者的权限(同上)
3.打开目标进程(同上)
4.在目标进程分配内存(分配两块分别存放代码和参数&返回值)
5.将函数写入到分配的内存中(WriteProcessMemory)
6.执行写入的函数(CreateRemoteThread创建远程线程执行函数)
7.执行成功后获取结果并释放内存
实现
提升注入者权限
BOOL AddDebugPrivilege(void)
{
TOKEN_PRIVILEGES tp;
LUID luid;
HANDLE hToken;
if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
{
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid=luid;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,&hToken))
{
return FALSE;
}
if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL))
{
return FALSE;
}
return TRUE;
}
打开被注入者目标进程
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE,PID/*目标进程ID*/);
注入DLL(分配内存、写入、执行、释放。参数为被注入线程的句柄和DLL路径)
int InjectDll( HANDLE hProcess, char* szLibPath)
{
HANDLE hThread;
void* pLibRemote = 0; // the address (in the remote process) where
DWORD hLibModule = 0; // base adress of loaded module (==HMODULE);
HMODULE hKernel32 = ::GetModuleHandle("Kernel32");
if (szLibPath == NULL || hProcess == NULL)
return FALSE;
pLibRemote = ::VirtualAllocEx( hProcess, NULL, strlen(szLibPath)+1, MEM_COMMIT, PAGE_READWRITE );
if( pLibRemote == NULL )
return false;
::WriteProcessMemory(hProcess, pLibRemote, (void*)szLibPath,strlen(szLibPath)+1,NULL);
hThread = ::CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,“LoadLibraryA”), pLibRemote, 0, NULL );
//UNICODE为GetProcAddressW
if( hThread == NULL )
goto JUMP;
::WaitForSingleObject( hThread, INFINITE );
::GetExitCodeThread( hThread, &hLibModule );
::CloseHandle( hThread );
JUMP:
::VirtualFreeEx( hProcess, pLibRemote, strlen(szLibPath)+1, MEM_RELEASE );
if( hLibModule == NULL )
return false;
return hLibModule;
}
直接注入函数(分配内存、写入、执行、释放。参数为被注入线程的句柄)
void InjCode (HANDLE hProcess)
{
INJDATA *pDataRemote;
DWORD *pCodeRemote;
HANDLE hThread = NULL;
DWORD dwThreadId = 0;
DWORD dwNumBytesXferred = 0;
pDataRemote = (INJDATA*) VirtualAllocEx( hProcess, 0, sizeof(INJDATA), MEM_COMMIT,
PAGE_READWRITE );
WriteProcessMemory( hProcess, pDataRemote, &DataLocal, sizeof(INJDATA), &dwNumBytesXferred );
const int cbCodeSize = ((LPBYTE) AfterThreadFunc - (LPBYTE) ThreadFunc);
pCodeRemote = (PDWORD) VirtualAllocEx( hProcess, 0, cbCodeSize, MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
WriteProcessMemory( hProcess, pCodeRemote, &ThreadFunc, cbCodeSize, &dwNumBytesXferred );
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pCodeRemote, pDataRemote, 0 , &dwThreadId);
WaitForSingleObject(hThread, INFINITE);
ReadProcessMemory( hProcess, pDataRemote, &DataLocal, sizeof(INJDATA), &dwNumBytesXferred);
//需要判断pDataRemote,pCodeRemote,hThread的有效性
VirtualFreeEx( hProcess, pDataRemote, 0, MEM_RELEASE );
VirtualFreeEx( hProcess, pCodeRemote, 0, MEM_RELEASE );
CloseHandle(hThread);
}
代码来自麦洛克菲