BOOL Initialize(PVOID BaseAddress) { PVOID hModule; SizeT Length, Length2; LPWSTR lpCmdLineW, pCmdLine; WChar end, szCmdLine[MAX_PATH + 40]; static WChar AddCmdLineHeadW[] = L" --user-data-dir=\""; static WChar AddCmdLineTailW[] = L"UserData\" --purge-memory-button"; LdrDisableThreadCalloutsForDll(BaseAddress); Length = Nt_GetSystemDirectory(szCmdLine, countof(szCmdLine)); CopyStruct(szCmdLine + Length, L"wtsapi32.dll", sizeof(L"wtsapi32.dll")); hModule = Ldr::LoadDll(szCmdLine); *(PVOID *)&StubWTSFreeMemory = GetRoutineAddress(hModule, "WTSFreeMemory"); *(PVOID *)&StubWTSQuerySessionInformationW = GetRoutineAddress(hModule, "WTSQuerySessionInformationW"); *(PVOID *)&StubWTSUnRegisterSessionNotification = GetRoutineAddress(hModule, "WTSUnRegisterSessionNotification"); *(PVOID *)&StubWTSRegisterSessionNotification = GetRoutineAddress(hModule, "WTSRegisterSessionNotification"); *(PVOID *)&StubWTSQueryUserToken = GetRoutineAddress(hModule, "WTSQueryUserToken"); lpCmdLineW = Ps::GetCommandLine(); Length = StrLengthW(lpCmdLineW); pCmdLine = szCmdLine; StrCopyW(pCmdLine, AddCmdLineHeadW); pCmdLine += countof(AddCmdLineHeadW) - 1; pCmdLine += Nt_GetExeDirectory(pCmdLine, countof(szCmdLine) - (pCmdLine - szCmdLine)); StrCopyW(pCmdLine, AddCmdLineTailW); pCmdLine += countof(AddCmdLineTailW); Length2 = pCmdLine - szCmdLine; g_pCmdLineW = (PWChar)AllocateMemory(Length * 2 + Length2 * 2 + 2); pCmdLine = lpCmdLineW; end = *pCmdLine++ == '\"' ? '\"' : ' '; while (*pCmdLine && *pCmdLine != end) ++pCmdLine; ++pCmdLine; /* if (*++pCmdLine) { while (*pCmdLine == ' ' || *pCmdLine == '\t') ++pCmdLine; } */ end = *pCmdLine; *pCmdLine = 0; StrCopyW(g_pCmdLineW, lpCmdLineW); *pCmdLine = end; lpCmdLineW = g_pCmdLineW + (pCmdLine - lpCmdLineW); StrCopyW(lpCmdLineW, szCmdLine); lpCmdLineW += Length2 - 1; StrCopyW(lpCmdLineW, pCmdLine); Length = StrLengthW(g_pCmdLineW); g_pCmdLineA = (PChar)AllocateMemory(Length * 2); // WideCharToMultiByte(CP_ACP, 0, g_pCmdLineW, -1, g_pCmdLineA, Length * 2, NULL, NULL); UnicodeToAnsi(g_pCmdLineA, Length * 2, g_pCmdLineW, -1); hModule = Nt_GetModuleHandle(L"chrome.dll"); MEMORY_FUNCTION_PATCH f[] = { INLINE_HOOK_JUMP_NULL(::GetCommandLineW, MyGetCommandLineW), INLINE_HOOK_JUMP_NULL(::GetCommandLineA, MyGetCommandLineA), INLINE_HOOK_JUMP(LoadAcceleratorsW, MyLoadAcceleratorsW, StubLoadAcceleratorsW), }; Nt_PatchMemory(0, 0, f, countof(f), 0); return TRUE; }
ForceInline VOID main2(Int argc, WChar **argv) { NTSTATUS Status; WCHAR *pExePath, szDllPath[MAX_NTPATH], FullExePath[MAX_NTPATH]; STARTUPINFOW si; PROCESS_INFORMATION pi; #if 0 PVOID buf; // CNtFileDisk file; UNICODE_STRING str; // file.Open((FIELD_BASE(FindLdrModuleByName(NULL)->InLoadOrderModuleList.Flink, LDR_MODULE, InLoadOrderModuleList))->FullDllName.Buffer); // buf = AllocateMemory(file.GetSize32()); // file.Read(buf); // file.Close(); RTL_CONST_STRING(str, L"OllyDbg.exe"); LoadDllFromMemory(GetNtdllHandle(), -1, &str, NULL, LMD_MAPPED_DLL); PrintConsoleW( L"%s handle = %08X\n" L"%s.NtSetEvent = %08X\n", str.Buffer, GetModuleHandleW(str.Buffer), str.Buffer, Nt_GetProcAddress(GetModuleHandleW(str.Buffer), "NtSetEvent") ); getch(); FreeMemory(buf); return; #endif #if 1 if (argc == 1) return; RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, (PBOOLEAN)&Status); while (--argc) { pExePath = findextw(*++argv); if (CHAR_UPPER4W(*(PULONG64)pExePath) == CHAR_UPPER4W(TAG4W('.LNK'))) { if (FAILED(GetPathFromLinkFile(*argv, FullExePath, countof(FullExePath)))) { pExePath = *argv; } else { pExePath = FullExePath; } } else { pExePath = *argv; } RtlGetFullPathName_U(pExePath, sizeof(szDllPath), szDllPath, NULL); #if 0 Status = FakeCreateProcess(szDllPath, NULL); if (!NT_SUCCESS(Status)) #else rmnamew(szDllPath); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); Status = CreateProcessInternalW( NULL, pExePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, *szDllPath == 0 ? NULL : szDllPath, &si, &pi, NULL); if (!Status) #endif { PrintConsoleW(L"%s: CreateProcess() failed\n", pExePath); continue; } ULONG Length; UNICODE_STRING DllFullPath; Length = Nt_GetExeDirectory(szDllPath, countof(szDllPath)); CopyStruct(szDllPath + Length, L"XP3Viewer.dll", sizeof(L"XP3Viewer.dll")); DllFullPath.Buffer = szDllPath; DllFullPath.Length = (USHORT)(Length + CONST_STRLEN(L"XP3Viewer.dll")); DllFullPath.Length *= sizeof(WCHAR); DllFullPath.MaximumLength = DllFullPath.Length; Status = InjectDllToRemoteProcess(pi.hProcess, pi.hThread, &DllFullPath, FALSE); if (!NT_SUCCESS(Status)) { // PrintError(GetLastError()); NtTerminateProcess(pi.hProcess, 0); } NtClose(pi.hProcess); NtClose(pi.hThread); } #endif }
NTSTATUS InjectSelfToRemoteProcess(HANDLE hProcess, HANDLE hThread) { NTSTATUS Status; PVOID pvBuffer; DWORD Length; WCHAR szSelfPath[MAX_PATH]; CONTEXT ThreadContext; LARGE_INTEGER TimeOut; INJECT_DLL_CURRENT_THREAD inj; ThreadContext.ContextFlags = CONTEXT_CONTROL; Status = NtGetContextThread(hThread, &ThreadContext); if (!NT_SUCCESS(Status)) { // BaseSetLastNTError(Status); // PrintError(RtlGetLastWin32Error()); return Status; } // PrintConsoleW(L"Eip = %08X\n", ThreadContext.Eip); // getch(); Length = Nt_GetExeDirectory(szSelfPath, countof(szSelfPath)); if (Length == NULL) return STATUS_UNSUCCESSFUL; static WCHAR szDll[] = L"LocaleEmulator.dll"; StrCopyW(szSelfPath + Length, szDll); Length += CONST_STRLEN(szDll); pvBuffer = NULL; Status = Nt_AllocateMemory(hProcess, &pvBuffer, MEMORY_PAGE_SIZE); if (!NT_SUCCESS(Status)) { // BaseSetLastNTError(Status); // PrintError(RtlGetLastWin32Error()); return Status; } Length *= sizeof(WCHAR); inj.pfLdrLoadDll = LdrLoadDll; inj.ReturnAddr = ThreadContext.Eip; inj.ModuleFileName.Length = Length; inj.ModuleFileName.MaximumLength = Length + sizeof(WCHAR); inj.ModuleFileName.Buffer = (LPWSTR)((ULONG_PTR)pvBuffer + sizeof(inj)); Status = STATUS_UNSUCCESSFUL; LOOP_ONCE { Status = Nt_WriteMemory(hProcess, pvBuffer, &inj, sizeof(inj)); if (!NT_SUCCESS(Status)) break; Length += sizeof(WCHAR); Status = Nt_WriteMemory(hProcess, (PVOID)((ULONG_PTR)pvBuffer + sizeof(inj)), szSelfPath, Length); if (!NT_SUCCESS(Status)) break; ThreadContext.Eip = (DWORD)(PBYTE)pvBuffer + sizeof(inj) + Length; Status = Nt_WriteMemory( hProcess, (PVOID)ThreadContext.Eip, LoadExternDll, (ULONG_PTR)_LoadExternDllEnd - (ULONG_PTR)LoadExternDll ); if (!NT_SUCCESS(Status)) break; Status = NtSetContextThread(hThread, &ThreadContext); if (!NT_SUCCESS(Status)) break; Status = NtResumeThread(hThread, NULL); if (!NT_SUCCESS(Status)) break; BaseFormatTimeOut(&TimeOut, 500); for (DWORD TryTimes = 30; TryTimes; --TryTimes) { DWORD Val; Status = Nt_ReadMemory(hProcess, pvBuffer, &Val, sizeof(Val)); if (!NT_SUCCESS(Status)) break; if (Val != 0) { NtDelayExecution(FALSE, &TimeOut); continue; } break; } if (!NT_SUCCESS(Status)) break; NtDelayExecution(FALSE, &TimeOut); Status = NtGetContextThread(hThread, &ThreadContext); if (!NT_SUCCESS(Status)) break; if ((ULONG_PTR)ThreadContext.Eip < (ULONG_PTR)pvBuffer || (ULONG_PTR)ThreadContext.Eip > (ULONG_PTR)pvBuffer + MEMORY_PAGE_SIZE) { Status = STATUS_SUCCESS; } else { Status = STATUS_UNSUCCESSFUL; } } // BaseSetLastNTError(Status); // PrintError(RtlGetLastWin32Error()); // Nt_FreeMemory(hProcess, pvBuffer); return Status; }