1
0
mirror of synced 2025-02-01 04:15:50 +01:00

Add EX3 Loader and Star Wars support

- Add EX3 Loader. Star Wars, Time Crisis 5 etc need RCLauncher.exe selected not the main exe.
- Star Wars support modules.
- Ancient PE parser
This commit is contained in:
Reaver 2019-11-15 02:51:43 +02:00
parent 6e962e60c8
commit 8f746177e2
7 changed files with 445 additions and 1 deletions

View File

@ -0,0 +1,153 @@
#include <StdInc.h>
#ifdef _M_AMD64
#include "Utility/ES3XLauncherHook.h"
#include "Utility/InitFunction.h"
#include "Functions/Global.h"
static unsigned char hasp_buffer[0xD40];
static void GenerateDongleData()
{
memset(hasp_buffer, 0, 0xD40);
hasp_buffer[0] = 0x01;
hasp_buffer[0x13] = 0x01;
hasp_buffer[0x17] = 0x0A;
hasp_buffer[0x1B] = 0x04;
hasp_buffer[0x1C] = 0x3B;
hasp_buffer[0x1D] = 0x6B;
hasp_buffer[0x1E] = 0x40;
hasp_buffer[0x1F] = 0x87;
hasp_buffer[0x23] = 0x01;
hasp_buffer[0x27] = 0x0A;
hasp_buffer[0x2B] = 0x04;
hasp_buffer[0x2C] = 0x3B;
hasp_buffer[0x2D] = 0x6B;
hasp_buffer[0x2E] = 0x40;
hasp_buffer[0x2F] = 0x87;
memcpy(hasp_buffer + 0xD00, "274320990002", 12);
hasp_buffer[0xD3E] = 0x6A;
hasp_buffer[0xD3F] = 0x95;
}
#define HASP_STATUS_OK 0
static unsigned int Hook_hasp_login(int feature_id, void* vendor_code, int hasp_handle) {
#ifdef _DEBUG
OutputDebugStringA("hasp_login\n");
#endif
return HASP_STATUS_OK;
}
static unsigned int Hook_hasp_logout(int hasp_handle) {
#ifdef _DEBUG
OutputDebugStringA("hasp_logout\n");
#endif
return HASP_STATUS_OK;
}
static unsigned int Hook_hasp_encrypt(int hasp_handle, unsigned char* buffer, unsigned int buffer_size) {
#ifdef _DEBUG
OutputDebugStringA("hasp_encrypt\n");
#endif
return HASP_STATUS_OK;
}
static unsigned int Hook_hasp_decrypt(int hasp_handle, unsigned char* buffer, unsigned int buffer_size) {
#ifdef _DEBUG
OutputDebugStringA("hasp_decrypt\n");
#endif
return HASP_STATUS_OK;
}
static unsigned int Hook_hasp_get_size(int hasp_handle, int hasp_fileid, unsigned int* hasp_size) {
#ifdef _DEBUG
OutputDebugStringA("hasp_get_size\n");
#endif
*hasp_size = 0xD40; // Max addressable size by the game... absmax is 4k
return HASP_STATUS_OK;
}
static unsigned int Hook_hasp_read(int hasp_handle, int hasp_fileid, unsigned int offset, unsigned int length, unsigned char* buffer) {
#ifdef _DEBUG
OutputDebugStringA("hasp_read\n");
#endif
memcpy(buffer, hasp_buffer + offset, length);
return HASP_STATUS_OK;
}
static unsigned int Hook_hasp_write(int hasp_handle, int hasp_fileid, unsigned int offset, unsigned int length, unsigned char* buffer) {
return HASP_STATUS_OK;
}
extern LPCSTR hookPort;
static InitFunction StarWarsEs3XFunc([]()
{
hookPort = "COM3";
GenerateDongleData();
MH_Initialize();
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_write", Hook_hasp_write, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_read", Hook_hasp_read, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_get_size", Hook_hasp_get_size, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_decrypt", Hook_hasp_decrypt, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_encrypt", Hook_hasp_encrypt, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_logout", Hook_hasp_logout, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_login", Hook_hasp_login, NULL);
MH_EnableHook(MH_ALL_HOOKS);
}, GameID::StarWarsEs3X);
static InitFunction StarWarsEs3XLauncherFunc([]()
{
uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0);
GenerateDongleData();
MH_Initialize();
MH_CreateHookApi(L"kernel32.dll", "CreateProcessW", CreateProcessWHook, (void**)&g_origCreateProcessW);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_write", Hook_hasp_write, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_read", Hook_hasp_read, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_get_size", Hook_hasp_get_size, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_decrypt", Hook_hasp_decrypt, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_encrypt", Hook_hasp_encrypt, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_logout", Hook_hasp_logout, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_login", Hook_hasp_login, NULL);
MH_EnableHook(MH_ALL_HOOKS);
// Ignore Projector Error
injector::WriteMemory<BYTE>(imageBase + 0x35580, 0xC3, true);
hookPort = "COM3";
}, GameID::StarWarsEs3XLauncher);
static InitFunction StarWarsJapEs3XLauncherFunc([]()
{
uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0);
GenerateDongleData();
MH_Initialize();
MH_CreateHookApi(L"kernel32.dll", "CreateProcessW", CreateProcessWHook, (void**)& g_origCreateProcessW);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_write", Hook_hasp_write, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_read", Hook_hasp_read, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_get_size", Hook_hasp_get_size, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_decrypt", Hook_hasp_decrypt, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_encrypt", Hook_hasp_encrypt, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_logout", Hook_hasp_logout, NULL);
MH_CreateHookApi(L"hasp_windows_x64_100610.dll", "hasp_login", Hook_hasp_login, NULL);
MH_EnableHook(MH_ALL_HOOKS);
// Ignore Projector Error
injector::WriteMemory<BYTE>(imageBase + 0x3E4D0, 0xC3, true);
// Ignore powershell
injector::MakeRET(imageBase + 0x5E440);
injector::MakeRET(imageBase + 0x5E540);
hookPort = "COM3";
}, GameID::StarWarsJapEs3XLauncher);
#endif

57
OpenParrot/src/PE.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "PE.H"
DWORD PEAlign(DWORD dwTarNum, DWORD dwAlignTo);
PEStruct getPEFileInformation(char *filename)
{
HANDLE hFile;
PEStruct pRetnStruct;
pRetnStruct.fileSize = 0;
DWORD dwBytesRead;
hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!hFile)
return pRetnStruct;
pRetnStruct.fileSize = GetFileSize(hFile, 0);
if (!pRetnStruct.fileSize)
return pRetnStruct;
pRetnStruct.fileImage = malloc(pRetnStruct.fileSize);
if (!pRetnStruct.fileImage)
return pRetnStruct;
ReadFile(hFile, pRetnStruct.fileImage, pRetnStruct.fileSize, &dwBytesRead, NULL);
CloseHandle(hFile);
if (!dwBytesRead)
return pRetnStruct;
//copy portions to relevant sections
CopyMemory(&pRetnStruct.image_dos_header, pRetnStruct.fileImage, sizeof(IMAGE_DOS_HEADER));
CopyMemory(&pRetnStruct.image_nt_headers,
((BYTE *)pRetnStruct.fileImage + pRetnStruct.image_dos_header.e_lfanew), sizeof(IMAGE_NT_HEADERS));
//address of first section
pRetnStruct.dwRO_first_section = pRetnStruct.image_dos_header.e_lfanew + sizeof(IMAGE_NT_HEADERS);
pRetnStruct.numOfSecs = pRetnStruct.image_nt_headers.FileHeader.NumberOfSections;
CopyMemory(&pRetnStruct.image_section_header, ((BYTE *)pRetnStruct.fileImage + pRetnStruct.dwRO_first_section),
pRetnStruct.numOfSecs*sizeof(IMAGE_SECTION_HEADER));
//now to fill in individual sections (.text .data)
for (int i = 0; i < pRetnStruct.numOfSecs; i++)
{
pRetnStruct.image_section[i] = (char *)malloc(PEAlign(pRetnStruct.image_section_header[i].SizeOfRawData,
pRetnStruct.image_nt_headers.OptionalHeader.FileAlignment));
CopyMemory(pRetnStruct.image_section[i], ((BYTE *)pRetnStruct.fileImage + pRetnStruct.image_section_header[i].PointerToRawData),
pRetnStruct.image_section_header[i].SizeOfRawData);
}
return pRetnStruct;
}
//googled function to correct file alignement in PE header.
//Just makes sure the outputted number will align correctly with the rest of the data.
DWORD PEAlign(DWORD dwTarNum, DWORD dwAlignTo)
{
DWORD dwtemp;
dwtemp = dwTarNum / dwAlignTo;
if ((dwTarNum%dwAlignTo) != 0)
{
dwtemp++;
}
dwtemp = dwtemp*dwAlignTo;
return(dwtemp);
}

18
OpenParrot/src/PE.h Normal file
View File

@ -0,0 +1,18 @@
#include <windows.h>
#include <WinNT.h>
#define MAX_SECTION_NUM 20
typedef struct _PEStruct
{
DWORD dwRO_first_section;
IMAGE_DOS_HEADER image_dos_header;
char *reservedheader;
IMAGE_NT_HEADERS image_nt_headers;
IMAGE_SECTION_HEADER image_section_header[MAX_SECTION_NUM];
char *image_section[MAX_SECTION_NUM];
void *fileImage;
DWORD fileSize;
DWORD numOfSecs;
} PEStruct, *PPEStruct;
PEStruct getPEFileInformation(char *filename);

View File

@ -0,0 +1,177 @@
#ifdef _M_AMD64
#include <StdInc.h>
#include <winternl.h>
#include "GameDetect.h"
#include "InitFunction.h"
#include "PE.h"
#pragma comment(lib, "ntdll.lib")
_CONTEXT mycontext;
DWORD_PTR MyLoadLibraryA = 0;
PEStruct FilePEFile;
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
static int RunTo(LPPROCESS_INFORMATION lpProcessInformation, DWORD_PTR Address, DWORD Mode, DWORD_PTR Eip)
{
char tempbuf[4];
if (Eip != 0)
{
GetThreadContext(lpProcessInformation->hThread, &mycontext);
mycontext.Rip = Eip;
SetThreadContext(lpProcessInformation->hThread, &mycontext);
}
ReadProcessMemory(lpProcessInformation->hProcess, (LPVOID)Address, tempbuf, 4, 0);
WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)Address, "\xEB\xFE", 2, 0);
ResumeThread(lpProcessInformation->hThread);
while (GetThreadContext(lpProcessInformation->hThread, &mycontext))
{
if (Mode == 1) WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)Address, "\xEB\xFE", 2, 0);
if (mycontext.Rip == Address) break;
Sleep(100);
}
SuspendThread(lpProcessInformation->hThread);
if (!GetThreadContext(lpProcessInformation->hThread, &mycontext)) return 0;
WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)Address, tempbuf, 4, 0);
return 1;
}
static int LoadHookDLL(LPPROCESS_INFORMATION lpProcessInformation, char *dllLocation, DWORD_PTR address)
{
MyLoadLibraryA = (DWORD_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
DWORD_PTR addy = (DWORD_PTR)VirtualAllocEx(lpProcessInformation->hProcess, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//printf("addy: %08X", addy);
DWORD_PTR OEP = address;
DWORD_PTR TextLocation = addy + 0x30;
DWORD_PTR CallLoadLibraryA = MyLoadLibraryA - (addy + 10);
DWORD addyOffset = 30;
WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)addy, "\x48\x83\xEC\x28\x48\xB9\x00\x00\x00\x00\x00\x00\x00\x00\x48\xB8\x11\x11\x11\x11\x01\x00\x00\x00\xFF\xD0\x48\x83\xC4\x28\xEB\xFE", 32, 0);
WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)(addy + 6), &TextLocation, 8, 0);
WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)(addy + 16), &MyLoadLibraryA, 8, 0);
//printf("%s\n", dllLocation);
WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)TextLocation, dllLocation, strlen(dllLocation) + 1, 0);
GetThreadContext(lpProcessInformation->hThread, &mycontext);
Sleep(1000);
if (!RunTo(lpProcessInformation, addy + addyOffset, 0, addy))
{
printf("Failed to Load DLL!");
return 0;
}
if (mycontext.Rax == 0)
{
printf("Failed to Load DLL!");
return 0;
}
GetThreadContext(lpProcessInformation->hThread, &mycontext);
Sleep(100);
mycontext.Rip = OEP;
Sleep(100);
SetThreadContext(lpProcessInformation->hThread, &mycontext);
Sleep(100);
//WriteProcessMemory(pi.hProcess, (LPVOID)OEP, backbuf, 256, 0);
Sleep(100);
return 1;
}
BOOL(WINAPI* g_origCreateProcessW)(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation);
char nonWideDll[256];
char currentDir[256];
BOOL WINAPI CreateProcessWHook(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
memset(nonWideDll, 0, 256);
memset(currentDir, 0, 256);
GetCurrentDirectoryA(256, currentDir);
sprintf(nonWideDll, "%s\\%ws", currentDir, lpCommandLine);
for (int i = 0; i < 256; i++)
{
// In case no args
if (nonWideDll[i] == 0)
{
break;
}
// Remove args from behind
if (nonWideDll[i] == '.'
&& nonWideDll[i + 1] == 'e'
&& nonWideDll[i + 2] == 'x'
&& nonWideDll[i + 3] == 'e')
{
nonWideDll[i + 4] = 0x00;
break;
}
}
FilePEFile = getPEFileInformation(nonWideDll);
printf("%s", nonWideDll);
printf("%08X", FilePEFile.image_nt_headers.OptionalHeader.AddressOfEntryPoint);
auto myProc = g_origCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
GetThreadContext(lpProcessInformation->hThread, &mycontext);
mycontext.ContextFlags = 0x00010000 + 1 + 2 + 4 + 8 + 0x10;
GetThreadContext(lpProcessInformation->hThread, &mycontext);
PROCESS_BASIC_INFORMATION pbi;
DWORD pbiSize = sizeof(pbi);
if (!NT_SUCCESS(NtQueryInformationProcess(lpProcessInformation->hProcess, ProcessBasicInformation, &pbi, pbiSize, &pbiSize)))
{
MessageBoxA(0, "Failed to inject in to a new process!", "Error", 0);
TerminateProcess(lpProcessInformation->hProcess, 0);
ExitProcess(0);
}
DWORD_PTR baseAddress;
SIZE_T read = 0;
ReadProcessMemory(lpProcessInformation->hProcess, (void*)((DWORD_PTR)pbi.PebBaseAddress + (sizeof(DWORD_PTR) * 2)), &baseAddress, sizeof(baseAddress), &read);
if (read != sizeof(DWORD_PTR))
{
MessageBoxA(0, "Failed to get process environment!", "Error", 0);
TerminateProcess(lpProcessInformation->hProcess, 0);
ExitProcess(0);
}
Sleep(1000);
if (!RunTo(lpProcessInformation, baseAddress + FilePEFile.image_nt_headers.OptionalHeader.AddressOfEntryPoint, 1, 0))
{
MessageBoxA(0, "Failed to run the process", "Error", 0);
TerminateProcess(lpProcessInformation->hProcess, 0);
ExitProcess(0);
}
char DllPath[MAX_PATH] = { 0 };
GetModuleFileNameA((HINSTANCE)&__ImageBase, DllPath, MAX_PATH);
if (!LoadHookDLL(lpProcessInformation, (char *)DllPath, baseAddress + FilePEFile.image_nt_headers.OptionalHeader.AddressOfEntryPoint))
{
TerminateProcess(lpProcessInformation->hProcess, 0);
ExitProcess(0);
}
Sleep(500);
ResumeThread(lpProcessInformation->hThread);
}
#endif

View File

@ -0,0 +1,26 @@
#pragma once
#ifdef _M_AMD64
#include <StdInc.h>
extern BOOL(WINAPI* g_origCreateProcessW)(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation);
extern BOOL WINAPI CreateProcessWHook(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
#endif

View File

@ -477,6 +477,16 @@ void GameDetect::DetectCurrentGame()
case 0xdb9c3a90:
currentGame = GameID::TER;
break;
case 0xf3d3f699:
currentGame = GameID::StarWarsEs3XLauncher;
break;
case 0x5424a6d8:
currentGame = GameID::StarWarsJapEs3XLauncher;
break;
case 0x8505c794:
case 0xe1e9e32c: // JPN
currentGame = GameID::StarWarsEs3X;
break;
#endif
default:
#ifdef _DEBUG

View File

@ -60,5 +60,8 @@ enum class GameID
GHA,
JLeague,
Theatrhythm,
TER
TER,
StarWarsJapEs3XLauncher,
StarWarsEs3XLauncher,
StarWarsEs3X
};