From fb82ecfec5893b00f68b72f912c6b3975b5fdb4f Mon Sep 17 00:00:00 2001
From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com>
Date: Mon, 6 Sep 2021 00:24:52 +0100
Subject: moving to using unpacked for launcher
---
LauncherInjector/LauncherInjector.vcxproj | 10 +
LauncherInjector/LauncherInjector.vcxproj.filters | 15 ++
LauncherInjector/main.cpp | 236 +++++++++-------------
LauncherInjector/ns_icon.ico | Bin 0 -> 4286 bytes
LauncherInjector/resource1.h | 16 ++
LauncherInjector/resources.rc | 71 +++++++
6 files changed, 204 insertions(+), 144 deletions(-)
create mode 100644 LauncherInjector/ns_icon.ico
create mode 100644 LauncherInjector/resource1.h
create mode 100644 LauncherInjector/resources.rc
(limited to 'LauncherInjector')
diff --git a/LauncherInjector/LauncherInjector.vcxproj b/LauncherInjector/LauncherInjector.vcxproj
index 620303b1..07d45e75 100644
--- a/LauncherInjector/LauncherInjector.vcxproj
+++ b/LauncherInjector/LauncherInjector.vcxproj
@@ -24,6 +24,7 @@
{0ea82cb0-53fe-4d4c-96df-47fa970513d0}
LauncherInjector
10.0
+ NorthstarLauncher
@@ -147,6 +148,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/LauncherInjector/LauncherInjector.vcxproj.filters b/LauncherInjector/LauncherInjector.vcxproj.filters
index ce0c35cc..87e25fa8 100644
--- a/LauncherInjector/LauncherInjector.vcxproj.filters
+++ b/LauncherInjector/LauncherInjector.vcxproj.filters
@@ -19,4 +19,19 @@
Source Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
\ No newline at end of file
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp
index 86c50804..c335390b 100644
--- a/LauncherInjector/main.cpp
+++ b/LauncherInjector/main.cpp
@@ -8,155 +8,103 @@ namespace fs = std::filesystem;
DWORD GetProcessByName(std::wstring processName)
{
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-
- PROCESSENTRY32 processSnapshotEntry = { 0 };
- processSnapshotEntry.dwSize = sizeof(PROCESSENTRY32);
-
- if (snapshot == INVALID_HANDLE_VALUE)
- return 0;
-
- if (!Process32First(snapshot, &processSnapshotEntry))
- return 0;
-
- while (Process32Next(snapshot, &processSnapshotEntry))
- {
- if (!wcscmp(processSnapshotEntry.szExeFile, processName.c_str()))
- {
- CloseHandle(snapshot);
- return processSnapshotEntry.th32ProcessID;
- }
- }
-
- CloseHandle(snapshot);
- return 0;
-}
-
-void InjectInjectorIntoProcess(DWORD pid)
-{
- HANDLE procHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
-
- std::wstring path = (fs::current_path() / "GameInjector.dll").wstring();
- size_t length = (path.length() + 1) * 2;
- LPVOID lpLibName = VirtualAllocEx(procHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(procHandle, lpLibName, path.c_str(), length, 0);
-
- // load minhook, since origin's loadlibrary won't load it from the tf directly by default
- std::wstring minhookPath = (fs::current_path() / "MinHook.x86.dll").wstring();
- size_t minhookLength = (minhookPath.length() + 1) * 2;
- LPVOID lpMinhookLibName = VirtualAllocEx(procHandle, NULL, minhookLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(procHandle, lpMinhookLibName, minhookPath.c_str(), minhookLength, 0);
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
- LPTHREAD_START_ROUTINE pLoadLibraryW = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryW");
- HANDLE thread = CreateRemoteThread(procHandle, NULL, 0, pLoadLibraryW, lpMinhookLibName, 0, 0);
- WaitForSingleObject(thread, INFINITE);
+ PROCESSENTRY32 processSnapshotEntry = { 0 };
+ processSnapshotEntry.dwSize = sizeof(PROCESSENTRY32);
- thread = CreateRemoteThread(procHandle, NULL, 0, pLoadLibraryW, lpLibName, 0, 0);
- WaitForSingleObject(thread, INFINITE);
+ if (snapshot == INVALID_HANDLE_VALUE)
+ return 0;
- DWORD dwExitCode;
- GetExitCodeThread(thread, &dwExitCode);
- std::cout << dwExitCode << std::endl;
+ if (!Process32First(snapshot, &processSnapshotEntry))
+ return 0;
- CloseHandle(procHandle);
+ while (Process32Next(snapshot, &processSnapshotEntry))
+ {
+ if (!wcscmp(processSnapshotEntry.szExeFile, processName.c_str()))
+ {
+ CloseHandle(snapshot);
+ return processSnapshotEntry.th32ProcessID;
+ }
+ }
- std::cout << pid << std::endl;
+ CloseHandle(snapshot);
+ return 0;
}
-void CreateAndHookUnpackedTitanfallProcess()
-{
- PROCESS_INFORMATION tfPi;
- memset(&tfPi, 0, sizeof(tfPi));
- STARTUPINFO si;
- memset(&si, 0, sizeof(si));
- CreateProcessA("Titanfall2-unpacked.exe", (LPSTR)"", NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, (LPSTARTUPINFOA)&si, &tfPi);
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(pi));
- memset(&si, 0, sizeof(si));
-
- std::stringstream argStream;
- argStream << tfPi.dwProcessId;
- argStream << " ";
- argStream << tfPi.dwThreadId;
-
- CreateProcessA("InjectionProxy64.exe", (LPSTR)(argStream.str().c_str()), NULL, NULL, false, 0, NULL, NULL, (LPSTARTUPINFOA)&si, &pi);
- WaitForSingleObject(pi.hThread, INFINITE);
-
- CloseHandle(pi.hThread);
- CloseHandle(tfPi.hThread);
-}
-
-int main()
-{
- //AllocConsole();
-
- // check if we're in the titanfall directory
- if (!fs::exists("Titanfall2.exe") && !fs::exists("Titanfall2-unpacked.exe"))
- {
- MessageBox(NULL, L"Titanfall2.exe not found! Please launch from your titanfall 2 directory!", L"", MB_OK);
- return 1;
- }
-
- // check for steam dll and unpacked exe
- bool unpacked = fs::exists("Titanfall2-unpacked.exe");
- //bool steamBuild = !unpacked && fs::exists("steam_api64.dll"); // dont actually need to check for this
-
- // unpacked origin
- if (unpacked)
- {
- // check origin process
- DWORD origin = GetProcessByName(L"Origin.exe");
-
- if (!origin)
- {
- // unpacked exe will crash if origin isn't open on launch, so launch it
- // get origin path from registry, code here is reversed from OriginSDK.dll
- HKEY key;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Origin", 0, KEY_READ, &key) != ERROR_SUCCESS)
- return 1;
-
- char originPath[520];
- DWORD originPathLength = 520;
- if (RegQueryValueExA(key, "ClientPath", 0, 0, (LPBYTE)&originPath, &originPathLength) != ERROR_SUCCESS)
- return 1;
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(pi));
- STARTUPINFO si;
- memset(&si, 0, sizeof(si));
- CreateProcessA(originPath, (LPSTR)"", NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, (LPSTARTUPINFOA)&si, &pi);
-
- // bit of a hack, but wait 12.5s to give origin a sec to init
- // would be nice if we could do this dynamically, but idk how rn
- Sleep(12500);
- }
-
- CreateAndHookUnpackedTitanfallProcess();
- }
- // packed
- else
- {
- // create a titanfall process, this will cause origin to start launching the game
- // if we're on steam, origin will launch the steam release here, too
- // we can't hook the titanfall process here unfortunately, since the titanfall process we create here dies when origin stuff starts
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(pi));
- STARTUPINFO si;
- memset(&si, 0, sizeof(si));
- CreateProcessA("Titanfall2.exe", (LPSTR)"", NULL, NULL, false, 0, NULL, NULL, (LPSTARTUPINFOA)&si, &pi);
-
- // hook launcher
- DWORD launcherPID;
- // dont actually need to check for steam, origin launches game no matter what
- //if (steamBuild)
- // while (!(launcherPID = GetProcessByName(L"EASteamProxy.exe"))) Sleep(50);
- //else
- while (!(launcherPID = GetProcessByName(L"Origin.exe"))) Sleep(50);
-
- // injector should clean itself up after its job is done
- InjectInjectorIntoProcess(launcherPID);
- }
+#define PROCESS_NAME L"Titanfall2-unpacked.exe"
+#define DLL_NAME L"Northstar.dll"
+
+int main() {
+ if (!fs::exists(PROCESS_NAME))
+ {
+ MessageBoxA(0, "Titanfall2-unpacked.exe not found! Please launch from your titanfall 2 directory and ensure you have Northstar installed correctly!", "", MB_OK);
+ return 1;
+ }
+
+ if (!fs::exists(DLL_NAME))
+ {
+ MessageBoxA(0, "Northstar.dll not found! Please launch from your titanfall 2 directory and ensure you have Northstar installed correctly!", "", MB_OK);
+ return 1;
+ }
+
+ if (!GetProcessByName(L"Origin.exe"))
+ {
+ // unpacked exe will crash if origin isn't open on launch, so launch it
+ // get origin path from registry, code here is reversed from OriginSDK.dll
+ HKEY key;
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Origin", 0, KEY_READ, &key) != ERROR_SUCCESS)
+ {
+ MessageBoxA(0, "Error: failed reading origin path!", "", MB_OK);
+ return 1;
+ }
+
+ char originPath[520];
+ DWORD originPathLength = 520;
+ if (RegQueryValueExA(key, "ClientPath", 0, 0, (LPBYTE)&originPath, &originPathLength) != ERROR_SUCCESS)
+ {
+ MessageBoxA(0, "Error: failed reading origin path!", "", MB_OK);
+ return 1;
+ }
+
+ PROCESS_INFORMATION pi;
+ memset(&pi, 0, sizeof(pi));
+ STARTUPINFO si;
+ memset(&si, 0, sizeof(si));
+ CreateProcessA(originPath, (LPSTR)"", NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, (LPSTARTUPINFOA)&si, &pi);
+
+ // wait for origin to be ready, this process is created when origin is ready enough to launch game without any errors
+ while (!GetProcessByName(L"OriginClientService.exe"))
+ Sleep(200);
+ }
+
+ STARTUPINFO startupInfo;
+ PROCESS_INFORMATION processInfo;
+
+ memset(&startupInfo, 0, sizeof(startupInfo));
+ memset(&processInfo, 0, sizeof(processInfo));
+
+ CreateProcessW(PROCESS_NAME, (LPWSTR)L"-multiple -novid", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfo);
+
+ HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
+ LPTHREAD_START_ROUTINE pLoadLibraryW = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryW");
+
+ SIZE_T dwLength = (wcslen(DLL_NAME) + 1) * 2;
+ LPVOID lpLibName = VirtualAllocEx(processInfo.hProcess, NULL, dwLength, MEM_COMMIT, PAGE_READWRITE);
+
+ SIZE_T written = 0;
+ WriteProcessMemory(processInfo.hProcess, lpLibName, DLL_NAME, dwLength, &written);
+
+ HANDLE hThread = CreateRemoteThread(processInfo.hProcess, NULL, NULL, pLoadLibraryW, lpLibName, NULL, NULL);
+ WaitForSingleObject(hThread, INFINITE);
+ CloseHandle(hThread);
+
+ ResumeThread(processInfo.hThread);
+
+ VirtualFreeEx(processInfo.hProcess, lpLibName, dwLength, MEM_RELEASE);
+
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+
+ return 0;
}
\ No newline at end of file
diff --git a/LauncherInjector/ns_icon.ico b/LauncherInjector/ns_icon.ico
new file mode 100644
index 00000000..eb78efef
Binary files /dev/null and b/LauncherInjector/ns_icon.ico differ
diff --git a/LauncherInjector/resource1.h b/LauncherInjector/resource1.h
new file mode 100644
index 00000000..60157c4b
--- /dev/null
+++ b/LauncherInjector/resource1.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resources.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/LauncherInjector/resources.rc b/LauncherInjector/resources.rc
new file mode 100644
index 00000000..a51894c4
--- /dev/null
+++ b/LauncherInjector/resources.rc
@@ -0,0 +1,71 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource1.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United Kingdom) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource1.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON "ns_icon.ico"
+
+#endif // English (United Kingdom) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
--
cgit v1.2.3