Skip to content

Commit

Permalink
Add KIP1 patching support (with 2 FS patches included)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajkosto committed Jul 29, 2018
1 parent d33f60e commit 977ef6f
Show file tree
Hide file tree
Showing 10 changed files with 1,552 additions and 1,038 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ OBJS = $(addprefix $(BUILD)/, \
main.o \
config.o \
btn.o \
blz.o \
clock.o \
cluster.o \
fuse.o \
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Capti
| secmon={SD path} | Replaces the security monitor binary |
| kernel={SD path} | Replaces the kernel binary |
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
| kip1patch=patchname| Enables a kip1 patch. Specify with multiple lines and/or as CSV. Implemented patches right now are nosigchk,nogc |
| fullsvcperm=1 | Disables SVC verification |
| debugmode=1 | Enables Debug mode |

Expand Down
97 changes: 97 additions & 0 deletions ipl/blz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2018 rajkosto
* Copyright (c) 2018 SciresM
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <string.h>
#include "blz.h"

const blz_footer* blz_get_footer(const unsigned char* compData, unsigned int compDataLen, blz_footer* outFooter)
{
if (compDataLen < sizeof(blz_footer))
return NULL;

const blz_footer* srcFooter = (const blz_footer*)&compData[compDataLen-sizeof(blz_footer)];
if (outFooter != NULL)
memcpy(outFooter, srcFooter, sizeof(blz_footer)); //must be a memcpy because no umaligned accesses on ARMv4

return srcFooter;
}

//from https://github.com/SciresM/hactool/blob/master/kip.c which is exactly how kernel does it, thanks SciresM!
int blz_uncompress_inplace(unsigned char* dataBuf, unsigned int compSize, const blz_footer* footer)
{
u32 addl_size = footer->addl_size;
u32 header_size = footer->header_size;
u32 cmp_and_hdr_size = footer->cmp_and_hdr_size;

unsigned char* cmp_start = &dataBuf[compSize] - cmp_and_hdr_size;
u32 cmp_ofs = cmp_and_hdr_size - header_size;
u32 out_ofs = cmp_and_hdr_size + addl_size;

while (out_ofs)
{
unsigned char control = cmp_start[--cmp_ofs];
for (unsigned int i=0; i<8; i++)
{
if (control & 0x80)
{
if (cmp_ofs < 2)
return 0; //out of bounds

cmp_ofs -= 2;
u16 seg_val = ((unsigned int)(cmp_start[cmp_ofs+1]) << 8) | cmp_start[cmp_ofs];
u32 seg_size = ((seg_val >> 12) & 0xF) + 3;
u32 seg_ofs = (seg_val & 0x0FFF) + 3;
if (out_ofs < seg_size) // Kernel restricts segment copy to stay in bounds.
seg_size = out_ofs;

out_ofs -= seg_size;

for (unsigned int j = 0; j < seg_size; j++)
cmp_start[out_ofs + j] = cmp_start[out_ofs + j + seg_ofs];
}
else
{
// Copy directly.
if (cmp_ofs < 1)
return 0; //out of bounds

cmp_start[--out_ofs] = cmp_start[--cmp_ofs];
}
control <<= 1;
if (out_ofs == 0) // blz works backwards, so if it reaches byte 0, it's done
return 1;
}
}

return 1;
}

int blz_uncompress_srcdest(const unsigned char* compData, unsigned int compDataLen, unsigned char* dstData, unsigned int dstSize)
{
blz_footer footer;
const blz_footer* compFooterPtr = blz_get_footer(compData, compDataLen, &footer);
if (compFooterPtr == NULL)
return 0;

//decompression must be done in-place, so need to copy the relevant compressed data first
unsigned int numCompBytes = (const unsigned char*)(compFooterPtr)-compData;
memcpy(dstData, compData, numCompBytes);
memset(&dstData[numCompBytes], 0, dstSize-numCompBytes);

return blz_uncompress_inplace(dstData, compDataLen, &footer);
}
36 changes: 36 additions & 0 deletions ipl/blz.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018 rajkosto
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _BLZ_H_
#define _BLZ_H_

#include "types.h"

typedef struct _blz_footer
{
u32 cmp_and_hdr_size;
u32 header_size;
u32 addl_size;
} blz_footer;

//returns pointer to footer in compData if present, additionally copies it to outFooter if not NULL
const blz_footer* blz_get_footer(const unsigned char* compData, unsigned int compDataLen, blz_footer* outFooter);
//returns 0 on failure
int blz_uncompress_inplace(unsigned char* dataBuf, unsigned int compSize, const blz_footer* footer);
//returns 0 on failure
int blz_uncompress_srcdest(const unsigned char* compData, unsigned int compDataLen, unsigned char* dstData, unsigned int dstSize);

#endif
Loading

0 comments on commit 977ef6f

Please sign in to comment.