diff --git a/libexeinfo/StringHandlers.cs b/libexeinfo/StringHandlers.cs new file mode 100644 index 0000000..ae9481a --- /dev/null +++ b/libexeinfo/StringHandlers.cs @@ -0,0 +1,185 @@ +// +// StringHandlers.cs +// +// Author: +// Natalia Portillo +// +// Copyright (c) 2017 Copyright © Claunia.com +// +// 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.Text; + +namespace libexeinfo +{ + public static class StringHandlers + { + /// + /// Converts a null-terminated (aka C string) ASCII byte array to a C# string + /// + /// The corresponding C# string + /// A null-terminated (aka C string) ASCII byte array + public static string CToString(byte[] CString) + { + return CToString(CString, Encoding.ASCII); + } + + /// + /// Converts a null-terminated (aka C string) byte array with the specified encoding to a C# string + /// + /// The corresponding C# string + /// A null-terminated (aka C string) byte array in the specified encoding + /// Encoding. + /// Set if encoding uses 16-bit characters. + /// Start decodint at this position + public static string CToString(byte[] CString, Encoding encoding, bool twoBytes = false, int start = 0) + { + if(CString == null) return null; + + int len = 0; + + for(int i = start; i < CString.Length; i++) + { + if(CString[i] == 0) + if(twoBytes) + { + if(i + 1 < CString.Length && CString[i + 1] == 0) + { + len++; + break; + } + + // if((i + 1) == CString.Length) + // break; + } + else + break; + + len++; + } + + byte[] dest = new byte[len]; + Array.Copy(CString, start, dest, 0, len); + + return len == 0 ? "" : encoding.GetString(dest); + } + + /// + /// Converts a length-prefixed (aka Pascal string) ASCII byte array to a C# string + /// + /// The corresponding C# string + /// A length-prefixed (aka Pascal string) ASCII byte array + public static string PascalToString(byte[] PascalString) + { + return PascalToString(PascalString, Encoding.ASCII); + } + + /// + /// Converts a length-prefixed (aka Pascal string) ASCII byte array to a C# string + /// + /// The corresponding C# string + /// A length-prefixed (aka Pascal string) ASCII byte array + /// Encoding. + /// Start decodint at this position + public static string PascalToString(byte[] PascalString, Encoding encoding, int start = 0) + { + if(PascalString == null) return null; + + byte length = PascalString[start]; + int len = 0; + + for(int i = start + 1; i < length + 1 && i < PascalString.Length; i++) + { + if(PascalString[i] == 0) break; + + len++; + } + + byte[] dest = new byte[len]; + Array.Copy(PascalString, start + 1, dest, 0, len); + + return len == 0 ? "" : encoding.GetString(dest); + } + + /// + /// Converts a space (' ', 0x20, ASCII SPACE) padded ASCII byte array to a C# string + /// + /// The corresponding C# string + /// A space (' ', 0x20, ASCII SPACE) padded ASCII byte array + public static string SpacePaddedToString(byte[] SpacePaddedString) + { + return SpacePaddedToString(SpacePaddedString, Encoding.ASCII); + } + + /// + /// Converts a space (' ', 0x20, ASCII SPACE) padded ASCII byte array to a C# string + /// + /// The corresponding C# string + /// A space (' ', 0x20, ASCII SPACE) padded ASCII byte array + /// Encoding. + /// Start decodint at this position + public static string SpacePaddedToString(byte[] SpacePaddedString, Encoding encoding, int start = 0) + { + if(SpacePaddedString == null) return null; + + int len = start; + + for(int i = SpacePaddedString.Length; i >= start; i--) + { + if(i == start) return ""; + + if(SpacePaddedString[i - 1] == 0x20) continue; + + len = i; + break; + } + + return len == 0 ? "" : encoding.GetString(SpacePaddedString, start, len); + } + + /// + /// Converts an OSTA compressed unicode byte array to a C# string + /// + /// The C# string. + /// OSTA compressed unicode byte array. + public static string DecompressUnicode(byte[] dstring) + { + ushort unicode; + byte compId = dstring[0]; + string temp = ""; + + if(compId != 8 && compId != 16) return null; + + for(int byteIndex = 1; byteIndex < dstring.Length;) + { + if(compId == 16) unicode = (ushort)(dstring[byteIndex++] << 8); + else unicode = 0; + + if(byteIndex < dstring.Length) unicode |= dstring[byteIndex++]; + + if(unicode == 0) break; + + temp += Encoding.Unicode.GetString(BitConverter.GetBytes(unicode)); + } + + return temp; + } + } +} \ No newline at end of file diff --git a/libexeinfo/libexeinfo.csproj b/libexeinfo/libexeinfo.csproj index 30e2934..2c5a8d5 100644 --- a/libexeinfo/libexeinfo.csproj +++ b/libexeinfo/libexeinfo.csproj @@ -86,6 +86,7 @@ +