diff --git a/Build.bat b/Build.bat new file mode 100644 index 0000000..5a81e30 --- /dev/null +++ b/Build.bat @@ -0,0 +1,3 @@ +git pull && FOR %%a in (*.sln) DO "D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" %%a /p:Configuration=Release + + diff --git a/FileConfunder.sln b/Confunder.sln similarity index 62% rename from FileConfunder.sln rename to Confunder.sln index c24976e..f4b92cf 100644 --- a/FileConfunder.sln +++ b/Confunder.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.572 +# Visual Studio Version 18 +VisualStudioVersion = 18.8.12009.203 stable MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileConfunder", "FileConfunder\FileConfunder.csproj", "{11E4908A-80F5-4C7E-9994-379927B5FF28}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Confunder", "Confunder\Confunder.csproj", "{DDCB9592-9AAA-7392-366F-B6F351FF1712}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +15,10 @@ Global {11E4908A-80F5-4C7E-9994-379927B5FF28}.Debug|Any CPU.Build.0 = Debug|Any CPU {11E4908A-80F5-4C7E-9994-379927B5FF28}.Release|Any CPU.ActiveCfg = Release|Any CPU {11E4908A-80F5-4C7E-9994-379927B5FF28}.Release|Any CPU.Build.0 = Release|Any CPU + {DDCB9592-9AAA-7392-366F-B6F351FF1712}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDCB9592-9AAA-7392-366F-B6F351FF1712}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDCB9592-9AAA-7392-366F-B6F351FF1712}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDCB9592-9AAA-7392-366F-B6F351FF1712}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Confunder/Confunder.csproj b/Confunder/Confunder.csproj new file mode 100644 index 0000000..e1868f1 --- /dev/null +++ b/Confunder/Confunder.csproj @@ -0,0 +1,18 @@ + + + + Exe + confunder + Confunder + net10.0 + disable + disable + + + + + PreserveNewest + + + + diff --git a/FileConfunder/FPE.Net/Ciphers.cs b/Confunder/FPE.Net/Ciphers.cs similarity index 94% rename from FileConfunder/FPE.Net/Ciphers.cs rename to Confunder/FPE.Net/Ciphers.cs index 8b0389e..9469ee6 100644 --- a/FileConfunder/FPE.Net/Ciphers.cs +++ b/Confunder/FPE.Net/Ciphers.cs @@ -33,12 +33,12 @@ internal class Ciphers /** * Instance of the AES cipher in ECB mode with no padding. */ - private AesManaged mAesEcbCipher; + private Aes mAesEcbCipher; /** * Instance of the AES cipher in CBC mode with no padding. */ - private AesManaged mAesCbcCipher; + private Aes mAesCbcCipher; /** * Constructs a Ciphers instance with the required AES ciphers. @@ -47,18 +47,15 @@ public Ciphers() { try { - mAesEcbCipher = new AesManaged() { - Mode = CipherMode.ECB, - Padding = PaddingMode.None, - KeySize = 128 - }; - - mAesCbcCipher = new AesManaged() - { - Mode = CipherMode.CBC, - Padding = PaddingMode.None, - KeySize = 128 - }; + mAesEcbCipher = Aes.Create(); + mAesEcbCipher.Mode = CipherMode.ECB; + mAesEcbCipher.Padding = PaddingMode.None; + mAesEcbCipher.KeySize = 128; + + mAesCbcCipher = Aes.Create(); + mAesCbcCipher.Mode = CipherMode.CBC; + mAesCbcCipher.Padding = PaddingMode.None; + mAesCbcCipher.KeySize = 128; } catch (Exception e) { diff --git a/FileConfunder/FPE.Net/Common.cs b/Confunder/FPE.Net/Common.cs similarity index 99% rename from FileConfunder/FPE.Net/Common.cs rename to Confunder/FPE.Net/Common.cs index 2ae68a7..e26ae58 100644 --- a/FileConfunder/FPE.Net/Common.cs +++ b/Confunder/FPE.Net/Common.cs @@ -210,10 +210,7 @@ public static int[] str(BigInteger x, int radix, int m) // type conversion for readability BigInteger r = radix; - - // validate x - if (x == null) - throw new NullReferenceException("x must not be null"); + if (x.CompareTo(BigInteger.Zero) < 0 || x.CompareTo(BigInteger.Pow(r, m)) >= 0) throw new Exception("X is not within the permitted range of 0.." + BigInteger.Pow(r, m) + ": " + x); diff --git a/FileConfunder/FPE.Net/Constants.cs b/Confunder/FPE.Net/Constants.cs similarity index 100% rename from FileConfunder/FPE.Net/Constants.cs rename to Confunder/FPE.Net/Constants.cs diff --git a/FileConfunder/FPE.Net/FF1.cs b/Confunder/FPE.Net/FF1.cs similarity index 100% rename from FileConfunder/FPE.Net/FF1.cs rename to Confunder/FPE.Net/FF1.cs diff --git a/Confunder/Program.cs b/Confunder/Program.cs new file mode 100644 index 0000000..d1452b6 --- /dev/null +++ b/Confunder/Program.cs @@ -0,0 +1,725 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace Confunder +{ + internal static class Program + { + private static readonly byte[] _confundedMark = [40, 148, 255, 79, 150, 33, 167, 55, 240, 229, 188, 178, 88, 107, 97, 7, 9, 81, 136, 15, 179, 169, 191, 121, 209, 203, 64, 167, 87, 63, 248, 181, 111, 63, 243, 215, 10, 27, 233, 125, 104, 166, 130, 99, 115, 110, 159, 111, 135, 214, 18, 144, 126, 189, 31, 197, 187, 138, 202, 60, 96, 27, 123, 107, 159, 199, 146, 112, 79, 112, 143, 144, 209, 40, 102, 95, 169, 25, 136, 215, 189, 228, 180, 65, 199, 86, 160, 59, 39, 178, 16, 112, 201, 56, 34, 39, 141, 87, 49, 3, 74, 4, 57, 191, 26, 154, 135, 8, 118, 56, 131, 185, 230, 127, 66, 102, 162, 155, 20, 34, 156, 1, 34, 68, 175, 234, 209, 82, 240, 43, 137, 37, 136, 205, 13, 136, 233, 8, 141, 87, 18, 252, 19, 247, 143, 248, 244, 244, 222, 214, 234, 219, 164, 26, 72, 14, 12, 206, 137, 141, 146, 221, 8, 116, 52, 200, 128, 172, 105, 31, 53, 0, 27, 158, 112, 84, 152, 161, 222, 140, 130, 152, 65, 148, 118, 158, 222, 67, 135, 84, 124, 206, 14, 128, 74, 137, 167, 233, 212, 68, 177, 5, 115, 139, 173, 199, 94, 200, 192, 172, 214, 180, 59, 172, 126, 137, 211, 169, 165, 68, 240, 226, 145, 96, 28, 104, 172, 52, 27, 205, 108, 120, 185, 133, 30, 202, 17, 216, 192, 25, 235, 40, 176, 114, 39, 225, 241, 15, 10, 138, 67, 165, 234, 191, 144, 18, 127, 197, 177, 202, 112, 132, 171, 183, 126, 124, 83, 138, 130, 214, 108, 177, 22, 129, 64, 122, 128, 204, 67, 120, 189, 31, 164, 74, 116, 190, 50, 202, 216, 90, 100, 9, 8, 84, 49, 17, 158, 122, 24, 102, 24, 98, 99, 134, 220, 200, 155, 33, 120, 122, 229, 41, 53, 114, 94, 70, 89, 146, 59, 118, 73, 207, 3, 199, 239, 134, 230, 83, 204, 176, 15, 236, 47, 16, 136, 245, 9, 108, 12, 68, 150, 179, 83, 146, 27, 181, 69, 134, 83, 163, 145, 27, 96, 252, 236, 185, 242, 119, 176, 226, 63, 28, 114, 6, 94, 231, 187, 239, 167, 171, 148, 23, 91, 167, 232, 84, 78, 166, 109, 44, 212, 150, 138, 178, 30, 91, 172, 79, 37, 14, 202, 76, 241, 80, 187, 68, 177, 220, 252, 110, 22, 92, 130, 73, 8, 202, 246, 138, 139, 164, 68, 33, 248, 59, 213, 118, 126, 60, 247, 46, 94, 223, 172, 119, 237, 9, 246, 167, 70, 70, 34, 157, 254, 166, 150, 46, 87, 53, 71, 223, 171, 139, 218, 168, 8, 207, 224, 53, 64, 190, 199, 68, 157, 16, 65, 48, 106, 172, 188, 196, 168, 147, 72, 131, 137, 57, 223, 150, 131, 37, 229, 4, 66, 45, 177, 57, 137, 30, 30, 98, 14, 65, 204, 209, 158, 117, 224, 38, 246, 3, 230, 116, 86, 224, 62, 157, 60, 137, 205, 129, 165, 108, 16, 154, 208, 133, 68, 113, 92, 220, 56, 164, 110, 8, 33, 33, 88, 73, 7, 219, 224, 235, 35, 209, 164, 62, 155, 130, 123, 132, 28, 85, 198, 43, 95, 42, 31, 2, 206, 19, 206, 0, 208, 196, 66, 189, 15, 226, 245, 63, 24, 145, 39, 62, 213, 231, 39, 160, 115, 46, 13, 45, 250, 218, 74, 60, 150, 254, 245, 29, 53, 123, 15, 140, 24, 16, 153, 187, 150, 232, 139, 73, 107, 149, 116, 105, 195, 136, 209, 150, 176, 206, 201, 42, 227, 58, 93, 158, 26, 231, 186, 222, 135, 229, 108, 203, 213, 215, 141, 85, 133, 199, 31, 183, 193, 35, 131, 114, 90, 143, 60, 147, 3, 15, 109, 209, 126, 0, 91, 43, 53, 126, 17, 71, 46, 175, 90, 232, 236, 94, 185, 192, 123, 50, 74, 109, 245, 57, 242, 147, 100, 195, 79, 138, 121, 137, 243, 70, 100, 124, 172, 59, 96, 51, 77, 58, 141, 87, 104, 212, 107, 228, 195, 123, 77, 71, 44, 184, 120, 51, 146, 58, 89, 49, 234, 177, 140, 50, 157, 166, 71, 177, 165, 21, 95, 254, 190, 37, 60, 63, 90, 44, 74, 214, 235, 126, 79, 192, 87, 227, 169, 97, 199, 46, 9, 82, 221, 164, 5, 151, 223, 201, 192, 248, 220, 91, 110, 186, 64, 218, 250, 177, 140, 157, 10, 160, 124, 139, 33, 167, 154, 196, 21, 127, 17, 34, 162, 147, 251, 20, 178, 191, 92, 225, 164, 31, 32, 13, 60, 205, 208, 181, 56, 8, 195, 179, 223, 247, 123, 2, 84, 203, 47, 164, 235, 143, 171, 181, 107, 51, 116, 243, 189, 221, 173, 78, 172, 224, 147, 54, 110, 33, 120, 204, 157, 240, 93, 201, 208, 65, 118, 113, 11, 130, 101, 178, 96, 186, 240, 198, 40, 85, 4, 7, 167, 138, 60, 181, 33, 240, 128, 175, 56, 92, 66, 14, 12, 157, 53, 152, 9, 167, 15, 21, 137, 127, 57, 92, 145, 79, 170, 150, 51, 124, 197, 99, 47, 167, 157, 106, 133, 59, 61, 226, 54, 159, 236, 160, 149, 252, 254, 65, 88, 96, 124, 156, 244, 158, 108, 188, 194, 85, 51, 190, 237, 209, 90, 168, 172, 253, 14, 82, 96, 42, 45, 42, 29, 77, 183, 187, 215, 125, 125, 103, 235, 175, 3, 212, 121, 40, 223, 59, 182, 76, 125, 16, 169, 251, 143, 90, 122, 114, 26, 38, 205, 63, 137, 121, 140, 68, 247, 242, 107, 110, 86, 126, 126, 247, 234, 89, 216, 240, 105, 199, 152, 192, 157, 223, 245, 121, 155, 15, 167, 145, 112, 254, 106, 131, 63, 140, 215, 218, 159, 226, 100, 114, 39, 209, 202, 72, 91, 12, 106, 183, 85, 9, 97, 249, 76, 107, 103, 254, 219, 46, 162, 42, 5, 238, 10, 188, 254, 157, 199, 233, 3, 42, 174, 167, 203, 147, 73, 214, 76, 131, 46, 41, 161, 50, 209, 114, 98, 64, 171, 28, 184, 77, 225, 229, 124, 106, 64, 7, 107, 116, 70, 74, 172, 8, 206, 29, 69, 249, 188, 68, 201, 116, 111, 158, 21, 235, 2, 155, 108, 130, 212, 232, 50, 162, 224, 245, 237, 47, 108, 146, 17, 75, 223, 43, 235, 138, 215, 96, 209, 255, 42, 83, 191, 173, 78, 243, 9, 181, 249, 188, 72, 252, 44, 137, 57, 245, 108, 248, 70, 23, 241, 134, 31, 151, 11, 140, 114, 91, 218, 9, 152, 252, 82, 251, 166, 240, 181, 177, 218, 47, 230, 182, 191, 55, 95, 197, 96, 16, 191, 0, 152, 123, 75, 156, 121, 183, 175, 90, 33, 139, 26, 15, 247, 17, 158, 242, 90, 22, 36, 92, 175, 224, 97, 64, 213, 178, 35, 162, 105, 239, 155, 124, 144, 151, 47, 41, 105, 144, 43, 61, 86, 185, 117, 154, 131, 129, 161, 128, 112, 179, 123, 46, 7, 67, 64, 115, 152, 44, 64, 196, 103, 61, 113, 250, 240, 254, 63, 110, 198, 237, 138, 86, 29, 229, 203, 92, 145, 152, 153, 14, 166, 20, 92, 26, 239, 68, 121, 120, 9, 55, 100, 145, 96, 151, 199, 90, 44, 169, 245, 190, 249, 237, 99, 62, 26, 150, 142, 3, 184, 160, 189, 96, 90, 137, 51, 108, 208, 43, 25, 124, 165, 216, 248, 173, 118, 110, 59, 249, 249, 63, 47, 42, 15, 218, 247, 86, 106, 93, 86, 125, 155, 2, 51, 133, 237, 102, 22, 242, 150, 179, 146, 170, 166, 184, 163, 114, 195, 94, 223, 167, 17, 234, 240, 28, 128, 240, 191, 192, 90, 238, 14, 16, 158, 103, 252, 191, 91, 34, 55, 216, 22, 132, 35, 193, 27, 152, 160, 96, 86, 31, 12, 206, 246, 62, 134, 102, 209, 56, 67, 165, 198, 83, 117, 14, 91, 54, 237, 240, 174, 163, 138, 63, 101, 136, 235, 23, 203, 214, 248, 15, 64, 175, 207, 149, 32, 54, 116, 243, 185, 46, 33, 55, 197, 166, 78, 47, 244, 225, 217, 16, 195, 118, 66, 78, 135, 120, 155, 186, 208, 22, 125, 28, 57, 180, 55, 224, 201, 73, 147, 22, 169, 69, 63, 135, 35, 231, 10, 147, 181, 159, 60, 84, 234, 102, 7, 186, 125, 118, 236, 50, 241, 88, 167, 182, 232, 176, 197, 125, 200, 186, 137, 147, 27, 105, 57, 120, 36, 20, 228, 232, 247, 183, 72, 124, 237, 198, 34, 148, 191, 176, 6, 205, 86, 29, 205, 209, 143, 5, 62, 91, 68, 217, 30, 217, 253, 197, 182, 134, 113, 24, 237, 50, 183, 110, 143, 49, 77, 241, 126, 131, 215, 195, 17, 71, 120, 212, 193, 84, 109, 143, 64, 36, 1, 188, 221, 92, 76, 60, 227, 172, 80, 252, 149, 228, 54, 218, 126, 106, 193, 226, 142, 152, 147, 223, 224, 102, 10, 97, 185, 37, 220, 240, 93, 140, 70, 158, 179, 181, 1, 140, 9, 132, 42, 114, 231, 66, 120, 224, 185, 242, 242, 61, 157, 210, 76, 215, 53, 130, 162, 187, 151, 25, 247, 100, 30, 97, 150, 220, 136, 159, 251, 118, 225, 33, 249, 129, 147, 232, 148, 74, 84, 45, 155, 246, 219, 174, 112, 141, 197, 252, 173, 255, 178, 80, 16, 199, 81, 225, 89, 194, 196, 178, 28, 202, 109, 82, 116, 253, 83, 132, 250, 173, 247, 93, 139, 248, 171, 55, 252, 79, 68, 26, 4, 253, 24, 192, 248, 220, 77, 1, 234, 39, 59, 138, 223, 144, 13, 138, 166, 89, 67, 154, 223, 30, 32, 127, 141, 213, 161, 117, 251, 90, 142, 189, 188, 86, 160, 224, 115, 242, 161, 231, 215, 186, 101, 24, 249, 63, 184, 15, 1, 137, 22, 158, 238, 179, 57, 231, 61, 171, 104, 152, 225, 86, 65, 196, 143, 181, 116, 145, 14, 88, 26, 174, 72, 106, 208, 7, 68, 246, 194, 84, 38, 17, 241, 111, 31, 182, 5, 49, 174, 45, 202, 219, 224, 42, 195, 197, 31, 225, 202, 4, 117, 193, 60, 171, 26, 147, 136, 170, 86, 195, 202, 148, 7, 27, 196, 54, 236, 207, 59, 111, 174, 119, 96, 124, 114, 242, 92, 20, 162, 92, 32, 130, 250, 189, 158, 154, 222, 155, 221, 53, 139, 244, 50, 37, 89, 225, 240, 129, 196, 17, 143, 177, 87, 192, 233, 5, 5, 143, 26, 142, 68, 52, 173, 43, 238, 195, 8, 197, 122, 49, 139, 210, 117, 171, 200, 11, 124, 38, 224, 235, 113, 54, 220, 56, 214, 8, 252, 111, 170, 46, 185, 116, 120, 50, 174, 48, 180, 233, 117, 137, 205, 46, 196, 110, 112, 27, 160, 152, 195, 168, 16, 205, 162, 166, 242, 196, 34, 144, 127, 154, 148, 83, 16, 253, 108, 222, 101, 229, 5, 48, 222, 157, 84, 217, 110, 109, 224, 101, 176, 110, 57, 226, 153, 37, 231, 237, 213, 25, 46, 184, 87, 127, 210, 192, 178, 179, 186, 40, 210, 204, 68, 211, 100, 18, 117, 185, 116, 127, 33, 53, 1, 17, 199, 25, 91, 104, 60, 164, 30, 22, 28, 171, 34, 66, 126, 136, 37, 202, 18, 182, 37, 191, 103, 123, 46, 80, 93, 78, 4, 96, 160, 230, 227, 228, 15, 132, 52, 185, 45, 216, 213, 127, 145, 237, 179, 47, 174, 153, 21, 230, 137, 241, 114, 43, 201, 182, 218, 103, 197, 121, 141, 62, 9, 245, 208, 232, 14, 20, 190, 111, 178, 184, 242, 102, 140, 238, 68, 135, 150, 140, 0, 109, 194, 187, 202, 47, 92, 79, 89, 54, 126, 219, 154, 173, 17, 143, 173, 115, 177, 87, 35, 249, 29, 183, 94, 83, 112, 169, 164, 83, 113, 157, 60, 202, 43, 111, 69, 37, 13, 238, 254, 90, 82, 29, 181, 134, 231, 250, 154, 54, 11, 135, 38, 208, 17, 152, 242, 219, 52, 54, 78, 127, 108, 158, 142, 67, 203, 222, 116, 152, 236, 239, 254, 222, 179, 157, 220, 143, 153, 211, 32, 18, 248, 79, 214, 76, 154, 96, 112, 162, 100, 153, 60, 206, 185, 42, 79, 197, 117, 49, 9, 72, 51, 165, 45, 38, 112, 162, 156, 34, 40, 221, 78, 48, 59, 253, 244, 110, 243, 16, 222, 82, 26, 113, 185, 203, 149, 108, 49, 132, 127, 54, 1, 58, 137, 242, 109, 189, 151, 15, 74, 161, 63, 1, 99, 123, 76, 217, 229, 190, 42, 151, 157, 205, 36, 140, 9, 139, 157, 87, 226, 187, 108, 179, 45, 207, 208, 248, 209, 77, 220, 8, 34, 226, 175, 51, 61, 69, 206, 192, 39, 234, 244, 163, 185, 96, 8, 61, 237, 199, 55, 250, 59, 186, 250, 243, 125, 91, 86, 198, 45, 73, 161, 92, 206, 202, 253, 85, 220, 132, 197, 107, 136, 246, 156, 134, 231, 67, 236, 5, 179, 69, 62, 118, 117, 6, 222, 171, 239, 132, 207, 133, 138, 177, 77, 38, 133, 52, 109, 50, 107, 59, 39, 210, 240, 69, 252, 250, 248, 55, 213, 95, 130, 134, 18, 228, 238, 244, 221, 177, 206, 7, 119, 75, 180, 227, 231, 246, 145, 221, 102, 53, 200, 123, 228, 103, 60, 44, 138, 120, 195, 111, 1, 88, 161, 40, 30, 59, 132, 44, 211, 23, 137, 108, 151, 90, 96, 194, 62, 218, 163, 199, 74, 9, 105, 172, 205, 111, 63, 25, 48, 211, 20, 147, 222, 76, 128, 82, 200, 106, 219, 223, 6, 31, 221, 254, 217, 19, 72, 135, 76, 152, 26, 0, 143, 31, 66, 124, 65, 105, 128, 184, 165, 75, 67, 160, 153, 177, 150, 186, 52, 102, 178, 198, 94, 222, 93, 1, 239, 93, 49, 183, 53, 23, 211, 214, 113, 72, 254, 43, 53, 89, 181, 22, 85, 169, 182, 76, 76, 91, 24, 45, 185, 170, 154, 228, 238, 170, 51, 12, 14, 66, 22, 194, 153, 245, 54, 50, 182, 250, 125, 125, 243, 137, 118, 54, 138, 47, 127, 67, 98, 116, 78, 163, 193, 16, 61, 203, 68, 93, 163, 101, 120, 52, 34, 106, 184, 1, 191, 119, 148, 138, 72, 244, 119, 148, 233, 158, 181, 15, 234, 25, 157, 8, 205, 148, 4, 147, 18, 182, 37, 18, 81, 222, 145, 236, 232, 82, 52, 2, 67, 67, 211, 241, 12, 19, 27, 86, 242, 164, 60, 118, 11, 153, 203, 185, 88, 196, 92, 82, 128, 33, 94, 161, 0, 59, 208, 9, 197, 164, 98, 139, 29, 141, 188, 190, 45, 25, 56, 107, 253, 139, 196, 10, 15, 217, 134, 84, 25, 94, 188, 61, 156, 81, 77, 50, 40, 206, 247, 199, 107, 166, 251, 206, 207, 85, 192, 102, 248, 34, 0, 57, 71, 243, 85, 121, 10, 35, 53, 6, 189, 223, 134, 209, 163, 179, 194, 184, 32, 156, 75, 21, 17, 191, 235, 52, 149, 168, 211, 114, 252, 153, 99, 151, 30, 76, 131, 54, 3, 65, 131, 104, 230, 218, 201, 228, 224, 90, 153, 165, 82, 143, 215, 41, 119, 29, 67, 72, 183, 27, 35, 189, 230, 32, 222, 49, 239, 95, 246, 137, 75, 196, 114, 130, 250, 144, 112, 246, 161, 36, 174, 29, 248, 93, 9, 106, 223, 148, 73, 179, 242, 83, 195, 184, 67, 31, 230, 237, 129, 14, 112, 91, 52, 68, 173, 215, 229, 6, 9, 56, 250, 185, 12, 157, 228, 234, 25, 134, 80, 116, 118, 166, 162, 192, 202, 50, 222, 58, 212, 164, 149, 246, 202, 162, 242, 229, 28, 48, 194, 156, 49, 149, 244, 38, 247, 207, 69, 128, 178, 233, 219, 73, 22, 238, 179, 174, 16, 79, 184, 182, 4, 142, 131, 10, 163, 153, 2, 67, 217, 154, 110, 197, 106, 89, 152, 160, 215, 161, 253, 138, 129, 51, 174, 144, 205, 0, 207, 225, 35, 108, 165, 63, 156, 123, 35, 137, 16, 139, 221, 253, 30, 48, 165, 198, 140, 74, 216, 231, 74, 107, 186, 253, 42, 130, 115, 232, 0, 166, 215, 55, 96, 155, 210, 131, 20, 52, 163, 137, 181, 185, 180, 202, 99, 89, 74, 108, 29, 56, 237, 251, 55, 221, 133, 59, 177, 191, 153, 96, 158, 223, 170, 22, 90, 31, 29, 147, 201, 131, 156, 16, 90, 236, 69, 49, 123, 32, 43, 7, 121, 49, 149, 127, 114, 79, 164, 48, 234, 133, 133, 206, 0, 226, 79, 160, 86, 140, 89, 123, 17, 12, 26, 77, 44, 193, 88, 84, 166, 67, 170, 89, 73, 205, 54, 29, 72, 169, 103, 91, 217, 226, 116, 215, 77, 138, 223, 220, 208, 11, 164, 109, 62, 189, 2, 94, 10, 113, 247, 94, 115, 249, 82, 53, 12, 24, 52, 154, 99, 111, 170, 44, 245, 124, 94, 173, 11, 167, 193, 210, 37, 242, 125, 249, 167, 31, 34, 203, 101, 214, 35, 6, 32, 224, 147, 190, 171, 248, 77, 137, 132, 41, 138, 20, 96, 218, 238, 214, 93, 221, 206, 41, 77, 59, 166, 252, 56, 22, 148, 225, 91, 243, 127, 195, 235, 40, 126, 135, 153, 186, 174, 230, 189, 65, 35, 132, 95, 188, 27, 112, 39, 135, 160, 118, 153, 99, 74, 139, 220, 32, 148, 141, 163, 78, 199, 220, 70, 211, 17, 104, 171, 15, 198, 65, 234, 129, 119, 129, 8, 124, 50, 115, 120, 63, 167, 13, 162, 85, 50, 30, 69, 91, 143, 165, 143, 99, 192, 224, 53, 122, 65, 190, 222, 199, 30, 215, 233, 64, 124, 5, 102, 38, 85, 184, 180, 56, 196, 170, 83, 238, 230, 211, 101, 8, 243, 79, 253, 238, 175, 118, 149, 16, 244, 61, 141, 131, 115, 141, 181, 156, 195, 180, 208, 226, 254, 244, 92, 166, 16, 239, 219, 111, 121, 32, 166, 34, 180, 183, 51, 160, 151, 162, 33, 97, 85, 19, 190, 231, 33, 252, 46, 131, 73, 128, 211, 222, 83, 54, 77, 183, 227, 206, 24, 23, 229, 223, 187, 141, 71, 64, 254, 30, 204, 230, 150, 212, 11, 156, 12, 179, 127, 4, 40, 134, 33, 43, 104, 180, 57, 146, 216, 115, 43, 219, 114, 46, 107, 36, 59, 74, 176, 1, 73, 20, 34, 31, 142, 125, 117, 249, 101, 60, 79, 246, 135, 194, 181, 206, 38, 94, 176, 85, 202, 155, 127, 34, 124, 56, 11, 81, 112, 216, 8, 191, 217, 213, 186, 71, 222, 152, 9, 88, 10, 176, 37, 199, 108, 83, 185, 102, 24, 69, 178, 113, 254, 164, 114, 26, 78, 203, 161, 105, 134, 146, 14, 134, 39, 156, 13, 68, 220, 255, 215, 84, 142, 235, 191, 14, 150, 232, 12, 246, 219, 125, 119, 147, 173, 60, 103, 172, 146, 153, 245, 74, 243, 196, 194, 159, 178, 20, 151, 126, 242, 66, 244, 216, 13, 114, 253, 211, 230, 239, 246, 78, 105, 95, 219, 84, 5, 230, 186, 238, 167, 94, 157, 16, 4, 118, 127, 185, 122, 15, 22, 98, 30, 159, 210, 163, 215, 109, 159, 94, 78, 163, 203, 179, 115, 80, 95, 163, 135, 131, 206, 226, 84, 190, 216, 17, 30, 211, 36, 233, 194, 113, 31, 255, 45, 144, 30, 137, 208, 236, 190, 109, 27, 53, 242, 86, 231, 41, 101, 239, 221, 119, 219, 27, 241, 239, 171, 156, 116, 40, 139, 130, 203, 198, 86, 188, 35, 12, 5, 233, 239, 204, 105, 45, 178, 40, 183, 131, 246, 90, 169, 96, 65, 223, 54, 30, 202, 189, 133, 165, 111, 216, 212, 77, 204, 241, 106, 92, 150, 40, 150, 171, 125, 146, 153, 148, 124, 112, 221, 46, 209, 44, 82, 78, 46, 163, 128, 100, 234, 38, 3, 116, 182, 133, 176, 199, 195, 243, 95, 109, 163, 216, 58, 248, 82, 40, 80, 212, 63, 163, 73, 68, 51, 37, 174, 168, 247, 209, 254, 134, 223, 197, 23, 22, 79, 139, 35, 101, 197, 238, 86, 165, 57, 123, 74, 13, 202, 181, 113, 249, 80, 255, 0, 96, 45, 6, 47, 110, 72, 94, 171, 122, 99, 144, 55, 241, 181, 138, 99, 106, 164, 143, 57, 54, 174, 167, 173, 12, 134, 124, 0, 159, 10, 58, 164, 17, 222, 171, 228, 198, 10, 135, 173, 79, 171, 209, 52, 72, 94, 234, 214, 78, 50, 165, 50, 77, 120, 226, 140, 81, 71, 247, 182, 107, 41, 225, 150, 63, 1, 122, 128, 150, 122, 230, 207, 241, 221, 123, 126, 219, 181, 224, 120, 206, 81, 146, 195, 79, 186, 120, 196, 99, 18, 91, 207, 142, 172, 68, 186, 147, 44, 89, 10, 70, 60, 222, 99, 194, 53, 150, 2, 138, 35, 58, 153, 182, 70, 108, 119, 233, 171, 182, 4, 238, 211, 211, 134, 41, 33, 159, 164, 200, 248, 232, 226, 168, 221, 143, 253, 177, 172, 99, 247, 166, 196, 242, 32, 13, 249, 59, 171, 154, 108, 199, 135, 158, 242, 53, 194, 54, 194, 133, 0, 68, 129, 191, 211, 83, 46, 102, 86, 245, 34, 113, 171, 160, 255, 185, 198, 232, 10, 208, 205, 120, 32, 27, 9, 155, 219, 42, 105, 60, 209, 16, 73, 145, 230, 245, 51, 17, 203, 62, 53, 18, 165, 219, 195, 169, 177, 68, 83, 112, 156, 10, 124, 233, 3, 147, 208, 198, 181, 158, 225, 61, 77, 72, 135, 145, 146, 96, 22, 213, 118, 51, 105, 199, 237, 143, 41, 65, 120, 235, 144, 9, 203, 65, 142, 250, 65, 115, 190, 186, 255, 84, 237, 247, 168, 198, 42, 96, 160, 78, 244, 142, 233, 198, 65, 148, 136, 159, 91, 61, 56, 241, 83, 254, 84, 78, 141, 68, 240, 249, 122, 178, 232, 111, 217, 114, 153, 184, 125, 255, 53, 255, 248, 206, 244, 53, 78, 72, 23, 167, 93, 255, 239, 155, 105, 226, 140, 74, 76, 123, 108, 244, 116, 226, 4, 128, 174, 70, 231, 85, 255, 187, 165, 210, 39, 145, 140, 201, 46, 213, 130, 37, 156, 153, 215, 123, 64, 166, 183, 140, 225, 157, 111, 204, 196, 17, 101, 69, 156, 87, 59, 89, 173, 51, 233, 201, 138, 166, 118, 115, 14, 217, 101, 177, 40, 195, 246, 235, 159, 100, 29, 150, 10, 154, 72, 226, 157, 239, 169, 106, 147, 219, 14, 210, 245, 53, 32, 183, 57, 193, 181, 201, 253, 231, 223, 120, 183, 94, 133, 133, 254, 183, 46, 157, 150, 184, 0, 140, 145, 127, 143, 189, 60, 74, 44, 14, 171, 178, 43, 128, 240, 54, 180, 73, 116, 88, 31, 150, 158, 251, 254, 196, 46, 217, 198, 170, 154, 127, 86, 243, 180, 23, 232, 244, 10, 114, 84, 222, 111, 50, 109, 211, 28, 65, 174, 64, 162, 66, 33, 147, 229, 99, 180, 133, 184, 250, 91, 138, 93, 79, 124, 120, 195, 53, 7, 12, 103, 135, 253, 235, 90, 254, 15, 232, 45, 143, 253, 151, 175, 64, 236, 161, 179, 78, 53, 251, 129, 136, 20, 60, 198, 216, 104, 229, 82, 215, 84, 156, 127, 162, 214, 31, 197, 156, 170, 222, 53, 234, 32, 55, 90, 125, 160, 32, 252, 7, 216, 214, 241, 156, 74, 194, 61, 63, 45, 9, 255, 164, 254, 93, 255, 17, 146, 152, 128, 31, 32, 240, 115, 115, 7, 83, 135, 30, 193, 169, 146, 99, 209, 35, 227, 162, 134, 160, 164, 85, 12, 25, 177, 53, 19, 6, 95, 86, 244, 12, 165, 169, 151, 32, 100, 210, 38, 183, 210, 120, 151, 79, 82, 170, 214, 171, 187, 163, 236, 22, 212, 235, 40, 160, 110, 213, 163, 174, 147, 14, 255, 97, 159, 215, 26, 83, 44, 15, 207, 6, 36, 75, 156, 36, 51, 249, 28, 35, 133, 53, 36, 55, 155, 216, 238, 147, 178, 114, 199, 47, 120, 205, 37, 81, 3, 200, 120, 148, 165, 138, 218, 22, 38, 148, 212, 125, 4, 210, 213, 141, 105, 93, 122, 53, 140, 83, 77, 170, 98, 98, 185, 10, 212, 78, 86, 92, 234, 157, 232, 205, 213, 97, 90, 141, 214, 91, 150, 191, 240, 200, 244, 57, 50, 239, 179, 249, 130, 122, 220, 83, 2, 50, 134, 47, 30, 239, 50, 100, 186, 179, 153, 128, 84, 26, 105, 78, 120, 120, 212, 31, 250, 191, 99, 144, 201, 13, 239, 177, 130, 106, 138, 164, 5, 21, 25, 137, 223, 197, 181, 42, 94, 164, 167, 32, 170, 243, 219, 188, 107, 229, 71, 41, 107, 122, 230, 155, 204, 240, 35, 23, 176, 69]; + private static string _key = null; + private static int _bufferLength = 4096; + private static string _path = null; + private static string _action = null; + private static string _pattern = "*"; + private static bool _silent = false; + private static bool _isFolder = false; + private const string _keyAtRestEncryptionKey = "5otf7MjpE3CDioZSf1Y2M5J/RH1Fl4CbXBYRCfP5Y3o="; + private const string HELP_TEXT = @"----------------------------------------------------------------------------------- +Confunder - ""Confunding"" is the process of making it difficult to determine the file type +and contents from the byte format to prevent the file from being run normally. +----------------------------------------------------------------------------------- +USAGE: + confunder path [-action] [-pattern] [-silent] + + path: The first argument is always the path to a file or folder. + If it is a folder, all files in the folder will be processed. + ""-action"" which action to run. The action can be any one of the following values: + * ""confund"" - confund the given file or all the files in a given folder. + If path is a folder and -pattern is supplied, only those files matching the pattern will be processed. + * ""unconfund"" - unconfund the given file or all the files in a given folder. + If path is a folder and -pattern is supplied, only those files matching the pattern will be processed. + * ""run"" - run a single file. If it is confunded, unconfunds it first. + When the app exits, if the file was previously confunded the file is reconfunded. + * ""setkey"" - update the key stored securely on this machine for future runs. The -key argument must be supplied with this action. + * ""help"" - show this help text + If -action is not supplied and the path is a single file. + * If the file was not previously confunded, then the file will be confunded. + * If the file was previously confunded, + then the file will be unconfunded, run and reconfunded afterwards. + [-pattern *] For use if the path is a folder. + If supplied, only those files within this folder matching the pattern will be processed. + [-key] Any text key to use for confunding and unconfunding. The app derives a base64 key from this text. + [-silent] No console output and on Windows the command window is hidden."; + + private static void Main(string[] args) + { + if (!ProcessArgs(args)) + { + return; + } + + switch (_action) + { + case "setkey": + if (!SetKey()) + { + return; + } + break; + case "confund": + if (!EnsureKeyLoaded()) { return; } + if (_isFolder) + { + ConfundAll(_path, _pattern); + } + else + { + ConfundFile(_path); + } + break; + case "unconfund": + if (!EnsureKeyLoaded()) { return; } + if (_isFolder) + { + UnConfundAll(_path, _pattern); + } + else + { + UnConfundFile(_path); + } + break; + case "run": + if (_isFolder) + { + SpitOut("{0} is a folder.", _path); + } + else + { + var wasConfunded = IsFileConfunded(_path); + if (wasConfunded) + { + if (!EnsureKeyLoaded()) { return; } + UnConfundFile(_path); + SpitOut("{0} has been successfully unconfunded", _path); + } + SpitOut("Running {0}", _path); + + string fullPath = new FileInfo(_path).FullName; + ProcessStartInfo startInfo = new() + { + FileName = fullPath, + UseShellExecute = true + }; + using var pr = Process.Start(startInfo); + pr.WaitForExit(); + SpitOut("Process for {0} has exited", _path); + if (wasConfunded) + { + SpitOut("Starting to reconfund {0}", _path); + ConfundFile(_path); + } + } + break; + default: + SpitOut(HELP_TEXT); + break; + } + + if (_silent) + { + return; + } + + SpitOut("...........................\n\nPress to exit..."); + Console.ReadLine(); + } + + private static bool UnConfundFile(string path) + { + if (!IsFileConfunded(path)) + { + SpitOut("{0} is not confunded", path); + return false; + } + var success = ConfundFile(path, unconfund: true); + SpitOut("{0} has {1} unconfunded", path, + success + ? "been successfully" + : "FAILED to be"); + return success; + } + + private static void UnConfundAll(string path, string pattern) + { + foreach (var f in Directory.GetFiles(path, pattern)) + { + UnConfundFile(f); + } + SpitOut("{0} has been processed", path); + } + + private static bool ConfundFile(string path) + { + if (IsFileConfunded(path)) + { + SpitOut("{0} is already confunded", path); + return false; + } + var success = ConfundFile(path, unconfund: false); + SpitOut("{0} has {1} confunded", path, + success + ? "been successfully" + : "FAILED to be"); + return success; + } + + private static void ConfundAll(string path, string pattern) + { + foreach (var f in Directory.GetFiles(path, pattern)) + { + ConfundFile(f); + } + SpitOut("{0} has been processed", path); + return; + } + + private static bool ProcessArgs(string[] args) + { + if (args.Length < 1) + { + Console.WriteLine(HELP_TEXT); + return false; + } + + if (args.Contains("-action")) + { + var actionIndex = Array.IndexOf(args, "-action"); + if (actionIndex < 0 || actionIndex + 1 >= args.Length) + { + Console.Error.WriteLine("Invalid action specified"); + return false; + } + + var legalActions = new string[] { "confund", "unconfund", "run", "setkey", "help" }; + var action = args[actionIndex + 1]; + if (legalActions.Contains(action.ToLower())) + { + _action = action.ToLower(); + } + else + { + Console.Error.WriteLine("Invalid action specified"); + return false; + } + } + + var actionNeedsPath = _action != "setkey" && _action != "help"; + + if (actionNeedsPath) + { + if (args.Contains("-path")) + { + _path = args[Array.IndexOf(args, "-path") + 1]; + } + else + { + _path = args[0]; + } + + if (_path == null) + { + Console.Error.WriteLine("No file or folder path supplied"); + return false; + } + else + { + if (Directory.Exists(_path)) + { + _isFolder = true; + } + else if (File.Exists(_path)) + { + _isFolder = false; + } + else + { + Console.Error.WriteLine("file or folder path supplied could not be found"); + return false; + } + } + + if (string.IsNullOrWhiteSpace(_action)) + { + if (!_isFolder) + { + if (IsFileConfunded(_path)) + { + _action = "run"; + } + else + { + _action = "confund"; + } + } + else + { + Console.Error.WriteLine($"{_path} is a directory and the -action argument has not been supplied"); + _action = "help"; + return false; + } + } + } + + if (args.Contains("-pattern")) + { + if (actionNeedsPath && _isFolder) + { + _pattern = args[Array.IndexOf(args, "-pattern") + 1]; + } + else if (actionNeedsPath) + { + Console.Error.WriteLine($"{_path} is not a directory and the pattern has been supplied"); + _action = "help"; + return false; + } + } + if (args.Contains("-key")) + { + if(args.Length < 2 || Array.IndexOf(args, "-key") + 1 >= args.Length) + { + Console.Error.WriteLine("No key was supplied with the -key argument"); + return false; + } + var rawKey = args[Array.IndexOf(args, "-key") + 1]; + if (!TryDeriveBase64Key(rawKey, out var derivedKey, out var error)) + { + Console.Error.WriteLine(error); + return false; + } + + _key = derivedKey; + } + + if (args.Contains("-silent")) + { + _silent = true; + try + { + if (OperatingSystem.IsWindows()) + { + Console.SetBufferSize(1, 1); + Console.SetWindowSize(1, 1); + Console.SetWindowPosition(-1, -1); + } + } + catch + { + } + } + + return true; + } + + private static bool EnsureKeyLoaded() + { + if (!string.IsNullOrWhiteSpace(_key)) + { + return true; + } + + if (TryLoadStoredKey(out var storedKey)) + { + _key = storedKey; + return true; + } + + if (_silent || Console.IsInputRedirected) + { + Console.Error.WriteLine("No stored key found and the app cannot prompt for one in silent mode."); + return false; + } + + var key = PromptForKey("Enter the text key used to confound files", confirm: true); + if (key == null) + { + return false; + } + + SaveStoredKey(key); + _key = key; + return true; + } + + private static bool SetKey() + { + if (_key == null) + { + Console.Error.WriteLine("No key was supplied. Use -key with -action setkey."); + return false; + } + + SaveStoredKey(_key); + SpitOut("Key updated securely for this user."); + SpitOut("Files encrypted with the previous key will still require that key to be unconfunded."); + return true; + } + + private static string PromptForKey(string prompt, bool confirm) + { + while (true) + { + Console.WriteLine(prompt + ":"); + var firstEntryRaw = ReadSecretLine(); + + if (string.IsNullOrWhiteSpace(firstEntryRaw)) + { + Console.Error.WriteLine("The key cannot be empty."); + continue; + } + + if (!TryDeriveBase64Key(firstEntryRaw, out var firstEntry, out var validationError)) + { + Console.Error.WriteLine(validationError); + continue; + } + + if (confirm) + { + Console.WriteLine("Confirm the key:"); + var secondEntryRaw = ReadSecretLine(); + if (!string.Equals(firstEntryRaw, secondEntryRaw, StringComparison.Ordinal)) + { + Console.Error.WriteLine("The keys do not match."); + continue; + } + } + + return firstEntry; + } + } + + private static string ReadSecretLine() + { + if (Console.IsInputRedirected) + { + return Console.ReadLine() ?? string.Empty; + } + + var builder = new StringBuilder(); + while (true) + { + var key = Console.ReadKey(intercept: true); + if (key.Key == ConsoleKey.Enter) + { + Console.WriteLine(); + break; + } + + if (key.Key == ConsoleKey.Backspace) + { + if (builder.Length > 0) + { + builder.Length--; + } + + continue; + } + + if (!char.IsControl(key.KeyChar)) + { + builder.Append(key.KeyChar); + } + } + + return builder.ToString(); + } + + private static bool IsValidKey(string key, out string error) + { + error = null; + + try + { + var keyBytes = Convert.FromBase64String(key); + if (keyBytes.Length != 16 && keyBytes.Length != 24 && keyBytes.Length != 32) + { + error = "The key must decode to a 128, 192, or 256-bit AES key."; + return false; + } + + return true; + } + catch + { + error = "The key must be valid base64."; + return false; + } + } + + private static bool TryDeriveBase64Key(string rawKeyText, out string key, out string error) + { + key = null; + error = null; + + if (string.IsNullOrWhiteSpace(rawKeyText)) + { + error = "The key cannot be empty."; + return false; + } + + // The cipher expects a 128/192/256-bit AES key. Use SHA-256 to derive a fixed 256-bit key from any text input. + var keyBytes = SHA256.HashData(Encoding.UTF8.GetBytes(rawKeyText)); + key = Convert.ToBase64String(keyBytes); + return true; + } + + private static bool TryLoadStoredKey(out string key) + { + key = null; + + try + { + var keyPath = GetKeyStorePath(); + if (!File.Exists(keyPath)) + { + return false; + } + + var protectedBytes = File.ReadAllBytes(keyPath); + var unprotectedBytes = EncryptData(protectedBytes, _keyAtRestEncryptionKey, ungarble: true); + var storedKey = Encoding.UTF8.GetString(unprotectedBytes); + if (!IsValidKey(storedKey, out _)) + { + return false; + } + + key = storedKey; + return true; + } + catch + { + return false; + } + } + + private static void SaveStoredKey(string key) + { + var keyPath = GetKeyStorePath(); + var directory = Path.GetDirectoryName(keyPath); + if (!string.IsNullOrWhiteSpace(directory)) + { + Directory.CreateDirectory(directory); + } + + var protectedBytes = EncryptData(Encoding.UTF8.GetBytes(key), _keyAtRestEncryptionKey); + File.WriteAllBytes(keyPath, protectedBytes); + } + + private static string GetKeyStorePath() + { + var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + if (string.IsNullOrWhiteSpace(basePath)) + { + basePath = AppContext.BaseDirectory; + } + + return Path.Combine(basePath, "Confunder", "key.dat"); + } + + private static void SpitOut(string txt, params object[] par) + { + if (!_silent) + { + Console.WriteLine(txt, par); + } + } + + private static bool ConfundFile(string path, bool unconfund) + { + bool success = false; + try + { + if (unconfund) + { + if (!RemoveConfundMarkFromFile(path)) + { + Console.Error.WriteLine("Failed to remove \"confund mark\" from file {0}", path); + return false; + } + } + + FileInfo fi = new(path); + int bufferLength = (int)Math.Min(_bufferLength, fi.Length); + using var file = fi.Open(FileMode.Open, FileAccess.ReadWrite); + byte[] buf = new byte[bufferLength]; + file.ReadExactly(buf, 0, bufferLength); + buf = EncryptData(buf, ungarble: unconfund); + file.Position = 0; + file.Write(buf, 0, bufferLength); + file.Close(); + + if (unconfund || PrependConfundMarkToFile(path)) + { + success = true; + + } + } + catch (Exception ex) + { + Console.Error.WriteLine(ex.Message); + } + + return success; + } + + private static bool PrependConfundMarkToFile(string path) + { + try + { + string tempPath = Path.GetTempFileName(); + // 1. Create a temporary file and write the new bytes first + using (FileStream tempStream = new(tempPath, FileMode.Create, FileAccess.Write)) + { + tempStream.Write(_confundedMark, 0, _confundedMark.Length); + + // 2. Stream the original file contents right after the new bytes + if (File.Exists(path)) + { + using (FileStream originalStream = new(path, FileMode.Open, FileAccess.Read)) + { + originalStream.CopyTo(tempStream); // Copies in chunks efficiently + } + } + } + + // 3. Swap the temporary file with the original file + File.Delete(path); + File.Move(tempPath, path); + return true; + } + catch (Exception ex) + { + Console.Error.WriteLine(ex.Message); + return false; + } + } + + private static bool RemoveConfundMarkFromFile(string path) + { + try + { + int bytesToRemove = _confundedMark.Length; + // Open the file with Read and Write permissions + using FileStream fs = new(path, FileMode.Open, FileAccess.ReadWrite); + long fileLength = fs.Length; + if (bytesToRemove >= fileLength) + { + fs.Close(); + return false; + } + + // Use a 4KB buffer for optimal I/O chunking + byte[] buffer = new byte[4096]; + long writePosition = 0; + long readPosition = bytesToRemove; + + // Shift data from right to left + while (readPosition < fileLength) + { + fs.Position = readPosition; + int bytesRead = fs.Read(buffer, 0, buffer.Length); + + fs.Position = writePosition; + fs.Write(buffer, 0, bytesRead); + + readPosition += bytesRead; + writePosition += bytesRead; + } + + // Truncate the trailing duplicate data at the end of the file + fs.SetLength(writePosition); + return true; + + } + catch (Exception ex) + { + Console.Error.WriteLine(ex.Message); + return false; + } + } + + private static bool IsFileConfunded(string path) + { + bool isConfunded = false; + FileInfo fi = new(path); + + if (fi.Length < _confundedMark.Length) + { + return false; + } + int bufLen = _confundedMark.Length; + try + { + using var file = fi.Open(FileMode.Open, FileAccess.Read); + byte[] buf = new byte[bufLen]; + file.ReadExactly(buf, 0, bufLen); + + isConfunded = buf.SequenceEqual(_confundedMark); + file.Close(); + } + catch (Exception ex) + { + Console.Error.WriteLine(ex.Message); + } + + return isConfunded; + } + + private static byte[] EncryptData(byte[] data, bool ungarble = false) + { + return EncryptData(data, _key, ungarble); + } + + private static byte[] EncryptData(byte[] data, string encryptionKey, bool ungarble = false) + { + var intArray = data.Select(b => (int)b).ToArray(); + byte[] aes = Convert.FromBase64String(encryptionKey); + var ff1 = new FPE.Net.FF1(byte.MaxValue + 1, _bufferLength); + int[] enced = ungarble + ? ff1.decrypt(aes, new byte[] { }, intArray) + : ff1.encrypt(aes, new byte[] { }, intArray); + return enced.Select(i => (byte)i).ToArray(); + } + + public static void RemoveBytesFromStart(FileStream fs, int bytesToRemove) + { + long fileLength = fs.Length; + if (bytesToRemove >= fileLength) + { + // If removing more than the file size, just clear the file + fs.SetLength(0); + return; + } + + // Buffer size for shifting data (4096 to 65536 bytes is ideal) + byte[] buffer = new byte[65536]; + long readPosition = bytesToRemove; + long writePosition = 0; + + // Shift all data forward + int bytesRead; + while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) + { + // Save current read position + readPosition = fs.Position; + + // Move pointer to write position and write + fs.Position = writePosition; + fs.Write(buffer, 0, bytesRead); + + // Advance write position and restore read position + writePosition = fs.Position; + fs.Position = readPosition; + } + + // Truncate the leftover duplicate data at the end + fs.SetLength(writePosition); + } + + + } +} diff --git a/Confunder/Properties/launchSettings.json b/Confunder/Properties/launchSettings.json new file mode 100644 index 0000000..900c307 --- /dev/null +++ b/Confunder/Properties/launchSettings.json @@ -0,0 +1,7 @@ +{ + "profiles": { + "FileConfunder_2": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/Confunder/appsettings.json b/Confunder/appsettings.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/Confunder/appsettings.json @@ -0,0 +1 @@ +{} diff --git a/FileConfunder/App.config b/FileConfunder/App.config deleted file mode 100644 index ba905e6..0000000 --- a/FileConfunder/App.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - -
- - - - - - C:\Program Files\MPC-HC\mpc-hc64.exe - - - 4096 - - - fnwrkUFPnw9GuxubyIrQu+5ENJND3g947zsmcknbAYQ= - - - - \ No newline at end of file diff --git a/FileConfunder/FileConfunder.csproj b/FileConfunder/FileConfunder.csproj deleted file mode 100644 index b1aca32..0000000 --- a/FileConfunder/FileConfunder.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - Debug - AnyCPU - {11E4908A-80F5-4C7E-9994-379927B5FF28} - Exe - FileConfunder - fcn - v4.7.2 - 512 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - \ No newline at end of file diff --git a/FileConfunder/Program.cs b/FileConfunder/Program.cs deleted file mode 100644 index 6326656..0000000 --- a/FileConfunder/Program.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; - -namespace FileConfunder -{ - class Program - { - private static string _path = null; - private static string _action = "run"; - private static string _pattern = "*"; - private static int _bufferLength = Properties.Settings.Default.BufferSize; - private static string _key = Properties.Settings.Default.Key; - private static string _runWith = Properties.Settings.Default.OpenWithPath; - private static bool _silent; - private const string HELP_TEXT = @"Encrypts a set number of bytes in the beginning of a file. -Use to prevent easy determination of the file type from the byte format and prevent running the file normally. -USAGE: fnc -path fileOrFolderPath -action actionName -The ""-action"" argument value can be any one of the following values: - ""confund"" confund the given file - ""unconfund"" unconfund the given file - ""run"" unconfund the given file then run the file with the app specified in the -runwith argument or in the config file. When the app exits, the file is reconfunded. - ""rununconfund"" unconfund the given file then run the file with the app specified in the -runwith argument or in the config file. When app exits, the file is not reconfunded. - ""confundall"" confund all the files in the given folder. If -pattern is supplied, only those files matching the pattern will be processed. - ""unconfundall"" unconfund all the files in the given folder. If -pattern is supplied, only those files matching the pattern will be processed. - ""help"" show this help text -OTHER OPTIONAL ARGUMENTS - [-runwith *] For use with the actions ""run"" or ""rununconfund"". If this argument is supplied, after the file has been unconfunded, the file will be run with the app specified in the value given for this -runwith argument. If this argument is not supplied the app at the path set in the config file is used. - [-pattern *] For use with the action ""confundall"" or ""unconfundall"". If supplied, only those files matching the pattern will be processed. - [-buflen *] The number of bytes in the file to be ""confunded"" by encryption. If this argument is not supplied the value set in the config file is used. NOTE: files need to be unconfunded with the same buffer length and key values with which they were originally confunded. - [-key *] The AES 256 key used to encrypt the data during ""confunding"". If this argument is not set, the value set in the config file is used. NOTE: files need to be unconfunded with the same buffer length and key values with which they were originally confunded. - [-silent] The command window is hidden and automatically. If this argument is not supplied, the user needs to press enter to exit."; - static void Main(string[] args) - { - if (args.Length < 2 || !args.Contains("-path")) - { - Console.WriteLine(HELP_TEXT); - return; - } - - _path = args[Array.IndexOf(args, "-path") + 1]; - - if (args.Contains("-action")) - { - _action = args[Array.IndexOf(args, "-action") + 1]; - } - if (args.Contains("-runwith")) - { - _runWith = args[Array.IndexOf(args, "-runwith") + 1]; - } - if (args.Contains("-pattern")) - { - _pattern = args[Array.IndexOf(args, "-pattern") + 1]; - } - if (args.Contains("-buflen")) - { - string str = args[Array.IndexOf(args, "-buflen") + 1]; - int buflen; - if (int.TryParse(str, out buflen)) - { - _bufferLength = buflen; - if(_bufferLength > FPE.Net.Constants.MAXLEN) - { - Console.Error.WriteLine("The max value for the buffer length is {0}\nThe recommended buffer length is 4096", - FPE.Net.Constants.MAXLEN); - return; - } - else if (_bufferLength > 4096) - { - ConsoleColor prevCColor = ConsoleColor.White; - try - { - prevCColor = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Red; - } - catch { } - SpitOut("WARNING! Your buffer length has been set to {0}.\nEncryption time for buffer lengths more than 4096 bytes may be prohibitively long.", - _bufferLength); - try - { - Console.ForegroundColor = prevCColor; - } - catch { } - } - } - else - { - Console.Error.WriteLine("{0} is not a valid value for the -buflen argument", str); - return; - } - } - if (args.Contains("-key")) - { - _key = args[Array.IndexOf(args, "-offset") + 1]; - } - - if (args.Contains("-silent")) - { - _silent = true; - try - { - Console.SetBufferSize(1, 1); - Console.SetWindowSize(1, 1); - Console.SetWindowPosition(-1, -1); - } - catch { } - } - if (_action != "help" && ((_action.EndsWith("all") && !Directory.Exists(_path)) || - (!_action.EndsWith("all") && !File.Exists(_path)))) - { - Console.Error.WriteLine("{0} cannot be found", _path); - return; - } - - switch (_action) - { - case "confundall": - foreach (var f in Directory.GetFiles(_path, _pattern)) - { - SpitOut("{0} has {1} confunded", f, - ConfundFile(f) - ? "been successfully" - : "FAILED to be"); - } - SpitOut("{0} has been processed", _path); - break; - case "unconfundall": - foreach (var f in Directory.GetFiles(_path, _pattern)) - { - SpitOut("{0} has {1} unconfunded", f, - ConfundFile(f, true) - ? "been successfully" - : "FAILED to be"); - } - SpitOut("{0} has been processed", _path); - break; - case "confund": - SpitOut("{0} has {1} confunded", _path, - ConfundFile(_path) - ? "been successfully" - : "FAILED to be"); - break; - case "unconfund": - SpitOut("{0} has {1} unconfunded", _path, - ConfundFile(_path, true) - ? "been successfully" - : "FAILED to be"); - break; - case "run": - case "rununconfund": - if (ConfundFile(_path, true)) - { - SpitOut("{0} has been successfully unconfunded", _path); - SpitOut("Running {0} {1}", _runWith, _path); - using (var pr = Process.Start(_runWith, _path)) - { - if (_action == "run") - { - pr.WaitForExit(); - SpitOut("{0} has exited", Path.GetFileName(_runWith)); - SpitOut("Starting to reconfund {0}", _path); - SpitOut("{0} has {1} re-confunded", _path, - ConfundFile(_path) ? "been successfully" : "FAILED to be"); - } - } - } - else - { - SpitOut("{0} cannot be unconfunded", _path); - } - break; - default: - SpitOut(HELP_TEXT); - break; - } - - if (_silent) - { - return; - } - SpitOut("...........................\n\nPress to exit..."); - Console.ReadLine(); - } - - private static void SpitOut(string txt, params object[] par) - { - if (!_silent) - { - Console.WriteLine(txt, par); - } - } - - private static bool ConfundFile(string path, bool unconfund = false) - { - bool success = false; - FileInfo fi = new FileInfo(path); - int bufferLength = (int)Math.Min(_bufferLength, fi.Length); - try - { - using (var file = fi.Open(FileMode.Open, FileAccess.ReadWrite)) - { - byte[] buf = new byte[bufferLength]; - file.Read(buf, 0, bufferLength); - buf = EncryptData(buf, unconfund); - file.Position = 0; - file.Write(buf, 0, bufferLength); - file.Close(); - success = true; - } - } - catch (Exception ex) - { - Console.Error.WriteLine(ex.Message); - } - - return success; - } - - private static byte[] EncryptData(byte[] data, bool ungarble = false) - { - var intArray = data.Select(b => (int)b).ToArray(); - byte[] aes = Convert.FromBase64String(_key); - var ff1 = new FPE.Net.FF1(Byte.MaxValue + 1, _bufferLength); - int[] enced = ungarble - ? ff1.decrypt(aes, new byte[] { }, intArray) - : ff1.encrypt(aes, new byte[] { }, intArray); - return enced.Select(i => (byte)i).ToArray(); - } - } -} diff --git a/FileConfunder/Properties/AssemblyInfo.cs b/FileConfunder/Properties/AssemblyInfo.cs deleted file mode 100644 index bced6f4..0000000 --- a/FileConfunder/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("FileConfunder")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("FileConfunder")] -[assembly: AssemblyCopyright("Copyright © 2019")] -[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("11e4908a-80f5-4c7e-9994-379927b5ff28")] - -// 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")] diff --git a/FileConfunder/Properties/Settings.Designer.cs b/FileConfunder/Properties/Settings.Designer.cs deleted file mode 100644 index 0cf40e4..0000000 --- a/FileConfunder/Properties/Settings.Designer.cs +++ /dev/null @@ -1,53 +0,0 @@ -//------------------------------------------------------------------------------ -// -// 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. -// -//------------------------------------------------------------------------------ - -namespace FileConfunder.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.1.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; - } - } - - [global::System.Configuration.ApplicationScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("C:\\Program Files\\MPC-HC\\mpc-hc64.exe")] - public string OpenWithPath { - get { - return ((string)(this["OpenWithPath"])); - } - } - - [global::System.Configuration.ApplicationScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("4096")] - public int BufferSize { - get { - return ((int)(this["BufferSize"])); - } - } - - [global::System.Configuration.ApplicationScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("fnwrkUFPnw9GuxubyIrQu+5ENJND3g947zsmcknbAYQ=")] - public string Key { - get { - return ((string)(this["Key"])); - } - } - } -} diff --git a/FileConfunder/Properties/Settings.settings b/FileConfunder/Properties/Settings.settings deleted file mode 100644 index 7a58995..0000000 --- a/FileConfunder/Properties/Settings.settings +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - C:\Program Files\MPC-HC\mpc-hc64.exe - - - 4096 - - - fnwrkUFPnw9GuxubyIrQu+5ENJND3g947zsmcknbAYQ= - - - \ No newline at end of file