Garmin applications can specify which permissions they need to run. The firmware will enforce those permissions at runtime, and abort any code attempting to use restricted modules without being authorized.
The PRG file contains a permissions section. Each permission entry references the module ID it needs access to.
When checking for permission, the firmware has an exception for SensorHistory when the version specified by the PRG file is too old (most likely because the module did not exist prior to that version):
uint prg_tvm_has_permission-?(s_tvm_ctx *ctx,int module_id,byte *out_bool)
{
uint uVar1;
uint *permissions_data;
int current_module_id;
bool bVar2;
int *local_14;
bVar2 = module_id == module_Toybox_SensorHistory;
*out_bool = 0;
if ((bVar2) && ((code *)ctx->version < VERSION_2.3.0)) {
*out_bool = 1;
return 0;
}
// [...]
}It is possible to modify an application to specify a version lower than 2.3.0, which can then use the SensorHistory module without any permission.
In our scenario, we have an application that uses the following code (taken from the official documentation):
var sensorIter = SensorHistory.getHeartRateHistory({});
if (sensorIter != null) {
System.println(sensorIter.next().data);
}The application does not specify the SensorHistory permission. When running it, we get the following error:
Error: Permission Required
Details: Permission for module 'Toybox.SensorHistory' required
After patching the application version to 2.2.0, we can successfully get the heart-rate history:
80
See the patched application: https://github.com/anvilsecure/garmin-ciq-app-research/blob/main/poc/GRMN-05.prg