├── README.md
├── chimera_decrypt
├── README.md
├── chimera-leak.txt
├── polarsslwrapper.dll
├── src
│ ├── CMakeLists.txt
│ ├── main.cpp
│ └── wrapper.h
└── test_cases
│ ├── case1
│ ├── dumped_key.txt
│ ├── encrypted
│ │ ├── msg_01.txt.crypt
│ │ ├── msg_02.txt.crypt
│ │ ├── msg_03.txt.crypt
│ │ ├── msg_04.txt.crypt
│ │ ├── msg_05.txt.crypt
│ │ ├── msg_06.txt.crypt
│ │ ├── msg_07.txt.crypt
│ │ ├── msg_08.txt.crypt
│ │ ├── msg_09.txt.crypt
│ │ ├── msg_10.txt.crypt
│ │ ├── msg_11.txt.crypt
│ │ └── msg_12.txt.crypt
│ └── run.bat
│ ├── case2
│ ├── dumped_key.txt
│ ├── readme.txt.crypt
│ └── run.bat
│ ├── case3
│ ├── README.md
│ ├── redist.txt.crypt
│ └── run.bat
│ ├── chimera_private.txt
│ └── run.bat
├── dma_unlocker
├── CMakeLists.txt
├── LICENSE
├── Params.cpp
├── Params.h
├── README.md
├── cracking_crawler
│ ├── CMakeLists.txt
│ ├── CrackedSet.cpp
│ ├── CrackedSet.h
│ └── main.cpp
├── decryptor
│ ├── CMakeLists.txt
│ ├── aes256.cpp
│ ├── aes256.h
│ ├── decryptor.cpp
│ ├── decryptor.h
│ └── main.cpp
├── dma_crack.cpp
├── dma_crack.h
├── filetypes
│ ├── CMakeLists.txt
│ ├── FileTypes.cpp
│ ├── FileTypes.h
│ ├── TypeValidator.cpp
│ ├── TypeValidator.h
│ └── main.cpp
├── keygen
│ ├── CMakeLists.txt
│ ├── DmaKeygen.cpp
│ ├── DmaKeygen.h
│ ├── keygen.cpp
│ ├── keygen.h
│ └── main.cpp
├── main.cpp
├── main.h
├── recon
│ ├── CMakeLists.txt
│ ├── FileSet.cpp
│ ├── FileSet.h
│ ├── PathCrawler.cpp
│ ├── PathCrawler.h
│ └── main.cpp
├── timeconv.cpp
├── timeconv.h
├── types.h
├── unlocker
│ ├── CMakeLists.txt
│ ├── Unlocker.cpp
│ ├── Unlocker.h
│ └── main.cpp
└── util.h
└── princesslocker_decrypt
├── README.md
├── decryptor
├── CMakeLists.txt
├── PathCrawler.cpp
├── PathCrawler.h
├── README.md
├── decryptor.cpp
├── decryptor.h
└── main.cpp
└── keygen
├── CMakeLists.txt
├── README.md
├── aes_crypt.cpp
├── aes_crypt.h
└── main.cpp
/README.md:
--------------------------------------------------------------------------------
1 | # decryptors_archive
2 | Archive of ransomware decryptors.
3 | Warning: those decryptors are obsolete. They are available only for a case study for other researchers.
4 |
--------------------------------------------------------------------------------
/chimera_decrypt/README.md:
--------------------------------------------------------------------------------
1 | Tool for checking whether your files can be decrypted using leaked Chimera keys.
2 | Read more: https://blog.malwarebytes.com/cybercrime/2016/08/decrypting-chimera-ransomware/
3 |
--------------------------------------------------------------------------------
/chimera_decrypt/polarsslwrapper.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/polarsslwrapper.dll
--------------------------------------------------------------------------------
/chimera_decrypt/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | project (chimera_dec)
3 |
4 | set (srcs
5 | main.cpp
6 | )
7 |
8 | set (hdrs
9 | wrapper.h
10 | )
11 |
12 | add_executable (chimera_dec ${hdrs} ${srcs})
13 |
--------------------------------------------------------------------------------
/chimera_decrypt/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "wrapper.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #define KEYS_SET_FILE "chimera-leak.txt"
8 | #define OUT_KEY_FILE "found.key"
9 | #define DEFAULT_KEY_LEN 0x483
10 |
11 | using namespace std;
12 |
13 | BYTE *g_privKey = new BYTE [DEFAULT_KEY_LEN + 1];
14 | size_t g_keyLen = 0;
15 |
16 | BYTE* HexToBytes(const std::string& hex) {
17 | size_t hex_len = hex.length();
18 | size_t key_len = hex_len/2 + 1;
19 |
20 | memset(g_privKey, 0, key_len);
21 |
22 | const char* hex_str = hex.c_str();
23 | char chunk[3];
24 | memset(chunk, 0, 3);
25 | BYTE mByte = 0;
26 | g_keyLen = 0;
27 |
28 | for (size_t i = 0, j = 0; i < hex_len; i += 2, j++) {
29 | chunk[0] = hex_str[i];
30 | chunk[1] = hex_str[i + 1];
31 |
32 | g_privKey[g_keyLen] = static_cast(std::stoul(chunk, nullptr, 16));
33 | g_keyLen++;
34 | }
35 | return g_privKey;
36 | }
37 |
38 | bool save_to_file(const char* path, std::string line)
39 | {
40 | std::ofstream outfile(path);
41 | if (outfile.is_open() == false) {
42 | return false;
43 | }
44 | outfile << line << endl;
45 | outfile.close();
46 | return true;
47 | }
48 |
49 | bool file_exist(const char* path)
50 | {
51 | std::ifstream infile(path);
52 | if (infile.is_open() == false) {
53 | return false;
54 | }
55 | infile.close();
56 | return true;
57 | }
58 |
59 | bool search_priv_key(std::ifstream &infile, const char* file_path)
60 | {
61 | t_DecryptFileWrapper func1 = loadDecryptFunc();
62 | if (func1 == NULL) {
63 | system("pause");
64 | return false;
65 | }
66 |
67 | std::string line;
68 | size_t key_len = 0;
69 | size_t counter = 0;
70 | while (std::getline(infile, line))
71 | {
72 | std::istringstream iss(line);
73 | key_len = line.length() / 2;
74 | printf("key num: %d len = %#x = %d\n", counter++, key_len, key_len);
75 |
76 | BYTE *priv_key = HexToBytes(line);
77 |
78 | if (func1(file_path, priv_key, DEFAULT_KEY_LEN)) {
79 | printf("Success!\n");
80 | if (save_to_file(OUT_KEY_FILE, line)) {
81 | printf("Found key saved to the file: %s\n", OUT_KEY_FILE);
82 | } else {
83 | printf("[ERROR] Cannot save to the file: %s\n", file_path);
84 | }
85 | return true;
86 | }
87 | }
88 | return false;
89 | }
90 |
91 | bool rename_file(std::string filename)
92 | {
93 | std::size_t found = filename.find_last_of(".");
94 | std::string newname = filename.substr(0, found);
95 | std::string ext = filename.substr(found+1);
96 | if (ext == "crypt") {
97 | MoveFileA(filename.c_str(), newname.c_str());
98 | printf("Renamed decrypted file to: %s\n", newname.c_str());
99 | return true;
100 | }
101 | return false;
102 | }
103 |
104 | int main(int argc, char *argv[])
105 | {
106 | if (argc < 3) {
107 | printf("USAGE:\nchimera_dec.exe \nEXAMPLE:\nchimera_dec.exe myFile.docx.crypt chimera-leak.txt\n");
108 | system("pause");
109 | return -1;
110 | }
111 |
112 | const char *path = path = argv[1];
113 | const char *key_leak_file = argv[2];
114 |
115 | std::ifstream infile(key_leak_file);
116 | if (infile.is_open() == false) {
117 | printf("[ERROR] Cannot open the file with keys: %s\n", key_leak_file);
118 | system("pause");
119 | return -1;
120 | }
121 |
122 | if (file_exist(path) == false) {
123 | printf("[ERROR] Cannot open encrypted file: %s\n", path);
124 | system("pause");
125 | return -1;
126 | }
127 |
128 | if (search_priv_key(infile, path)) {
129 | rename_file(path);
130 | printf("Hurray! The set contains your key!\n");
131 | } else {
132 | printf("Sorry! None of the keys fit to your file!\n");
133 | }
134 |
135 | system("pause");
136 | return 0;
137 | }
138 |
--------------------------------------------------------------------------------
/chimera_decrypt/src/wrapper.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define DLL_PATH "polarsslwrapper"
5 | #define DECRYPT_FUNC "DecryptFileWrapper"
6 | #define ID_FUNC "GetHardwareIdWrapper"
7 |
8 | typedef bool (__cdecl *t_DecryptFileWrapper)(const char *filePath, BYTE *privateKey, size_t privateKeyLen);
9 |
10 | t_DecryptFileWrapper loadDecryptFunc()
11 | {
12 | HMODULE hLib = LoadLibraryA(DLL_PATH);
13 | if (hLib == NULL) {
14 | printf("Could not load the DLL!\n");
15 | return NULL;
16 | } else {
17 | printf("DLL loaded\n");
18 | }
19 |
20 | t_DecryptFileWrapper func = (t_DecryptFileWrapper) GetProcAddress(hLib, DECRYPT_FUNC);
21 | if (func == NULL) {
22 | printf("Could not get the %s\n", DECRYPT_FUNC);
23 | return NULL;
24 | }
25 | printf("Got the %s\n", DECRYPT_FUNC);
26 | return func;
27 | }
28 |
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/dumped_key.txt:
--------------------------------------------------------------------------------
1 | A4638D07923CE31933D75104B6C10687DFD9FEB5350CFB356858E06E909E1F7A4935838FDDF5CBF73141F9B82877FA5F83B1809099126620944B48BE067BE36761B02673FFB0A28EAAC37793B50500E9267D88DCFEAEB6AEDD3F1A0D2C741FDA5210625C5F3EE556642598ACE44642A7688985E6C4B1C0F154A4B95003310283A95915492E80E2100AD1FED14F3BA78A501E32C91E16B82132E74BC53804AE0A61FA8F9E6ECF0137FC3E37DA1318E0492D66680B42AEA933ABCB2FE519830AF12AE9AC2940C9F9F5913DB57051E14817EC40B1F418A328D42803492603F136E4BAF052A536CA2725C117AF3E1E1F58BCD38EA0C61C544C11392D9A343ED96F670100016C211F4EEF9E25331AAA729C4B29C485F3748CD9DCBF612DCC2949D6F041522B39A47D995042B19B3347565F101F7B0D00AEED062FE9AE4B97BFBD656116748A37F38A179B0430A8EF220BB198CC65C0F694744609301AF2028DD330FF20932323FFAAF35FA31B6F2C089ED87A7ECCB1194DFC49C2EFB91E04B32541C017A8B2A8CAC8EFF65FD00C0A0B643DBC6016DA3B2BE43AEB0C54FC8BA1493A98F7410DD2C8FA85F21E877F238107DBA0608CAA8103E5F86E286987679DFE46226BFA495214CDBACE4ECFEC122A2119321E7D1E2C61B5FAE985F8CD7BA4C464E0303BD1A6C1E9EB0FA900E4C31585D08FA6928862C3D99F1EC4F3384652DB68EFD70041EF40F86AF2BE3C0C14CD0C7E78DF91E47AA632B48A6FF030584C1B01173337A14D644FB20D618AABBC98B7CBA8C1428DB6235E50E3C923230FF671CFA2638BDA5E5666E04CA78F7EDDFB04EE95CB5376CB811FE6A303A5AC1224540EC242CC66B9841A4BD6E0963D3EDF5C5FB191591ACFC405C3BAED5B149BF159B52C2E3C9FAFE520337DDEB01CA72EA5420A15F1566332B0582364A61C091B328039B3A38F9C5FA17D1680F4AC58BAE203DDFA2305F307FDA8AC4876511E5A411072F417D85EE39BD9121A4D6B36EADFCE3A69B7BE43FA040BB4606E4DB5A7164A228253F6421BB67A86B9FBA03363C3D4F60CB6F98495F6B4FC96A6E3CE38CC1A00BC10398369BF49170DD0739E5546408D69D77B94B686F14D7CD083ED6BD8055055EC7F67BFEA5A5529377EBEF76F34A8FB85EFCA9440B0D37CDE14DB26B53AA3EA639DCCE54E5A7320321C3017398D46AFC8A75E7E0D24A4735363610F9D300219A8A5DFCE2497756E24777D7A3805C3C59F18AFF7EE66A4DCCC8354684BAACC9A94E7A9EBAFDAEE7AC52938FC5FDB5740F15EE1FFA2C9D28F35C519AAF37359CAC77441BD449541BB1C22AEA90314774960B22BA089947BB298D22E7F4421AEDB4D79D1D911C276B1801ED5F3BA775088B65F90EDA320E784CCAA37950D7C5AB00A8A783CAB60DC6C28C00F450E76D9A758CFDD1CBE33035C4A27021E6E55A4660949594FAA540D7482407C0AB53E1F22F206C73300A2E6FE1779EA49068813A4FB8BE223A9F6093AB828364ADB8B8F569EBD59F52058423DD84CB4D23C8E99CA7E6E13343BD464ADD931180FA8B4BC9380750A07FD60516CEB9C991E15B6259F9F5B9AA3E7F37487EE5B2F3CA03FF2704BCEF0FEDF06C641080D4840F212E6B406380
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_01.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_01.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_02.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_02.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_03.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_03.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_04.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_04.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_05.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_05.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_06.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_06.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_07.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_07.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_08.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_08.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_09.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_09.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_10.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_10.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_11.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_11.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/encrypted/msg_12.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case1/encrypted/msg_12.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case1/run.bat:
--------------------------------------------------------------------------------
1 | chimera_dec.exe encrypted\msg_01.txt.crypt dumped_key.txt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case2/dumped_key.txt:
--------------------------------------------------------------------------------
1 | AF76197D882C7FF4D7DEB7418FB2C656ECDD7330B022C4351EDD82808002885E7B8FD76E48B6E9994125526DFAC891DEDD75DAB92408F91F506379E278D07092958C303F97C87D3F6BCEF786862BF89B7236CCD6FDDFE91005171DBA567E6CACA137CCEDE9D5DCF7B9E38305B654ABFAB3AD1465FA007AA17C60DC02CBAA89C944DB80AC45B2C4AEA67471AE90C49B78F88F90281518565F4BE1ED59E153945A62005C040EBCE02ED8C80F24D518CE2E05BB26456BE202FB9800E458C0E03E5AB472BDE32327B8348173B17E6765F5AE390191A5E13EB69979E8B2B795FD4B7F027CB5FB9B77E448751C69D7A0E35B6B73AE06EAA2461299AB2E7719AF8CD7850100019C357E581E25CFFD413A8CD81780C7C797B547DA2ED5A4ECCDFFD33167C5D9769476E90ACC3DDC168EC31571C8754C38A7DD46CED16013BA672D48D3F14F51098F8E715E0C5977F84098D011B9DDE7C52C97D1220E7F8BD4B1537529F1DB381130AEA709A0C6BFA4E49FC2841161AC82D3F7E1533091C09B884A0B5589D0D83D1835F1824135228151B9881463CD4CDDFA93683426693FAC2AC08E20C6962F491C5D123FF78A1BBFE722932D18DF76DE6888833E7C7995D156AF2063BB32CEF0681C2124BA791F58D676607A7C0708493B3D19541E789452C857E3A646B7F7DA28DE732F04B914AD9CC85A3B21B66ED4444C57B6DF0065A064429391D7D63441DB10837D1E915A6F84133FDEB0DF45D2D6389B06DA782EC072133C7E3A01CD79CCF8801EC96C384AAA5B149A5600A6AD5316DCF01027504452CE216BD121F344FB6D6A6C2F3AEF83380667237C0F506F068DD345D2B7E1392960475815DDEF7C342AC92182F967D6DE4B37BDAD236284DFCE36A0D7D284BC8C0DFF7CD4B291ADCD0B8A76F2DE2E2FD8C96B3F0C70B7AE283B05C504200FF04F39C56E1BF2687C31E9E14BECA654E2E572DFD02532C78E09EF0B2ECD18A4FF03B2A7E2A09D59B7745C6A2E137FB7A23638AB85030AE0F3D1E3517C9A7D1928B1B737C1A1E1382E5CF0F7A5D6ECD1DE1B281C28221805478C3EF466DC2BFB06352EFB7335D108393A720C72BC4E116FC130159147653A4EC702B131C1E5E0AB4D841E569B095215D5FED2C7E3FB708553301BAE1595F4E23751D93E5F40EDE45CA74C3964C18712F775B8B8065DD5FB0F5E7DF3F4AC6D4C41D662F0B508841969159BD33F7A47E3BE534FF815E68EB2BFFA17740E966B3982309558925C4337BEB21960E7AA80BD1E1AB1ABA120C9BB30A2F1E201DB92BC391FE14AF9BE1358FEE8C679D214970E94ED77AC84042FB65865B34286139C84D8248689CA86F1C2973265BFBA411FE8F56694184BB896A7743A81C4379C2346E8EBED0CD449C5A5D9E1C287E55281C31CD62C25E7164201D00EE58366EE0BE86348E2ED2F2A2DE2CD70266ED5D9E8D1CF746A52DF5E15648D423FEF89FB1C10406F8B69357826A863A9CE78E7C5FCF246E90EB4FDC692753AE9B834CAB6E9D80DF68F82567EF4AF3F30937C4519E7326E9212DB2A2D2BA082D2A2F45E8B6643C78137978B7CEDD4C8AFD032FEB652BB5522427A0C3F2E23DB05DC7823F250D60246558CF1A755356A554C071E101780BA
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case2/readme.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case2/readme.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case2/run.bat:
--------------------------------------------------------------------------------
1 | chimera_dec.exe readme.txt.crypt dumped_key.txt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case3/README.md:
--------------------------------------------------------------------------------
1 | This sample file (redist.txt.crypt) has been encrypted with the help of public key from the leaked set.
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case3/redist.txt.crypt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hasherezade/decryptors_archive/0bd5384d47164035c28af4188d5700708c8e4244/chimera_decrypt/test_cases/case3/redist.txt.crypt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/case3/run.bat:
--------------------------------------------------------------------------------
1 | chimera_dec.exe redist.txt.crypt chimera-leak.txt
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/chimera_private.txt:
--------------------------------------------------------------------------------
1 | A4638D07923CE31933D75104B6C10687DFD9FEB5350CFB356858E06E909E1F7A4935838FDDF5CBF73141F9B82877FA5F83B1809099126620944B48BE067BE36761B02673FFB0A28EAAC37793B50500E9267D88DCFEAEB6AEDD3F1A0D2C741FDA5210625C5F3EE556642598ACE44642A7688985E6C4B1C0F154A4B95003310283A95915492E80E2100AD1FED14F3BA78A501E32C91E16B82132E74BC53804AE0A61FA8F9E6ECF0137FC3E37DA1318E0492D66680B42AEA933ABCB2FE519830AF12AE9AC2940C9F9F5913DB57051E14817EC40B1F418A328D42803492603F136E4BAF052A536CA2725C117AF3E1E1F58BCD38EA0C61C544C11392D9A343ED96F670100016C211F4EEF9E25331AAA729C4B29C485F3748CD9DCBF612DCC2949D6F041522B39A47D995042B19B3347565F101F7B0D00AEED062FE9AE4B97BFBD656116748A37F38A179B0430A8EF220BB198CC65C0F694744609301AF2028DD330FF20932323FFAAF35FA31B6F2C089ED87A7ECCB1194DFC49C2EFB91E04B32541C017A8B2A8CAC8EFF65FD00C0A0B643DBC6016DA3B2BE43AEB0C54FC8BA1493A98F7410DD2C8FA85F21E877F238107DBA0608CAA8103E5F86E286987679DFE46226BFA495214CDBACE4ECFEC122A2119321E7D1E2C61B5FAE985F8CD7BA4C464E0303BD1A6C1E9EB0FA900E4C31585D08FA6928862C3D99F1EC4F3384652DB68EFD70041EF40F86AF2BE3C0C14CD0C7E78DF91E47AA632B48A6FF030584C1B01173337A14D644FB20D618AABBC98B7CBA8C1428DB6235E50E3C923230FF671CFA2638BDA5E5666E04CA78F7EDDFB04EE95CB5376CB811FE6A303A5AC1224540EC242CC66B9841A4BD6E0963D3EDF5C5FB191591ACFC405C3BAED5B149BF159B52C2E3C9FAFE520337DDEB01CA72EA5420A15F1566332B0582364A61C091B328039B3A38F9C5FA17D1680F4AC58BAE203DDFA2305F307FDA8AC4876511E5A411072F417D85EE39BD9121A4D6B36EADFCE3A69B7BE43FA040BB4606E4DB5A7164A228253F6421BB67A86B9FBA03363C3D4F60CB6F98495F6B4FC96A6E3CE38CC1A00BC10398369BF49170DD0739E5546408D69D77B94B686F14D7CD083ED6BD8055055EC7F67BFEA5A5529377EBEF76F34A8FB85EFCA9440B0D37CDE14DB26B53AA3EA639DCCE54E5A7320321C3017398D46AFC8A75E7E0D24A4735363610F9D300219A8A5DFCE2497756E24777D7A3805C3C59F18AFF7EE66A4DCCC8354684BAACC9A94E7A9EBAFDAEE7AC52938FC5FDB5740F15EE1FFA2C9D28F35C519AAF37359CAC77441BD449541BB1C22AEA90314774960B22BA089947BB298D22E7F4421AEDB4D79D1D911C276B1801ED5F3BA775088B65F90EDA320E784CCAA37950D7C5AB00A8A783CAB60DC6C28C00F450E76D9A758CFDD1CBE33035C4A27021E6E55A4660949594FAA540D7482407C0AB53E1F22F206C73300A2E6FE1779EA49068813A4FB8BE223A9F6093AB828364ADB8B8F569EBD59F52058423DD84CB4D23C8E99CA7E6E13343BD464ADD931180FA8B4BC9380750A07FD60516CEB9C991E15B6259F9F5B9AA3E7F37487EE5B2F3CA03FF2704BCEF0FEDF06C641080D4840F212E6B406380
--------------------------------------------------------------------------------
/chimera_decrypt/test_cases/run.bat:
--------------------------------------------------------------------------------
1 | chimera_dec.exe encrypted\msg_01.txt.crypt chimera_private.txt
--------------------------------------------------------------------------------
/dma_unlocker/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | project (DMA_Unlocker)
3 |
4 | set (recon_srcs
5 | recon/PathCrawler.cpp
6 | recon/FileSet.cpp
7 | )
8 |
9 | set (srcs
10 | decryptor/decryptor.cpp
11 | decryptor/aes256.cpp
12 | keygen/keygen.cpp
13 | keygen/DmaKeygen.cpp
14 | filetypes/filetypes.cpp
15 | filetypes/TypeValidator.cpp
16 | cracking_crawler/CrackedSet.cpp
17 | main.cpp
18 | dma_crack.cpp
19 | timeconv.cpp
20 | Params.cpp
21 | )
22 |
23 | set (recon_hdrs
24 | recon/PathCrawler.h
25 | recon/FileSet.h
26 | )
27 |
28 | set (hdrs
29 | main.h
30 | util.h
31 | decryptor/decryptor.h
32 | decryptor/aes256.h
33 | keygen/keygen.h
34 | keygen/DmaKeygen.h
35 | filetypes/filetypes.h
36 | filetypes/TypeValidator.h
37 | cracking_crawler/CrackedSet.h
38 | dma_crack.h
39 | types.h
40 | timeconv.h
41 | Params.h
42 | )
43 |
44 | SOURCE_GROUP("Header Files\\recon" FILES ${recon_hdrs} )
45 | SOURCE_GROUP("Source Files\\recon" FILES ${recon_srcs} )
46 |
47 | add_executable (DMA_Unlocker ${hdrs} ${srcs} ${recon_hdrs} ${recon_srcs})
48 |
--------------------------------------------------------------------------------
/dma_unlocker/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016, hasherezade , https://keybase.io/hasherezade
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 |
--------------------------------------------------------------------------------
/dma_unlocker/Params.cpp:
--------------------------------------------------------------------------------
1 | #include "Params.h"
2 |
3 | const char Params::id_hash[] = "qWyYGuCxIkhne4XjTyli7ApK761u0xfG9exLhPteuj/bwJxWQzcmh9Zn56dcqnLX";
4 |
5 | //when it all started?
6 | uint32_t Params::encryptionStartTime()
7 | {
8 | time_t start = get_file_creation("C:\\ProgramData\\start.txt");
9 | if (start == 0) {
10 | start = get_file_creation("C:\\ProgramData\\cryptinfo.txt");
11 | }
12 | //---
13 | if (start > 0) {
14 | printf("Infections start time:\n");
15 | print_time_str(start);
16 | } else {
17 | printf("Infections start time: UNKNOWN\n");
18 | }
19 | return static_cast(start);
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/dma_unlocker/Params.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "types.h"
4 |
5 | #include
6 | #include /* printf, scanf, puts, NULL */
7 | #include
8 | #include "types.h"
9 | #include "timeconv.h"
10 |
11 | //#define DEBUG 1
12 |
13 | class Params {
14 |
15 | public:
16 | static uint32_t encryptionStartTime();
17 |
18 | Params()
19 | {
20 | this->timeNow = static_cast (time(NULL));
21 | this->startTime = encryptionStartTime();
22 | this->seed = timeNow;
23 | incrementalMode = false;
24 | filename = ""; //not known yet
25 | fileEncryptionTime = 0;
26 | key_num = 0;
27 | }
28 |
29 | void init(std::string enc_filename, uint32_t encryptionTime)
30 | {
31 | if (enc_filename.length() == 0) return;
32 | this->filename = enc_filename;
33 | this->fileEncryptionTime = encryptionTime;
34 | if (seed == 0 || seed > fileEncryptionTime) {
35 | seed = encryptionTime;
36 | }
37 | autosetMode();
38 | }
39 |
40 | void autosetMode() {
41 | this->incrementalMode = (seed < this->fileEncryptionTime);
42 | }
43 |
44 | //----
45 | std::string filename;
46 | uint32_t startTime; //optional
47 | uint32_t fileEncryptionTime; //optional
48 |
49 | uint32_t timeNow;
50 | uint32_t seed;
51 | size_t key_num;
52 | bool incrementalMode;
53 | size_t series_min, series_max;
54 | static const char id_hash[];
55 |
56 | protected:
57 | void setIncrementalMode(bool val);
58 | };
--------------------------------------------------------------------------------
/dma_unlocker/README.md:
--------------------------------------------------------------------------------
1 | Unlocker for DMA Locker ransomware
2 |
3 | # DMA Unlocker
4 | (plus some tiny helper tools)
5 | -
6 | Read more: https://hshrzd.wordpress.com/dma-unlocker/
7 |
8 | DISCLAIMER: this code is not polished or so, it is just a raw snapshot from the middle of the battle with this ransomware ;)
9 |
--------------------------------------------------------------------------------
/dma_unlocker/cracking_crawler/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | project (DMA_crawler)
3 |
4 | set (recon_srcs
5 | ../recon/PathCrawler.cpp
6 | ../recon/FileSet.cpp
7 | )
8 |
9 | set (srcs
10 | main.cpp
11 | CrackedSet.cpp
12 | ../decryptor/decryptor.cpp
13 | ../decryptor/aes256.cpp
14 | ../keygen/keygen.cpp
15 | ../filetypes/filetypes.cpp
16 | ../filetypes/TypeValidator.cpp
17 | ../dma_crack.cpp
18 | ../timeconv.cpp
19 | ../Params.cpp
20 | )
21 |
22 | set (recon_hdrs
23 | ../recon/PathCrawler.h
24 | ../recon/FileSet.h
25 | )
26 |
27 | set (hdrs
28 | CrackedSet.h
29 | ../decryptor/decryptor.h
30 | ../decryptor/aes256.h
31 | ../keygen/keygen.h
32 | ../filetypes/filetypes.h
33 | ../filetypes/TypeValidator.h
34 | ../dma_crack.h
35 | ../types.h
36 | ../timeconv.h
37 | ../Params.h
38 | )
39 |
40 | SOURCE_GROUP("Header Files\\recon" FILES ${recon_hdrs} )
41 | SOURCE_GROUP("Source Files\\recon" FILES ${recon_srcs} )
42 |
43 | add_executable (DMA_crawler ${hdrs} ${srcs} ${recon_hdrs} ${recon_srcs})
44 |
--------------------------------------------------------------------------------
/dma_unlocker/cracking_crawler/CrackedSet.cpp:
--------------------------------------------------------------------------------
1 | #include "CrackedSet.h"
2 | #define INFECTED_PER_MS 50
3 | #define UPPER_SERIES_BOUND 2000000
4 |
5 | #include "../timeconv.h"
6 |
7 |
8 | //virtual
9 | bool CrackedSet::processFile(std::string path, std::string ext, uint32_t writeTime)
10 | {
11 | if (params.fileEncryptionTime == 0) {
12 | params.fileEncryptionTime = writeTime;
13 | params.init(path, writeTime);
14 | }
15 | long dif = 0;
16 | if (this->lastDecryptedTimestamp != 0) {
17 | dif = abs(long(writeTime - lastDecryptedTimestamp));
18 | }
19 |
20 | if (params.seed == 0 || writeTime < params.seed || dif > HOUR_LEN) {
21 | #ifdef DEBUG
22 | printf ("Setting seed to the file encryption time!\n");
23 | #endif
24 | params.init(path, writeTime);
25 | params.seed = params.fileEncryptionTime;
26 | params.autosetMode();
27 | }
28 |
29 | if (params.fileEncryptionTime == params.seed) {
30 | #ifdef DEBUG
31 | printf("Smart timestamp enabled!\n");
32 | #endif
33 | params.series_min = INFECTED_PER_MS; //start from small series
34 | params.series_max = UPPER_SERIES_BOUND;
35 | } else {
36 | params.series_min = params.series_max;
37 | }
38 |
39 | params.filename = path;
40 | if (decrypt_file(fileTypes, params, path)) {
41 | printf("[SUCCESS]\n");
42 | this->lastDecryptedTimestamp = writeTime;
43 | logToFile(path, writeTime);
44 | return true;
45 | }
46 | return false;
47 | }
48 |
--------------------------------------------------------------------------------
/dma_unlocker/cracking_crawler/CrackedSet.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../recon/FileSet.h"
4 | #include "../dma_crack.h"
5 |
6 | class CrackedSet : public FileSet
7 | {
8 | public:
9 |
10 | CrackedSet(FileTypesSet &fTypes, Params &p)
11 | : fileTypes(fTypes), params(p) { lastDecryptedTimestamp = 0; }
12 |
13 | virtual void init()
14 | {
15 | logFilename = "cracked_log.txt";
16 | FILE *logFile = fopen(logFilename.c_str(), "w");
17 | if (!logFile) {
18 | printf ("Open log file failed\n");
19 | return;
20 | }
21 | fclose(logFile);
22 | }
23 |
24 | protected:
25 | virtual bool processFile(std::string path, std::string ext, uint32_t writeTime);
26 | void autoinitParams(std::string path, std::string ext, uint32_t writeTime);
27 |
28 | FileTypesSet &fileTypes;
29 | Params ¶ms;
30 | uint32_t lastDecryptedTimestamp;
31 | };
--------------------------------------------------------------------------------
/dma_unlocker/cracking_crawler/main.cpp:
--------------------------------------------------------------------------------
1 | #include "../types.h"
2 | #include
3 |
4 | #include /* printf, scanf, puts, NULL */
5 | #include
6 | #include
7 |
8 | #include "../Params.h"
9 | #include "../recon/PathCrawler.h"
10 | #include "../decryptor/decryptor.h"
11 | #include "../filetypes/FileTypes.h"
12 |
13 | #include "CrackedSet.h"
14 | #define MIN_ARG 2
15 | //----
16 |
17 | int main (int argc, char *argv[])
18 | {
19 | printf("---------------------------\n");
20 | printf("DMA CRAWLER v0.2, by hasherezade\n");
21 | printf("---------------------------\n");
22 |
23 | printf("Params:\n \n optional:[start_time] [increment_mode] [series][file_mod_time]\n\n");
24 | printf(" start_time (optional) : timestamp from which the search should start\n");
25 | printf(" increment_mode (optional) : 1 - increment start_time ; 0 - decrement start_time\n");
26 | printf(" series : how many keys to generate per single timestamp (max)\n");
27 | printf(" file_mod_time (optional) : file modification timestamp (in case if the saved one is invalid)\n");
28 | printf("---------------------------\n");
29 |
30 | bool isIncrementalMode = false;
31 | int seed = 0;
32 | uint32_t mod_timestamp = 0;
33 | size_t max_series = 2000000; //TODO: calculate dynamically
34 |
35 | FileTypesSet fileTypes;
36 | if (fileTypes.listDir(HDRS_DIR) == 0) {
37 | printf("[ERROR] Cannot load supported extensions!\n");
38 | }
39 |
40 | size_t arg_num = MIN_ARG;
41 | if (argc >= arg_num) {
42 | sscanf(argv[arg_num - 1],"%d", &seed);
43 | printf("SEED = %d = %#x\n", seed, seed);
44 | }
45 | arg_num++;
46 |
47 | if (argc >= arg_num) {
48 | int mode = 0;
49 | sscanf(argv[arg_num - 1],"%d", &mode);
50 | isIncrementalMode = (mode >= 1);
51 | printf("is INC MODE_ = %d\n", isIncrementalMode);
52 | }
53 | arg_num++;
54 |
55 | if (argc >= arg_num) {
56 | sscanf(argv[arg_num - 1],"%d", &max_series);
57 | printf("MAX_SERIES = %d\n", max_series);
58 | }
59 |
60 | arg_num++;
61 | if (argc >= arg_num) {
62 | sscanf(argv[arg_num - 1],"%d", &mod_timestamp);
63 | printf("overwriting FILEMODTIME = %d\n", mod_timestamp);
64 | }
65 |
66 | //max number of encrypted files per milisecons
67 | int infected_per_ms = 50; //todo: calculate this!
68 | int upper_search_bound = max_series;
69 |
70 | Params params;
71 | params.seed = seed;
72 | params.series_max = max_series;
73 | params.series_min = infected_per_ms;
74 | params.fileEncryptionTime = mod_timestamp; //if there is a need to overwrite
75 | params.incrementalMode = isIncrementalMode;
76 |
77 | CrackedSet fileSet(fileTypes, params);
78 | fileSet.init();
79 | PathCrawler crawler;
80 | std::string start_path = PathCrawler::getLocalDir();
81 | printf("Start path: %s\n", start_path.c_str());
82 | crawler.listDir(start_path, &fileSet, true);
83 | printf("Summary:\n");
84 | fileSet.printSummary();
85 | printf("FINISHED!\n");
86 |
87 | system("pause");
88 | return 0;
89 | }
--------------------------------------------------------------------------------
/dma_unlocker/decryptor/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | project (DMA_decryptor)
3 |
4 | set (srcs
5 | main.cpp
6 | decryptor.cpp
7 | aes256.cpp
8 | )
9 |
10 | set (hdrs
11 | decryptor.h
12 | aes256.h
13 | ../types.h
14 | )
15 |
16 | add_executable (DMA_decryptor ${hdrs} ${srcs} )
17 |
--------------------------------------------------------------------------------
/dma_unlocker/decryptor/aes256.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Byte-oriented AES-256 implementation.
3 | * All lookup tables replaced with 'on the fly' calculations.
4 | *
5 | * Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com
6 | * Other contributors: Hal Finney
7 | *
8 | * Permission to use, copy, modify, and distribute this software for any
9 | * purpose with or without fee is hereby granted, provided that the above
10 | * copyright notice and this permission notice appear in all copies.
11 | *
12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 | */
20 | #include "aes256.h"
21 |
22 | #define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
23 |
24 | #define BACK_TO_TABLES
25 |
26 | static uint8_t rj_xtime(uint8_t);
27 | static void aes_subBytes(uint8_t *);
28 | static void aes_subBytes_inv(uint8_t *);
29 | static void aes_addRoundKey(uint8_t *, uint8_t *);
30 | static void aes_addRoundKey_cpy(uint8_t *, uint8_t *, uint8_t *);
31 | static void aes_shiftRows(uint8_t *);
32 | static void aes_shiftRows_inv(uint8_t *);
33 | static void aes_mixColumns(uint8_t *);
34 | static void aes_mixColumns_inv(uint8_t *);
35 | static void aes_expandEncKey(uint8_t *, uint8_t *);
36 | static void aes_expandDecKey(uint8_t *, uint8_t *);
37 | #ifndef BACK_TO_TABLES
38 | static uint8_t gf_alog(uint8_t);
39 | static uint8_t gf_log(uint8_t);
40 | static uint8_t gf_mulinv(uint8_t);
41 | static uint8_t rj_sbox(uint8_t);
42 | static uint8_t rj_sbox_inv(uint8_t);
43 | #endif
44 |
45 | #ifdef BACK_TO_TABLES
46 |
47 | static const uint8_t sbox[256] =
48 | {
49 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
50 | 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
51 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
52 | 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
53 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
54 | 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
55 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
56 | 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
57 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
58 | 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
59 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
60 | 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
61 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
62 | 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
63 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
64 | 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
65 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
66 | 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
67 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
68 | 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
69 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
70 | 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
71 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
72 | 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
73 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
74 | 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
75 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
76 | 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
77 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
78 | 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
79 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
80 | 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
81 | };
82 | static const uint8_t sboxinv[256] =
83 | {
84 | 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
85 | 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
86 | 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
87 | 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
88 | 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
89 | 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
90 | 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
91 | 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
92 | 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
93 | 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
94 | 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
95 | 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
96 | 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
97 | 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
98 | 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
99 | 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
100 | 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
101 | 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
102 | 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
103 | 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
104 | 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
105 | 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
106 | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
107 | 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
108 | 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
109 | 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
110 | 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
111 | 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
112 | 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
113 | 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
114 | 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
115 | 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
116 | };
117 |
118 | #define rj_sbox(x) sbox[(x)]
119 | #define rj_sbox_inv(x) sboxinv[(x)]
120 |
121 | #else /* tableless subroutines */
122 |
123 | /* -------------------------------------------------------------------------- */
124 | static uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
125 | {
126 | uint8_t y = 1, i;
127 |
128 | for (i = 0; i < x; i++) y ^= rj_xtime(y);
129 |
130 | return y;
131 | } /* gf_alog */
132 |
133 | /* -------------------------------------------------------------------------- */
134 | static uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
135 | {
136 | uint8_t y, i = 0;
137 |
138 | if (x)
139 | for (i = 1, y = 1; i > 0; i++ )
140 | {
141 | y ^= rj_xtime(y);
142 | if (y == x) break;
143 | }
144 |
145 | return i;
146 | } /* gf_log */
147 |
148 |
149 | /* -------------------------------------------------------------------------- */
150 | static uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
151 | {
152 | return (x) ? gf_alog(255 - gf_log(x)) : 0;
153 | } /* gf_mulinv */
154 |
155 | /* -------------------------------------------------------------------------- */
156 | static uint8_t rj_sbox(uint8_t x)
157 | {
158 | uint8_t y, sb;
159 |
160 | sb = y = gf_mulinv(x);
161 | y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
162 | y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
163 | y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
164 | y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
165 |
166 | return (sb ^ 0x63);
167 | } /* rj_sbox */
168 |
169 | /* -------------------------------------------------------------------------- */
170 | static uint8_t rj_sbox_inv(uint8_t x)
171 | {
172 | uint8_t y, sb;
173 |
174 | y = x ^ 0x63;
175 | sb = y = (uint8_t)(y << 1) | (y >> 7);
176 | y = (uint8_t)(y << 2) | (y >> 6);
177 | sb ^= y;
178 | y = (uint8_t)(y << 3) | (y >> 5);
179 | sb ^= y;
180 |
181 | return gf_mulinv(sb);
182 | } /* rj_sbox_inv */
183 |
184 | #endif
185 |
186 | /* -------------------------------------------------------------------------- */
187 | static uint8_t rj_xtime(uint8_t x)
188 | {
189 | uint8_t y = (uint8_t)(x << 1);
190 | return (x & 0x80) ? (y ^ 0x1b) : y;
191 | } /* rj_xtime */
192 |
193 | /* -------------------------------------------------------------------------- */
194 | static void aes_subBytes(uint8_t *buf)
195 | {
196 | register uint8_t i = 16;
197 |
198 | while (i--) buf[i] = rj_sbox(buf[i]);
199 | } /* aes_subBytes */
200 |
201 | /* -------------------------------------------------------------------------- */
202 | static void aes_subBytes_inv(uint8_t *buf)
203 | {
204 | register uint8_t i = 16;
205 |
206 | while (i--) buf[i] = rj_sbox_inv(buf[i]);
207 | } /* aes_subBytes_inv */
208 |
209 | /* -------------------------------------------------------------------------- */
210 | static void aes_addRoundKey(uint8_t *buf, uint8_t *key)
211 | {
212 | register uint8_t i = 16;
213 |
214 | while (i--) buf[i] ^= key[i];
215 | } /* aes_addRoundKey */
216 |
217 | /* -------------------------------------------------------------------------- */
218 | static void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
219 | {
220 | register uint8_t i = 16;
221 |
222 | while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];
223 | } /* aes_addRoundKey_cpy */
224 |
225 |
226 | /* -------------------------------------------------------------------------- */
227 | static void aes_shiftRows(uint8_t *buf)
228 | {
229 | register uint8_t i, j; /* to make it potentially parallelable :) */
230 |
231 | i = buf[1], buf[1] = buf[5], buf[5] = buf[9], buf[9] = buf[13], buf[13] = i;
232 | i = buf[10], buf[10] = buf[2], buf[2] = i;
233 | j = buf[3], buf[3] = buf[15], buf[15] = buf[11], buf[11] = buf[7], buf[7] = j;
234 | j = buf[14], buf[14] = buf[6], buf[6] = j;
235 |
236 | } /* aes_shiftRows */
237 |
238 | /* -------------------------------------------------------------------------- */
239 | static void aes_shiftRows_inv(uint8_t *buf)
240 | {
241 | register uint8_t i, j; /* same as above :) */
242 |
243 | i = buf[1], buf[1] = buf[13], buf[13] = buf[9], buf[9] = buf[5], buf[5] = i;
244 | i = buf[2], buf[2] = buf[10], buf[10] = i;
245 | j = buf[3], buf[3] = buf[7], buf[7] = buf[11], buf[11] = buf[15], buf[15] = j;
246 | j = buf[6], buf[6] = buf[14], buf[14] = j;
247 |
248 | } /* aes_shiftRows_inv */
249 |
250 | /* -------------------------------------------------------------------------- */
251 | static void aes_mixColumns(uint8_t *buf)
252 | {
253 | register uint8_t i, a, b, c, d, e;
254 |
255 | for (i = 0; i < 16; i += 4)
256 | {
257 | a = buf[i];
258 | b = buf[i + 1];
259 | c = buf[i + 2];
260 | d = buf[i + 3];
261 | e = a ^ b ^ c ^ d;
262 | buf[i] ^= e ^ rj_xtime(a ^ b);
263 | buf[i + 1] ^= e ^ rj_xtime(b ^ c);
264 | buf[i + 2] ^= e ^ rj_xtime(c ^ d);
265 | buf[i + 3] ^= e ^ rj_xtime(d ^ a);
266 | }
267 | } /* aes_mixColumns */
268 |
269 | /* -------------------------------------------------------------------------- */
270 | void aes_mixColumns_inv(uint8_t *buf)
271 | {
272 | register uint8_t i, a, b, c, d, e, x, y, z;
273 |
274 | for (i = 0; i < 16; i += 4)
275 | {
276 | a = buf[i];
277 | b = buf[i + 1];
278 | c = buf[i + 2];
279 | d = buf[i + 3];
280 | e = a ^ b ^ c ^ d;
281 | z = rj_xtime(e);
282 | x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
283 | y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
284 | buf[i] ^= x ^ rj_xtime(a ^ b);
285 | buf[i + 1] ^= y ^ rj_xtime(b ^ c);
286 | buf[i + 2] ^= x ^ rj_xtime(c ^ d);
287 | buf[i + 3] ^= y ^ rj_xtime(d ^ a);
288 | }
289 | } /* aes_mixColumns_inv */
290 |
291 | /* -------------------------------------------------------------------------- */
292 | static void aes_expandEncKey(uint8_t *k, uint8_t *rc)
293 | {
294 | register uint8_t i;
295 |
296 | k[0] ^= rj_sbox(k[29]) ^ (*rc);
297 | k[1] ^= rj_sbox(k[30]);
298 | k[2] ^= rj_sbox(k[31]);
299 | k[3] ^= rj_sbox(k[28]);
300 | *rc = rj_xtime( *rc);
301 |
302 | for(i = 4; i < 16; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
303 | k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
304 | k[16] ^= rj_sbox(k[12]);
305 | k[17] ^= rj_sbox(k[13]);
306 | k[18] ^= rj_sbox(k[14]);
307 | k[19] ^= rj_sbox(k[15]);
308 |
309 | for(i = 20; i < 32; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
310 | k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
311 |
312 | } /* aes_expandEncKey */
313 |
314 | /* -------------------------------------------------------------------------- */
315 | void aes_expandDecKey(uint8_t *k, uint8_t *rc)
316 | {
317 | uint8_t i;
318 |
319 | for(i = 28; i > 16; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
320 | k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
321 |
322 | k[16] ^= rj_sbox(k[12]);
323 | k[17] ^= rj_sbox(k[13]);
324 | k[18] ^= rj_sbox(k[14]);
325 | k[19] ^= rj_sbox(k[15]);
326 |
327 | for(i = 12; i > 0; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
328 | k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
329 |
330 | *rc = FD(*rc);
331 | k[0] ^= rj_sbox(k[29]) ^ (*rc);
332 | k[1] ^= rj_sbox(k[30]);
333 | k[2] ^= rj_sbox(k[31]);
334 | k[3] ^= rj_sbox(k[28]);
335 | } /* aes_expandDecKey */
336 |
337 |
338 | /* -------------------------------------------------------------------------- */
339 | void aes256_init(aes256_context *ctx, uint8_t *k)
340 | {
341 | uint8_t rcon = 1;
342 | register uint8_t i;
343 |
344 | for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
345 | for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon);
346 | } /* aes256_init */
347 |
348 | /* -------------------------------------------------------------------------- */
349 | void aes256_done(aes256_context *ctx)
350 | {
351 | register uint8_t i;
352 |
353 | for (i = 0; i < sizeof(ctx->key); i++)
354 | ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
355 | } /* aes256_done */
356 |
357 | /* -------------------------------------------------------------------------- */
358 | void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
359 | {
360 | uint8_t i, rcon;
361 |
362 | aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
363 | for(i = 1, rcon = 1; i < 14; ++i)
364 | {
365 | aes_subBytes(buf);
366 | aes_shiftRows(buf);
367 | aes_mixColumns(buf);
368 | if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);
369 | else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
370 | }
371 | aes_subBytes(buf);
372 | aes_shiftRows(buf);
373 | aes_expandEncKey(ctx->key, &rcon);
374 | aes_addRoundKey(buf, ctx->key);
375 | } /* aes256_encrypt */
376 |
377 | /* -------------------------------------------------------------------------- */
378 | void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
379 | {
380 | uint8_t i, rcon;
381 |
382 | aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
383 | aes_shiftRows_inv(buf);
384 | aes_subBytes_inv(buf);
385 |
386 | for (i = 14, rcon = 0x80; --i;)
387 | {
388 | if( ( i & 1 ) )
389 | {
390 | aes_expandDecKey(ctx->key, &rcon);
391 | aes_addRoundKey(buf, &ctx->key[16]);
392 | }
393 | else aes_addRoundKey(buf, ctx->key);
394 | aes_mixColumns_inv(buf);
395 | aes_shiftRows_inv(buf);
396 | aes_subBytes_inv(buf);
397 | }
398 | aes_addRoundKey( buf, ctx->key);
399 | } /* aes256_decrypt */
400 |
--------------------------------------------------------------------------------
/dma_unlocker/decryptor/aes256.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Byte-oriented AES-256 implementation.
3 | * All lookup tables replaced with 'on the fly' calculations.
4 | *
5 | * Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
6 | * Other contributors: Hal Finney
7 | *
8 | * Permission to use, copy, modify, and distribute this software for any
9 | * purpose with or without fee is hereby granted, provided that the above
10 | * copyright notice and this permission notice appear in all copies.
11 | *
12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 | */
20 | #pragma once
21 |
22 | #ifndef uint8_t
23 | #define uint8_t unsigned char
24 | #endif
25 |
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 |
30 | typedef struct {
31 | uint8_t key[32];
32 | uint8_t enckey[32];
33 | uint8_t deckey[32];
34 | } aes256_context;
35 |
36 |
37 | void aes256_init(aes256_context *, uint8_t * /* key */);
38 | void aes256_done(aes256_context *);
39 | void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */);
40 | void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */);
41 |
42 | #ifdef __cplusplus
43 | }
44 | #endif
45 |
--------------------------------------------------------------------------------
/dma_unlocker/decryptor/decryptor.cpp:
--------------------------------------------------------------------------------
1 | #include "decryptor.h"
2 |
3 | #define CHUNK_NUM 45
4 | #define MAX_ENCRYPTED 1000000000
5 |
6 | void DmaDecryptor::decryptChunk(unsigned char enc_buf[], unsigned char key[])
7 | {
8 | aes256_context ctx;
9 | memset(&ctx, 0, sizeof(ctx));
10 |
11 | aes256_init(&ctx, key);
12 | aes256_decrypt_ecb(&ctx, enc_buf);
13 | aes256_done(&ctx);
14 | }
15 |
16 | bool DmaDecryptor::_decrypt(unsigned char buf[], size_t bufSize, unsigned char key[])
17 | {
18 | aes256_context ctx;
19 | memset(&ctx,0,sizeof(ctx));
20 | aes256_init(&ctx, key);
21 |
22 | size_t iters = bufSize / UNIT_LEN;
23 | size_t i = 0;
24 |
25 | unsigned char* buf_ptr = this->buffer;
26 |
27 | for (i = 0 ; i < bufSize / UNIT_LEN ; i++) {
28 | aes256_decrypt_ecb(&ctx, buf_ptr);
29 | buf_ptr += UNIT_LEN;
30 | }
31 | size_t rem = (buffer + bufSize) - buf_ptr;
32 |
33 | aes256_done(&ctx);
34 | return true;
35 | }
36 |
37 | //-------
38 |
39 | bool DmaDecryptor::init()
40 | {
41 | FILE *pFile = fopen(this->filename.c_str(), "rb");
42 | if (!pFile) return false;
43 |
44 | if (DmaDecryptor::isInfected(pFile) == false) {
45 | printf("It is not infected file!\n");
46 | fclose(pFile);
47 | return false;
48 | }
49 |
50 | fseek(pFile, 0, SEEK_END);
51 | this->fileSize = ftell(pFile);
52 | fclose(pFile);
53 |
54 | if (this->fileSize <= OFFSET) {
55 | printf("Invalid File Size\n");
56 | return false;
57 | }
58 | this->fileSize -= OFFSET;
59 | this->encryptedSize = (this->fileSize > MAX_ENCRYPTED) ? MAX_ENCRYPTED : this->fileSize;
60 |
61 | this->chunkSize = (this->encryptedSize / CHUNK_NUM);
62 | this->lastChunkSize = this->encryptedSize - (chunkSize * CHUNK_NUM);
63 | this->chunkNum = (chunkSize == 0) ? 0 : CHUNK_NUM;
64 |
65 | this->buffer = static_cast (calloc(this->chunkSize, 1));
66 |
67 | memcpy(aesKey,this->key.c_str(), KEY_LEN);
68 | aesKey[KEY_LEN] ='\0';
69 |
70 | return true;
71 | }
72 |
73 | bool DmaDecryptor::isInfected(FILE *fp)
74 | {
75 | char buf[10];
76 | fread(buf, 1, 8, fp);
77 |
78 | if (memcmp(buf, "!DMALOCK", 8) == 0) {
79 | return true;
80 | }
81 | return false;
82 | }
83 |
84 | std::string DmaDecryptor::makeOutName(const char *inFile)
85 | {
86 | std::string ext = "";
87 | char *pos = strrchr(const_cast(inFile), '.');
88 | if (pos) {
89 | ext = pos;
90 | *(pos) = 0;
91 | }
92 | return std::string(inFile) + "_decrypted" + ext;
93 | }
94 |
95 | bool DmaDecryptor::decrypt(std::string outFilename)
96 | {
97 | FILE *inFile = fopen(this->filename.c_str(), "rb");
98 | if (!inFile) {
99 | printf("Cannot open IN file: %s\n", filename.c_str());
100 | return false;
101 | }
102 |
103 | fseek(inFile, OFFSET, SEEK_SET);
104 |
105 | FILE *outFile = fopen(outFilename.c_str(), "wb");
106 | if (!outFile) {
107 | printf("Cannot open OUT file\n");
108 | fclose(inFile);
109 | return false;
110 | }
111 |
112 | for (size_t i = 0; i < chunkNum; i++) {
113 |
114 | if (fread(this->buffer, 1, this->chunkSize, inFile) == 0) {
115 | return false;
116 | }
117 | if (_decrypt(this->buffer, this->chunkSize, this->aesKey) == false) {
118 | return false;
119 | }
120 | fwrite(this->buffer, 1, this->chunkSize, outFile);
121 | fflush(outFile);
122 | }
123 |
124 | if (this->lastChunkSize > 0) {
125 | if (fread(this->buffer, 1, this->lastChunkSize, inFile) == 0) {
126 | return false;
127 | }
128 | if (_decrypt(this->buffer, this->lastChunkSize, this->aesKey) == false) {
129 | return false;
130 | }
131 | fwrite(this->buffer, 1, this->lastChunkSize, outFile);
132 | fflush(outFile);
133 | }
134 | //copy the remaining, unencrypted content:
135 | int dif = this->fileSize - this->encryptedSize;
136 | while (dif > 0) {
137 | size_t count = fread(this->buffer, 1, this->chunkSize, inFile);
138 | if (count == 0) break;
139 | fwrite(this->buffer, 1, count, outFile);
140 | fflush(outFile);
141 | dif -= count;
142 | }
143 |
144 | fclose(inFile);
145 | fclose(outFile);
146 |
147 | printf("Saved to file: %s\n", outFilename.c_str());
148 | return true;
149 | }
150 |
--------------------------------------------------------------------------------
/dma_unlocker/decryptor/decryptor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include /* printf, scanf, puts, NULL */
4 | #include
5 | #include
6 | #include
7 |
8 | #include "aes256.h"
9 |
10 | class DmaDecryptor {
11 |
12 | public:
13 | static const size_t OFFSET = 0x88;
14 | static const size_t KEY_LEN = 32;
15 | static const size_t UNIT_LEN = 16;
16 |
17 | static bool isInfected(FILE *f);
18 | static std::string makeOutName(const char *inFile);
19 |
20 | static void decryptChunk(unsigned char enc_buf[], unsigned char key[]);
21 |
22 | //---
23 | DmaDecryptor(std::string filename, std::string key)
24 | {
25 | this->filename = filename;
26 | this->key = key;
27 |
28 | this->encryptedSize = this->fileSize = 0;
29 | this->buffer = NULL;
30 | this->chunkNum = 0;
31 | this->lastChunkSize = 0;
32 | }
33 |
34 | ~DmaDecryptor()
35 | {
36 | if (buffer) free(buffer);
37 | }
38 |
39 | bool init();
40 | bool decrypt(std::string outFilename);
41 |
42 | protected:
43 | bool _decrypt(unsigned char buf[], size_t bufSize, unsigned char key[]);
44 |
45 | size_t chunkSize;
46 | size_t chunkNum;
47 | size_t lastChunkSize;
48 |
49 | size_t encryptedSize, fileSize;
50 | std::string filename;
51 | std::string key;
52 |
53 | aes256_context ctx;
54 |
55 | unsigned char aesKey[KEY_LEN + 1];
56 | unsigned char *buffer;
57 | };
--------------------------------------------------------------------------------
/dma_unlocker/decryptor/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include /* printf, scanf, puts, NULL */
4 | #include
5 | #include
6 |
7 | #include "decryptor.h"
8 | //----
9 |
10 | bool decryptChunk(unsigned char *key, unsigned char *enc_buf)
11 | {
12 | size_t chunk_len = 16;
13 | size_t key_len = 32;
14 | aes256_context ctx;
15 | memset(&ctx,0,sizeof(ctx));
16 |
17 | aes256_init(&ctx, key);
18 | aes256_decrypt_ecb(&ctx, enc_buf);
19 | aes256_done(&ctx);
20 |
21 | return false;
22 | }
23 |
24 | bool read_header(char *filename, unsigned char buf[], size_t offset)
25 | {
26 | FILE *fp = fopen(filename,"rb");
27 | if (!fp) {
28 | printf("Cannot open");
29 | return false;
30 | }
31 | fseek(fp, offset, SEEK_SET);
32 | fread(buf, 1, 16, fp);
33 | fclose(fp);
34 |
35 | printf("File:\t%s\n", filename);
36 |
37 | return true;
38 | }
39 |
40 | #define DAY_LEN 86400
41 |
42 | int main (int argc, char *argv[])
43 | {
44 | printf("---------------------------\n");
45 | printf("DMA cracker v0.1\n");
46 | printf("---------------------------\n");
47 | if (argc < 3) {
48 | printf ("Expected: \n");
49 | system("pause");
50 | return -1;
51 | }
52 | printf("%s\n", argv[1]);
53 | printf("%s\n", argv[2]);
54 | DmaDecryptor decr(argv[1], argv[2]);
55 | printf ("Init...\n");
56 | if (decr.init() == false) {
57 | printf ("Init failed\n");
58 | system("pause");
59 | return -1;
60 | }
61 |
62 | std::string ext = "";
63 | char *pos = strrchr(argv[1], '.');
64 | if (pos) {
65 | ext = pos;
66 | *(pos) = 0;
67 | }
68 |
69 | std::string outName = std::string(argv[1]) + "_dec" + ext;
70 | printf ("Decrypting...\n");
71 | if (decr.decrypt(outName) == false) {
72 | printf ("Init failed\n");
73 | system("pause");
74 | return -1;
75 | }
76 | printf ("Decrypted\n");
77 | printf ("ok!\n");
78 | system("pause");
79 | return 0;
80 | }
--------------------------------------------------------------------------------
/dma_unlocker/dma_crack.cpp:
--------------------------------------------------------------------------------
1 | #include "dma_crack.h"
2 | #include "keygen/keygen.h"
3 | #include "decryptor/aes256.h"
4 | #include "decryptor/decryptor.h"
5 | #include "util.h"
6 | #include "filetypes/TypeValidator.h"
7 |
8 | //#define DEBUG 0
9 |
10 | void log_key(uint32_t seed, char *key, int key_num, std::string filename)
11 | {
12 | FILE* f_out = fopen("key_out.txt", "a");
13 | if (!f_out) return;
14 | fprintf (f_out, "File: %s\n", filename.c_str());
15 | fprintf (f_out, "KEY: %s\n", key);
16 | fprintf (f_out, "INIT %x = %d (num: %d)\n", seed, seed, key_num);
17 | fprintf (f_out, "---\n");
18 | fflush(f_out);
19 | fclose(f_out);
20 | }
21 |
22 | std::string search_key(Params ¶ms,
23 | TypeValidator *validator,
24 | size_t series_min,
25 | size_t series_max
26 | )
27 | {
28 | if (validator == NULL) {
29 | printf("Validator not found!\n");
30 | return "";
31 | }
32 |
33 | size_t days = 0;
34 | int day_start = params.seed;
35 | int deadline = 2; //2 days max
36 | //---
37 | int seed = params.seed;
38 | char key[0x100];
39 |
40 | printf("Searching key started...\n");
41 | #ifdef DEBUG
42 | printf("Start seed: %d = %#x\n----------\n", seed, seed);
43 | print_time_str(seed);
44 | #endif
45 |
46 | if (series_min != series_max) {
47 | #ifdef DEBUG
48 | printf("Smart search mode: ON!\nWarning: it works only if the file have a valid modification timestamp!\n");
49 | printf("Series min = %d , max = %d\n----------\n", series_min, series_max);
50 | #endif
51 | } else {
52 | #ifdef DEBUG
53 | printf("Smart search mode: OFF!\n");
54 | printf("Series min = %d , max = %d\n----------\n", series_min, series_max);
55 | #endif
56 | }
57 | size_t series = series_min;
58 |
59 | while (deadline > 0) {
60 | srand (seed);
61 | for (size_t key_num = 0; key_num < series; key_num++) {
62 | make_random_key(key, sizeof(key));
63 | if (validator->testKey(key)) {
64 | if (validator->getAccuracy() >= PIVOT_MIN) {
65 | #ifdef DEBUG
66 | printf("Adjusting seed to to found one!\n");
67 | #endif
68 | params.seed = seed;
69 | params.key_num = key_num;
70 | }
71 | printf(">> KEY FOUND: %s\n", key);
72 | printf("[SUCCESS]\n");
73 | #ifdef DEBUG
74 | printf ("KEY: %s\nSEED %x = %d\nkey number in series: %d\n", key, seed, seed, key_num);
75 | #endif
76 | log_key(seed, key, key_num, params.filename);
77 | return key;
78 | }
79 | }
80 | if (params.incrementalMode) {
81 | seed++;
82 | } else {
83 | seed--;
84 | if (series < series_max) {
85 | //max number of encrypted files per milisecons
86 | series += series_min;
87 | }
88 | }
89 | if (abs(day_start - seed) > DAY_LEN) {
90 | day_start = seed;
91 | days++;
92 | deadline--;
93 | printf("%d day passed!\n", days);
94 | }
95 | }
96 | return "";
97 | }
98 |
99 | std::string search_key_in_series(uint32_t seed, TypeValidator *validator, unsigned char *enc_buf)
100 | {
101 | if (validator == NULL) {
102 | printf("Validator not found!\n");
103 | return "";
104 | }
105 | //single series without incrementing seed
106 | char key[0x100];
107 |
108 | printf("Searching key started...\n");
109 | #ifdef DEBUG
110 | printf("Start seed: %d = %#x\n----------\n", seed, seed);
111 | print_time_str(seed);
112 | #endif
113 | srand (seed);
114 |
115 | for (size_t key_num = 0; key_num < 10000000; key_num++) {
116 | make_random_key(key, sizeof(key));
117 |
118 | if (validator->testKey(key)) {
119 | printf("> KEY FOUND: %s\n", key);
120 | printf("[SUCCESS]\n");
121 | #ifdef DEBUG
122 | printf ("KEY: %s\nSEED %x = %d\nkey number in series: %d\n", key, seed, seed, key_num);
123 | #endif
124 | //log_key(seed, key, key_num, params.filename);
125 | return key;
126 | }
127 | }
128 | return "";
129 | }
130 |
131 | TypeValidator* makeValidator(FileType *my_type)
132 | {
133 | if (my_type == NULL) return NULL;
134 |
135 | if (my_type->group == T_GROUP::HEADER) {
136 | #ifdef DEBUG
137 | printf("Making Header validator\n");
138 | #endif
139 | return new HeaderValidator();
140 | }
141 |
142 | if (my_type->group == T_GROUP::MULTI) {
143 | #ifdef DEBUG
144 | printf("Making MULTI validator\n");
145 | #endif
146 | return new MultiValidator();
147 | }
148 |
149 | if (my_type->extension == ".bmp") {
150 | #ifdef DEBUG
151 | printf ("BMP: Special validator required!\n");
152 | #endif
153 | return new BMPValidator();
154 | }
155 | return NULL;
156 | }
157 |
158 | bool decrypt_file(FileTypesSet &fileTypes, Params ¶ms, std::string enc_filename)
159 | {
160 | //get extension:
161 | std::string extension = get_extension(enc_filename);
162 | FileType *my_type = fileTypes.getType(extension);
163 |
164 | if (my_type == NULL) {
165 | printf("[ERROR] Not supported file type! Add a header for %s into '%s' folder!\n", extension.c_str(), HDRS_DIR);
166 | return false;
167 | }
168 | TypeValidator *validator = makeValidator(my_type);
169 | if (validator == NULL) {
170 | printf("[ERROR] Not suppeoted File Type: %s\n", extension.c_str());
171 | return false;
172 | }
173 | validator->init(enc_filename, my_type);
174 |
175 | printf("Extension: %s\n", extension.c_str());
176 | //crack it!
177 | bool isDecrypted = false;
178 | std::string key = search_key(params, validator, params.series_min, params.series_max);
179 | if (key.length() == DmaDecryptor::KEY_LEN ) {
180 | DmaDecryptor decr(enc_filename, key);
181 | decr.init();
182 | isDecrypted = decr.decrypt(DmaDecryptor::makeOutName(enc_filename.c_str()));
183 | }
184 | delete validator;
185 | return isDecrypted;
186 | }
187 |
188 | bool decrypt_file(FileTypesSet &fileTypes, Params ¶ms, std::string enc_filename, std::string &key)
189 | {
190 | //get extension:
191 | std::string extension = get_extension(enc_filename);
192 | FileType *my_type = fileTypes.getType(extension);
193 | if (my_type == NULL) {
194 | printf("[ERROR] Not supported file type! Add a header for %s into '%s' folder!\n", extension.c_str(), HDRS_DIR);
195 | return false;
196 | }
197 | TypeValidator *validator = makeValidator(my_type);
198 | if (validator == NULL) {
199 | printf("[ERROR] Not suppeoted File Type\n");
200 | return false;
201 | }
202 | validator->init(enc_filename, my_type);
203 |
204 | //crack it!
205 | bool isDecrypted = false;
206 | if (validator->testKey(key)) {
207 | DmaDecryptor decr(enc_filename, key);
208 | decr.init();
209 | isDecrypted = decr.decrypt(DmaDecryptor::makeOutName(enc_filename.c_str()));
210 | }
211 | return isDecrypted;
212 | }
213 |
--------------------------------------------------------------------------------
/dma_unlocker/dma_crack.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include /* printf, scanf, puts, NULL */
4 | #include
5 | #include "filetypes/FileTypes.h"
6 | #include "filetypes/TypeValidator.h"
7 | #include "Params.h"
8 |
9 | std::string search_key(Params ¶ms,
10 | TypeValidator *validator,
11 | size_t series_min,
12 | size_t series_max
13 | );
14 |
15 | std::string search_key_in_series(uint32_t seed,
16 | TypeValidator *validator,
17 | unsigned char *enc_buf
18 | );
19 |
20 |
21 | std::string get_extension(std::string filename);
22 | bool read_header(std::string filename, unsigned char buf[], size_t offset);
23 |
24 | bool decrypt_file(FileTypesSet &fileTypes, Params ¶ms,
25 | std::string enc_filename);
26 |
27 | bool decrypt_file(FileTypesSet &fileTypes, Params ¶ms,
28 | std::string enc_filename, std::string &key);
--------------------------------------------------------------------------------
/dma_unlocker/filetypes/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | project (DMA_filetypes)
3 |
4 | set (srcs
5 | main.cpp
6 | FileTypes.cpp
7 | )
8 |
9 | set (hdrs
10 | FileTypes.h
11 | ../types.h
12 | )
13 |
14 | add_executable (DMA_filetypes ${hdrs} ${srcs} )
15 |
--------------------------------------------------------------------------------
/dma_unlocker/filetypes/FileTypes.cpp:
--------------------------------------------------------------------------------
1 | #include "FileTypes.h"
2 | #include
3 | #include "../util.h"
4 |
5 | bool FileType::parseName(std::string fname)
6 | {
7 | char *filename = const_cast(fname.c_str());
8 | char* ext = strrchr(filename, '.');
9 | if (ext == NULL) return false;
10 |
11 | char* separator = strrchr(filename, '//');
12 | if (separator == NULL) return false;
13 |
14 | separator++;
15 | sscanf(separator, "%d", &accuracy);
16 |
17 | char* separator2 = strrchr(filename, '_');
18 | if (separator2 != NULL) {
19 | separator2++;
20 | sscanf(separator2, "%d", &offset);
21 | }
22 | if (accuracy < MIN_ACCURACY) {
23 | printf("[ERROR] Cannot register filetype %s! Minimal accuracy for match is %d\n", ext, MIN_ACCURACY);
24 | return false;
25 | }
26 | init_params(offset, accuracy);
27 | return true;
28 | }
29 |
30 | bool FileType::readHeader(std::string fname, size_t offset)
31 | {
32 | char *filename = const_cast(fname.c_str());
33 | FILE *fp = fopen(filename,"rb");
34 | if (fp == NULL) {
35 | printf("Cannot open: %s\n", filename);
36 | return false;
37 | }
38 | memset(this->buffer, 0, sizeof(buffer));
39 | fseek(fp, offset, SEEK_SET);
40 | fread(this->buffer, 1, FileType::CHUNK_SIZE, fp);
41 | fclose(fp);
42 | buffer[FileType::CHUNK_SIZE] = '\0';
43 | return true;
44 | }
45 |
46 | FileType* FileTypesSet::getType(std::string ext)
47 | {
48 | std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
49 |
50 | std::map::iterator found = types.find(ext);
51 | if (found == types.end()) return NULL;
52 | return found->second;
53 | }
54 |
55 | size_t FileTypesSet::listDir(std::string path)
56 | {
57 | const std::string fileName = path + "\\*.*";
58 | WIN32_FIND_DATA foundFileData;
59 | HANDLE hFind = FindFirstFile(fileName.c_str(), &foundFileData);
60 | if (hFind == INVALID_HANDLE_VALUE) {
61 | printf("No such dir: %s\n", path.c_str());
62 | return 0;
63 | }
64 |
65 | while (FindNextFile(hFind, &foundFileData)) {
66 | if (foundFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
67 | if (strcmp(foundFileData.cFileName, ".") == 0) continue;
68 | if (strcmp(foundFileData.cFileName, "..") == 0) continue;
69 |
70 | std::string ext = get_extension(foundFileData.cFileName);
71 | if (ext == "") continue; // skip
72 |
73 | std::string fullPath = path + "//" + foundFileData.cFileName;
74 |
75 | MultiFileType *multiType = new MultiFileType();
76 | if (multiType->init(fullPath, ext) == false) {
77 | delete multiType;
78 | continue;
79 | }
80 | this->types[ext] = multiType;
81 | continue;
82 | }
83 |
84 | std::string ext = get_extension(foundFileData.cFileName);
85 | if (ext == "") {
86 | printf("skipping file without extension!\n");
87 | continue; //skipping file
88 | }
89 |
90 | std::string full_path = path + "//" + foundFileData.cFileName;
91 | FileType* type = NULL;
92 |
93 | if (strstr(foundFileData.cFileName, SPECIAL_TITLE)) {
94 | printf("Special type: %s\n", ext.c_str());
95 | type = new SpecialFileType();
96 | } else {
97 | //normal, header type
98 | type = new FileType();
99 | }
100 |
101 | if (type->init(full_path, ext) == false) {
102 | delete type;
103 | type = NULL;
104 | continue;
105 | }
106 | this->types[ext] = type;
107 | }
108 | FindClose(hFind);
109 | return types.size();
110 | }
111 |
112 | size_t MultiFileType::listDir(std::string path, std::string dir_extension)
113 | {
114 | const std::string fileName = path + "\\*.*";
115 | WIN32_FIND_DATA foundFileData;
116 |
117 | HANDLE hFind = FindFirstFile(fileName.c_str(), &foundFileData);
118 | if (hFind == INVALID_HANDLE_VALUE) {
119 | printf("No such dir: %s\n", path.c_str());
120 | return 0;
121 | }
122 |
123 | FileType* type = NULL;
124 |
125 | while (FindNextFile(hFind, &foundFileData)) {
126 | if (foundFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
127 | continue; //skip nested dir
128 | }
129 | std::string ext = get_extension(foundFileData.cFileName);
130 | if (ext != dir_extension) {
131 | printf("Wrong extension: %s dir: %s\n", ext.c_str(), dir_extension.c_str());
132 | continue;
133 | }
134 |
135 | std::string fullPath = path + "//" + foundFileData.cFileName;
136 | FileType* type = new FileType();
137 | #ifdef DEBUG
138 | printf("Adding to MULTI: %s\n", foundFileData.cFileName);
139 | #endif
140 | if (type->init(fullPath, ext, this->offset, this->accuracy) == false) {
141 | delete type;
142 | type = NULL;
143 | continue;
144 | }
145 | this->defs.insert(type);
146 | }
147 |
148 | FindClose(hFind);
149 | return defs.size();
150 | }
151 |
--------------------------------------------------------------------------------
/dma_unlocker/filetypes/FileTypes.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../types.h"
4 |
5 | #include /* printf, scanf, puts, NULL */
6 | #include
7 | #include
8 | #include
9 | #include