private void VirtualReleaseAll(IntPtr handle, params IntPtr[] allocations) { foreach (IntPtr ptr in allocations) { Kernel32Imports.VirtualFreeEx(handle, ptr, IntPtr.Zero, AllocationType.Release); } }
private static void Launch(string appPath, bool updateOkay) { string args = string.Format("-on_update {0}", (updateOkay ? "success" : "failure")); PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION(); STARTUPINFO sInfo = new STARTUPINFO(); sInfo.cb = Marshal.SizeOf(sInfo); sInfo.dwFlags = 1; sInfo.wShowWindow = 1; if (m_restartState == FormWindowState.Maximized) { sInfo.wShowWindow = 3; // SW_MAXIMIZE } else if (m_restartState == FormWindowState.Minimized) { sInfo.wShowWindow = 7; // SW_SHOWMINNOACTIVE } else { sInfo.wShowWindow = 1; // SW_SHOWNORMAL } Kernel32Imports.CreateProcess(appPath, args, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref sInfo, out pInfo); }
private unsafe bool ApplyCrcPatch(IntPtr handle) { uint pso2Base = 0x00400000u; uint * bCrc = stackalloc uint[1]; IntPtr pCrc = new IntPtr(pso2Base + 0x38); IntPtr dCrc = new IntPtr(bCrc); bCrc[0] = PATCHED_CRC; Protection newProtection = Protection.PAGE_EXECUTE_READWRITE; Protection oldProtection; if (!Kernel32Imports.VirtualProtectEx(handle, pCrc, 4, newProtection, out oldProtection)) { return(LogLastWin32Error("VirtualProtectEx") == 0); } if (!Kernel32Imports.WriteProcessMemory(handle, pCrc, dCrc, 4, IntPtr.Zero)) { return(LogLastWin32Error("WriteProcessMemory") == 0); } return(true); }
private unsafe bool ApplyCommDataPatch(IntPtr handle) { uint pso2Base = 0x00400000u; byte * bCommData = stackalloc byte[0x20]; IntPtr dCommData = (IntPtr)bCommData; IntPtr pCommData = new IntPtr(pso2Base + PCOMMDATA); // Read out old data if (!Kernel32Imports.ReadProcessMemory(handle, pCommData, dCommData, 0x20, IntPtr.Zero)) { return(LogLastWin32Error("ReadProcessMemory") == 0); } // Apply Functions Patch IntPtr pOldCommFunctions = new IntPtr(Marshal.ReadInt32(dCommData, 0x18)); IntPtr pCommFunctions = ApplyCommFunctionsPatch(handle, pOldCommFunctions); Marshal.Copy(Enumerable.Repeat((byte)0x00, 0x20).ToArray(), 0, dCommData, 0x18); Marshal.Copy(Encoding.ASCII.GetBytes("ARKSMT"), 0, dCommData, 6); Marshal.WriteInt32(dCommData, 0x10, Program.PID); Marshal.WriteInt32(dCommData, 0x14, m_commBuffer.ToInt32()); Marshal.WriteInt32(dCommData, 0x18, pCommFunctions.ToInt32()); if (!Kernel32Imports.WriteProcessMemory(handle, pCommData, dCommData, 0x20, IntPtr.Zero)) { return(LogLastWin32Error("WriteProcessMemory") == 0); } return(true); }
public static bool IsAvailable() { IntPtr hModule = Kernel32Imports.LoadLibrary("uxtheme.dll"); Kernel32Imports.FreeLibrary(hModule); return(hModule != IntPtr.Zero); }
private unsafe IntPtr ApplyCommFunctionsPatch(IntPtr handle, IntPtr pOldCommFunctions) { if (pOldCommFunctions != IntPtr.Zero) { return(pOldCommFunctions); } string[] functions = Resources.CommFunctions.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var byteCounts = functions.Select(x => Encoding.ASCII.GetByteCount(x) + 1); var paddedCounts = byteCounts.Select(x => (x + 0xF) & ~0xF); int[] offsets = paddedCounts.Select((x, i) => paddedCounts.Take(i).Sum()).ToArray(); int cbFunctionPointers = ((functions.Length * 0x4) + 0x1F) & ~0x1F; int cbNamePointers = cbFunctionPointers; int cbNames = paddedCounts.Sum(); int cbKernel32 = 0x10; int byteCount = cbFunctionPointers + cbNamePointers + cbNames + cbKernel32; byte * bCommFunctions = stackalloc byte[byteCount]; IntPtr dCommFunctions = new IntPtr(bCommFunctions); IntPtr pCommFunctions = VirtualAlloc(handle, byteCount); if (pCommFunctions == IntPtr.Zero) { LogLastWin32Error("VirtualAllocEx"); return(IntPtr.Zero); } IntPtr dNamePointers = IntPtr.Add(dCommFunctions, cbFunctionPointers); for (int i = 0; i < functions.Length; ++i) { int nameOffset = cbFunctionPointers + cbNamePointers + offsets[i]; IntPtr namePointer = IntPtr.Add(pCommFunctions, nameOffset); Marshal.WriteInt32(dNamePointers, i * 0x4, namePointer.ToInt32()); Encoding.ASCII.WriteString(dCommFunctions, nameOffset, functions[i]); } int k32nameOffset = cbFunctionPointers + cbNamePointers + cbNames; IntPtr k32namePointer = IntPtr.Add(pCommFunctions, k32nameOffset); Marshal.WriteInt32(dCommFunctions, cbFunctionPointers - 0x4, k32namePointer.ToInt32()); Encoding.ASCII.WriteString(dCommFunctions, k32nameOffset, "Kernel32.dll"); if (!Kernel32Imports.WriteProcessMemory(handle, pCommFunctions, dCommFunctions, byteCount, IntPtr.Zero)) { VirtualReleaseAll(handle, pCommFunctions); LogLastWin32Error("WriteProcessMemory"); return(IntPtr.Zero); } return(pCommFunctions); }
private IntPtr OpenProcessVirtualAccess(int processId) { IntPtr handle = Kernel32Imports.OpenProcess(ProcessAccessFlags.VirtualMemoryAll, false, processId); if (handle == IntPtr.Zero) { LogLastWin32Error("OpenProcess"); } return(handle); }
public static void RestorePrivilege(TOKEN_PRIVILEGES tokenPrivilage) { IntPtr cpHandle = Process.GetCurrentProcess().Handle; IntPtr pHandle = IntPtr.Zero; IntPtr tHandle = IntPtr.Zero; TOKEN_PRIVILEGES tOldState = new TOKEN_PRIVILEGES(); uint cb = (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGES)); uint tAccess = advapi32Imports.TOKEN_QUERY | advapi32Imports.TOKEN_ADJUST_PRIVILEGES; advapi32Imports.OpenProcessToken(cpHandle, tAccess, ref tHandle); advapi32Imports.AdjustTokenPrivileges(tHandle, false, ref tokenPrivilage, cb, ref tOldState, out cb); Kernel32Imports.CloseHandle(tHandle); }
private void Form1_Load(object sender, EventArgs e) { var letters = Enumerable.Range((int)'a', 26).Select(x => new string((char)x, 1)); var letter = letters.ElementAtOrDefault(Program.Version.Revision - 1); lblVersion.Text = string.Format("v{0}{1}", Program.Version.ToString(2), letter); Log("Arks Mod Tool"); Log("Version : {0}{1}", Program.Version.ToString(2), letter); Log("Target : pso2.exe v{0}.{1:D4}.{2}", PSO2VERSION.Major, PSO2VERSION.Minor, PSO2VERSION.Revision); Log("-------------------------------"); string[] args = Environment.GetCommandLineArgs(); string updateResult = args.SkipWhile(x => x != "-on_update").ElementAtOrDefault(1); if (updateResult == "success") { Log("Arks Mod Tool has been updated."); } if (updateResult == "failure") { Log("WARNING: The last update attempt failed."); } else { tmrAppUpdate.Start(); } AllocationType allocType = AllocationType.Reserve | AllocationType.Commit; m_commBuffer = Kernel32Imports.VirtualAlloc(m_commBufferLocation, m_commBufferSize, allocType, MemoryProtection.ReadWrite); if (m_commBuffer.ToInt64() >= 0x100000000 || m_commBuffer == IntPtr.Zero) { Log("ERROR: Could not initialize communication buffer."); SetStatus("Initialization Error", Color.Red); return; } WriteOutgoing(); Log("Waiting for PSO2 to launch..."); SetStatus("Waiting...", Color.Black); tmrScan.Start(); tmrCommunicationUpdate.Start(); }
private unsafe bool ApplyGamePatch(IntPtr handle, byte[] patchData) { uint pso2Base = 0x00400000u; fixed(byte *ptr = patchData) { uint offset = *(uint *)ptr; IntPtr pPatch = new IntPtr(pso2Base + offset); IntPtr pData = new IntPtr(ptr + 0x10); int size = patchData.Length - 0x10; if (!Kernel32Imports.WriteProcessMemory(handle, pPatch, pData, size, IntPtr.Zero)) { return(LogLastWin32Error("WriteProcessMemory") == 0); } } return(true); }
public static TOKEN_PRIVILEGES SetPrivilege(string privilegeName) { IntPtr cpHandle = Process.GetCurrentProcess().Handle; IntPtr pHandle = IntPtr.Zero; IntPtr tHandle = IntPtr.Zero; TOKEN_PRIVILEGES tNewState = GetTokenPrivilege(privilegeName, true); TOKEN_PRIVILEGES tOldState = new TOKEN_PRIVILEGES(); uint cb = (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGES)); uint tAccess = advapi32Imports.TOKEN_QUERY | advapi32Imports.TOKEN_ADJUST_PRIVILEGES; advapi32Imports.OpenProcessToken(cpHandle, tAccess, ref tHandle); advapi32Imports.AdjustTokenPrivileges(tHandle, false, ref tNewState, cb, ref tOldState, out cb); Kernel32Imports.CloseHandle(tHandle); return(tOldState); }
private bool ApplyPatches(Process process) { if (process == null) { return(false); } TOKEN_PRIVILEGES privilege = PrivilegeHelper.SetPrivilege("SeDebugPrivilege"); IntPtr handle = OpenProcessVirtualAccess(process.Id); bool isOkay = true; isOkay = isOkay && handle != IntPtr.Zero; isOkay = isOkay && CheckCrc(handle); isOkay = isOkay && ApplyCrcPatch(handle); isOkay = isOkay && ApplyCommPatch(handle); isOkay = isOkay && ApplyGamePatches(handle); Kernel32Imports.CloseHandle(handle); PrivilegeHelper.RestorePrivilege(privilege); return(isOkay); }
private unsafe bool CheckCrc(IntPtr handle) { uint pso2Base = 0x00400000u; IntPtr pCrc = new IntPtr(pso2Base + 0x38); UInt32 *crc = stackalloc UInt32[1]; if (!Kernel32Imports.ReadProcessMemory(handle, pCrc, (IntPtr)crc, sizeof(UInt32), IntPtr.Zero)) { return(LogLastWin32Error("ReadProcessMemory") == 0); } if (*crc != ORIGINAL_CRC && *crc != PATCHED_CRC) { Log("Game signature mismatch."); Log("Please download the latest version of"); Log("ArksMT when it becomes available."); SetStatus("Version Error", Color.Red); SetIcon(Resources.icon); return(false); } return(true); }
private IntPtr VirtualAlloc(IntPtr handle, int byteCount) { AllocationType allocType = AllocationType.Reserve | AllocationType.Commit; return(Kernel32Imports.VirtualAllocEx(handle, IntPtr.Zero, byteCount, allocType, MemoryProtection.ReadWrite)); }
private void Form1_FormClosed(object sender, FormClosedEventArgs e) { Kernel32Imports.VirtualFree(m_commBuffer, m_commBufferSize, AllocationType.Release); }