Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add KIP1 patching support (with 2 FS patches included) #51

Merged
merged 1 commit into from
Jul 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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