mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-08-11 18:41:16 +10:00
Add Patcher Project
The other Patcher repository is locked from future modifications
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -0,0 +1,301 @@
|
||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Gee.External.Capstone;
|
||||
using Gee.External.Capstone.Arm;
|
||||
//using PeNet;
|
||||
|
||||
namespace Patcher
|
||||
{
|
||||
public static class ArmDisassembler
|
||||
{
|
||||
public static AnalyzedFile Analyze(string FilePath, string AsmPath = null)
|
||||
{
|
||||
PeFile File = new(FilePath);
|
||||
|
||||
SortedList<UInt32, ArmInstruction> AnalyzedCode = new(0x1000000); // Default capacity of 0x100000 was not enough for analyzing ntoskrnl.exe
|
||||
|
||||
if ((AsmPath != null) && System.IO.File.Exists(AsmPath))
|
||||
{
|
||||
using StreamReader Reader = new(AsmPath);
|
||||
while (Reader.Peek() >= 0)
|
||||
{
|
||||
ArmInstruction Instruction = new(Reader.ReadLine());
|
||||
AnalyzedCode.Add(Instruction.Address, Instruction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CapstoneArmDisassembler Disassembler = CapstoneDisassembler.CreateArmDisassembler(ArmDisassembleMode.Thumb);
|
||||
|
||||
// Initially use a Dictionary and sort it afterwards. For analyzing ntoskrnl.exe this is about 60 times faster than using a SortedList from the start.
|
||||
// Default capacity of 0x100000 was not enough for analyzing ntoskrnl.exe
|
||||
Dictionary<UInt32, ArmInstruction> TempCode = new(0x1000000);
|
||||
|
||||
// Analyze from entrypoint
|
||||
Analyze(Disassembler, File.Sections, TempCode, (UInt32)(File.ImageBase + File.EntryPoint));
|
||||
|
||||
// Analyze from exports
|
||||
foreach (FunctionDescriptor Function in File.Exports)
|
||||
Analyze(Disassembler, File.Sections, TempCode, (UInt32)Function.VirtualAddress);
|
||||
|
||||
// Analyze from imports
|
||||
foreach (FunctionDescriptor Function in File.Imports)
|
||||
Analyze(Disassembler, File.Sections, TempCode, (UInt32)Function.VirtualAddress);
|
||||
|
||||
// Analyze from runtime-functions
|
||||
foreach (FunctionDescriptor Function in File.RuntimeFunctions)
|
||||
Analyze(Disassembler, File.Sections, TempCode, (UInt32)Function.VirtualAddress);
|
||||
|
||||
// Sort the instructions.
|
||||
// SortedList is used, because it can be indexed by value (not only by key).
|
||||
List<UInt32> Keys = TempCode.Keys.ToList();
|
||||
Keys.Sort();
|
||||
foreach (UInt32 Key in Keys)
|
||||
AnalyzedCode.Add(Key, TempCode[Key]);
|
||||
|
||||
if (AsmPath != null)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(AsmPath));
|
||||
|
||||
using StreamWriter Writer = new(AsmPath, false);
|
||||
for (int i = 0; i < AnalyzedCode.Count; i++)
|
||||
{
|
||||
Writer.WriteLine(AnalyzedCode.Values[i].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AnalyzedFile() { File = File, Code = AnalyzedCode };
|
||||
}
|
||||
|
||||
public static void Analyze(CapstoneArmDisassembler Disassembler, List<Section> Sections, Dictionary<UInt32, ArmInstruction> AnalyzedCode, UInt32 VirtualAddress)
|
||||
{
|
||||
VirtualAddress -= (VirtualAddress % 2);
|
||||
List<UInt32> AddressesToAnalyze = new();
|
||||
AddressesToAnalyze.Add(VirtualAddress);
|
||||
Section CurrentSection = null;
|
||||
|
||||
while (AddressesToAnalyze.Count > 0)
|
||||
{
|
||||
UInt32 CurrentAddress = AddressesToAnalyze[0];
|
||||
if ((CurrentSection == null) || (CurrentAddress < CurrentSection.VirtualAddress) || (CurrentAddress > (CurrentSection.VirtualAddress + CurrentSection.VirtualSize)))
|
||||
{
|
||||
CurrentSection = Sections.Find(s => (CurrentAddress >= s.VirtualAddress) && (CurrentAddress < (s.VirtualAddress + s.VirtualSize)) && s.IsCode);
|
||||
if (CurrentSection == null)
|
||||
{
|
||||
// throw new Exception("Address 0x" + CurrentAddress.ToString("X8") + " is not inside boundaries of code-sections");
|
||||
// Probably jumped to this address because data was disassembled as if it were code. Ignore this.
|
||||
// return;
|
||||
AddressesToAnalyze.RemoveAt(0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (AnalyzedCode.ContainsKey(CurrentAddress))
|
||||
{
|
||||
// return;
|
||||
AddressesToAnalyze.RemoveAt(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
Gee.External.Capstone.Arm.ArmInstruction[] NewInstructions = Disassembler.Disassemble(CurrentSection.Buffer.Skip((int)CurrentAddress - (int)CurrentSection.VirtualAddress).ToArray(), CurrentAddress);
|
||||
if (NewInstructions.Any())
|
||||
{
|
||||
UInt32 StartAddress = (UInt32)NewInstructions.First().Address;
|
||||
UInt32 EndAddress = (UInt32)NewInstructions.Last().Address;
|
||||
|
||||
ArmInstruction PreviousInstruction = null;
|
||||
foreach (Gee.External.Capstone.Arm.ArmInstruction DisassemblerInstruction in NewInstructions)
|
||||
{
|
||||
// ArmInstruction Instruction = new ArmInstruction(DisassemblerInstruction);
|
||||
ArmInstruction Instruction = new()
|
||||
{
|
||||
Address = (UInt32)DisassemblerInstruction.Address,
|
||||
Bytes = DisassemblerInstruction.Bytes,
|
||||
Mnemonic = DisassemblerInstruction.Mnemonic,
|
||||
Operand = DisassemblerInstruction.Operand.Replace("sb", "r9").Replace("sl", "r10").Replace("fp", "r11").Replace("ip", "r12")
|
||||
};
|
||||
|
||||
if (AnalyzedCode.ContainsKey((UInt32)Instruction.Address))
|
||||
break;
|
||||
|
||||
// Merge movw + movt into one command
|
||||
// movw r3, #0x6010 + movt r3, #0x1000 = mov r3, #0x10006010
|
||||
UInt32 HighPart, LowPart;
|
||||
string HighString, LowString;
|
||||
if ((PreviousInstruction?.Mnemonic == "movt") && (Instruction.Mnemonic == "movw") && (PreviousInstruction.Operand.Split(new char[] { ',' })[0] == Instruction.Operand.Split(new char[] { ',' })[0]))
|
||||
{
|
||||
byte[] Combined = new byte[8];
|
||||
System.Buffer.BlockCopy(PreviousInstruction.Bytes, 0, Combined, 0, 4);
|
||||
System.Buffer.BlockCopy(Instruction.Bytes, 0, Combined, 4, 4);
|
||||
PreviousInstruction.Bytes = Combined;
|
||||
PreviousInstruction.Mnemonic = "mov";
|
||||
|
||||
HighString = PreviousInstruction.Operand[(PreviousInstruction.Operand.IndexOf('#') + 1)..];
|
||||
HighPart = (HighString.Length >= 2) && (HighString.Substring(0, 2) == "0x")
|
||||
? UInt32.Parse(HighString[2..], System.Globalization.NumberStyles.HexNumber)
|
||||
: UInt32.Parse(HighString);
|
||||
LowString = Instruction.Operand[(Instruction.Operand.IndexOf('#') + 1)..];
|
||||
LowPart = (LowString.Length >= 2) && (LowString.Substring(0, 2) == "0x")
|
||||
? UInt32.Parse(LowString[2..], System.Globalization.NumberStyles.HexNumber)
|
||||
: UInt32.Parse(LowString);
|
||||
PreviousInstruction.Operand = string.Concat(PreviousInstruction.Operand.AsSpan(0, PreviousInstruction.Operand.IndexOf('#') + 1), "0x", ((HighPart << 16) + LowPart).ToString("X8"));
|
||||
continue;
|
||||
}
|
||||
if ((PreviousInstruction?.Mnemonic == "movw") && (Instruction.Mnemonic == "movt") && (PreviousInstruction.Operand.Split(new char[] { ',' })[0] == Instruction.Operand.Split(new char[] { ',' })[0]))
|
||||
{
|
||||
byte[] Combined = new byte[8];
|
||||
System.Buffer.BlockCopy(PreviousInstruction.Bytes, 0, Combined, 0, 4);
|
||||
System.Buffer.BlockCopy(Instruction.Bytes, 0, Combined, 4, 4);
|
||||
PreviousInstruction.Bytes = Combined;
|
||||
PreviousInstruction.Mnemonic = "mov";
|
||||
|
||||
HighString = Instruction.Operand[(Instruction.Operand.IndexOf('#') + 1)..];
|
||||
HighPart = (HighString.Length >= 2) && (HighString.Substring(0, 2) == "0x")
|
||||
? UInt32.Parse(HighString[2..], System.Globalization.NumberStyles.HexNumber)
|
||||
: UInt32.Parse(HighString);
|
||||
LowString = PreviousInstruction.Operand[(PreviousInstruction.Operand.IndexOf('#') + 1)..];
|
||||
LowPart = (LowString.Length >= 2) && (LowString.Substring(0, 2) == "0x")
|
||||
? UInt32.Parse(LowString[2..], System.Globalization.NumberStyles.HexNumber)
|
||||
: UInt32.Parse(LowString);
|
||||
PreviousInstruction.Operand = string.Concat(PreviousInstruction.Operand.AsSpan(0, PreviousInstruction.Operand.IndexOf('#') + 1), "0x", ((HighPart << 16) + LowPart).ToString("X8"));
|
||||
continue;
|
||||
}
|
||||
|
||||
AnalyzedCode.Add((UInt32)Instruction.Address, Instruction);
|
||||
|
||||
int IndexOfIndirectConstant = Instruction.Operand.IndexOf("[pc, #0x");
|
||||
if (IndexOfIndirectConstant >= 0)
|
||||
{
|
||||
int IndexOfEnd = Instruction.Operand.IndexOf("]", IndexOfIndirectConstant);
|
||||
string PCOffsetString = Instruction.Operand.Substring(IndexOfIndirectConstant + 8, IndexOfEnd - IndexOfIndirectConstant - 8);
|
||||
UInt32 PCOffset = UInt32.Parse(PCOffsetString, System.Globalization.NumberStyles.HexNumber);
|
||||
UInt32 PC = (UInt32)Instruction.Address + 4;
|
||||
UInt32 PCforIndirect = PC - (PC % 4);
|
||||
UInt32 VirtualAddressOfIndirectConstant = PCforIndirect + PCOffset;
|
||||
|
||||
// If the address is outside the range of the section, then this is probably data which is compiled as code.
|
||||
// In this case we will ignore this and not do this part of the analysis.
|
||||
if ((VirtualAddressOfIndirectConstant >= CurrentSection.VirtualAddress) && (VirtualAddressOfIndirectConstant < (CurrentSection.VirtualAddress + CurrentSection.VirtualSize)))
|
||||
{
|
||||
UInt32 RawOffsetOfIndirectConstant = VirtualAddressOfIndirectConstant - CurrentSection.VirtualAddress;
|
||||
UInt32 IndirectConstant = BitConverter.ToUInt32(CurrentSection.Buffer, (int)RawOffsetOfIndirectConstant);
|
||||
Instruction.Operand = Instruction.Operand.Substring(0, IndexOfIndirectConstant) + "#0x" + IndirectConstant.ToString("x8") + Instruction.Operand[(IndexOfEnd + 1)..];
|
||||
}
|
||||
}
|
||||
|
||||
if (JumpCommands.Contains(Instruction.Mnemonic))
|
||||
{
|
||||
UInt32 NewAddress = UInt32.Parse(Instruction.Operand[(Instruction.Operand.IndexOf("#0x") + 3)..], System.Globalization.NumberStyles.HexNumber);
|
||||
NewAddress -= (NewAddress % 2);
|
||||
if (((NewAddress < StartAddress) || (NewAddress > EndAddress)) && !AddressesToAnalyze.Any(a => a == NewAddress))
|
||||
AddressesToAnalyze.Add(NewAddress);
|
||||
}
|
||||
|
||||
PreviousInstruction = Instruction;
|
||||
}
|
||||
}
|
||||
|
||||
AddressesToAnalyze.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] JumpCommands = new string[]
|
||||
{
|
||||
"b", "b.w", "bl", "bl.w", "beq", "beq.w", "bne", "bne.w", "bhs", "bhs.w", "blo", "blo.w",
|
||||
"bmi", "bmi.w", "bpl", "bpl.w", "bvs", "bvs.w", "bvc", "bvc.w", "bhi", "bhi.w", "bls", "bls.w",
|
||||
"bge", "bge.w", "blt", "blt.w", "bgt", "bgt.w", "ble", "ble.w", "bal", "bal.w", "cbnz", "cbz"
|
||||
};
|
||||
|
||||
public static string[] ConditionalJumpInstructions = new string[]
|
||||
{
|
||||
"beq", "beq.w", "bne", "bne.w", "bhs", "bhs.w", "blo", "blo.w", "bmi", "bmi.w",
|
||||
"bpl", "bpl.w", "bvs", "bvs.w", "bvc", "bvc.w", "bhi", "bhi.w", "bls", "bls.w",
|
||||
"bge", "bge.w", "blt", "blt.w", "bgt", "bgt.w", "ble", "ble.w", "bal", "bal.w", "cbnz", "cbz"
|
||||
};
|
||||
|
||||
public static string WriteCode(SortedDictionary<UInt32, ArmInstruction> AnalyzedCode)
|
||||
{
|
||||
StringBuilder Code = new(1000);
|
||||
|
||||
foreach (var Instruction in AnalyzedCode)
|
||||
{
|
||||
Code.AppendFormat("{0:X}: \t {1} \t {2}\r\n", Instruction.Value.Address, Instruction.Value.Mnemonic, Instruction.Value.Operand);
|
||||
}
|
||||
|
||||
return Code.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class ArmInstruction
|
||||
{
|
||||
public UInt32 Address;
|
||||
public byte[] Bytes;
|
||||
public string Mnemonic;
|
||||
public string Operand;
|
||||
|
||||
public ArmInstruction()
|
||||
{
|
||||
}
|
||||
|
||||
public ArmInstruction(string Assembly)
|
||||
{
|
||||
Address = UInt32.Parse(Assembly.Substring(0, 8), System.Globalization.NumberStyles.HexNumber);
|
||||
string Hex = Assembly.Substring(12, 24).Trim();
|
||||
Bytes = new byte[(Hex.Length + 1) / 3];
|
||||
for (int i = 0; i < Bytes.Length; i++)
|
||||
Bytes[i] = byte.Parse(Hex.Substring(i * 3, 2), System.Globalization.NumberStyles.HexNumber);
|
||||
Mnemonic = Assembly.Substring(39, 16).Trim();
|
||||
Operand = Assembly[55..];
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder Result = new();
|
||||
|
||||
Result.Append(Address.ToString("X8")); // 0
|
||||
Result.Append(" ");
|
||||
for (int i = 0; i < Bytes.Length; i++) // 12
|
||||
{
|
||||
Result.Append(Bytes[i].ToString("X2"));
|
||||
Result.Append(' ');
|
||||
}
|
||||
Result.Append(new String(' ', (8 - Bytes.Length) * 3));
|
||||
Result.Append(" ");
|
||||
Result.Append(Mnemonic.PadRight(16)); // 39
|
||||
Result.Append(Operand); // 55
|
||||
|
||||
return Result.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class AnalyzedFile
|
||||
{
|
||||
public PeFile File;
|
||||
public SortedList<UInt32, ArmInstruction> Code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Patcher</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Patcher\ArmCompiler.cs">
|
||||
<Link>ArmCompiler.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Patcher\ByteOperations.cs">
|
||||
<Link>ByteOperations.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Patcher\HelperClasses.cs">
|
||||
<Link>HelperClasses.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Patcher\ObjectFileParser.cs">
|
||||
<Link>ObjectFileParser.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Patcher\PatchEngine.cs">
|
||||
<Link>PatchEngine.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Patcher\PeFile.cs">
|
||||
<Link>PeFile.cs</Link>
|
||||
</Compile>
|
||||
<None Include="..\Patcher\LICENSE">
|
||||
<Link>LICENSE</Link>
|
||||
</None>
|
||||
<None Update="BootUnllockAndRootAccessPatchScript.pds">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gee.External.Capstone" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<ItemGroup>
|
||||
<Compile Update="MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,698 @@
|
||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
||||
//
|
||||
// Patch Definition Script for Boot Unlock and Root Access on Windows Mobile
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
PatchDefinition Name="RootAccess-MainOS" VersionFrom="EFIESP\Windows\System32\Boot\mobilestartup.efi"
|
||||
|
||||
PatchFile Path="Windows\System32\sspisrv.dll"
|
||||
|
||||
JumpToImport "RpcImpersonateClient"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "CheckLowboxAccess" // Optional here
|
||||
PatchCode
|
||||
MOVS R1, #1
|
||||
STR R1, [R0]
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="Windows\System32\NtlmShared.dll"
|
||||
|
||||
JumpToExport "MsvpPasswordValidate"
|
||||
PatchCode
|
||||
MOVS R0, #1
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="Windows\System32\pacmanserver.dll"
|
||||
|
||||
FindFirstUnicode "GetMaxCountForDeployedApp"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
PatchCode
|
||||
LDR R1, =0x7FFFFFFF
|
||||
STR R1, [R0]
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="Windows\System32\mscoree.dll"
|
||||
|
||||
JumpToImport "GetModuleFileNameW"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "CompareWithWhiteList" // Optional here
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="Windows\System32\DeploymentExt.dll"
|
||||
|
||||
FindFirstUnicode "MaxUnsignedApp"
|
||||
JumpToReference
|
||||
FindValue 0x800413A0
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="Windows\System32\ntoskrnl.exe"
|
||||
|
||||
// Fase 1: find all kernel-functions
|
||||
|
||||
JumpToExport "SeAccessCheckWithHint"
|
||||
CreateLabel "SeAccessCheckWithHint"
|
||||
|
||||
FindFunctionCall R0 = "ADD R0, SP, #0x7C" R1 = "MOV R1, R?"
|
||||
JumpToTarget
|
||||
CreateLabel "SepFilterToDiscretionary"
|
||||
|
||||
JumpToReference R0 = "ADDS R0, R?, #0xD0"
|
||||
FindPreviousInstruction "PUSH"
|
||||
FindPreviousInstruction "PUSH"
|
||||
CreateLabel "SeAccessCheckByType"
|
||||
|
||||
FindFunctionCall R0 = "ADDS R0, R?, #0xF8" R1 = "MOV R1, R?" R2 = "LDR R2, [R?,#0x28]" R3 = "MOV R3, R?"
|
||||
JumpToTarget
|
||||
CreateLabel "SepConstrainByMandatory"
|
||||
|
||||
JumpBack // to SeAccessCheckByType
|
||||
JumpBack // to SepFilterToDiscretionary
|
||||
|
||||
JumpToReference R1 = "LDR R1, [R?,#8]"
|
||||
FindPreviousInstruction "PUSH"
|
||||
CreateLabel "SepCommonAccessCheckEx"
|
||||
|
||||
FindFunctionCall Result = "STR R0, [SP,#0xD4]"
|
||||
JumpToTarget
|
||||
CreateLabel "SepAccessCheckEx"
|
||||
|
||||
JumpBack // to SepCommonAccessCheckEx
|
||||
JumpBack // to SepFilterToDiscretionary
|
||||
|
||||
JumpToReference R0 = "ADDS R0, R?, #0x130"
|
||||
FindPreviousInstruction "PUSH"
|
||||
FindPreviousInstruction "PUSH"
|
||||
CreateLabel "SepAccessCheckAndAuditAlarm"
|
||||
|
||||
FindFunctionCall R0 = "LDR R0, [R?,#0x130]" R1 = "MOV R1, R?" R2 = "LDR R2, [R?,#0x50]" R3 = "MOV R3, R?"
|
||||
JumpToTarget
|
||||
CreateLabel "SepConstrainByConstraintMask"
|
||||
FindNextConditionalJump
|
||||
JumpToTarget
|
||||
CreateLabel "SepConstrainByConstraintMask_FunctionChunk01"
|
||||
|
||||
JumpBack // to SepConstrainByConstraintMask
|
||||
JumpBack // to SepAccessCheckAndAuditAlarm
|
||||
JumpBack // to SepFilterToDiscretionary
|
||||
JumpBack // to SeAccessCheckWithHint
|
||||
|
||||
FindFunctionCall R0 = "ADD R0, SP, #0x88" R1 = "MOV R1, R?"
|
||||
JumpToTarget
|
||||
CreateLabel "SepMandatoryToDiscretionary"
|
||||
JumpBack
|
||||
|
||||
FindFunctionCall Result = "STR R0, [SP,#0x70]"
|
||||
JumpToTarget
|
||||
CreateLabel "SepAccessCheck"
|
||||
|
||||
JumpToExport "SePrivilegeCheck"
|
||||
FindFunctionCall
|
||||
JumpToTarget
|
||||
CreateLabel "SepPrivilegeCheck"
|
||||
|
||||
JumpToExport "SeSinglePrivilegeCheck"
|
||||
CreateLabel "SeSinglePrivilegeCheck"
|
||||
|
||||
JumpToExport "ObReferenceObjectByHandleWithTag"
|
||||
CreateLabel "ObReferenceObjectByHandleWithTag"
|
||||
|
||||
// Fase 2: patches
|
||||
|
||||
JumpToLabel "SeAccessCheckByType"
|
||||
|
||||
// Patch 1:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
FindPreviousConditionalJump
|
||||
FindPreviousConditionalJump
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
FindNextValue 0xC0000022
|
||||
|
||||
// Patch 2:
|
||||
FindNextValue 0xC0000022
|
||||
FindStore
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
|
||||
// Patch 3:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional // This jump is right above the value 0xC0000022. After patch the pointer is back on that value.
|
||||
// FindNextValue 0xC0000022
|
||||
|
||||
// Patch 4:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional // This jump is right above the value 0xC0000022. After patch the pointer is back on that value.
|
||||
// FindNextValue 0xC0000022
|
||||
|
||||
// Patch 5:
|
||||
FindNextValue 0xC0000022
|
||||
FindNextInstruction "BNE"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch5"
|
||||
JumpBack
|
||||
FindPreviousInstruction "BEQ"
|
||||
PatchCode
|
||||
B TargetPatch5
|
||||
EndPatch
|
||||
|
||||
// Patch 6:
|
||||
FindNextValue 0xC0000022
|
||||
FindNextConditionalJump
|
||||
MakeJumpUnconditional
|
||||
|
||||
// Patch 7:
|
||||
FindNextValue 0xC0000022
|
||||
FindStore
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
|
||||
// Patch 8:
|
||||
FindNextValue 0xC0000022
|
||||
JumpToReference
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 9:
|
||||
FindNextValue 0xC0000022
|
||||
JumpToReference
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
JumpToLabel "SepAccessCheckAndAuditAlarm"
|
||||
|
||||
// Patch 10:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
FindNextValue 0xC0000022
|
||||
|
||||
// Patch 11:
|
||||
FindNextValue 0xC0000022
|
||||
FindStore
|
||||
CreateLabel "Patch11"
|
||||
FindNextConditionalJump
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch11"
|
||||
JumpToLabel "Patch11"
|
||||
PatchCode
|
||||
B TargetPatch11
|
||||
EndPatch
|
||||
|
||||
// Patch 12:
|
||||
FindNextValue 0xC0000022
|
||||
PatchCode
|
||||
MOV.W R2, #0
|
||||
EndPatch
|
||||
|
||||
JumpToLabel "SepCommonAccessCheckEx"
|
||||
|
||||
// Patch 13:
|
||||
FindNextInstruction "TST"
|
||||
FindNextInstruction "TST"
|
||||
FindPreviousConditionalJump
|
||||
ClearInstruction
|
||||
|
||||
JumpToLabel "SeAccessCheckWithHint"
|
||||
|
||||
// Patch 14:
|
||||
FindNextInstruction "BEQ"
|
||||
MakeJumpUnconditional
|
||||
|
||||
JumpToLabel "SeSinglePrivilegeCheck"
|
||||
|
||||
// Patch 15:
|
||||
PatchCode
|
||||
MOVS R0, #1
|
||||
BX LR
|
||||
EndPatch
|
||||
|
||||
JumpToLabel "ObReferenceObjectByHandleWithTag"
|
||||
|
||||
FindFunctionCall
|
||||
JumpToTarget
|
||||
CreateLabel "ObpReferenceObjectByHandleWithTag"
|
||||
FindInstructionPattern "LDR R?, [R?,#0x74]; CMP R?, #0; BNE ?" InstructionIndex = 2
|
||||
JumpToTarget
|
||||
|
||||
// Patch 16:
|
||||
FindNextConditionalJump
|
||||
MakeJumpUnconditional // This jump is right above the value 0xC0000022. After patch the pointer is on the error-value.
|
||||
|
||||
// Patch 17:
|
||||
JumpToReference
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
JumpBack
|
||||
|
||||
// Patch 18:
|
||||
FindNextValue 0xC0000022
|
||||
JumpToReference
|
||||
ClearInstruction
|
||||
|
||||
JumpToLabel "SepPrivilegeCheck"
|
||||
|
||||
// Patch 19:
|
||||
PatchCode
|
||||
MOVS R0, #1
|
||||
BX LR
|
||||
EndPatch
|
||||
|
||||
JumpToLabel "SepMandatoryToDiscretionary"
|
||||
|
||||
// Patch 20:
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
|
||||
JumpToLabel "SepAccessCheckEx"
|
||||
|
||||
// Patch 21:
|
||||
FindNextValue 0x2000000
|
||||
CreateLabel "Patch21"
|
||||
FindNextInstruction "B"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch21"
|
||||
JumpToLabel "Patch21"
|
||||
PatchCode
|
||||
B TargetPatch21
|
||||
EndPatch
|
||||
FindNextValue 0xC0000022
|
||||
|
||||
// Patch 22:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional // This jump is right above the value 0xC0000022. After patch the pointer is back on that value.
|
||||
// FindNextValue 0xC0000022
|
||||
|
||||
// Patch 23:
|
||||
JumpToReference 0
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 24:
|
||||
JumpToReference 1
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 25:
|
||||
JumpToReference 2
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 26:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
FindNextValue 0xC0000022
|
||||
|
||||
// Patch 27:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
FindNextValue 0xC0000022
|
||||
|
||||
// Patch 28:
|
||||
JumpToReference
|
||||
ClearInstruction
|
||||
|
||||
JumpToLabel "SepAccessCheck"
|
||||
|
||||
// Patch 29:
|
||||
FindFunctionCall R0 = "LDR R0, [SP,#0x28]"
|
||||
JumpToTarget
|
||||
CreateLabel "SepNormalAccessCheck"
|
||||
JumpBack
|
||||
FindNextInstruction "TST"
|
||||
FindNextConditionalJump
|
||||
ClearInstruction
|
||||
|
||||
// Patch 30:
|
||||
FindFunctionCall R0 = "MOV R0, R?" R1 = "MOV R1, R?" R2 = "MOV R2, R?" R3 = "LDR R3, [SP,#0x38]"
|
||||
JumpToTarget
|
||||
CreateLabel "SepMaximumAccessCheck"
|
||||
JumpBack
|
||||
FindNextConditionalJump
|
||||
ClearInstruction
|
||||
|
||||
// Patch 31:
|
||||
FindNextConditionalJump
|
||||
ClearInstruction
|
||||
|
||||
// Patch 32:
|
||||
FindNextValue 0xC0000022
|
||||
JumpToReference 1
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 33:
|
||||
JumpToReference 2
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 34:
|
||||
FindNextValue 0xC0000022
|
||||
FindPreviousInstruction "MOVS"
|
||||
FindPreviousInstruction "MOVS"
|
||||
JumpToReference
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
FindNextValue 0xC0000022
|
||||
|
||||
// Patch 35:
|
||||
JumpToReference CodePattern = "BEQ"
|
||||
ClearInstruction
|
||||
JumpBack
|
||||
|
||||
// Patch 36:
|
||||
JumpToReference CodePattern = "MOVS; B"
|
||||
FindPreviousInstruction "B"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch36"
|
||||
JumpBack
|
||||
FindPreviousInstruction "CMP"
|
||||
PatchCode
|
||||
B.W TargetPatch36
|
||||
EndPatch
|
||||
JumpBack
|
||||
|
||||
// Patch 37:
|
||||
JumpToReference CodePattern = "STR; B"
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
|
||||
// Patch 38:
|
||||
// Stay in function-chunk. Error-code is between previous two patches.
|
||||
FindPreviousValue 0xC0000022
|
||||
FindPreviousConditionalJump
|
||||
MakeJumpUnconditional
|
||||
|
||||
JumpToLabel "SepConstrainByMandatory"
|
||||
|
||||
// Patch 39:
|
||||
FindNextInstruction "BNE"
|
||||
JumpToTarget
|
||||
FindNextInstruction "CBNZ"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch39"
|
||||
JumpBack
|
||||
FindPreviousInstruction "BEQ"
|
||||
PatchCode
|
||||
B TargetPatch39
|
||||
EndPatch
|
||||
JumpBack
|
||||
|
||||
// Patch 40:
|
||||
FindNextInstruction "B"
|
||||
JumpToTarget
|
||||
FindNextInstruction "CBNZ"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch40"
|
||||
JumpBack
|
||||
FindPreviousInstruction "BEQ"
|
||||
PatchCode
|
||||
B TargetPatch40
|
||||
EndPatch
|
||||
|
||||
JumpToLabel "SepFilterToDiscretionary"
|
||||
|
||||
// Patch 41:
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
|
||||
JumpToLabel "SepConstrainByConstraintMask_FunctionChunk01"
|
||||
|
||||
// Patch 42:
|
||||
FindNextInstruction "TST"
|
||||
FindNextInstruction "CBNZ"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch42"
|
||||
JumpBack
|
||||
FindPreviousInstruction "BEQ"
|
||||
PatchCode
|
||||
B TargetPatch42
|
||||
EndPatch
|
||||
|
||||
// Patch 43:
|
||||
FindNextInstruction "TST"
|
||||
FindNextInstruction "CBNZ"
|
||||
JumpToTarget
|
||||
CreateLabel "TargetPatch43"
|
||||
JumpBack
|
||||
FindPreviousInstruction "BEQ"
|
||||
FindPreviousInstruction "BEQ" // This one is actually not necessary. Kept here for consistency.
|
||||
PatchCode
|
||||
B TargetPatch43
|
||||
EndPatch
|
||||
|
||||
PatchChecksum
|
||||
|
||||
PatchDefinition Name="SecureBootHack-MainOS" VersionFrom="EFIESP\Windows\System32\Boot\mobilestartup.efi"
|
||||
|
||||
PatchFile Path="Windows\System32\BOOT\winload.efi"
|
||||
|
||||
FindFirstAscii "1.3.6.1.4.1.311.61.4.1"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "ImgpValidateImageHash"
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="Windows\System32\ci.dll"
|
||||
|
||||
JumpToImport "PsGetProcessSignatureLevel"
|
||||
JumpToReference
|
||||
CreateLabel "PsGetProcessSignatureLevelWrapper"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "CipReportAndReprieveUMCIFailure"
|
||||
FindNextInstruction "TST.W"
|
||||
FindNextConditionalJump
|
||||
MakeJumpUnconditional "BNE" // BNE -> B, BEQ -> NOP
|
||||
PatchChecksum
|
||||
|
||||
PatchDefinition Name="SecureBootHack-V1-EFIESP" VersionFrom="EFIESP\Windows\System32\Boot\mobilestartup.efi" RelativePath="EFIESP" RelativeOutputPath="SecureBootHack-V1"
|
||||
|
||||
PatchFile Path="Windows\System32\boot\mobilestartup.efi" // Symbols taken from pdb from version 10.0.10586.107
|
||||
|
||||
FindFirstAscii "1.3.6.1.4.1.311.61.4.1"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "ImgpValidateImageHash"
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
FindFirstUnicode "BootDebugPolicyApplied"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "ApplyBootDebugPolicy"
|
||||
PatchCode // This patch is for the new unlock for Lumia Spec A
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchFile Path="efi\boot\bootarm.efi"
|
||||
|
||||
FindFirstAscii "1.3.6.1.4.1.311.61.4.1"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "ImgpValidateImageHash"
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
|
||||
PatchDefinition Name="SecureBootHack-V2-EFIESP" VersionFrom="EFIESP\Windows\System32\Boot\mobilestartup.efi" RelativePath="EFIESP"
|
||||
|
||||
PatchFile Path="Windows\System32\boot\mobilestartup.efi"
|
||||
|
||||
FindFirstAscii "MZ"
|
||||
CreateLabel "ImageBase"
|
||||
FindFirstAscii "1.3.6.1.4.1.311.61.4.1"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "ImgpValidateImageHash"
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
FindFirstUnicode "BootDebugPolicyApplied"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "ApplyBootDebugPolicy"
|
||||
PatchCode
|
||||
MOVS R0, #0
|
||||
BX LR
|
||||
EndPatch
|
||||
CreateLabel "EnterMassStorageModeShellCode" // Use the left-over space of the ApplyBootDebugPolicy-function to insert shell-code later on
|
||||
FindFirstUnicode "MassStorageFlag"
|
||||
CreateLabel "MassStorageName"
|
||||
PatchUnicode "Heathcliff74MSM"
|
||||
FindFirstBytes "41 E5 C1 A0 CE 73 7F 46 88 EC D4 4F 92 34 50 4A"
|
||||
CreateLabel "MassStorageGuid"
|
||||
JumpToLabel "MassStorageName"
|
||||
JumpToReference
|
||||
FindNextInstruction "BL"
|
||||
JumpToTarget
|
||||
CreateLabel "EfiGetVariableVolatile"
|
||||
FindValue 2
|
||||
FindNextConditionalJump
|
||||
MakeJumpUnconditional "BEQ"
|
||||
FindFirstUnicode "\Windows\System32\boot\ui\boot.ums.waiting.bmpx"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "EnterMassStorageMode"
|
||||
JumpToReference
|
||||
PatchCode
|
||||
B.W EnterMassStorageModeShellCode
|
||||
EndPatch
|
||||
CreateLabel ReturnFromMassStorageMode
|
||||
FindFirstValue 0x26000145
|
||||
IfNotFoundGo PatchForSetErrorDone
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "SetError"
|
||||
PatchCode
|
||||
MOVS R0, #1
|
||||
BX LR
|
||||
EndPatch
|
||||
PatchForSetErrorDone:
|
||||
FindFirstUnicode "DeviceIDVersion"
|
||||
JumpToReference
|
||||
FindNextInstruction "BL"
|
||||
JumpToTarget
|
||||
CreateLabel "EfiSetVariable"
|
||||
FindFirstAscii "charge: DisplayPowerState protocol successfully loaded"
|
||||
JumpToReference
|
||||
FindPreviousInstruction "PUSH.W"
|
||||
CreateLabel "InitGraphicsSubsystem"
|
||||
FindNextInstruction "BL"
|
||||
JumpToTarget
|
||||
CreateLabel "BlpArchQueryCurrentContextType"
|
||||
JumpBack
|
||||
FindNextInstruction "BL"
|
||||
FindNextInstruction "BL"
|
||||
FindNextInstruction "BL"
|
||||
JumpToTarget
|
||||
CreateLabel "BlpArchSwitchContext"
|
||||
JumpBack
|
||||
FindNextInstruction "LDR"
|
||||
JumpToTarget
|
||||
CreateLabel "EfiBS"
|
||||
JumpToLabel "EnterMassStorageModeShellCode"
|
||||
PatchCode
|
||||
MOV R0, PC
|
||||
LDR R1, =(ApplyBootDebugPolicy - ImageBase + 8) // Subtract (Offset of shell-code + 4)
|
||||
SUB R0, R0, R1 // R0 = relocated base of mobilestartup.efi
|
||||
PUSH {R4-R6}
|
||||
SUB SP, SP, #4
|
||||
MOV R4, R0 // R4 = relocated base of mobilestartup.efi
|
||||
|
||||
LDR R3, =(MassStorageName - ImageBase) // Offset of NV var name (which is patched to "Heathcliff74MSM")
|
||||
ADD R0, R4, R3
|
||||
LDR R3, =(MassStorageGuid - ImageBase) // Offset of NV var Guid
|
||||
ADD R1, R4, R3
|
||||
MOVS R2, #3 // Non-volatile, boot-services
|
||||
MOVS R3, #0 // Data-size
|
||||
STR R3, [SP] // Pointer to data-buffer = NULL
|
||||
LDR R6, =(EfiSetVariable - ImageBase + 1) // Offset of SetVariable + 1
|
||||
ADD R5, R4, R6
|
||||
BLX R5 // EfiSetVariable -> Delete variable
|
||||
|
||||
LDR R1, =(BlpArchQueryCurrentContextType - ImageBase + 1) // Offset to first thread-function + 1
|
||||
ADD R5, R4, R1
|
||||
BLX R5
|
||||
MOV R6, R0
|
||||
CMP R6, #1
|
||||
BEQ ContextSwitchDone1
|
||||
MOVS R0, #1
|
||||
LDR R1, =(BlpArchSwitchContext - ImageBase + 1) // Offset to second thread-function + 1
|
||||
ADD R5, R4, R1
|
||||
BLX R5
|
||||
ContextSwitchDone1:
|
||||
|
||||
LDR R0, =(EfiBS - ImageBase) // Offset of pointer to BootServices function-table
|
||||
ADD R1, R4, R0 // R1 = pointer to pointer to BootServices function-table
|
||||
LDR R1, [R1] // R1 = pointer to BootServices function-table
|
||||
LDR.W R5, [R1,#0xAC] // LocateProtocol
|
||||
ADR R0, VarServicesGuid // This is relative, no need to relocate
|
||||
MOVS R1, #0
|
||||
MOV R2, SP
|
||||
BLX R5 // LocateProtocol - pVarServices in [SP]
|
||||
LDR R5, [SP] // R5 = Pointer to VariableServices interface
|
||||
LDR R5, [R5,#4] // R5 = pointer to FlushVariableNV()
|
||||
CMP R5, #0
|
||||
BNE PointerFound
|
||||
LDR R5, [SP] // R5 = Pointer to VariableServices interface
|
||||
LDR R5, [R5,#8] // R5 = pointer to FlushVariableNV()
|
||||
PointerFound:
|
||||
BLX R5 // FlushVariableNV()
|
||||
|
||||
CMP R6, #1
|
||||
BEQ ContextSwitchDone2
|
||||
MOV R0, R6
|
||||
LDR R1, =(BlpArchSwitchContext - ImageBase + 1) // Offset to second thread-function + 1
|
||||
ADD R5, R4, R1
|
||||
BLX R5
|
||||
ContextSwitchDone2:
|
||||
|
||||
LDR R6, =(EnterMassStorageMode - ImageBase + 1) // Offset of EnterMassStorageMode + 1
|
||||
ADD R5, R4, R6
|
||||
BLX R5 // EnterMassStorageMode
|
||||
|
||||
LDR R6, =(ReturnFromMassStorageMode - ImageBase + 1) // Offset of return address + 1
|
||||
ADD R0, R4, R6
|
||||
ADD SP, SP, #4
|
||||
POP {R4-R6}
|
||||
BX R0
|
||||
|
||||
VarServicesGuid:
|
||||
DCD 0xf9085b9d
|
||||
DCW 0x9304, 0x40fb
|
||||
DCB 0x8f, 0xe0, 0x4a, 0xee, 0x3b, 0x1a, 0x78, 0x4b
|
||||
EndPatch
|
||||
PatchChecksum
|
||||
@@ -0,0 +1,120 @@
|
||||
// This class was found online.
|
||||
// Original author is probably: Swizzy
|
||||
// https://github.com/ttgxdinger/Random/blob/master/CPUKey%20Checker/CPUKey%20Checker/FolderSelectDialog.cs
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps System.Windows.Forms.OpenFileDialog to make it present
|
||||
/// a vista-style dialog.
|
||||
/// </summary>
|
||||
public class FolderSelectDialog
|
||||
{
|
||||
// Wrapped dialog
|
||||
private readonly OpenFileDialog ofd = null;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public FolderSelectDialog()
|
||||
{
|
||||
ofd = new OpenFileDialog
|
||||
{
|
||||
Filter = "Folders|\n",
|
||||
AddExtension = false,
|
||||
CheckFileExists = false,
|
||||
DereferenceLinks = true,
|
||||
Multiselect = false
|
||||
};
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the initial folder to be selected. A null value selects the current directory.
|
||||
/// </summary>
|
||||
public string InitialDirectory
|
||||
{
|
||||
get { return ofd.InitialDirectory; }
|
||||
set { ofd.InitialDirectory = string.IsNullOrEmpty(value) ? Environment.CurrentDirectory : value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the title to show in the dialog
|
||||
/// </summary>
|
||||
public string Title
|
||||
{
|
||||
get { return ofd.Title; }
|
||||
set { ofd.Title = value ?? "Select a folder"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the selected folder
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get { return ofd.FileName; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Shows the dialog
|
||||
/// </summary>
|
||||
/// <returns>True if the user presses OK else false</returns>
|
||||
public bool ShowDialog()
|
||||
{
|
||||
return ShowDialog(IntPtr.Zero);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the dialog
|
||||
/// </summary>
|
||||
/// <param name="hWndOwner">Handle of the control to be parent</param>
|
||||
/// <returns>True if the user presses OK else false</returns>
|
||||
public bool ShowDialog(IntPtr hWndOwner)
|
||||
{
|
||||
var fbd = new FolderBrowserDialog
|
||||
{
|
||||
Description = this.Title,
|
||||
SelectedPath = this.InitialDirectory,
|
||||
ShowNewFolderButton = false
|
||||
};
|
||||
if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ofd.FileName = fbd.SelectedPath;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates IWin32Window around an IntPtr
|
||||
/// </summary>
|
||||
public class WindowWrapper : IWin32Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle to wrap</param>
|
||||
public WindowWrapper(IntPtr handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Original ptr
|
||||
/// </summary>
|
||||
public IntPtr Handle { get; }
|
||||
}
|
||||
}
|
||||
Generated
+423
@@ -0,0 +1,423 @@
|
||||
namespace Patcher
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.txtVisualStudioPath = new System.Windows.Forms.TextBox();
|
||||
this.FolderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.OpenFileDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
this.SaveFileDialog = new System.Windows.Forms.SaveFileDialog();
|
||||
this.cmdVisualStudioPath = new System.Windows.Forms.Button();
|
||||
this.cmdInputFolder = new System.Windows.Forms.Button();
|
||||
this.txtInputFolder = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.cmdOutputFolder = new System.Windows.Forms.Button();
|
||||
this.txtOutputFolder = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.cmdPatchDefinitionsFile = new System.Windows.Forms.Button();
|
||||
this.txtPatchDefinitionsFile = new System.Windows.Forms.TextBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.txtConsole = new System.Windows.Forms.TextBox();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.cmdCompile = new System.Windows.Forms.Button();
|
||||
this.cmdPatch = new System.Windows.Forms.Button();
|
||||
this.cmdScriptFile = new System.Windows.Forms.Button();
|
||||
this.txtScriptFile = new System.Windows.Forms.TextBox();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.cmdBackupFolder = new System.Windows.Forms.Button();
|
||||
this.txtBackupFolder = new System.Windows.Forms.TextBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.CapstoneLink = new System.Windows.Forms.LinkLabel();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.CapstoneNetLink = new System.Windows.Forms.LinkLabel();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(15, 13);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(191, 13);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Path to Visual Studio with ARM32 SDK";
|
||||
//
|
||||
// txtVisualStudioPath
|
||||
//
|
||||
this.txtVisualStudioPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtVisualStudioPath.Location = new System.Drawing.Point(18, 29);
|
||||
this.txtVisualStudioPath.Name = "txtVisualStudioPath";
|
||||
this.txtVisualStudioPath.Size = new System.Drawing.Size(665, 20);
|
||||
this.txtVisualStudioPath.TabIndex = 1;
|
||||
//
|
||||
// OpenFileDialog
|
||||
//
|
||||
this.OpenFileDialog.FileName = "openFileDialog1";
|
||||
//
|
||||
// cmdVisualStudioPath
|
||||
//
|
||||
this.cmdVisualStudioPath.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdVisualStudioPath.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.cmdVisualStudioPath.Location = new System.Drawing.Point(689, 28);
|
||||
this.cmdVisualStudioPath.Name = "cmdVisualStudioPath";
|
||||
this.cmdVisualStudioPath.Size = new System.Drawing.Size(35, 22);
|
||||
this.cmdVisualStudioPath.TabIndex = 2;
|
||||
this.cmdVisualStudioPath.Text = "...";
|
||||
this.cmdVisualStudioPath.UseVisualStyleBackColor = true;
|
||||
this.cmdVisualStudioPath.Click += new System.EventHandler(this.cmdVisualStudioPath_Click);
|
||||
//
|
||||
// cmdInputFolder
|
||||
//
|
||||
this.cmdInputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdInputFolder.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.cmdInputFolder.Location = new System.Drawing.Point(689, 224);
|
||||
this.cmdInputFolder.Name = "cmdInputFolder";
|
||||
this.cmdInputFolder.Size = new System.Drawing.Size(35, 22);
|
||||
this.cmdInputFolder.TabIndex = 8;
|
||||
this.cmdInputFolder.Text = "...";
|
||||
this.cmdInputFolder.UseVisualStyleBackColor = true;
|
||||
this.cmdInputFolder.Click += new System.EventHandler(this.cmdInputFolder_Click);
|
||||
//
|
||||
// txtInputFolder
|
||||
//
|
||||
this.txtInputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtInputFolder.Location = new System.Drawing.Point(18, 225);
|
||||
this.txtInputFolder.Name = "txtInputFolder";
|
||||
this.txtInputFolder.Size = new System.Drawing.Size(665, 20);
|
||||
this.txtInputFolder.TabIndex = 7;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(15, 209);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(71, 13);
|
||||
this.label2.TabIndex = 12;
|
||||
this.label2.Text = "Input location";
|
||||
//
|
||||
// cmdOutputFolder
|
||||
//
|
||||
this.cmdOutputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdOutputFolder.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.cmdOutputFolder.Location = new System.Drawing.Point(689, 322);
|
||||
this.cmdOutputFolder.Name = "cmdOutputFolder";
|
||||
this.cmdOutputFolder.Size = new System.Drawing.Size(35, 22);
|
||||
this.cmdOutputFolder.TabIndex = 12;
|
||||
this.cmdOutputFolder.Text = "...";
|
||||
this.cmdOutputFolder.UseVisualStyleBackColor = true;
|
||||
this.cmdOutputFolder.Click += new System.EventHandler(this.cmdOutputFolder_Click);
|
||||
//
|
||||
// txtOutputFolder
|
||||
//
|
||||
this.txtOutputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtOutputFolder.Location = new System.Drawing.Point(18, 323);
|
||||
this.txtOutputFolder.Name = "txtOutputFolder";
|
||||
this.txtOutputFolder.Size = new System.Drawing.Size(665, 20);
|
||||
this.txtOutputFolder.TabIndex = 11;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(15, 307);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(125, 13);
|
||||
this.label3.TabIndex = 15;
|
||||
this.label3.Text = "Output location (optional)";
|
||||
//
|
||||
// cmdPatchDefinitionsFile
|
||||
//
|
||||
this.cmdPatchDefinitionsFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdPatchDefinitionsFile.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.cmdPatchDefinitionsFile.Location = new System.Drawing.Point(689, 91);
|
||||
this.cmdPatchDefinitionsFile.Name = "cmdPatchDefinitionsFile";
|
||||
this.cmdPatchDefinitionsFile.Size = new System.Drawing.Size(35, 22);
|
||||
this.cmdPatchDefinitionsFile.TabIndex = 4;
|
||||
this.cmdPatchDefinitionsFile.Text = "...";
|
||||
this.cmdPatchDefinitionsFile.UseVisualStyleBackColor = true;
|
||||
this.cmdPatchDefinitionsFile.Click += new System.EventHandler(this.cmdPatchDefinitionsFile_Click);
|
||||
//
|
||||
// txtPatchDefinitionsFile
|
||||
//
|
||||
this.txtPatchDefinitionsFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtPatchDefinitionsFile.Location = new System.Drawing.Point(18, 92);
|
||||
this.txtPatchDefinitionsFile.Name = "txtPatchDefinitionsFile";
|
||||
this.txtPatchDefinitionsFile.Size = new System.Drawing.Size(665, 20);
|
||||
this.txtPatchDefinitionsFile.TabIndex = 3;
|
||||
this.txtPatchDefinitionsFile.Leave += new System.EventHandler(this.txtPatchDefinitionsFile_Leave);
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(15, 76);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(117, 13);
|
||||
this.label4.TabIndex = 3;
|
||||
this.label4.Text = "Patch defintions xml-file";
|
||||
//
|
||||
// txtConsole
|
||||
//
|
||||
this.txtConsole.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtConsole.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.txtConsole.Location = new System.Drawing.Point(18, 383);
|
||||
this.txtConsole.Multiline = true;
|
||||
this.txtConsole.Name = "txtConsole";
|
||||
this.txtConsole.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.txtConsole.Size = new System.Drawing.Size(706, 392);
|
||||
this.txtConsole.TabIndex = 13;
|
||||
//
|
||||
// label9
|
||||
//
|
||||
this.label9.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.label9.AutoSize = true;
|
||||
this.label9.Location = new System.Drawing.Point(15, 367);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(78, 13);
|
||||
this.label9.TabIndex = 24;
|
||||
this.label9.Text = "Console output";
|
||||
//
|
||||
// cmdCompile
|
||||
//
|
||||
this.cmdCompile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdCompile.Location = new System.Drawing.Point(470, 792);
|
||||
this.cmdCompile.Name = "cmdCompile";
|
||||
this.cmdCompile.Size = new System.Drawing.Size(120, 33);
|
||||
this.cmdCompile.TabIndex = 14;
|
||||
this.cmdCompile.Text = "Compile";
|
||||
this.cmdCompile.UseVisualStyleBackColor = true;
|
||||
this.cmdCompile.Click += new System.EventHandler(this.cmdCompile_Click);
|
||||
//
|
||||
// cmdPatch
|
||||
//
|
||||
this.cmdPatch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdPatch.Location = new System.Drawing.Point(604, 792);
|
||||
this.cmdPatch.Name = "cmdPatch";
|
||||
this.cmdPatch.Size = new System.Drawing.Size(120, 33);
|
||||
this.cmdPatch.TabIndex = 15;
|
||||
this.cmdPatch.Text = "Patch";
|
||||
this.cmdPatch.UseVisualStyleBackColor = true;
|
||||
this.cmdPatch.Click += new System.EventHandler(this.cmdPatch_Click);
|
||||
//
|
||||
// cmdScriptFile
|
||||
//
|
||||
this.cmdScriptFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdScriptFile.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.cmdScriptFile.Location = new System.Drawing.Point(689, 155);
|
||||
this.cmdScriptFile.Name = "cmdScriptFile";
|
||||
this.cmdScriptFile.Size = new System.Drawing.Size(35, 22);
|
||||
this.cmdScriptFile.TabIndex = 6;
|
||||
this.cmdScriptFile.Text = "...";
|
||||
this.cmdScriptFile.UseVisualStyleBackColor = true;
|
||||
this.cmdScriptFile.Click += new System.EventHandler(this.cmdScriptFile_Click);
|
||||
//
|
||||
// txtScriptFile
|
||||
//
|
||||
this.txtScriptFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtScriptFile.Location = new System.Drawing.Point(18, 156);
|
||||
this.txtScriptFile.Name = "txtScriptFile";
|
||||
this.txtScriptFile.Size = new System.Drawing.Size(665, 20);
|
||||
this.txtScriptFile.TabIndex = 5;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(15, 140);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(50, 13);
|
||||
this.label5.TabIndex = 28;
|
||||
this.label5.Text = "Script-file";
|
||||
//
|
||||
// cmdBackupFolder
|
||||
//
|
||||
this.cmdBackupFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdBackupFolder.Font = new System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.cmdBackupFolder.Location = new System.Drawing.Point(689, 273);
|
||||
this.cmdBackupFolder.Name = "cmdBackupFolder";
|
||||
this.cmdBackupFolder.Size = new System.Drawing.Size(35, 22);
|
||||
this.cmdBackupFolder.TabIndex = 10;
|
||||
this.cmdBackupFolder.Text = "...";
|
||||
this.cmdBackupFolder.UseVisualStyleBackColor = true;
|
||||
this.cmdBackupFolder.Click += new System.EventHandler(this.cmdBackupFolder_Click);
|
||||
//
|
||||
// txtBackupFolder
|
||||
//
|
||||
this.txtBackupFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtBackupFolder.Location = new System.Drawing.Point(18, 274);
|
||||
this.txtBackupFolder.Name = "txtBackupFolder";
|
||||
this.txtBackupFolder.Size = new System.Drawing.Size(665, 20);
|
||||
this.txtBackupFolder.TabIndex = 9;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(15, 258);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(130, 13);
|
||||
this.label6.TabIndex = 31;
|
||||
this.label6.Text = "Backup location (optional)";
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(20, 807);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(66, 13);
|
||||
this.label7.TabIndex = 32;
|
||||
this.label7.Text = "Powered by ";
|
||||
//
|
||||
// CapstoneLink
|
||||
//
|
||||
this.CapstoneLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.CapstoneLink.AutoSize = true;
|
||||
this.CapstoneLink.Location = new System.Drawing.Point(80, 807);
|
||||
this.CapstoneLink.Name = "CapstoneLink";
|
||||
this.CapstoneLink.Size = new System.Drawing.Size(52, 13);
|
||||
this.CapstoneLink.TabIndex = 33;
|
||||
this.CapstoneLink.TabStop = true;
|
||||
this.CapstoneLink.Text = "Capstone";
|
||||
this.CapstoneLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.CapstoneLink_LinkClicked);
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(129, 807);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(28, 13);
|
||||
this.label8.TabIndex = 34;
|
||||
this.label8.Text = "and ";
|
||||
//
|
||||
// CapstoneNetLink
|
||||
//
|
||||
this.CapstoneNetLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.CapstoneNetLink.AutoSize = true;
|
||||
this.CapstoneNetLink.Location = new System.Drawing.Point(151, 807);
|
||||
this.CapstoneNetLink.Name = "CapstoneNetLink";
|
||||
this.CapstoneNetLink.Size = new System.Drawing.Size(77, 13);
|
||||
this.CapstoneNetLink.TabIndex = 35;
|
||||
this.CapstoneNetLink.TabStop = true;
|
||||
this.CapstoneNetLink.Text = "Capstone.NET";
|
||||
this.CapstoneNetLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.CapstoneNetLink_LinkClicked);
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(225, 807);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(42, 13);
|
||||
this.label10.TabIndex = 36;
|
||||
this.label10.Text = "libraries";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(742, 840);
|
||||
this.Controls.Add(this.label10);
|
||||
this.Controls.Add(this.CapstoneNetLink);
|
||||
this.Controls.Add(this.label8);
|
||||
this.Controls.Add(this.CapstoneLink);
|
||||
this.Controls.Add(this.label7);
|
||||
this.Controls.Add(this.cmdBackupFolder);
|
||||
this.Controls.Add(this.txtBackupFolder);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.cmdScriptFile);
|
||||
this.Controls.Add(this.txtScriptFile);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.cmdPatch);
|
||||
this.Controls.Add(this.cmdCompile);
|
||||
this.Controls.Add(this.txtConsole);
|
||||
this.Controls.Add(this.label9);
|
||||
this.Controls.Add(this.cmdPatchDefinitionsFile);
|
||||
this.Controls.Add(this.txtPatchDefinitionsFile);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.cmdOutputFolder);
|
||||
this.Controls.Add(this.txtOutputFolder);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.cmdInputFolder);
|
||||
this.Controls.Add(this.txtInputFolder);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.cmdVisualStudioPath);
|
||||
this.Controls.Add(this.txtVisualStudioPath);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Name = "MainForm";
|
||||
this.Text = "ARM Auto-patcher by Rene Lergner";
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed);
|
||||
this.Load += new System.EventHandler(this.MainForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox txtVisualStudioPath;
|
||||
private System.Windows.Forms.FolderBrowserDialog FolderBrowserDialog;
|
||||
private System.Windows.Forms.OpenFileDialog OpenFileDialog;
|
||||
private System.Windows.Forms.SaveFileDialog SaveFileDialog;
|
||||
private System.Windows.Forms.Button cmdVisualStudioPath;
|
||||
private System.Windows.Forms.Button cmdInputFolder;
|
||||
private System.Windows.Forms.TextBox txtInputFolder;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Button cmdOutputFolder;
|
||||
private System.Windows.Forms.TextBox txtOutputFolder;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Button cmdPatchDefinitionsFile;
|
||||
private System.Windows.Forms.TextBox txtPatchDefinitionsFile;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.TextBox txtConsole;
|
||||
private System.Windows.Forms.Label label9;
|
||||
private System.Windows.Forms.Button cmdCompile;
|
||||
private System.Windows.Forms.Button cmdPatch;
|
||||
private System.Windows.Forms.Button cmdScriptFile;
|
||||
private System.Windows.Forms.TextBox txtScriptFile;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Button cmdBackupFolder;
|
||||
private System.Windows.Forms.TextBox txtBackupFolder;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.LinkLabel CapstoneLink;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.LinkLabel CapstoneNetLink;
|
||||
private System.Windows.Forms.Label label10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using WPinternals;
|
||||
|
||||
namespace Patcher
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
private PatchEngine PatchEngine = null;
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
LoadPaths();
|
||||
CenterToScreen();
|
||||
}
|
||||
|
||||
private void LoadPaths()
|
||||
{
|
||||
RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\Patcher", true) ?? Registry.CurrentUser.CreateSubKey(@"Software\Patcher");
|
||||
|
||||
txtVisualStudioPath.Text = (string)Key.GetValue("VisualStudioPath", "");
|
||||
if (txtVisualStudioPath.Text.Length == 0)
|
||||
txtVisualStudioPath.Text = FindVisualStudioPath();
|
||||
|
||||
txtPatchDefinitionsFile.Text = (string)Key.GetValue("PatchDefinitionsFilePath", "");
|
||||
txtScriptFile.Text = (string)Key.GetValue("ScriptFilePath", "");
|
||||
txtInputFolder.Text = (string)Key.GetValue("InputFolderPath", "");
|
||||
txtOutputFolder.Text = (string)Key.GetValue("OutputFolderPath", "");
|
||||
txtBackupFolder.Text = (string)Key.GetValue("BackupFolderPath", "");
|
||||
|
||||
LoadPatchDefinitions();
|
||||
}
|
||||
|
||||
public static string[] FindMSVCBinaryPaths(string s)
|
||||
{
|
||||
string LegacyPath = Path.Combine(s, @"VC\bin");
|
||||
if (Directory.Exists(LegacyPath))
|
||||
{
|
||||
return new string[] { LegacyPath };
|
||||
}
|
||||
|
||||
if (Directory.Exists(Path.Combine(s, @"VC\Tools\MSVC")))
|
||||
{
|
||||
IEnumerable<string> MSVCs = Directory.EnumerateDirectories(Path.Combine(s, @"VC\Tools\MSVC"));
|
||||
IEnumerable<string> Bins = MSVCs.Select(s => Path.Combine(s, "bin")).Where(s => Directory.Exists(s));
|
||||
return Bins.ToArray();
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
public static string FindArmAsmPath(string s)
|
||||
{
|
||||
foreach (string MSVCBin in FindMSVCBinaryPaths(s))
|
||||
{
|
||||
string path1 = Path.Combine(MSVCBin, "x86_arm");
|
||||
string path2 = Path.Combine(MSVCBin, @"Hostx86\arm");
|
||||
|
||||
if (File.Exists(Path.Combine(path1, "armasm.exe")))
|
||||
{
|
||||
return path1;
|
||||
}
|
||||
|
||||
if (File.Exists(Path.Combine(path2, "armasm.exe")))
|
||||
{
|
||||
return path2;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static string FindVisualStudioPath()
|
||||
{
|
||||
IEnumerable<string> MainX86VSDirectories = Directory.EnumerateDirectories(@"C:\Program Files (x86)\", "Microsoft Visual Studio*");
|
||||
IEnumerable<string> MainX64VSDirectories = Directory.EnumerateDirectories(@"C:\Program Files\", "Microsoft Visual Studio*");
|
||||
|
||||
IEnumerable<string> MainVSDirectories = MainX86VSDirectories.Union(MainX64VSDirectories);
|
||||
|
||||
IEnumerable<string> SubMainVSDirectories = MainVSDirectories.SelectMany(s => Directory.EnumerateDirectories(s));
|
||||
IEnumerable<string> SubSubMainVSDirectories = SubMainVSDirectories.SelectMany(s => Directory.EnumerateDirectories(s));
|
||||
IEnumerable<string> Directories = MainVSDirectories.Union(SubMainVSDirectories).Union(SubSubMainVSDirectories);
|
||||
|
||||
string attempt1 = Directories.Where(s => FindArmAsmPath(s) != "").OrderByDescending(s => File.GetCreationTime(Path.Combine(s, @"VC\bin\x86_arm\armasm.exe"))).FirstOrDefault() ?? "";
|
||||
|
||||
if (attempt1 != "")
|
||||
return attempt1;
|
||||
|
||||
return Directories.Where(s => Directory.Exists(Path.Combine(s, @"VC\Tools\MSVC"))).Select(s => Path.Combine(s, @"VC\Tools\MSVC")).SelectMany(s => Directory.EnumerateDirectories(s)).Where(s => File.Exists(Path.Combine(s, @"bin\Hostx86\arm\armasm.exe"))).OrderByDescending(s => File.GetCreationTime(Path.Combine(s, @"bin\Hostx86\arm\armasm.exe"))).FirstOrDefault() ?? "";
|
||||
}
|
||||
|
||||
private void StorePaths()
|
||||
{
|
||||
RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\Patcher", true) ?? Registry.CurrentUser.CreateSubKey(@"Software\Patcher");
|
||||
|
||||
string VisualStudioPath = txtVisualStudioPath.Text.Trim();
|
||||
if (VisualStudioPath.Length == 0)
|
||||
{
|
||||
if (Key.GetValue("VisualStudioPath") != null)
|
||||
Key.DeleteValue("VisualStudioPath");
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("VisualStudioPath", VisualStudioPath);
|
||||
}
|
||||
|
||||
string PatchDefinitionsFilePath = txtPatchDefinitionsFile.Text.Trim();
|
||||
if (PatchDefinitionsFilePath.Length == 0)
|
||||
{
|
||||
if (Key.GetValue("PatchDefinitionsFilePath") != null)
|
||||
Key.DeleteValue("PatchDefinitionsFilePath");
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("PatchDefinitionsFilePath", PatchDefinitionsFilePath);
|
||||
}
|
||||
|
||||
string ScriptFilePath = txtScriptFile.Text.Trim();
|
||||
if (ScriptFilePath.Length == 0)
|
||||
{
|
||||
if (Key.GetValue("ScriptFilePath") != null)
|
||||
Key.DeleteValue("ScriptFilePath");
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("ScriptFilePath", ScriptFilePath);
|
||||
}
|
||||
|
||||
string InputFolderPath = txtInputFolder.Text.Trim();
|
||||
if (InputFolderPath.Length == 0)
|
||||
{
|
||||
if (Key.GetValue("InputFolderPath") != null)
|
||||
Key.DeleteValue("InputFolderPath");
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("InputFolderPath", InputFolderPath);
|
||||
}
|
||||
|
||||
string OutputFolderPath = txtOutputFolder.Text.Trim();
|
||||
if (OutputFolderPath.Length == 0)
|
||||
{
|
||||
if (Key.GetValue("OutputFolderPath") != null)
|
||||
Key.DeleteValue("OutputFolderPath");
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("OutputFolderPath", OutputFolderPath);
|
||||
}
|
||||
|
||||
string BackupFolderPath = txtBackupFolder.Text.Trim();
|
||||
if (BackupFolderPath.Length == 0)
|
||||
{
|
||||
if (Key.GetValue("BackupFolderPath") != null)
|
||||
Key.DeleteValue("BackupFolderPath");
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("BackupFolderPath", BackupFolderPath);
|
||||
}
|
||||
}
|
||||
|
||||
private bool LoadingPatchDefinitions = false;
|
||||
|
||||
private void LoadPatchDefinitions()
|
||||
{
|
||||
if (LoadingPatchDefinitions)
|
||||
return;
|
||||
LoadingPatchDefinitions = true;
|
||||
|
||||
try
|
||||
{
|
||||
string Definitions = File.ReadAllText(txtPatchDefinitionsFile.Text);
|
||||
PatchEngine = new PatchEngine(Definitions);
|
||||
}
|
||||
catch
|
||||
{
|
||||
PatchEngine = new PatchEngine();
|
||||
}
|
||||
|
||||
LoadingPatchDefinitions = false;
|
||||
}
|
||||
|
||||
private void cmdVisualStudioPath_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog.SelectedPath = txtVisualStudioPath.Text;
|
||||
FolderBrowserDialog.Description = "Select path to Visual Studio with ARM32 SDK";
|
||||
System.Windows.Forms.DialogResult Result = FolderBrowserDialog.ShowDialog();
|
||||
if (Result == System.Windows.Forms.DialogResult.OK)
|
||||
txtVisualStudioPath.Text = FolderBrowserDialog.SelectedPath;
|
||||
}
|
||||
|
||||
private void cmdPatchDefinitionsFile_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog.CheckFileExists = false;
|
||||
OpenFileDialog.DefaultExt = "xml";
|
||||
try
|
||||
{
|
||||
OpenFileDialog.FileName = Path.GetFileName(txtPatchDefinitionsFile.Text);
|
||||
OpenFileDialog.InitialDirectory = Path.GetDirectoryName(txtPatchDefinitionsFile.Text);
|
||||
}
|
||||
catch { }
|
||||
OpenFileDialog.Multiselect = false;
|
||||
OpenFileDialog.Title = "Open patch-definitions file";
|
||||
System.Windows.Forms.DialogResult Result = OpenFileDialog.ShowDialog();
|
||||
if (Result == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
txtPatchDefinitionsFile.Text = OpenFileDialog.FileName;
|
||||
WindowsFormsSynchronizationContext.Current.Post(s => LoadPatchDefinitions(), null);
|
||||
}
|
||||
}
|
||||
|
||||
private void txtPatchDefinitionsFile_Leave(object sender, EventArgs e)
|
||||
{
|
||||
WindowsFormsSynchronizationContext.Current.Post(s => LoadPatchDefinitions(), null);
|
||||
}
|
||||
|
||||
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
StorePaths();
|
||||
}
|
||||
|
||||
private void cmdInputFolder_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderSelectDialog Dialog = new();
|
||||
Dialog.Title = "Select input location";
|
||||
Dialog.InitialDirectory = txtInputFolder.Text;
|
||||
try
|
||||
{
|
||||
Dialog.InitialDirectory = txtInputFolder.Text;
|
||||
}
|
||||
catch { }
|
||||
bool Result = Dialog.ShowDialog();
|
||||
if (Result)
|
||||
{
|
||||
txtInputFolder.Text = Dialog.FileName;
|
||||
txtOutputFolder.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdOutputFolder_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderSelectDialog Dialog = new();
|
||||
Dialog.Title = "Select output location";
|
||||
Dialog.InitialDirectory = txtOutputFolder.Text;
|
||||
try
|
||||
{
|
||||
Dialog.InitialDirectory = txtOutputFolder.Text;
|
||||
}
|
||||
catch { }
|
||||
bool Result = Dialog.ShowDialog();
|
||||
if (Result)
|
||||
{
|
||||
txtOutputFolder.Text = Dialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdScriptFile_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog.CheckFileExists = true;
|
||||
OpenFileDialog.DefaultExt = "pds";
|
||||
try
|
||||
{
|
||||
OpenFileDialog.FileName = Path.GetFileName(txtScriptFile.Text);
|
||||
OpenFileDialog.InitialDirectory = Path.GetDirectoryName(txtScriptFile.Text);
|
||||
}
|
||||
catch { }
|
||||
OpenFileDialog.Multiselect = false;
|
||||
OpenFileDialog.Title = "Open patch-definition-script-file";
|
||||
System.Windows.Forms.DialogResult Result = OpenFileDialog.ShowDialog();
|
||||
if (Result == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
txtScriptFile.Text = OpenFileDialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdCompile_Click(object sender, EventArgs e)
|
||||
{
|
||||
ClearLog();
|
||||
StorePaths();
|
||||
ScriptEngine.ExecuteScript(txtVisualStudioPath.Text.Trim(), txtScriptFile.Text.Trim(), txtInputFolder.Text.Trim(), PatchEngine: PatchEngine, WriteLog: WriteLog);
|
||||
}
|
||||
|
||||
private void cmdPatch_Click(object sender, EventArgs e)
|
||||
{
|
||||
ClearLog();
|
||||
StorePaths();
|
||||
ScriptEngine.ExecuteScript(txtVisualStudioPath.Text.Trim(), txtScriptFile.Text.Trim(), txtInputFolder.Text.Trim(), PatchEngine, txtOutputFolder.Text.Trim(), txtBackupFolder.Text.Trim().Length == 0 ? null : txtBackupFolder.Text.Trim(), WriteLog);
|
||||
|
||||
PatchEngine.WriteDefinitions(txtPatchDefinitionsFile.Text);
|
||||
WriteLog("Patch-definitions written to: " + txtPatchDefinitionsFile.Text);
|
||||
}
|
||||
|
||||
private void ClearLog()
|
||||
{
|
||||
txtConsole.Clear();
|
||||
}
|
||||
|
||||
private void WriteLog(string Line)
|
||||
{
|
||||
if (txtConsole.InvokeRequired)
|
||||
{
|
||||
txtConsole.Invoke((MethodInvoker)delegate { WriteLog(Line); });
|
||||
}
|
||||
else
|
||||
{
|
||||
txtConsole.AppendText(Line + Environment.NewLine);
|
||||
txtConsole.Select(txtConsole.Text.Length, 0);
|
||||
txtConsole.ScrollToCaret();
|
||||
System.Diagnostics.Debug.WriteLine(Line);
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdBackupFolder_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderSelectDialog Dialog = new();
|
||||
Dialog.Title = "Select backup location";
|
||||
Dialog.InitialDirectory = txtBackupFolder.Text;
|
||||
try
|
||||
{
|
||||
Dialog.InitialDirectory = txtBackupFolder.Text;
|
||||
}
|
||||
catch { }
|
||||
bool Result = Dialog.ShowDialog();
|
||||
if (Result)
|
||||
{
|
||||
txtBackupFolder.Text = Dialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void CapstoneLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/aquynh/capstone/blob/master/LICENSE.TXT");
|
||||
}
|
||||
|
||||
private void CapstoneNetLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/9ee1/Capstone.NET/blob/master/LICENSE");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="FolderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="OpenFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>182, 17</value>
|
||||
</metadata>
|
||||
<metadata name="SaveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>317, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Patcher
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
private static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AutoPatcher")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AutoPatcher")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("95cf9509-c1c4-40f5-a60e-9d93ea6f438c")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Patcher.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Patcher.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Patcher.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user