Skip to content

Commit

Permalink
Sigcheck rewrite and many other fixes
Browse files Browse the repository at this point in the history
Add iOS 9 - 14 support
Add more detailed version array
Fix demote patch for iOS 14
Fix freshnonce
TODO: Fix bootargs on dev iboots/iOS 12 also fix nvram whitelist.
  • Loading branch information
Cryptiiiic committed Mar 28, 2021
1 parent 35d3411 commit 5872501
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 116 deletions.
1 change: 1 addition & 0 deletions include/liboffsetfinder64/ibootpatchfinder64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace tihmstar {
class ibootpatchfinder64 : public patchfinder64{
protected:
uint32_t _vers;
uint32_t _vers_arr[5];

ibootpatchfinder64(bool freeBuf);
public:
Expand Down
9 changes: 9 additions & 0 deletions liboffsetfinder64/ibootpatchfinder64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ibootpatchfinder64 *ibootpatchfinder64::make_ibootpatchfinder64(const char * fil
ibootpatchfinder64 *ibootpatchfinder64::make_ibootpatchfinder64(const void *buffer, size_t bufSize, bool takeOwnership){
uint8_t *buf = NULL;
uint32_t vers = 0;
uint32_t vers_arr[5];

buf = (uint8_t*)buffer;
assure(bufSize > 0x1000);
Expand All @@ -67,6 +68,14 @@ ibootpatchfinder64 *ibootpatchfinder64::make_ibootpatchfinder64(const void *buff
retassure(*(uint32_t*)&buf[0] == 0x90000000, "invalid magic");

retassure(vers = atoi((char*)&buf[IBOOT_VERS_STR_OFFSET+6]), "No iBoot version found!\n");
std::string vers_str = std::string((char*)&buf[IBOOT_VERS_STR_OFFSET+6]);
for(int i = 0; i < 5; i++) {
std::size_t pos = vers_str.find('.');
if(pos != std::string::npos) {
vers_str = vers_str.substr(pos + 1, vers_str.size() - 1);
vers_arr[i] = atoi((char*)vers_str.c_str());
}
}
debug("iBoot-%d inputted\n", vers);

if (vers >= 6671) {
Expand Down
114 changes: 63 additions & 51 deletions liboffsetfinder64/ibootpatchfinder64_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using namespace tihmstar::libinsn;
#define DEBUG_ENABLED_DTRE_VAR_STR "debug-enabled"
#define DEFAULT_BOOTARGS_STR "rd=md0 nand-enable-reformat=1 -progress"
#define DEFAULT_BOOTARGS_STR_13 "rd=md0 -progress -restore"
#define DEFAULT_BOOTARGS_STR_OTHER " rd=md0"
#define CERT_STR "Apple Inc.1"

ibootpatchfinder64_base::ibootpatchfinder64_base(const char * filename) :
Expand Down Expand Up @@ -52,6 +53,14 @@ ibootpatchfinder64_base::ibootpatchfinder64_base(const char * filename) :
debug("iBoot base at=0x%016llx\n", _base);
_vmem = new vmem({{_buf,_bufSize,_base, vsegment::vmprot::kVMPROTREAD | vsegment::vmprot::kVMPROTWRITE | vsegment::vmprot::kVMPROTEXEC}});
retassure(_vers = atoi((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]), "No iBoot version found!\n");
std::string _vers_str = std::string((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]);
for(int i = 0; i < 5; i++) {
std::size_t pos = _vers_str.find('.');
if(pos != std::string::npos) {
_vers_str = _vers_str.substr(pos + 1, _vers_str.size() - 1);
_vers_arr[i] = atoi((char*)_vers_str.c_str());
}
}
debug("iBoot-%d inputted\n", _vers);

didConstructSuccessfully = true;
Expand All @@ -71,6 +80,14 @@ ibootpatchfinder64_base::ibootpatchfinder64_base(const void *buffer, size_t bufS
debug("iBoot base at=0x%016llx\n", _base);
_vmem = new vmem({{_buf,_bufSize,_base, vsegment::vmprot::kVMPROTREAD | vsegment::vmprot::kVMPROTWRITE | vsegment::vmprot::kVMPROTEXEC}});
retassure(_vers = atoi((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]), "No iBoot version found!\n");
std::string _vers_str = std::string((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]);
for(int i = 0; i < 5; i++) {
std::size_t pos = _vers_str.find('.');
if(pos != std::string::npos) {
_vers_str = _vers_str.substr(pos + 1, _vers_str.size() - 1);
_vers_arr[i] = atoi((char*)_vers_str.c_str());
}
}
debug("iBoot-%d inputted\n", _vers);
}

Expand All @@ -96,21 +113,46 @@ bool ibootpatchfinder64_base::has_recovery_console(){

std::vector<patch> ibootpatchfinder64_base::get_sigcheck_patch(){
std::vector<patch> patches;
loc_t img4str = findstr("IMG4", true);
debug("img4str=%p\n",img4str);
loc_t img4decodemanifestexists = 0x0;
bool isnotptr = false;
if(_vers == 5540 && _vers_arr[0] >= 100 || _vers >= 5540) {
debug("get_sigcheck_patch: iOS 13.4 or later(iBoot-%d.%d) detected.",_vers, _vers_arr[0]);
img4decodemanifestexists = _vmem->memmem("\xE8\x03\x00\xAA\xC0\x00\x80\x52\xE8\x00\x00\xB4", 12);
} else if(_vers == 5540 && _vers_arr[0] <= 100 || _vers <= 5540 && _vers > 2817) {
debug("get_sigcheck_patch: iOS 13.3 or lower(iBoot-%d.%d) detected.",_vers, _vers_arr[0]);
img4decodemanifestexists = _vmem->memmem("\xE8\x03\x00\xAA\xE0\x07\x1F\x32\xE8\x00\x00\xB4", 12);
} else if(_vers <= 2817) {
debug("get_sigcheck_patch: iOS 9.3.5 or lower(iBoot-%d.%d) detected.",_vers, _vers_arr[0]);
isnotptr = true;
img4decodemanifestexists = _vmem->memmem("\xE8\x07\x1F\x32\xE0\x00\x00\xB4\xC1\x00\x00\xB4", 12);
} else {
reterror("unknown or unsupported iboot version");
}
debug("img4decodemanifestexists=%p",img4decodemanifestexists);
assure(img4decodemanifestexists);

loc_t img4strref = find_literal_ref(img4str);
debug("img4strref=%p\n",img4strref);
loc_t img4decodemanifestexistsref = find_call_ref(img4decodemanifestexists);
debug("img4decodemanifestexistsref=%p",img4decodemanifestexistsref);
assure(img4decodemanifestexistsref);

loc_t f1top = find_bof(img4strref);
debug("f1top=%p\n",f1top);
vmem iter(*_vmem,img4decodemanifestexistsref);
vmem iter2(*_vmem,img4decodemanifestexistsref);

loc_t f1topref = find_call_ref(f1top,1);
debug("f1topref=%p\n",f1topref);
while(++iter != insn::adr);
if((uint8_t)iter().rd() != 2) {
while(++iter2 != insn::adr);
assure((uint8_t)iter().rd() == 2);
}
loc_t img4interposercallbackptr = iter().imm();
debug("img4interposercallbackptr=%p",img4interposercallbackptr);
assure(img4interposercallbackptr);

loc_t f2top = find_bof(f1topref);
debug("f2top=%p\n",f2top);

loc_t img4interposercallback = (isnotptr == true) ? img4interposercallbackptr : _vmem->deref(img4interposercallbackptr);
debug("img4interposercallback=%p",img4interposercallback);
assure(img4interposercallback);

patches.push_back({img4interposercallback,"\x00\x00\x80\xD2" /*mov x0, 0*/,4});
patches.push_back({img4interposercallback + 4,"\xC0\x03\x5F\xD6" /*ret*/,4});
{
/* always production patch*/
for (uint64_t demoteReg : {0x3F500000UL,0x3F500000UL,0x3F500000UL,0x481BC000UL,0x481BC000UL,0x20E02A000UL,0x2102BC000UL,0x2102BC000UL,0x2352BC000UL}) {
Expand All @@ -126,43 +168,6 @@ std::vector<patch> ibootpatchfinder64_base::get_sigcheck_patch(){
}
}
}

vmem iter(*_vmem,f2top);

loc_t adr_x3 = 0;
loc_t adr_x2 = 0;

while (true) {
if (++iter == insn::adr && iter().rd() == 2){
adr_x2 = iter;
}else if (iter() == insn::adr && iter().rd() == 3){
adr_x3 = iter;
}else if (iter() == insn::bl){
if (adr_x2 && adr_x3) {
break;
}else{
adr_x2 = 0;
adr_x3 = 0;
}
}
}

assure(adr_x2);
iter = adr_x2;

loc_t callback = (loc_t)_vmem->deref((loc_t)iter().imm());
debug("callback=%p\n",callback);

iter = callback;

while (++iter != insn::ret);

loc_t ret = iter;
debug("ret=%p\n",ret);

const char p[] ="\x00\x00\x80\xD2" /*mov x0,0*/ "\xC0\x03\x5F\xD6" /*ret*/;
patches.push_back({ret,p,sizeof(p)-1});

return patches;
}

Expand All @@ -174,8 +179,13 @@ std::vector<patch> ibootpatchfinder64_base::get_boot_arg_patch(const char *boota
try{
default_boot_args_str_loc = _vmem->memstr(DEFAULT_BOOTARGS_STR);
}catch(...){
debug("DEFAULT_BOOTARGS_STR not found, trying fallback to DEFAULT_BOOTARGS_STR_13\n");
default_boot_args_str_loc = _vmem->memstr(DEFAULT_BOOTARGS_STR_13);
try{
debug("DEFAULT_BOOTARGS_STR not found, trying fallback to DEFAULT_BOOTARGS_STR_13\n");
default_boot_args_str_loc = _vmem->memstr(DEFAULT_BOOTARGS_STR_13);
}catch(...){
debug("DEFAULT_BOOTARGS_STR_13 not found, trying fallback to DEFAULT_BOOTARGS_STR_OTHER\n");
default_boot_args_str_loc = _vmem->memstr(DEFAULT_BOOTARGS_STR_OTHER);
}
}

assure(default_boot_args_str_loc);
Expand Down Expand Up @@ -214,6 +224,8 @@ std::vector<patch> ibootpatchfinder64_base::get_boot_arg_patch(const char *boota
vmem iter(*_vmem,default_boot_args_xref);
uint8_t xrefRD = iter().rd();
debug("xrefRD=%d\n",xrefRD);
if(xrefRD > 9)
return patches;


while (++iter != insn::csel);
Expand Down Expand Up @@ -573,7 +585,7 @@ std::vector<patch> ibootpatchfinder64_base::get_freshnonce_patch(){

vmem iter(*_vmem,noncefun2_blref);

assure((--iter).supertype() == insn::sut_branch_imm);
while((--iter).supertype() != insn::sut_branch_imm);

loc_t branchloc = iter;
debug("branchloc=%p\n",branchloc);
Expand Down
110 changes: 45 additions & 65 deletions liboffsetfinder64/ibootpatchfinder64_iOS14.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ using namespace tihmstar::offsetfinder64;
using namespace tihmstar::libinsn;

#define iBOOT_BASE_OFFSET 0x300
#define PROD "effective-production-status-ap"

ibootpatchfinder64_iOS14::ibootpatchfinder64_iOS14(const char *filename)
: ibootpatchfinder64_base(filename)
Expand All @@ -31,85 +32,64 @@ ibootpatchfinder64_iOS14::ibootpatchfinder64_iOS14(const void *buffer, size_t bu
debug("iBoot base at=0x%016llx\n", _base);
}


std::vector<patch> ibootpatchfinder64_iOS14::get_sigcheck_patch(){
std::vector<patch> patches;
loc_t findpos = 0;
vmem iter(*_vmem);

/* We are looking for this:
0x00000001800312dc cmp w8, #0x1
0x00000001800312e0 b.ne loc_1800313d8
0x00000001800312e4 ldr x8, [x19, #0x10]
0x00000001800312e8 cmp x8, #0x4
0x00000001800312ec b.eq loc_180031388
0x00000001800312f0 cmp x8, #0x2
0x00000001800312f4 b.eq loc_180031344
0x00000001800312f8 cmp x8, #0x1
0x00000001800312fc b.ne loc_180031a88
*/

while (!findpos) {
if (++iter != insn::cmp) continue;

if (iter().imm() != 1) continue;

if ((++iter).supertype() != insn::sut_branch_imm) continue;

if (++iter != insn::ldr || iter().imm() != 0x10) continue;
loc_t img4decodemanifestexists = img4decodemanifestexists = _vmem->memmem("\xE8\x03\x00\xAA\xC0\x00\x80\x52\xE8\x00\x00\xB4", 12); //0x180032144;
debug("img4decodemanifestexists=%p",img4decodemanifestexists);
assure(img4decodemanifestexists);

if (++iter != insn::cmp || iter().imm() != 4) continue;
if ((++iter).supertype() != insn::sut_branch_imm) continue;
loc_t img4decodemanifestexistsref = find_call_ref(img4decodemanifestexists);
debug("img4decodemanifestexistsref=%p",img4decodemanifestexistsref);
assure(img4decodemanifestexistsref);

if (++iter != insn::cmp || iter().imm() != 2) continue;
if ((++iter).supertype() != insn::sut_branch_imm) continue;
vmem iter(*_vmem,img4decodemanifestexistsref);
vmem iter2(*_vmem,img4decodemanifestexistsref);

if (++iter != insn::cmp || iter().imm() != 1) continue;
if ((++iter).supertype() != insn::sut_branch_imm) continue;


findpos = iter;
while(++iter != insn::adr);
if((uint8_t)iter().rd() != 2) {
while(++iter2 != insn::adr);
assure((uint8_t)iter().rd() == 2);
}
debug("findpos=%p",findpos);
loc_t img4interposercallbackptr = iter().imm();
debug("img4interposercallbackptr=%p",img4interposercallbackptr);
assure(img4interposercallbackptr);


while (++iter != insn::ret);

loc_t funcend = iter;
debug("funcend=%p",funcend);
loc_t img4interposercallback = _vmem->deref(img4interposercallbackptr);
debug("img4interposercallback=%p",img4interposercallback);
assure(img4interposercallback);

{
insn pins = insn::new_immediate_movz(funcend, 0, 0, 0);
uint32_t opcode = pins.opcode();
patches.push_back({(loc_t)pins.pc(), &opcode, 4});
}

{
insn pins = insn::new_general_ret(funcend+4);
uint32_t opcode = pins.opcode();
patches.push_back({(loc_t)pins.pc(), &opcode, 4});
}


patches.push_back({img4interposercallback,"\x00\x00\x80\xD2" /*mov x0, 0*/,4});
patches.push_back({img4interposercallback + 4,"\xC0\x03\x5F\xD6" /*ret*/,4});
{
/* always production patch*/
for (uint64_t demoteReg : {0x3F500000UL,0x3F500000UL,0x3F500000UL,0x481BC000UL,0x481BC000UL,0x20E02A000UL,0x2102BC000UL,0x2102BC000UL,0x2352BC000UL}) {
loc_t demoteRef = find_literal_ref(demoteReg);
if (demoteRef) {
vmem iter(*_vmem,demoteRef);

while (++iter != insn::and_);
assure((uint32_t)iter().imm() == 1);
loc_t productionStr = _vmem->memstr(PROD);
debug("productionStr=%p\n",productionStr);
assure(productionStr);
loc_t productionRef = find_literal_ref(productionStr);
debug("productionRef=%p\n",productionRef);
assure(productionRef);
vmem iter(*_vmem,productionRef);
while (++iter != insn::bl);
++iter;
while (++iter != insn::bl);
iter = iter().imm();
while (++iter != insn::bl);
loc_t demoteRef = iter().imm();
if (demoteRef) {
iter = demoteRef;
while (++iter != insn::b);
iter = iter().imm();
assure((uint32_t)iter().imm() == 1 || (uint32_t)iter().imm() == 0x100);
demoteRef = iter;
debug("demoteRef=%p\n",demoteRef);
patches.push_back({demoteRef,"\x20\x00\x80\xD2" /*mov x0, 0*/,4});
if(++iter != insn::ret) {
demoteRef = iter;
debug("demoteRef=%p\n",demoteRef);
patches.push_back({demoteRef,"\x20\x00\x80\xD2" /*mov x0, 0*/,4});
debug("demoteRef2=%p\n",demoteRef);
patches.push_back({demoteRef,"\xD5\x03\x20\x1F" /*nop*/,4});
}
}
}

return patches;
}

Expand Down

0 comments on commit 5872501

Please sign in to comment.