недавно нагуглил исходник инжекта dll в Winlogon и решил выдрать оттуда код для собственного использования, но при адаптатации онго всвоем приложении вылетаю в синьку в функции CreateRemoteThread : Код (Text): DWORD LoadDllInProcessEx(DWORD dwPid,char* DllPathName) { HANDLE hProcess,hThread; RemoteProcessData rpd; PWSTR pwModuleFileName; HANDLE hModule=NULL; UNICODE_STRING usModule; LPVOID lpParameters,lpThread; SECURITY_ATTRIBUTES saSecAttr; DWORD dwActual,dwResult=0,rc; hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); if (hProcess==NULL) goto cleanup; rpd.pLdrLoadDll=(LDRLOADDLL)GetProcAddress(GetModuleHandle("ntdll"),"LdrLoadDll"); if (!rpd.pLdrLoadDll) goto cleanup; rpd.Flags=0; rpd.PathToFile=NULL; rpd.ModuleHandle=NULL; pwModuleFileName=(PWSTR)malloc((strlen(DllPathName)*2)+1); if (!pwModuleFileName) goto cleanup; MultiByteToWideChar(CP_ACP,0,DllPathName,strlen(DllPathName),pwModuleFileName,(strlen(DllPathName)*2)+1); usModule.Buffer=(PWSTR)InjectData(hProcess,pwModuleFileName,(strlen(DllPathName)*2)+1); free(pwModuleFileName); if (!usModule.Buffer) goto cleanup; usModule.Length=(strlen(DllPathName)*2)+1; usModule.MaximumLength=(strlen(DllPathName)*2)+1; memcpy(&rpd.ModuleFileName,&usModule,sizeof(UNICODE_STRING)); lpParameters=InjectData(hProcess,&rpd,sizeof(RemoteProcessData)+4096); if (!lpParameters) goto cleanup; lpThread=InjectData(hProcess,&RemoteThread,(PBYTE)EndRemoteThread-(PBYTE)RemoteThread+4096); if (!lpThread) goto cleanup; // Set security attributes saSecAttr.nLength=sizeof(SECURITY_ATTRIBUTES); saSecAttr.lpSecurityDescriptor = NULL; saSecAttr.bInheritHandle = TRUE; hThread=CreateRemoteThread(hProcess,&saSecAttr,0,(LPTHREAD_START_ROUTINE)lpThread,lpParameters,0,&dwActual); if (hThread==NULL) goto cleanup; rc=WaitForSingleObject(hThread, INFINITE); switch (rc) { case WAIT_TIMEOUT: break; case WAIT_FAILED: break; case WAIT_OBJECT_0: if (ReadProcessMemory(hProcess,lpParameters,&rpd,sizeof(RemoteProcessData),&dwActual)) dwResult=(DWORD)rpd.ModuleHandle; break; default: break; } cleanup: if (rpd.ModuleFileName.Buffer!=NULL) VirtualFreeEx(hProcess,rpd.ModuleFileName.Buffer,0,MEM_RELEASE); if (lpParameters!=NULL) VirtualFreeEx(hProcess,lpParameters,0,MEM_RELEASE); if (lpThread!=NULL) VirtualFreeEx(hProcess,lpThread,0,MEM_RELEASE); if (hThread) CloseHandle(hThread); if (hProcess) CloseHandle(hProcess); return dwResult; } Привелелии на отладку получаюься ,VirtualAllocEx и WriteProcessMemory отрабатыают нормально ,но в итоге синий экран . В чем может быть причина ?
просто тестирую Код (Text): BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
Код (Text): ; dwPID - идентификатор процесса ; lpDllName - имя DLL ; lpProcAddress - адрес LoadLibraryA InjectDll proc dwPID, lpDllName, lpProcAddress : DWORD LOCAL lpMemory : DWORD LOCAL hProcess : DWORD xinvoke OpenProcess, PROCESS_ALL_ACCESS, 0, dwPID test eax, eax jnz @F ret @@: mov hProcess, eax xinvoke VirtualAllocEx, hProcess, 0, 10, MEM_COMMIT, PAGE_EXECUTE_READWRITE test eax, eax jz _proc_close mov lpMemory, eax xinvoke _strlen, lpDllName xinvoke WriteProcessMemory, hProcess, lpMemory, lpDllName, eax, offset dwBytes test eax, eax jz _free_mem xinvoke CreateRemoteThread, hProcess, 0, 0, lpProcAddress, lpMemory, 0, offset dwBytes test eax, eax jz _free_mem xinvoke CloseHandle, eax _free_mem: push eax xinvoke VirtualFree, lpMemory, 0, MEM_RELEASE pop eax _proc_close: push eax xinvoke CloseHandle, hProcess pop eax ret InjectDll endp
вообще код взят из Winlogonhijack Injector Written by JeFFOsZ _http://en.pudn.com/downloads3/sourcecode/hack/detail11999_en.html
main.cpp Код (Text): #include <windows.h> #include <tlhelp32.h> #include <tchar.h> #include <stdio.h> #include "injector.h" #define PROCESS_SIZE MAX_PATH #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004 typedef LONG NTSTATUS; // NTQUERYSYSTEMINFORMATION typedef struct _tagThreadInfo { FILETIME ftCreationTime; DWORD dwUnknown1; DWORD dwStartAddress; DWORD dwOwningPID; DWORD dwThreadID; DWORD dwCurrentPriority; DWORD dwBasePriority; DWORD dwContextSwitches; DWORD dwThreadState; DWORD dwWaitReason; DWORD dwUnknown2[5]; } THREADINFO, *PTHREADINFO; #pragma warning(disable:4200) typedef struct _tagProcessInfo { DWORD dwOffset; DWORD dwThreadCount; DWORD dwUnknown1[6]; FILETIME ftCreationTime; DWORD dwUnknown2[5]; WCHAR* pszProcessName; DWORD dwBasePriority; DWORD dwProcessID; DWORD dwParentProcessID; DWORD dwHandleCount; DWORD dwUnknown3; DWORD dwUnknown4; DWORD dwVirtualBytesPeak; DWORD dwVirtualBytes; DWORD dwPageFaults; DWORD dwWorkingSetPeak; DWORD dwWorkingSet; DWORD dwUnknown5; DWORD dwPagedPool; DWORD dwUnknown6; DWORD dwNonPagedPool; DWORD dwPageFileBytesPeak; DWORD dwPrivateBytes; DWORD dwPageFileBytes; DWORD dwUnknown7[4]; THREADINFO ti[0]; } _PROCESSINFO, *PPROCESSINFO; #pragma warning( default:4200 ) long(__stdcall *NtQuerySystemInformation)(ULONG,PVOID,ULONG,ULONG)=NULL; // END NTQUERYSYSTEMINFORMATION ULONG InjectAllWinLogons(char* argv) { PBYTE pbyInfo = NULL; DWORD cInfoSize = 0x2000; ULONG ret=0; CHAR szProcessName[PROCESS_SIZE]; PPROCESSINFO pProcessInfo; BOOL bLast; DWORD dwResult=0; if (!NtQuerySystemInformation) NtQuerySystemInformation=(long( __stdcall * )(ULONG,PVOID,ULONG,ULONG)) GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation"); pbyInfo=(PBYTE)malloc(cInfoSize); if (pbyInfo) { while(NtQuerySystemInformation(5,pbyInfo,cInfoSize,0)==STATUS_INFO_LENGTH_MISMATCH) // check for size { cInfoSize += 0x2000; pbyInfo=(PBYTE)realloc(pbyInfo,cInfoSize); } pProcessInfo=(PPROCESSINFO)pbyInfo; bLast = FALSE; do { if (pProcessInfo->dwOffset==0) // last? bLast = TRUE; if (pProcessInfo->dwProcessID!=0) // ignore system idle { WideCharToMultiByte(CP_ACP, 0, pProcessInfo->pszProcessName, -1,szProcessName, PROCESS_SIZE, NULL, NULL); // convert processname if (strnicmp(szProcessName,"winlogon.exe",11)==0) { printf("[*] LoadDllInProcess(PID: %u): ",pProcessInfo->dwProcessID); // Load our DLL in the given process if (dwResult=LoadDllInProcessEx(pProcessInfo->dwProcessID,argv)) printf("OK (Base: 0x%08X).\r\n",dwResult); else printf("FAILED.\r\n"); } ret++; } pProcessInfo=(PPROCESSINFO)((PBYTE)pProcessInfo+pProcessInfo->dwOffset); // next } while(bLast==FALSE); free(pbyInfo); } return ret; } int main(int argc,char* argv[]) { BOOL bNt,bDeb; DWORD dwMinorVer,dwMajorVer; TOKEN_PRIVILEGES tkpOld; printf("[+] Winlogon Hijack v0.3 Injector written by JeFFOsZ\r\n"); // Check if we're running on a NT based windows. bNt=IsWinNt(&dwMajorVer,&dwMinorVer); printf("[*] IsWinNt(): "); if (bNt) printf("OK [Version: %d.%d].\r\n",dwMajorVer,dwMinorVer); else { printf("FAILED.\r\n"); return 0; } // Get debug privileges bDeb=GetDebugPriv(&tkpOld); printf("[*] GetDebugPriv(): "); if (bDeb) printf("OK.\r\n"); else { printf("FAILED.\r\n"); return 0; } // Inject all "winlogon.exe" processes. InjectAllWinLogons("c:\\HOOK.dll"); return 0; } ijector.cpp Код (Text): //////////////////////////////////////////////////////////////////// // // This file contains the functions that are used for injecting data // and loading a dll in a remote process. Written by JeFFOsZ // //////////////////////////////////////////////////////////////////// #include <WINDOWS.H> #include <STDIO.H> #include "injector.h" BOOL GetDebugPriv(PTOKEN_PRIVILEGES ptkpPrev) { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; BOOL bRet; ULONG ulRet; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) return FALSE; bRet=LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue); if (!bRet) { CloseHandle(hToken); return bRet; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet=AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),ptkpPrev,&ulRet); CloseHandle(hToken); return bRet; } BOOL RestorePrivileges(TOKEN_PRIVILEGES tkp) { HANDLE hToken; BOOL bRet; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) return FALSE; bRet=AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL); CloseHandle(hToken); return bRet; } BOOL IsWinNt(PDWORD pdwMajorVersion,PDWORD pdwMinorVersion) { OSVERSIONINFO ovi; DWORD lRet; ovi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); lRet=GetVersionEx(&ovi); if (!lRet) return FALSE; if (ovi.dwPlatformId!=VER_PLATFORM_WIN32_NT) return FALSE; *pdwMajorVersion=ovi.dwMajorVersion; *pdwMinorVersion=ovi.dwMinorVersion; return TRUE; } LPVOID InjectData(HANDLE hProcess,LPVOID lpData,ULONG ulFuncLen) { LPVOID lpAddress=NULL; DWORD dwOldProtect; DWORD BytesWritten=0; // Allocate memory for lpData int the remote process lpAddress=VirtualAllocEx(hProcess,NULL,ulFuncLen,MEM_COMMIT|MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE); if (lpAddress) { // Change the protection for the allocated memory if (VirtualProtectEx(hProcess,lpAddress,ulFuncLen,PAGE_EXECUTE_READWRITE,&dwOldProtect)) { // ... FlushInstructionCache(hProcess,lpAddress,ulFuncLen); // Write lpData into the remote process if (WriteProcessMemory(hProcess,lpAddress,lpData,ulFuncLen,&BytesWritten)) { // Restore old protection :) VirtualProtectEx(hProcess,lpAddress,ulFuncLen,dwOldProtect,NULL); // Return remote address for lpData return lpAddress; } // Restore old protection :) VirtualProtectEx(hProcess,lpAddress,ulFuncLen,dwOldProtect,NULL); } } return 0; } // !! we use LoadDllInProcessEx instead !!! // Loads a dll in a process, uses kernel32.LoadLibraryA // NOTE: we should use NTDLL.LdrLoadDll instead ! /*BOOL LoadDllInProcess(DWORD dwPid,char* DllPathName) { HANDLE hProcess,hThread; ULONG ulSize; SECURITY_ATTRIBUTES saSecAttr; DWORD dwActual; LPVOID lpAddress=NULL; HMODULE hmKernel32; FARPROC fpLoadLibraryA; // Open process if (hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid)) { ulSize=strlen(DllPathName)+1; // size to write if (lpAddress=InjectData(hProcess,DllPathName,ulSize)) // Inject the LoadLibraryA parameter in the process { // Set security attributes saSecAttr.nLength=sizeof(SECURITY_ATTRIBUTES); saSecAttr.lpSecurityDescriptor = NULL; saSecAttr.bInheritHandle = TRUE; // Get address from kernel32 hmKernel32=GetModuleHandle("kernel32"); // Get address from kernel32.LoadLibraryA fpLoadLibraryA=GetProcAddress(hmKernel32,"LoadLibraryA"); // Execute LoadLibraryA in the process if (hThread=CreateRemoteThread(hProcess,&saSecAttr,0,(LPTHREAD_START_ROUTINE)fpLoadLibraryA,lpAddress,0,&dwActual)) { // Wait till thread responds WaitForSingleObject(hThread, INFINITE); // Get result for unhooking ?? // Free memory allocated by InjectData VirtualFreeEx(hProcess, lpAddress, ulSize, MEM_RELEASE); // close remotethreead handle CloseHandle(hThread); // close process handle CloseHandle(hProcess); return TRUE; } } CloseHandle(hProcess); } return FALSE; }*/ NTSTATUS __stdcall RemoteThread(RemoteProcessData *rpd) { NTSTATUS rc= (NTSTATUS)rpd->pLdrLoadDll( rpd->PathToFile, rpd->Flags, &rpd->ModuleFileName, &rpd->ModuleHandle ); return rc; } void __stdcall EndRemoteThread(void) { } // Loads a dll in a process (uses ntdll.LdrLoadData) DWORD LoadDllInProcessEx(DWORD dwPid,char* DllPathName) { HANDLE hProcess,hThread; RemoteProcessData rpd; PWSTR pwModuleFileName; HANDLE hModule=NULL; UNICODE_STRING usModule; LPVOID lpParameters,lpThread; SECURITY_ATTRIBUTES saSecAttr; DWORD dwActual,dwResult=0,rc; hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); if (hProcess==NULL) goto cleanup; rpd.pLdrLoadDll=(LDRLOADDLL)GetProcAddress(GetModuleHandle("ntdll"),"LdrLoadDll"); if (!rpd.pLdrLoadDll) goto cleanup; rpd.Flags=0; rpd.PathToFile=NULL; rpd.ModuleHandle=NULL; pwModuleFileName=(PWSTR)malloc((strlen(DllPathName)*2)+1); if (!pwModuleFileName) goto cleanup; MultiByteToWideChar(CP_ACP,0,DllPathName,strlen(DllPathName),pwModuleFileName,(strlen(DllPathName)*2)+1); usModule.Buffer=(PWSTR)InjectData(hProcess,pwModuleFileName,(strlen(DllPathName)*2)+1); free(pwModuleFileName); if (!usModule.Buffer) goto cleanup; usModule.Length=(strlen(DllPathName)*2)+1; usModule.MaximumLength=(strlen(DllPathName)*2)+1; memcpy(&rpd.ModuleFileName,&usModule,sizeof(UNICODE_STRING)); lpParameters=InjectData(hProcess,&rpd,sizeof(RemoteProcessData)+4096); if (!lpParameters) goto cleanup; lpThread=InjectData(hProcess,&RemoteThread,(PBYTE)EndRemoteThread-(PBYTE)RemoteThread+4096); if (!lpThread) goto cleanup; // Set security attributes saSecAttr.nLength=sizeof(SECURITY_ATTRIBUTES); saSecAttr.lpSecurityDescriptor = NULL; saSecAttr.bInheritHandle = TRUE; hThread=CreateRemoteThread(hProcess,&saSecAttr,0,(LPTHREAD_START_ROUTINE)lpThread,lpParameters,0,&dwActual); if (hThread==NULL) goto cleanup; rc=WaitForSingleObject(hThread, INFINITE); switch (rc) { case WAIT_TIMEOUT: break; case WAIT_FAILED: break; case WAIT_OBJECT_0: if (ReadProcessMemory(hProcess,lpParameters,&rpd,sizeof(RemoteProcessData),&dwActual)) dwResult=(DWORD)rpd.ModuleHandle; break; default: break; } cleanup: if (rpd.ModuleFileName.Buffer!=NULL) VirtualFreeEx(hProcess,rpd.ModuleFileName.Buffer,0,MEM_RELEASE); if (lpParameters!=NULL) VirtualFreeEx(hProcess,lpParameters,0,MEM_RELEASE); if (lpThread!=NULL) VirtualFreeEx(hProcess,lpThread,0,MEM_RELEASE); if (hThread) CloseHandle(hThread); if (hProcess) CloseHandle(hProcess); return dwResult; } injector.h Код (Text): #define NTSTATUS LONG #define NTAPI __stdcall #define NTSYSAPI DECLSPEC_IMPORT #define ACCESS_MASK DWORD; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef NTSTATUS (NTAPI* LDRLOADDLL)(PWCHAR,ULONG,PUNICODE_STRING,PHANDLE); typedef struct _RemoteProcessData { LDRLOADDLL pLdrLoadDll; PWCHAR PathToFile; ULONG Flags; UNICODE_STRING ModuleFileName; HANDLE ModuleHandle; } RemoteProcessData; // Get debug privileges BOOL GetDebugPriv(PTOKEN_PRIVILEGES); // Restores original privileges BOOL RestorePrivileges(TOKEN_PRIVILEGES); // Checks for NT and returns version numbers when true BOOL IsWinNt(PDWORD,PDWORD); // Injects data into a process and returns the address of the data LPVOID InjectData(HANDLE,LPVOID,ULONG); // Loads a dll in a process. (uses kernel32.LoadLibraryA). // Use LoadDllInProcessEx instead ! // BOOL LoadDllInProcess(DWORD,char*); // Loads a dll in a process (uses ntdll.LdrLoadDll) and returns the // ModuleHandle. DWORD LoadDllInProcessEx(DWORD,char*);
quporos Бсодит так как процесс завершается с ошибкой. Размеры структур для слепка различны в версиях. Их размер нужно находить динамически. Используйте поиск. Ошибка может быть где угодно, например исключение. Для решения таких проблем используют отладчик. Более того винлогон отлаживается олей без проблем. Аттачитесь к процессу, ставите брейк на NtContinue и запускаете свой тред. Там будет видно где проблема.