private static void HandleCmdLine(string[] args) { // If the application is being run from the command line if (args[0] == "/geninfofile") { if (args.Length != 3) { MessageBox.Show("Pass the EXE path as the first parameter and the output file as the second."); return; } // Get the EXE path string exePath = args[1]; string outFile = args[2]; FileInfo exeInfo = new FileInfo(exePath); if (!exeInfo.Exists) { Console.WriteLine("Cannot find EXE file (" + exePath + ")"); } else { PTExeDiscovery.GenerateExeInfoFile(exePath, outFile); } return; } else if (args[0] == "/genmacinfofile") { if (args.Length != 3) { MessageBox.Show("Pass the EXE path as the first parameter and the output file as the second."); return; } // Get the EXE path string exePath = args[1]; string outFile = args[2]; FileInfo exeInfo = new FileInfo(exePath); if (!exeInfo.Exists) { Console.WriteLine("Cannot find EXE file (" + exePath + ")"); } else { PTExeDiscovery.GenerateMacExeInfoFile(exePath, outFile); } return; } else if (args[0] == "/setkey") { if (args.Length != 5) { MessageBox.Show("USAGE: MsgKeyGen /setkey keyoffset intra64Padding keyvalue exepath"); return; } // Get the values long keyOffsetVal = long.Parse(args[1]); UInt64 keyValue = UInt64.Parse(args[2]); int intra64Padding = int.Parse(args[3]); string exePath = args[4]; FileInfo exeInfo = new FileInfo(exePath); if (!exeInfo.Exists) { Console.WriteLine("Cannot find EXE file (" + exePath + ")"); } else { PTWebApp.PTCustomizeUtil util = new PTWebApp.PTCustomizeUtil(); PTCustomizeUtil.FullKeyOffset keyOffset = new PTCustomizeUtil.FullKeyOffset(); keyOffset.KeyOffset = keyOffsetVal; keyOffset.Intra64bitPadding = intra64Padding; // Modify the EXE util.OverwriteValueInEXE(exePath, keyValue, keyOffset); Console.WriteLine("EXE key updated"); } return; } else if (args[0] == "/findandsetkey") { if (args.Length != 3) { MessageBox.Show("USAGE: MsgKeyGen /findandsetkey keyvalue exepath"); return; } // Get the values UInt64 keyValue = UInt64.Parse(args[1]); string exePath = args[2]; FileInfo exeInfo = new FileInfo(exePath); if (!exeInfo.Exists) { Console.WriteLine("Cannot find EXE file (" + exePath + ")"); } else { PTCustomizeUtil util = new PTCustomizeUtil(); // Modify the EXE PTCustomizeUtil.FullKeyOffset keyOffset = PTExeDiscovery.FindKeyOffset(exePath); if (keyOffset.KeyOffset != 0) { util.OverwriteValueInEXE(exePath, keyValue, keyOffset); Console.WriteLine("EXE key updated (Key found at:" + keyOffset + ")"); } else { Console.WriteLine("Failed to find key offsset"); } } return; } else if (args[0] == "/setmsg") { if (args.Length != 4) { MessageBox.Show("USAGE: MsgKeyGen /setmsg msgoffset msg exepath"); return; } // Get the values long msgOffset = long.Parse(args[1]); string msg = args[2]; string exePath = args[3]; FileInfo exeInfo = new FileInfo(exePath); if (!exeInfo.Exists) { Console.WriteLine("Cannot find EXE file (" + exePath + ")"); } else { PTCustomizeUtil util = new PTCustomizeUtil(); // Modify the EXE util.OverwriteMsg(exePath, msgOffset, msg); Console.WriteLine("EXE message updated"); } return; } else if (args[0] == "/findandsetmsg") { if (args.Length != 3) { MessageBox.Show("USAGE: MsgKeyGen /findandsetmsg msg exepath"); return; } // Get the values string msg = args[1]; string exePath = args[2]; FileInfo exeInfo = new FileInfo(exePath); if (!exeInfo.Exists) { Console.WriteLine("Cannot find EXE file (" + exePath + ")"); } else { long msgOffset = PTExeDiscovery.FindMsgOffset(exePath); // Modify the EXE if (msgOffset != 0) { new PTCustomizeUtil().OverwriteMsg(exePath, msgOffset, msg); Console.WriteLine("EXE message updated (message found at: " + msgOffset + ")"); } else { Console.WriteLine("Failed to find message offset"); } } return; } }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary>Find the offset with in the Prime Time executable of the key value.</summary> /// <param name="exePath">The full path to the Prime Time executable</param> /// <returns>The offset to the key or 0 on error</returns> /////////////////////////////////////////////////////////////////////////////////////////// public static PTCustomizeUtil.FullKeyOffset FindKeyOffset(string exePath, long startOffset) { PTCustomizeUtil.FullKeyOffset retOffset = new PTCustomizeUtil.FullKeyOffset(); // Open the file try { FileStream exeFileStream = File.OpenRead(exePath); BinaryReader reader = new BinaryReader(exeFileStream); byte[] exeFileData = reader.ReadBytes((int)exeFileStream.Length); exeFileStream.Close(); byte[] searchBytes = PTCustomizeUtil.UInt64ToArray(GAME_FIXED_KEYS[0], CharByteOrder); // Go through the file int keyMatchIndex = 0; int byteMatchIndex = 0; long keyMatchStartPosition = 0; long curExeDataByteIndex = startOffset; while (curExeDataByteIndex < exeFileData.Length) { byte curByte = exeFileData[curExeDataByteIndex++]; // If the byte matches the value currently being tested if (curByte == searchBytes[byteMatchIndex]) { // If this is the first match if (byteMatchIndex == 0 && keyMatchIndex == 0) { keyMatchStartPosition = curExeDataByteIndex - 1; } // Increment the search ++byteMatchIndex; } // Else restart the search if there are matches else if (keyMatchIndex > 0 || byteMatchIndex > 0) { // If there are matches then restart keyMatchIndex = 0; searchBytes = PTCustomizeUtil.UInt64ToArray(GAME_FIXED_KEYS[keyMatchIndex], CharByteOrder); byteMatchIndex = 0; // If this byte matches the first byte to find if (curByte == searchBytes[byteMatchIndex]) { ++byteMatchIndex; // Store the offset keyMatchStartPosition = curExeDataByteIndex - 1; } continue; } // If the match has found the first four bytes if (byteMatchIndex == 4) { int oldPadding = retOffset.Intra64bitPadding; // Get passed the padding between the two DWORDs that make up the 64-bit integer retOffset.Intra64bitPadding = StepPassed64Padding(searchBytes[byteMatchIndex], exeFileData, curExeDataByteIndex); curExeDataByteIndex += retOffset.Intra64bitPadding; // If the padding changed then FREAK OUT if (oldPadding != -1 && oldPadding != retOffset.Intra64bitPadding) { // The padding is incorrect so ignore this keyMatchIndex = 0; searchBytes = PTCustomizeUtil.UInt64ToArray(GAME_FIXED_KEYS[keyMatchIndex], CharByteOrder); byteMatchIndex = 0; //throw new ApplicationException( "Intra-64-bit integer offset (Between DWORDs) not standard!" ); } continue; } // Else if the key was matched else if (byteMatchIndex == 8) { ++keyMatchIndex; // If all of the keys have matched if (keyMatchIndex == GAME_FIXED_KEYS.Length) { break; } // The 3 item in the key list is the one that gets overwritten so skip it else if (keyMatchIndex == 2) { int amountToSkip = 8 + retOffset.Inter64bitPadding + retOffset.Intra64bitPadding; curExeDataByteIndex += amountToSkip; keyMatchIndex = 3; } // Get the new bytes to find searchBytes = PTCustomizeUtil.UInt64ToArray(GAME_FIXED_KEYS[keyMatchIndex], CharByteOrder); byteMatchIndex = 0; int oldPadding = retOffset.Inter64bitPadding; // Get past the padding between 64-bit integers retOffset.Inter64bitPadding = StepPassed64Padding(searchBytes[byteMatchIndex], exeFileData, curExeDataByteIndex); curExeDataByteIndex += retOffset.Inter64bitPadding; // If the padding changed then FREAK OUT if (oldPadding != -1 && oldPadding != retOffset.Inter64bitPadding) { throw new ApplicationException("64-bit integer offset not standard!"); } continue; } } // If the keys were found if (keyMatchIndex == GAME_FIXED_KEYS.Length) { long PACKED_KEY_LEN = 8 + retOffset.Inter64bitPadding + retOffset.Intra64bitPadding; long actualKeyOffsetFromStart = PACKED_KEY_LEN * ACTUAL_KEY_INDEX; // Store the offset retOffset.KeyOffset = keyMatchStartPosition + actualKeyOffsetFromStart; } } catch (Exception) { // This is just here for convenience in case I want to handle the exception or not throw; } return(retOffset); }