Skip to content

Commit

Permalink
Merge pull request #23 from toniebox-reverse-engineering/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
SciLor authored Feb 10, 2021
2 parents 0938a35 + 3669569 commit e05b3f8
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 59 deletions.
6 changes: 3 additions & 3 deletions sd-bootloader-ng/bootmanager/globalDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@
#define POWER_PORT_MASK GPIO_PIN_6
#define CHARGER_PORT_MASK GPIO_PIN_1

#define PATCH_MAX_BYTES 128
#define PATCH_MAX_PER_IMAGE 9
#define PATCH_MAX_NAME_LENGTH 16
#define PATCH_MAX_BYTES 256
#define PATCH_MAX_PER_IMAGE 32
#define PATCH_MAX_NAME_LENGTH 32

#endif
34 changes: 1 addition & 33 deletions sd-bootloader-ng/bootmanager/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,39 +600,7 @@ int main()
for (uint8_t i=0; i<PATCH_MAX_PER_IMAGE; i++) {
if (Config_imageInfos[selectedImgNum].patches[i][0] == '\0')
break;
Patch_Read(Config_imageInfos[selectedImgNum].patches[i]);
sSearchAndReplacePatch* patch = &Patch_searchAndReplace;
if (patch->length > 0) {
bool doPatch = false;
uint32_t offset = 0;
for (offset=0; offset<filesize-patch->length; offset++) {
if (patch->searchMask[0] == 0x00)
continue;
if (patch->search[0] != pImgRun[offset])
continue;

uint32_t offset2;
for (offset2=1; offset2<patch->length; offset2++) {
if (patch->searchMask[offset2] == 0x00)
continue;
if (patch->search[offset2] != pImgRun[offset+offset2]) {
offset2 = 0;
break;
}
}
if (offset2 == patch->length) {
doPatch = true;
break;
}
}
if (doPatch) {
for (uint32_t replaceOffset=0; replaceOffset<patch->length; replaceOffset++) {
if (patch->replaceMask[replaceOffset] == 0x00)
continue;
pImgRun[offset+replaceOffset] = patch->replace[replaceOffset];
}
}
}
Patch_Apply(pImgRun, Config_imageInfos[selectedImgNum].patches[i], filesize);
}
#endif

Expand Down
75 changes: 61 additions & 14 deletions sd-bootloader-ng/bootmanager/patch.c
Original file line number Diff line number Diff line change
@@ -1,25 +1,72 @@
#include "patch.h"

sSearchAndReplacePatch Patch_searchAndReplace;
static sSearchAndReplacePatch searchAndReplacePatch;
static char* image;
static uint32_t imageLen;

static jsmn_stream_parser parser;
static char jsonGroupName[17];
static char jsonValueName[17];
static uint8_t cursor = 0;

static void clearSearchAndReplace() {
sSearchAndReplacePatch* patch = &searchAndReplacePatch;
patch->length = 0;
memset(patch->search, 0x00, COUNT_OF(patch->search));
memset(patch->searchMask, 0x00, COUNT_OF(patch->searchMask));
memset(patch->replace, 0x00, COUNT_OF(patch->replace));
memset(patch->replaceMask, 0x00, COUNT_OF(patch->replaceMask));
}
static void doSearchAndReplace() {
sSearchAndReplacePatch* patch = &searchAndReplacePatch;
if (patch->length > 0) {
bool doPatch = false;
uint32_t offset = 0;
for (offset=0; offset<imageLen-patch->length; offset++) {
if (patch->searchMask[0] == 0x00)
continue;
if (patch->search[0] != image[offset])
continue;

uint32_t offset2;
for (offset2=1; offset2<patch->length; offset2++) {
if (patch->searchMask[offset2] == 0x00)
continue;
if (patch->search[offset2] != image[offset+offset2]) {
offset2 = 0;
break;
}
}
if (offset2 == patch->length) {
doPatch = true;
break;
}
}
if (doPatch) {
for (uint32_t replaceOffset=0; replaceOffset<patch->length; replaceOffset++) {
if (patch->replaceMask[replaceOffset] == 0x00)
continue;
image[offset+replaceOffset] = patch->replace[replaceOffset];
}
}
}
clearSearchAndReplace();
}

static void jsmn_start_arr(void *user_arg) {
cursor = 0;
cursor = 0;
}
static void jsmn_end_arr(void *user_arg) {
if (parser.stack_height != 6)
return;

if (strcmp("searchAndReplace", jsonGroupName) == 0) {
if (strcmp("search", jsonValueName) == 0 || strcmp("replace", jsonValueName) == 0) {
if (Patch_searchAndReplace.length == 0) {
Patch_searchAndReplace.length = cursor;
if (searchAndReplacePatch.length == 0) {
searchAndReplacePatch.length = cursor;
} else {
Patch_searchAndReplace.length = min(cursor, Patch_searchAndReplace.length);
searchAndReplacePatch.length = min(cursor, searchAndReplacePatch.length);
doSearchAndReplace();
}
}
}
Expand Down Expand Up @@ -55,11 +102,11 @@ static void jsmn_obj_key(const char *key, size_t key_len, void *user_arg) {
char* values;
char* mask;
if (strcmp("search", jsonValueName) == 0) {
values = Patch_searchAndReplace.search;
mask = Patch_searchAndReplace.searchMask;
values = searchAndReplacePatch.search;
mask = searchAndReplacePatch.searchMask;
} else if (strcmp("replace", jsonValueName) == 0) {
values = Patch_searchAndReplace.replace;
mask = Patch_searchAndReplace.replaceMask;
values = searchAndReplacePatch.replace;
mask = searchAndReplacePatch.replaceMask;
}
if (strcmp("??", key) == 0) {
mask[cursor] = 0x00;
Expand Down Expand Up @@ -95,7 +142,7 @@ static jsmn_stream_callbacks_t cbs = {
jsmn_primitive
};

void Patch_Read(char* name) {
void Patch_Apply(char* imageBytes, char* patchName, uint32_t imageLength) {
//TODO ERRORS

FIL ffile;
Expand All @@ -104,18 +151,18 @@ void Patch_Read(char* name) {
char filepath[COUNT_OF(PATCH_SD_BASE_PATH)+32+5];
strcpy(filepath, PATCH_SD_BASE_PATH);
char* filename = filepath + COUNT_OF(PATCH_SD_BASE_PATH)-1;
strcpy(filename, name);
strcpy(filename, patchName);
char* fileext = filename + strlen(filename);
strcpy(fileext, ".json");

Patch_searchAndReplace.length = 0;


ffs_result = f_open(&ffile, filepath, FA_READ);
if (ffs_result == FR_OK) {
uint32_t filesize = f_size(&ffile);
uint32_t bytesRead = 0;
uint32_t allBytesRead = 0;
clearSearchAndReplace();
image = imageBytes;
imageLen = imageLength;

jsmn_stream_init(&parser, &cbs, NULL);
char buffer[512];
Expand Down
3 changes: 1 addition & 2 deletions sd-bootloader-ng/bootmanager/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ typedef struct sSearchAndReplacePatch
char replaceMask[PATCH_MAX_BYTES];

} sSearchAndReplacePatch;
extern sSearchAndReplacePatch Patch_searchAndReplace;

void Patch_Read(char* name);
void Patch_Apply(char* imageBytes, char* patchName, uint32_t imageLength);

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion sd-bootloader-ng/bootmanager/sd/revvox/boot/ngCfg.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"hashFile": false,
"watchdog": true,
"ofwFix": true,
"patches": ["blockCheck.308", "noCerts.305", "noChargWake.305", "noHideA.308", "noPass.305", "noPrivacy.305", "uidCheck.305"]
"patches": ["blockCheck.308", "blockCheckRemove.308", "noCerts.305", "noChargWake.305", "noHide.308", "noPass.305", "noPrivacy.305", "uidCheck.305"]
},
"cfw1": {
"checkHash": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"general": {
"_desc": "Always unhides files instead of hiding them. Breaks updating tonie (creative/live) content.",
"_memPos": "",
"_fwVer": "3.0.8"
},
"searchAndReplace": [{
"search": ["00", "29", "14", "bf", "02", "27", "00", "27"],
"replace": ["??", "??", "??", "??", "00", "??", "??", "??"]
}]
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"general": {
"_desc": "Removes check for tag blocks count = 8",
"_memPos": "",
"_desc": "Removes check for tag blocks count > 8",
"_memPos": "0x1F82",
"_fwVer": "3.0.8+"
},
"searchAndReplace": [{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"general": {
"_desc": "Removes check for tag blocks completely (broken tags)",
"_memPos": "0x1F46",
"_fwVer": "3.0.8+"
},
"searchAndReplace": [{
"search": ["08", "f0", "56", "fa", "04", "46", "88", "b1", "03", "46", "32", "46"],
"replace": ["00", "20", "00", "bf", "??", "??", "??", "??", "??", "??", "??", "??"]
}]
}
11 changes: 11 additions & 0 deletions sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/noHide.308.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"general": {
"_desc": "Do not hide files, if they are marked as deprecated from server. Breaks updating tonie (creative/live) content.",
"_memPos": "",
"_fwVer": "3.0.8"
},
"searchAndReplace": [{
"search": ["01", "21", "1c", "a8", "fc", "f7", "77", "fa"],
"replace": ["??", "??", "??", "??", "00", "bf", "00", "bf"]
}]
}
2 changes: 1 addition & 1 deletion wiki/Bootloader.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ For example all OFW binaries have a SHA256 appended to their file ending (except
The older Hackiebox CFW doesn't have a SHA256 appened. So you may need to create ng-*cfwX*.sha yourself if you want to use it. For HackieboxNG the SHA256 hash will be directly appended to the firmware file itself.

### Patches
The integrated patch engine allows to apply patches to the loaded firmware in-memory. Currently just a simple dup2 patcher style *Search & Replace* engine ist implemented. You may patch up to 128 bytes per patch and apply up to nine patches per slot.
The integrated patch engine allows to apply patches to the loaded firmware in-memory. Currently just a simple dup2 patcher style *Search & Replace* engine ist implemented. You may patch up to 256 bytes per patch and apply up to 32 patches per slot. The patchname is limited to 32 characters.
[More about available ofw patches](https://github.com/toniebox-reverse-engineering/hackiebox_cfw/wiki/OFWPatches)

## Error codes
14 changes: 11 additions & 3 deletions wiki/OFWPatches.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@ This patch clears the paths to the certificates. This way the box will abort the
## Alternative Tags (SLIX / SLIX2)
If you want to use alternative tags those patches will help you. Even other iso15693 tags may work.

### Block count ([blockCheck.308.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/blockCheck.308.json))
### Block count >8 ([blockCheck.308.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/blockCheck.308.json))
Usally the toniebox checks if the tag has exactly 8 blocks. The check allows the tag to have more than that. (ex. SLIX or SLIX2)

### Block count <=8 ([blockCheckRemove.308.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/blockCheckRemove.308.json))
Usally the toniebox checks if the tag has exactly 8 blocks. The check allows the tag to have less than that. (ex. broken SLIX-L fake tags)

### No privacy password ([noPass.305.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/noPass.305.json))
Usally doesn't allow tags without the boxine specific or the NXP specific privacy mode password. With the patch you can use tags without having privacy password support (ex. SLIX).

### No UID check ([uidCheck.305.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/uidCheck.305.json))
Usally the toniebox checks if the UID of the tag starts with *E0:04:03*. With that patch you may use tags with other UIDs (ex SLIX or SLIX2)

### Unhide files that should be hidden ([noHideA.308.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/noHideA.308.json))
Usally the toniebox sets the file attribute hidden of the tonie file for all live tags and since v3.0.8 all custom tags. If the toniebox is online, it will delete that file to redownload its content. This patch replaces the hide functionality with unhide. So the files won't be deleted and redownloaded.
### Hide A: Do not hide files that need new content ([noHide.308.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/noHide.308.json))
*You just need one of the hide patches! This one is recommended*
Usally the toniebox sets the file attribute hidden of the tonie file for all live tags or tags having new content. If the toniebox is online and the tag is placed on top it will delete that file to redownload its content. This also applies to all custom tags. This patch disabled the hide function. So the files won't be deleted and redownloaded. **Attention** You won't be able to update creative tonies anymore!

### Hide B: Unhide files that should be hidden (because they have new content) ([alwaysUnhide.308.json](https://github.com/toniebox-reverse-engineering/hackiebox_cfw_ng/blob/master/sd-bootloader-ng/bootmanager/sd/revvox/boot/patch/alwaysUnhide.308.json))
*You just need one of the hide patches!*
Usally the toniebox sets the file attribute hidden of the tonie file for all live tags or tags having new content. If the toniebox is online and the tag is placed on top it will delete that file to redownload its content. This also applies to all custom tags. This patch replaces the hide functionality with unhide. So the files won't be deleted and redownloaded. **Attention** You won't be able to update creative tonies anymore!


## Additional
Expand Down

0 comments on commit e05b3f8

Please sign in to comment.