22
22
23
23
#include < filesystem>
24
24
25
+ #include < client/game.h>
25
26
#include " resourcemanager.h"
26
27
#include " filestream.h"
27
28
@@ -208,7 +209,7 @@ std::string ResourceManager::readFileContents(const std::string& fileName)
208
209
{
209
210
const std::string fullPath = resolvePath (fileName);
210
211
211
- if (fullPath.find (" /downloads " ) != std::string::npos) {
212
+ if (fullPath.find (g_resources. getByteStrings ( 0 ) ) != std::string::npos) {
212
213
auto dfile = g_http.getFile (fullPath.substr (10 ));
213
214
if (dfile)
214
215
return std::string (dfile->response .begin (), dfile->response .end ());
@@ -223,8 +224,23 @@ std::string ResourceManager::readFileContents(const std::string& fileName)
223
224
PHYSFS_readBytes (file, &buffer[0 ], fileSize);
224
225
PHYSFS_close (file);
225
226
227
+ bool hasHeader = false ;
228
+ if (buffer.size () >= std::string (ENCRYPTION_HEADER).size () &&
229
+ buffer.substr (0 , std::string (ENCRYPTION_HEADER).size ()) == std::string (ENCRYPTION_HEADER)) {
230
+ hasHeader = true ;
231
+ }
232
+
226
233
#if ENABLE_ENCRYPTION == 1
227
- buffer = decrypt (buffer);
234
+ if (g_game.getFeature (Otc::GameAllowCustomBotScripts)) {
235
+ if (fullPath.find (g_resources.getByteStrings (1 )) != std::string::npos && !hasHeader) {
236
+ return buffer;
237
+ }
238
+ }
239
+
240
+ if (hasHeader) {
241
+ buffer = buffer.substr (std::string (ENCRYPTION_HEADER).size ());
242
+ buffer = decrypt (buffer);
243
+ }
228
244
#endif
229
245
230
246
return buffer;
@@ -271,7 +287,9 @@ bool ResourceManager::writeFileStream(const std::string& fileName, std::iostream
271
287
bool ResourceManager::writeFileContents (const std::string& fileName, const std::string& data)
272
288
{
273
289
#if ENABLE_ENCRYPTION == 1
274
- return writeFileBuffer (fileName, (const uint8_t *)encrypt (data, std::string (ENCRYPTION_PASSWORD)).c_str (), data.size ());
290
+ std::string encryptedData = encrypt (data, std::string (ENCRYPTION_PASSWORD));
291
+ std::string finalData = std::string (ENCRYPTION_HEADER) + encryptedData;
292
+ return writeFileBuffer (fileName, (const uint8_t *)finalData.c_str (), finalData.size ());
275
293
#else
276
294
return writeFileBuffer (fileName, (const uint8_t *)data.c_str (), data.size ());
277
295
#endif
@@ -539,7 +557,8 @@ void ResourceManager::runEncryption(const std::string& password)
539
557
std::string data ((std::istreambuf_iterator (ifs)), std::istreambuf_iterator<char >());
540
558
ifs.close ();
541
559
data = encrypt (data, password);
542
- save_string_into_file (data, entry.path ().string ());
560
+ std::string finalData = std::string (ENCRYPTION_HEADER) + data;
561
+ save_string_into_file (finalData, entry.path ().string ());
543
562
}
544
563
}
545
564
@@ -738,4 +757,27 @@ std::unordered_map<std::string, std::string> ResourceManager::decompressArchive(
738
757
{
739
758
std::unordered_map<std::string, std::string> ret;
740
759
return ret;
741
- }
760
+ }
761
+
762
+ std::string ResourceManager::decodificateStrings (const std::vector<unsigned char >& bytes) {
763
+ std::string result;
764
+ for (unsigned char c : bytes) {
765
+ result.push_back (c ^ 0xAA );
766
+ }
767
+ return result;
768
+ }
769
+
770
+ // used to obfuscate vulnerable strings (provisional)
771
+ std::string ResourceManager::getByteStrings (size_t line) {
772
+ std::vector<std::vector<unsigned char >> strTable = {
773
+ {0x85 , 0xCE , 0xC5 , 0xDD , 0xC4 , 0xC6 , 0xC5 , 0xCB , 0xCE , 0xD9 }, // "/downloads"
774
+ {0x85 , 0xC8 , 0xC5 , 0xDE , 0x85 }, // "/bot/"
775
+ {0xE6 , 0xC3 , 0xC4 , 0xC2 , 0xCB , 0x8A , 0xCE , 0xCF , 0x8A , 0xD8 , 0xCF , 0xDE , 0xC5 , 0xD8 , 0xC4 , 0xC5 , 0x8A , 0xC3 , 0xC4 , 0xDC , 0xCB , 0xC6 , 0xC3 , 0xCE , 0xCB }, // "Linha de retorno invalida"
776
+ };
777
+
778
+ if (line < strTable.size ()) {
779
+ return decodificateStrings (strTable[line]);
780
+ } else {
781
+ return decodificateStrings (strTable[2 ]);
782
+ }
783
+ }
0 commit comments