diff --git a/Program.cs b/Program.cs index ce35399..0ccb554 100644 --- a/Program.cs +++ b/Program.cs @@ -8,17 +8,49 @@ */ using System; using System.IO; +using System.Text; +using System.Runtime.InteropServices; +using System.Reflection; using Tea; using Utils; +public class dllimport +{ + Assembly asm = Assembly.LoadFrom(@".\base64.dll"); + + //public string test(string str) + //{ + // return Base64Encode(Encoding.UTF8.GetBytes(str), 8); + //} +} namespace ModelCoder { class Program { - private static readonly int encodeSize = 3000; + private static IUtil util; + private static ITeaCoding tea; + private static dllimport dlltest; + private static readonly uint blockSize = 12; + private static readonly uint blockNums = 3000; + private static readonly uint encodeSize = blockSize * blockNums; + private static string checkBlockBytes(byte block) + { + const int byteCount = 8; + string newBlock = block.ToString(); + int size = Encoding.UTF8.GetByteCount(newBlock); + //Console.WriteLine("newBlock: " + newBlock); + //Console.WriteLine("newBlock size: " + size); + if (size < byteCount) + for (int i = 0; i < (byteCount - size); i++) + newBlock += '\0'; + //Console.WriteLine("newblock size: " + System.Text.ASCIIEncoding.UTF8.GetByteCount(newBlock)); + return newBlock; + } + private static bool encodeFile(string path, uint[] key) { + #region Reading file Console.WriteLine("[OUTPUT] Reading: " + path); byte[] file_bytes; try { @@ -27,16 +59,70 @@ namespace ModelCoder Console.WriteLine("[OUTPUT] File '" + path + "' not found"); return false; } - - ITeaCoding tea = new TeaCoding(); - var block = new uint[2]; - for (uint i = 0; i < encodeSize; i += 2) { - Console.WriteLine(i + " start iteration"); - block[0] = file_bytes[i]; - block[1] = file_bytes[i + 1]; - Console.WriteLine(i + " start encoding"); - tea.code(block, key); + #endregion + + /*string[] test = {"22\0\0\0\0\0\0", "1\0\0\0\0\0\0\0"}; + foreach (var i in test) + { + Console.WriteLine(i + " bytes: " + Encoding.UTF8.GetByteCount(i)); + Console.WriteLine(i + " b64: " + util.Base64Encode(i)); } + string blockCheck = checkBlockBytes(file_bytes[0]); + Console.WriteLine("first file block: " + blockCheck); + Console.WriteLine("first file block size: " + Encoding.UTF8.GetByteCount(blockCheck)); + blockCheck = util.Base64Encode(blockCheck); + Console.WriteLine("first file block b64e: " + blockCheck); + Console.WriteLine("first file block b64d: " + util.Base64Decode(blockCheck));*/ + + // TEA and Base64 encoding + var block = new uint[2]; + string result = ""; + for (uint i = 0; i < 10; i += 2) + { + block[0] = Convert.ToUInt32(checkBlockBytes(file_bytes[i])); + block[1] = Convert.ToUInt32(checkBlockBytes(file_bytes[i + 1])); + + Console.WriteLine("st block0: " + block[0]); + Console.WriteLine("st block1: " + block[1]); + + tea.encode(block, key); + + Console.WriteLine("enc block0: " + block[0]); + Console.WriteLine("enc block1: " + block[1]); + + Console.WriteLine("block0 bytes:"); + foreach (var j in BitConverter.GetBytes(block[0])) + Console.WriteLine(" " + j); + + Console.WriteLine("block1 bytes:"); + foreach (var j in BitConverter.GetBytes(block[1])) + Console.WriteLine(" " + j); + + Console.WriteLine(util.Base64Encode(block[0].ToString())); + Console.WriteLine(util.Base64Encode(block[1].ToString())); + + Console.WriteLine(); + + //result += util.Base64Encode(BitConverter.GetBytes(block[0])) + + // util.Base64Encode(BitConverter.GetBytes(block[1])); + result += util.Base64Encode(block[0].ToString()) + + util.Base64Encode(block[1].ToString()); + } + Console.WriteLine("Result: " + result); + Console.WriteLine("[OUTPUT] File '" + path + "' has been TEA and Base64 encoded"); + + #region Writing file with encoded and non-encoded part + string encodedPath = path + ".enc"; + // encoded part + File.WriteAllText(encodedPath, result); + // non-encoded part + FileStream ofile = File.OpenWrite(encodedPath); + ofile.Seek(encodeSize, 0); + for (uint i = blockNums; i < file_bytes.Length; i++) + ofile.WriteByte(file_bytes[i]); + ofile.Close(); + Console.WriteLine("[OUTPUT] File '" + encodedPath + "' successfully written"); + #endregion return true; } @@ -44,28 +130,31 @@ namespace ModelCoder [STAThread] static void Main(string[] args) { - IUtil util = new Util(); + util = new Util(); + tea = new TeaCoding(); + dlltest = new dllimport(); + //Console.WriteLine(dlltest.test("22")); string fpath; - if (args.Length > 0) { + if (args.Length > 0) fpath = args[0]; - } else { - Console.WriteLine("[OUTPUT] You can open file(s) with this program"); - Console.WriteLine("[OUTPUT] Or drag'n'drop on it"); - Console.Write("[INPUT] Enter filename (without spaces): "); - fpath = Console.ReadLine(); + else + { + Console.WriteLine("[OUTPUT] You can open file(s) with this program"); + Console.WriteLine("[OUTPUT] Or drag'n'drop on it"); + Console.Write("[INPUT] Enter filename (without spaces): "); + fpath = Console.ReadLine(); } Console.Write("[INPUT] Enter key: "); uint[] uKey = util.ConvertKey(Console.ReadLine()); - + Console.WriteLine("[OUTPUT] Reading file(s)..."); - if (args.Length > 1) { + if (args.Length > 0) foreach (string i in args) encodeFile(i, uKey); - } else { + else encodeFile(fpath, uKey); - } Console.Write("Press any key to continue . . . "); Console.ReadKey(true); diff --git a/base64/base64.cbp b/base64/base64.cbp new file mode 100644 index 0000000..f7a0e06 --- /dev/null +++ b/base64/base64.cbp @@ -0,0 +1,51 @@ + + + + + + diff --git a/base64/base64.cpp b/base64/base64.cpp new file mode 100644 index 0000000..fe33a06 --- /dev/null +++ b/base64/base64.cpp @@ -0,0 +1,93 @@ +#include "base64.h" +#include + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(BYTE c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64encode(BYTE const* buf, unsigned int bufLen) { + std::string ret; + int i = 0, j = 0; + BYTE char_array_3[3], char_array_4[4]; + + while(bufLen--) { + char_array_3[i++] = *(buf++); + if(i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; i < 4; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if(i) { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(j = 0; j < (i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while(i++ < 3) + ret += '='; + } + + return ret; +} + +std::vector base64decode(std::string const& encoded_string) { + int in_len = encoded_string.size(), + i = 0, + j = 0, + in_ = 0; + BYTE char_array_4[4], char_array_3[3]; + std::vector ret; + + while(in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; + in_++; + if(i == 4) { + for(i = 0; i < 4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for(i = 0; i < 3; i++) + ret.push_back(char_array_3[i]); + i = 0; + } + } + + if(i) { + for(j = i; j < 4; j++) + char_array_4[j] = 0; + + for(j = 0; j < 4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for(j = 0; j < (i - 1); j++) + ret.push_back(char_array_3[j]); + } + + return ret; +} diff --git a/base64/base64.depend b/base64/base64.depend new file mode 100644 index 0000000..ff9fab4 --- /dev/null +++ b/base64/base64.depend @@ -0,0 +1,17 @@ +# depslib dependency file v1.0 +1600530854 source:c:\users\jdm17\desktop\base64\base64.cpp + "base64.h" + + +1600530854 c:\users\jdm17\desktop\base64\base64.h + + + +1601296249 source:c:\users\jdm17\desktop\base64\main.cpp + "main.h" + "base64.h" + +1601297599 c:\users\jdm17\desktop\base64\main.h + + + diff --git a/base64/base64.h b/base64/base64.h new file mode 100644 index 0000000..ee962ea --- /dev/null +++ b/base64/base64.h @@ -0,0 +1,11 @@ +#ifndef _BASE64_H_ +#define _BASE64_H_ + +#include +#include +typedef unsigned char BYTE; + +std::string base64encode(BYTE const*, unsigned int); +std::vector base64decode(std::string const&); + +#endif diff --git a/base64/base64.layout b/base64/base64.layout new file mode 100644 index 0000000..63fe404 --- /dev/null +++ b/base64/base64.layout @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/base64/main.cpp b/base64/main.cpp new file mode 100644 index 0000000..1348167 --- /dev/null +++ b/base64/main.cpp @@ -0,0 +1,37 @@ +#include "main.h" +#include "base64.h" + +// a sample exported function +void DLL_EXPORT SomeFunction(const LPCSTR sometext) +{ + MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); +} + +extern "C" DLL_EXPORT std::string Base64Encode(BYTE const* buf, unsigned int bufLen) +{ + return base64encode(buf, bufLen); +} + +extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + // attach to process + // return FALSE to fail DLL load + break; + + case DLL_PROCESS_DETACH: + // detach from process + break; + + case DLL_THREAD_ATTACH: + // attach to thread + break; + + case DLL_THREAD_DETACH: + // detach from thread + break; + } + return TRUE; // succesful +} diff --git a/base64/main.h b/base64/main.h new file mode 100644 index 0000000..4140454 --- /dev/null +++ b/base64/main.h @@ -0,0 +1,30 @@ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#include + +/* To use this exported function of dll, include this header + * in your project. + */ + +#ifdef BUILD_DLL + #define DLL_EXPORT __declspec(dllexport) +#else + #define DLL_EXPORT __declspec(dllimport) +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + +//#include +void DLL_EXPORT SomeFunction(const LPCSTR sometext); +//std::string DLL_EXPORT Base64Encode(unsigned char const* buf, unsigned int bufLen); + +#ifdef __cplusplus +} +#endif + +#endif // __MAIN_H__ diff --git a/model_coder.csproj b/model_coder.csproj index 27d88f3..9dd7531 100644 --- a/model_coder.csproj +++ b/model_coder.csproj @@ -48,6 +48,10 @@ TRACE + + base64.dll + True + 4.0 diff --git a/tea.cs b/tea.cs index fb54fa0..dc27678 100644 --- a/tea.cs +++ b/tea.cs @@ -12,62 +12,67 @@ namespace Tea { public interface ITeaCoding { - void code(uint[] v, uint[] k); + void encode(uint[] v, uint[] k); //void decode(uint[] v, uint[] k); } public partial class TeaCoding: ITeaCoding { private readonly uint c_delta = 0x9E3779B9; - /* + public void encode(uint[] v, uint[] k) { uint v0 = v[0], v1 = v[1]; uint sum = 0; - //for(int i = 0; i < 32; i++) { - for(uint i = 32; i > 0; i--) { - //v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); - //sum += c_delta; - //v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); - + for (int i = 0; i < 32; i++) { + //for (uint i = 32; i > 0; i--) { + unchecked { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += c_delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); + } //sum += c_delta; //v0 += (v1 << 4) + k[0] ^ v1 + sum ^ (v1 >> 5) + k[1]; //v1 += (v0 << 4) + k[2] ^ v0 + sum ^ (v0 >> 5) + k[3]; - v0 += (v1 << 4 ^ v1 >> 5) + v1 ^ sum + k[sum & 3]; - sum += c_delta; - v1 += (v0 << 4 ^ v0 >> 5) + v0 ^ sum + k[sum >> 11 & 3]; + //v0 += (v1 << 4 ^ v1 >> 5) + v1 ^ sum + k[sum & 3]; + //sum += c_delta; + //v1 += (v0 << 4 ^ v0 >> 5) + v0 ^ sum + k[sum >> 11 & 3]; } v[0] = v0; v[1] = v1; } - */ - public void code(uint[] v, uint[] k) + /* + public void encode(uint[] v, uint[] k) { - uint y = v[0]; - uint z = v[1]; - uint sum = 0; - uint n = 32; + uint y = v[0]; + uint z = v[1]; + uint sum = 0; + uint n = 32; - while (n-- > 0) - { - y += (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3]; - sum += c_delta; - z += (y << 4 ^ y >> 5) + y ^ sum + k[sum >> 11 & 3]; - } + unchecked { + while (n-- > 0) + { + y += (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3]; + sum += c_delta; + z += (y << 4 ^ y >> 5) + y ^ sum + k[sum >> 11 & 3]; + } + } - v[0] = y; - v[1] = z; + v[0] = y; + v[1] = z; } - + */ /* private readonly uint c_sum = 0xC6EF3720; public void decode(uint[] v, uint[] k) { uint v0 = v[0], v1 = v[1]; uint sum = c_sum; for (int i = 0; i < 32; i++) { - v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); - sum -= c_delta; - v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + unchecked { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); + sum -= c_delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + } } v[0] = v0; v[1] = v1; diff --git a/test/partial_file_encode.enc b/test/partial_file_encode.enc index 0eaa28a..f166b4f 100644 Binary files a/test/partial_file_encode.enc and b/test/partial_file_encode.enc differ diff --git a/utils.cs b/utils.cs index ae9a5fa..af01b0c 100644 --- a/utils.cs +++ b/utils.cs @@ -18,43 +18,165 @@ namespace Utils uint[] ConvertKey(string input); uint ConvertStringToUInt(string input); string ConvertUIntToString(uint input); + string Base64Encode(string plainText); + //string Base64Encode(byte[] plainText); + string Base64Decode(string base64EncodedData); } public partial class Util: IUtil { + #region Convert Key to MD5, then to UInt public uint[] ConvertKey(string input) { // MD5 Hashing var md5 = MD5.Create(); - byte[] inputBytes = Encoding.ASCII.GetBytes(input); - byte[] hashBytes = md5.ComputeHash(inputBytes); - var sb = new StringBuilder(); - for (int i = 0; i < hashBytes.Length; i++) - sb.Append(hashBytes[i].ToString("X2")); - // Converting to uint[] - string key = sb.ToString().ToLower().Substring(0, 16); - var formattedKey = new uint[4]; + byte[] inputBytes = Encoding.ASCII.GetBytes(input); + byte[] hashBytes = md5.ComputeHash(inputBytes); + var sb = new StringBuilder(); + for (int i = 0; i < hashBytes.Length; i++) + sb.Append(hashBytes[i].ToString("X2")); + // Converting to uint[] + string key = sb.ToString().ToLower().Substring(0, 16); + var formattedKey = new uint[4]; int j = 0; for (int i = 0; i < key.Length; i += 4) formattedKey[j++] = ConvertStringToUInt(key.Substring(i, 4)); return formattedKey; } + #endregion + #region Convert String to UInt and reverse public uint ConvertStringToUInt(string input) { uint output; - output = ((uint)input[0]); - output += ((uint)input[1] << 8); - output += ((uint)input[2] << 16); - output += ((uint)input[3] << 24); - return output; + output = ((uint)input[0]); + output += ((uint)input[1] << 8); + output += ((uint)input[2] << 16); + output += ((uint)input[3] << 24); + return output; } public string ConvertUIntToString(uint input) { - var output = new StringBuilder(); - output.Append((char)((input & 0xFF))); - output.Append((char)((input >> 8) & 0xFF)); - output.Append((char)((input >> 16) & 0xFF)); - output.Append((char)((input >> 24) & 0xFF)); - return output.ToString(); + var output = new StringBuilder(); + output.Append((char)((input & 0xFF))); + output.Append((char)((input >> 8) & 0xFF)); + output.Append((char)((input >> 16) & 0xFF)); + output.Append((char)((input >> 24) & 0xFF)); + return output.ToString(); } + #endregion + #region Base64 encoding/decoding + public string Base64Encode(string plainText) + { + var plainTextBytes = Encoding.UTF8.GetBytes(plainText); + return Convert.ToBase64String(plainTextBytes); + } + /*public string Base64Encode(byte[] data) + return Convert.ToBase64String(data); + public char[] Base64Encode(byte[] data) + { + int length, length2; + int blockCount; + int paddingCount; + + length = data.Length; + + if ((length % 3) == 0) + { + paddingCount = 0; + blockCount = length / 3; + } + else + { + paddingCount = 3 - (length % 3); + blockCount = (length + paddingCount) / 3; + } + + length2 = length + paddingCount; + + Console.WriteLine("length: " + length); + Console.WriteLine("length2: " + length2); + Console.WriteLine("blockCount: " + blockCount); + Console.WriteLine("paddingCount: " + paddingCount); + + byte[] source2; + source2 = new byte[length2]; + + for (int x = 0; x < length2; x++) + source2[x] = x < length ? data[x] : (byte)0; + + byte b1, b2, b3; + byte temp, temp1, temp2, temp3, temp4; + var buffer = new byte[blockCount * 4]; + var result = new char[blockCount * 4]; + + for (int x = 0; x < blockCount; x++) + { + b1 = source2[x * 3]; + b2 = source2[x * 3 + 1]; + b3 = source2[x * 3 + 2]; + + temp1 = (byte)((b1 & 252) >> 2); + + temp = (byte)((b1 & 3) << 4); + temp2 = (byte)((b2 & 240) >> 4); + temp2 += temp; + + temp = (byte)((b2 & 15) << 2); + temp3 = (byte)((b3 & 192) >> 6); + temp3 += temp; + + temp4 = (byte)(b3 & 63); + + buffer[x * 4] = temp1; + buffer[x * 4 + 1] = temp2; + buffer[x * 4 + 2] = temp3; + buffer[x * 4 + 3] = temp4; + } + + for (int x = 0; x < blockCount * 4; x++) + result[x] = SixBitToChar(buffer[x]); + + switch (paddingCount) + { + case 0: + break; + case 1: + result[blockCount * 4 - 1] = '='; + break; + case 2: + result[blockCount * 4 - 1] = '='; + result[blockCount * 4 - 2] = '='; + break; + default: + break; + } + + return result; + } + private static char SixBitToChar(byte b) + { + var lookupTable = new char[64] { + 'A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j','k','l','m', + 'n','o','p','q','r','s','t','u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9','+','/' + }; + + if ((b >= 0) && (b <= 63)) + { + return lookupTable[(int)b]; + } + else + { + return ' '; + } + }*/ + + public string Base64Decode(string base64EncodedData) + { + var base64EncodedBytes = Convert.FromBase64String(base64EncodedData); + return Encoding.UTF8.GetString(base64EncodedBytes); + } + #endregion } }