Skip to content

Commit 682e548

Browse files
committed
Bunch of mem fixes and leaks
1 parent 295e212 commit 682e548

23 files changed

Lines changed: 567 additions & 229 deletions
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package net.rusjj;
22
public class amlcore
33
{
4-
public native void launchAMLCore();
5-
public native void earlyLaunchAMLCore(String lib1, String lib2);
6-
}
4+
public static native void launchAMLCore();
5+
public static native void earlyLaunchAMLCore(String lib1, String lib2);
6+
}

‎include/cryptutils.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ struct JMD5
7676
Update(buffer, bytesRead);
7777
}
7878

79+
bool ok = !ferror(file);
7980
fclose(file);
80-
return true;
81+
return ok;
8182
}
8283

8384
inline void Finalize()

‎include/httputils.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct JHTTPUtils
185185
env->DeleteLocalRef(ex);
186186
}
187187
else snprintf(buf, sizeof(buf), "httputils.h: EXC @%s (pending but null)", where);
188-
logger->Info(buf);
188+
logger->Info("%s", buf);
189189
return true;
190190
}
191191

@@ -592,4 +592,4 @@ struct JHTTPUtils
592592
}
593593
};
594594

595-
#endif // __HTTPUTILS_H
595+
#endif // __HTTPUTILS_H

‎include/jnifn.h‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ extern std::unordered_map<std::string, jobject> g_InjectedInstances;
1414

1515
inline jobject GetGlobalContext(JNIEnv *env)
1616
{
17+
if(!env) return NULL;
1718
jclass activityThread = env->FindClass("android/app/ActivityThread");
19+
if(!activityThread) { if(env->ExceptionCheck()) env->ExceptionClear(); return NULL; }
1820
jmethodID currentActivityThread = env->GetStaticMethodID(activityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
21+
if(!currentActivityThread) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(activityThread); return NULL; }
1922
jobject at = env->CallStaticObjectMethod(activityThread, currentActivityThread);
23+
if(env->ExceptionCheck()) env->ExceptionClear();
24+
if(!at) { env->DeleteLocalRef(activityThread); return NULL; }
2025
jmethodID getApplication = env->GetMethodID(activityThread, "getApplication", "()Landroid/app/Application;");
26+
if(!getApplication) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(at); env->DeleteLocalRef(activityThread); return NULL; }
2127
jobject context = env->CallObjectMethod(at, getApplication);
2228
if (env->ExceptionCheck()) env->ExceptionClear();
2329
env->DeleteLocalRef(at);
@@ -27,8 +33,11 @@ inline jobject GetGlobalContext(JNIEnv *env)
2733

2834
inline jstring GetPackageName(JNIEnv *env, jobject jActivity)
2935
{
36+
if(!env || !jActivity) return NULL;
3037
jclass activityClass = env->GetObjectClass(jActivity);
38+
if(!activityClass) { if(env->ExceptionCheck()) env->ExceptionClear(); return NULL; }
3139
jmethodID method = env->GetMethodID(activityClass, "getPackageName", "()Ljava/lang/String;");
40+
if(!method) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(activityClass); return NULL; }
3241
jstring ret = (jstring)env->CallObjectMethod(jActivity, method);
3342
if (env->ExceptionCheck()) env->ExceptionClear();
3443
env->DeleteLocalRef(activityClass);
@@ -37,8 +46,11 @@ inline jstring GetPackageName(JNIEnv *env, jobject jActivity)
3746

3847
inline jobject GetFilesDir(JNIEnv *env, jobject jActivity)
3948
{
49+
if(!env || !jActivity) return NULL;
4050
jclass activityClass = env->GetObjectClass(jActivity);
51+
if(!activityClass) { if(env->ExceptionCheck()) env->ExceptionClear(); return NULL; }
4152
jmethodID method = env->GetMethodID(activityClass, "getFilesDir", "()Ljava/io/File;");
53+
if(!method) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(activityClass); return NULL; }
4254
jobject ret = env->CallObjectMethod(jActivity, method);
4355
if (env->ExceptionCheck()) env->ExceptionClear();
4456
env->DeleteLocalRef(activityClass);
@@ -47,8 +59,11 @@ inline jobject GetFilesDir(JNIEnv *env, jobject jActivity)
4759

4860
inline jstring GetAbsolutePath(JNIEnv *env, jobject jFile)
4961
{
62+
if(!env || !jFile) return NULL;
5063
jclass fileClass = env->GetObjectClass(jFile);
64+
if(!fileClass) { if(env->ExceptionCheck()) env->ExceptionClear(); return NULL; }
5165
jmethodID method = env->GetMethodID(fileClass, "getAbsolutePath", "()Ljava/lang/String;");
66+
if(!method) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(fileClass); return NULL; }
5267
jstring ret = (jstring)env->CallObjectMethod(jFile, method);
5368
if (env->ExceptionCheck()) env->ExceptionClear();
5469
env->DeleteLocalRef(fileClass);
@@ -363,4 +378,4 @@ inline jobject InjectSmaliDEX(JNIEnv* env, const uint8_t* dexBytes, size_t dexSi
363378
return instance;
364379
}
365380

366-
#endif // __JNIFN_H
381+
#endif // __JNIFN_H

‎include/modslist.h‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <fstream>
55
#include <mod/amlmod.h>
66

7-
class Mods;
7+
struct Mods;
88
extern Mods* listMods;
99

1010
typedef void (*OnInterfaceAddedFn)(const char*, const void*);
@@ -42,8 +42,8 @@ class ModsList
4242
{
4343
// Functions
4444
public:
45-
bool AddMod(ModInfo* modinfo, void* modhandle, const char* path);
46-
bool RemoveMod(ModInfo* modinfo);
45+
bool AddMod(ModInfo* modInfo, void* modhandle, const char* path);
46+
bool RemoveMod(ModInfo* modInfo);
4747
bool RemoveMod(const char* szGUID);
4848
bool HasMod(const char* szGUID);
4949
bool HasModOfVersion(const char* szGUID, const char* szVersion);

‎main.cpp‎

Lines changed: 109 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <fcntl.h> // "open" flags
1111
#include <android/looper.h> // ALooper
1212
#include <dlfcn.h>
13+
#include <limits.h>
1314

1415
#include <aml.h>
1516
#include <defines.h>
@@ -32,6 +33,14 @@
3233
#include <interfaces.h>
3334
#include <modslist.h>
3435

36+
#ifndef AML_PATH_MAX
37+
#ifdef PATH_MAX
38+
#define AML_PATH_MAX PATH_MAX
39+
#else
40+
#define AML_PATH_MAX 4096
41+
#endif
42+
#endif
43+
3544
pid_t g_MainThreadID = 0;
3645
bool g_bShowUpdatedToast, g_bShowUpdateFailedToast, g_bEnableFileDownloads;
3746
bool g_bCrashAML, g_bNoMods, g_bSimplerCrashLog = false, g_bNoSPInLog, g_bNoModsInLog, g_bMLSOnlyManualSaves, g_bDumpAllThreads, g_bEHUnwind, g_bMoreRegsInfo, g_bUnixBacktrace = false;
@@ -181,14 +190,43 @@ inline bool HasFakeAppName()
181190
return (g_szFakeAppName[0] != 0 && strlen(g_szFakeAppName) > 5);
182191
}
183192

193+
static bool CopyJStringUTF(JNIEnv* env, jstring str, char* out, size_t outLen, bool lowercase = false)
194+
{
195+
if(!env || !str || !out || outLen == 0) return false;
196+
197+
const char* tmp = env->GetStringUTFChars(str, NULL);
198+
if(!tmp)
199+
{
200+
if(env->ExceptionCheck()) env->ExceptionClear();
201+
return false;
202+
}
203+
204+
size_t i = 0;
205+
if(lowercase)
206+
{
207+
for(; tmp[i] != 0 && i < outLen - 1; ++i)
208+
{
209+
out[i] = (char)tolower((unsigned char)tmp[i]);
210+
}
211+
out[i] = 0;
212+
}
213+
else
214+
{
215+
snprintf(out, outLen, "%s", tmp);
216+
}
217+
218+
env->ReleaseStringUTFChars(str, tmp);
219+
return true;
220+
}
221+
184222
typedef const char* (*SpecificGameFn)();
185223
void LoadMods(const char* path)
186224
{
187225
ModInfo* pModInfo = NULL;
188226
SpecificGameFn maybeINeedAGame = NULL;
189227
GetModInfoFn modInfoFn = NULL;
190228

191-
char buf[256], dataBuf[256];
229+
char buf[AML_PATH_MAX], dataBuf[AML_PATH_MAX];
192230
DIR* dir = opendir(path);
193231
if (dir != NULL)
194232
{
@@ -205,8 +243,13 @@ void LoadMods(const char* path)
205243
//logger->Error("File %s is not a mod, atleast it is NOT .SO file!", diread->d_name);
206244
continue;
207245
}
208-
snprintf(buf, sizeof(buf), "%s/%s", path, diread->d_name);
209-
snprintf(dataBuf, sizeof(dataBuf), "%s/%s", g_szDataDir, diread->d_name);
246+
int srcLen = snprintf(buf, sizeof(buf), "%s/%s", path, diread->d_name);
247+
int tmpLen = snprintf(dataBuf, sizeof(dataBuf), "%s/%s", g_szDataDir, diread->d_name);
248+
if(srcLen < 0 || srcLen >= (int)sizeof(buf) || tmpLen < 0 || tmpLen >= (int)sizeof(dataBuf))
249+
{
250+
logger->Error("Skipping mod %s: path is too long", diread->d_name);
251+
continue;
252+
}
210253
//unlink(dataBuf);
211254
chmod(dataBuf, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP); // XMDS
212255
int removeStatus = remove(dataBuf);
@@ -226,27 +269,36 @@ void LoadMods(const char* path)
226269
continue;
227270
}
228271

272+
bool keepLoaded = false;
229273
modInfoFn = (GetModInfoFn)dlsym(handle, "__GetModInfo");
230274
if(modInfoFn != NULL)
231275
{
232276
pModInfo = modInfoFn();
233-
maybeINeedAGame = (SpecificGameFn)dlsym(handle, "__INeedASpecificGame");
234-
if(maybeINeedAGame != NULL && strcmp(maybeINeedAGame(), gameName) != 0)
277+
if(pModInfo == NULL)
235278
{
236-
logger->Error("Mod (GUID %s) built for the game %s!", pModInfo->GUID(), maybeINeedAGame());
237-
goto nextMod;
279+
logger->Error("Mod %s returned NULL from __GetModInfo!", diread->d_name);
238280
}
239-
if(!modlist->AddMod(pModInfo, handle, buf))
281+
else
240282
{
241-
logger->Error("Mod (GUID %s) is already loaded!", pModInfo->GUID());
242-
goto nextMod;
283+
maybeINeedAGame = (SpecificGameFn)dlsym(handle, "__INeedASpecificGame");
284+
const char* requiredGame = maybeINeedAGame ? maybeINeedAGame() : NULL;
285+
if(requiredGame != NULL && requiredGame[0] != 0 && strcmp(requiredGame, gameName) != 0)
286+
{
287+
logger->Error("Mod (GUID %s) built for the game %s!", pModInfo->GUID(), requiredGame);
288+
}
289+
else if(!modlist->AddMod(pModInfo, handle, buf))
290+
{
291+
logger->Error("Mod (GUID %s) is already loaded!", pModInfo->GUID());
292+
}
293+
else
294+
{
295+
logger->Info("Mod (GUID %s) has been preprocessed.", pModInfo->GUID());
296+
keepLoaded = true;
297+
}
243298
}
244-
245-
logger->Info("Mod (GUID %s) has been preprocessed.", pModInfo->GUID());
246299
}
247-
else
300+
if(!keepLoaded)
248301
{
249-
nextMod:
250302
dlclose(handle);
251303
}
252304
//unlink(dataBuf);
@@ -310,13 +362,19 @@ jobject GetCurrentContext()
310362
if(!env) return NULL;
311363

312364
jclass activityThread = env->FindClass("android/app/ActivityThread");
365+
if(!activityThread) { if(env->ExceptionCheck()) env->ExceptionClear(); return NULL; }
313366
jmethodID currentActivityThread = env->GetStaticMethodID(activityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
367+
if(!currentActivityThread) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(activityThread); return NULL; }
314368
jobject activityThreadObj = env->CallStaticObjectMethod(activityThread, currentActivityThread);
369+
if(env->ExceptionCheck()) env->ExceptionClear();
370+
if(!activityThreadObj) { env->DeleteLocalRef(activityThread); return NULL; }
315371
jmethodID getApplication = env->GetMethodID(activityThread, "getApplication", "()Landroid/app/Application;");
372+
if(!getApplication) { if(env->ExceptionCheck()) env->ExceptionClear(); env->DeleteLocalRef(activityThreadObj); env->DeleteLocalRef(activityThread); return NULL; }
316373

317374
jobject localContext = env->CallObjectMethod(activityThreadObj, getApplication);
375+
if(env->ExceptionCheck()) env->ExceptionClear();
318376
if(localContext) g_GlobalContext = env->NewGlobalRef(localContext);
319-
env->DeleteLocalRef(localContext);
377+
if(localContext) env->DeleteLocalRef(localContext);
320378
env->DeleteLocalRef(activityThreadObj);
321379
env->DeleteLocalRef(activityThread);
322380
return g_GlobalContext;
@@ -439,7 +497,7 @@ void StartAMLRightNow(const char* libName1 = NULL, const char* libName2 = NULL)
439497
}
440498

441499
logger->SetTag("AndroidModLoader");
442-
const char* szTmp; jstring jTmp;
500+
jstring jTmp;
443501

444502
/* JNI Environment */
445503
if (g_pJavaVM->GetEnv(reinterpret_cast<void**>(&g_env), JNI_VERSION_1_6) != JNI_OK)
@@ -450,6 +508,11 @@ void StartAMLRightNow(const char* libName1 = NULL, const char* libName2 = NULL)
450508

451509
/* Application Context */
452510
jobject localContext = ::GetGlobalContext(g_env);
511+
if(localContext == NULL)
512+
{
513+
logger->Error("Failed to resolve Android application context.");
514+
return;
515+
}
453516
appContext = g_env->NewGlobalRef(localContext);
454517
g_env->DeleteLocalRef(localContext);
455518
if(appContext == NULL)
@@ -485,23 +548,25 @@ void StartAMLRightNow(const char* libName1 = NULL, const char* libName2 = NULL)
485548
/* Internal Storage */
486549
jobject storageDir = GetStorageDir(g_env);
487550
jTmp = GetAbsolutePath(g_env, storageDir);
488-
szTmp = g_env->GetStringUTFChars(jTmp, NULL);
489-
snprintf(g_szInternalStoragePath, sizeof(g_szInternalStoragePath), "%s", szTmp);
490-
g_env->ReleaseStringUTFChars(jTmp, szTmp);
491-
g_env->DeleteLocalRef(jTmp);
492-
g_env->DeleteLocalRef(storageDir);
551+
if(!CopyJStringUTF(g_env, jTmp, g_szInternalStoragePath, sizeof(g_szInternalStoragePath)))
552+
{
553+
logger->Error("Failed to determine internal storage path.");
554+
if(jTmp) g_env->DeleteLocalRef(jTmp);
555+
if(storageDir) g_env->DeleteLocalRef(storageDir);
556+
return;
557+
}
558+
if(jTmp) g_env->DeleteLocalRef(jTmp);
559+
if(storageDir) g_env->DeleteLocalRef(storageDir);
493560

494561
/* Package Name */
495-
int i = 0;
496562
jTmp = GetPackageName(g_env, appContext);
497-
szTmp = g_env->GetStringUTFChars(jTmp, NULL);
498-
while(szTmp[i] != 0 && i < sizeof(g_szAppName)-1)
499-
{
500-
g_szAppName[i] = tolower(szTmp[i]);
501-
++i;
502-
} g_szAppName[i] = 0;
503-
g_env->ReleaseStringUTFChars(jTmp, szTmp);
504-
g_env->DeleteLocalRef(jTmp);
563+
if(!CopyJStringUTF(g_env, jTmp, g_szAppName, sizeof(g_szAppName), true))
564+
{
565+
logger->Error("Failed to determine package name.");
566+
if(jTmp) g_env->DeleteLocalRef(jTmp);
567+
return;
568+
}
569+
if(jTmp) g_env->DeleteLocalRef(jTmp);
505570
logger->Info("Determined app info: %s", g_szAppName);
506571

507572
#ifdef FASTMAN92_CODE
@@ -546,11 +611,15 @@ void StartAMLRightNow(const char* libName1 = NULL, const char* libName2 = NULL)
546611
/* root/data/data Folder */
547612
jobject filesDir = GetFilesDir(g_env, appContext);
548613
jstring filesPath = GetAbsolutePath(g_env, filesDir);
549-
szTmp = g_env->GetStringUTFChars(filesPath, NULL);
550-
snprintf(g_szDataDirPath, sizeof(g_szDataDirPath), "%s", szTmp);
551-
g_env->ReleaseStringUTFChars(filesPath, szTmp);
552-
g_env->DeleteLocalRef(filesPath);
553-
g_env->DeleteLocalRef(filesDir);
614+
if(!CopyJStringUTF(g_env, filesPath, g_szDataDirPath, sizeof(g_szDataDirPath)))
615+
{
616+
logger->Error("Failed to determine app data path.");
617+
if(filesPath) g_env->DeleteLocalRef(filesPath);
618+
if(filesDir) g_env->DeleteLocalRef(filesDir);
619+
return;
620+
}
621+
if(filesPath) g_env->DeleteLocalRef(filesPath);
622+
if(filesDir) g_env->DeleteLocalRef(filesDir);
554623

555624
/* AML Config */
556625
logger->Info("Reading core config...");
@@ -667,7 +736,7 @@ void StartAMLRightNow(const char* libName1 = NULL, const char* libName2 = NULL)
667736
{
668737
for(int i = 0; i < g_nEnableNews; ++i)
669738
{
670-
aml->ShowToast(true, g_szNewsString);
739+
aml->ShowToast(true, "%s", g_szNewsString);
671740
}
672741

673742
newsBuf[16] = '|'; // Anti- news spamming :p
@@ -731,13 +800,13 @@ extern "C" JNIEXPORT void JNICALL Java_net_rusjj_amlcore_earlyLaunchAMLCore(JNIE
731800
{
732801
// Early stage starting
733802
// LAUNCHES lib1 AND lib2 BY ITSELF!!!
734-
const char* szLib1 = env->GetStringUTFChars(lib1, NULL);
735-
const char* szLib2 = env->GetStringUTFChars(lib2, NULL);
803+
const char* szLib1 = lib1 ? env->GetStringUTFChars(lib1, NULL) : NULL;
804+
const char* szLib2 = lib2 ? env->GetStringUTFChars(lib2, NULL) : NULL;
736805

737806
StartAMLRightNow(szLib1, szLib2);
738807

739-
env->ReleaseStringUTFChars(lib1, szLib1);
740-
env->ReleaseStringUTFChars(lib2, szLib2);
808+
if(lib1 && szLib1) env->ReleaseStringUTFChars(lib1, szLib1);
809+
if(lib2 && szLib2) env->ReleaseStringUTFChars(lib2, szLib2);
741810
}
742811

743812
static ALooper* g_pJavaUILooper = NULL;

0 commit comments

Comments
 (0)