Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tihmstar committed Aug 1, 2024
2 parents 26ff1ed + f932db7 commit 7f982dd
Show file tree
Hide file tree
Showing 27 changed files with 440 additions and 241 deletions.
13 changes: 0 additions & 13 deletions .github/FUNDING.yml

This file was deleted.

13 changes: 8 additions & 5 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ CFLAGS+=" -std=c11"
CXXFLAGS+=" -D EXPECTIONNAME=OFexception"

# Checks for libraries.
IMG4TOOL_REQUIRES_STR="libimg4tool >= 202"
IMG3TOOL_REQUIRES_STR="libimg3tool >= 8"
LIBGENERAL_REQUIRES_STR="libgeneral >= 75"
LIBINSN_REQUIRES_STR="libinsn >= 49"
IMG4TOOL_REQUIRES_STR="libimg4tool >= 198"
IMG3TOOL_REQUIRES_STR="libimg3tool >= 2"
LIBGENERAL_REQUIRES_STR="libgeneral >= 65"
LIBINSN_REQUIRES_STR="libinsn >= 38"
PKG_CHECK_MODULES(libimg4tool, $IMG4TOOL_REQUIRES_STR, have_img4tool=yes, have_img4tool=no)
PKG_CHECK_MODULES(libimg3tool, $IMG3TOOL_REQUIRES_STR, have_img3tool=yes, have_img3tool=no)
PKG_CHECK_MODULES(libgeneral, $LIBGENERAL_REQUIRES_STR)
Expand Down Expand Up @@ -159,6 +159,8 @@ AM_CONDITIONAL(WITH_WTFPWNDFU, test x$with_wtfpwndfu == xyes)

# Checks for header files.

ORIG_CFLAGS=${CFLAGS}
CFLAGS+=" -I${lt_sysroot}/include -I${lt_sysroot}/${prefix}/include -I${lt_sysroot}/${ac_default_prefix}/include"
AC_CHECK_HEADERS([mach-o/loader.h mach-o/nlist.h], [
AC_DEFINE(HAVE_MACHO_O_HEADER, 1, [Define if you have apple cctools headers])
AC_SUBST([HAVE_MACHO_O_HEADER], [1])
Expand All @@ -167,6 +169,7 @@ AC_CHECK_HEADERS([mach-o/loader.h mach-o/nlist.h], [
AC_SUBST([HAVE_MACHO_O_HEADER], [0])
have_macho_header=no;
], [])
CFLAGS=${ORIG_CFLAGS}

if test "x$have_macho_header" != "xyes"; then
AC_MSG_ERROR(["Macho-O headers not found, are apple cctools headers installed?"])
Expand All @@ -187,7 +190,7 @@ AC_CONFIG_FILES([Makefile
tools/Makefile
tools/binrider/Makefile
tools/offsetexporter/Makefile
libpatchfinder.pc])
libpatchfinder.pc])
AC_OUTPUT

echo "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ namespace tihmstar {
class ibootpatchfinder64 : public patchfinder64, public ibootpatchfinder {
protected:
ibootpatchfinder64(bool freeBuf);
ibootpatchfinder64(ibootpatchfinder64 &&mv);
public:

static ibootpatchfinder64 *make_ibootpatchfinder64(const char *filename);
Expand Down
12 changes: 7 additions & 5 deletions include/libpatchfinder/patch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@
namespace tihmstar {
namespace patchfinder{
class patch{
void *_patch;
size_t _patchSize;
bool _slideme;
bool _dofree;
void(*_slidefunc)(class patch *patch, uint64_t slide);
public:
uint64_t _location;
size_t _patchSize;
const void *_patch;
patch(uint64_t location, const void *patch, size_t patchSize, void(*slidefunc)(class patch *patch, uint64_t slide) = NULL, bool dofree = true);
patch(uint64_t location, const void *patch, size_t patchSize, void(*slidefunc)(class patch *patch, uint64_t slide) = NULL);
patch(const patch& cpy) noexcept;
~patch();


inline const void *getPatch(){return _patch;}
inline size_t getPatchSize(){return _patchSize;}

patch &operator=(const patch& cpy);
void slide(uint64_t slide);
};
Expand Down
6 changes: 6 additions & 0 deletions libpatchfinder.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
2A0D862E2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A0D862C2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.cpp */; };
2A102B482ADD3CDD00F86D9E /* ibootpatchfinder32_iOS8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A102B462ADD3CDD00F86D9E /* ibootpatchfinder32_iOS8.cpp */; };
2A32E5DE2A41CD5A007170DA /* kernelpatchfinder64_iOS17.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A32E5DC2A41CD5A007170DA /* kernelpatchfinder64_iOS17.cpp */; };
2A44ABC12A84C0650076F87C /* StableHash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8739AE2F2A6B48E000630CEA /* StableHash.cpp */; };
Expand Down Expand Up @@ -167,6 +168,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
2A0D862C2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = kernelpatchfinder64_iOS8.cpp; sourceTree = "<group>"; };
2A0D862D2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kernelpatchfinder64_iOS8.hpp; sourceTree = "<group>"; };
2A102B462ADD3CDD00F86D9E /* ibootpatchfinder32_iOS8.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ibootpatchfinder32_iOS8.cpp; sourceTree = "<group>"; };
2A102B472ADD3CDD00F86D9E /* ibootpatchfinder32_iOS8.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ibootpatchfinder32_iOS8.hpp; sourceTree = "<group>"; };
2A32E5DC2A41CD5A007170DA /* kernelpatchfinder64_iOS17.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = kernelpatchfinder64_iOS17.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -472,6 +475,8 @@
87C7D5B22854D9EC001CE584 /* sbops64.h */,
87F0A57626A5BD950090C657 /* kernelpatchfinder64_base.hpp */,
8738E8FA2695981A00C03872 /* kernelpatchfinder64_base.cpp */,
2A0D862D2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.hpp */,
2A0D862C2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.cpp */,
87F0A57526A5BD950090C657 /* kernelpatchfinder64_iOS9.hpp */,
8738E8FC2695981A00C03872 /* kernelpatchfinder64_iOS9.cpp */,
87F0A57426A5BD950090C657 /* kernelpatchfinder64_iOS12.hpp */,
Expand Down Expand Up @@ -653,6 +658,7 @@
8738E8F7269597FE00C03872 /* ibootpatchfinder64.cpp in Sources */,
8738E87226945D5300C03872 /* patchfinder64.cpp in Sources */,
8738E91426959AEE00C03872 /* ibootpatchfinder32_base.cpp in Sources */,
2A0D862E2BF4FABC00CE4FA7 /* kernelpatchfinder64_iOS8.cpp in Sources */,
8738E88626945EE500C03872 /* patchfinder32.cpp in Sources */,
87F8453A2771C93D0018347B /* ibootpatchfinder32_iOS12.cpp in Sources */,
8738E8F4269597FE00C03872 /* ibootpatchfinder64_iOS12.cpp in Sources */,
Expand Down
36 changes: 13 additions & 23 deletions libpatchfinder/ibootpatchfinder/ibootpatchfinder32_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,55 +31,44 @@ using namespace tihmstar::libinsn::arm32;
ibootpatchfinder32_base::ibootpatchfinder32_base(const char * filename) :
ibootpatchfinder32(true)
{
struct stat fs = {0};
int fd = 0;
bool didConstructSuccessfully = false;
int fd = -1;
cleanup([&]{
if (fd>0) close(fd);
if (!didConstructSuccessfully) {
safeFreeConst(_buf);
}
safeClose(fd);
})

struct stat fs = {0};

assure((fd = open(filename, O_RDONLY)) != -1);
assure(!fstat(fd, &fs));
assure((_buf = (uint8_t*)malloc( _bufSize = fs.st_size)));
assure(read(fd,(void*)_buf,_bufSize)==_bufSize);

assure(_bufSize > 0x1000);

assure(!strncmp((char*)&_buf[IBOOT_VERS_STR_OFFSET], "iBoot", sizeof("iBoot")-1));
retassure(*(uint32_t*)&_buf[0] == IBOOT32_RESET_VECTOR_BYTES, "invalid magic");

_entrypoint = _base = (loc_t)((*(uint32_t*)&_buf[0x20]) & ~0xFFF);
debug("iBoot base at=0x%08x", _base);
_vmemThumb = new vmem_thumb({{_buf,_bufSize,_base, (vmprot)(kVMPROTREAD | kVMPROTWRITE | kVMPROTEXEC)}});
_vmemArm = new vmem_arm({{_buf,_bufSize,_base, (vmprot)(kVMPROTREAD | kVMPROTWRITE | kVMPROTEXEC)}});
retassure(_vers = atoi((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]), "No iBoot version found!\n");
debug("iBoot-%d inputted", _vers);

didConstructSuccessfully = true;
init();
}

ibootpatchfinder32_base::ibootpatchfinder32_base(const void *buffer, size_t bufSize, bool takeOwnership)
: ibootpatchfinder32(takeOwnership)
{
_bufSize = bufSize;
_buf = (uint8_t*)buffer;
init();
}

void ibootpatchfinder32_base::init(){
assure(_bufSize > 0x1000);

retassure(*(uint32_t*)&_buf[0] == IBOOT32_RESET_VECTOR_BYTES, "invalid magic");

_entrypoint = _base = (loc_t)((*(uint32_t*)&_buf[0x20]) & ~0xFFF);
debug("iBoot base at=0x%08x", _base);
safeDelete(_vmemThumb);
safeDelete(_vmemArm);
_vmemThumb = new vmem_thumb({{_buf,_bufSize,_base, (vmprot)(kVMPROTREAD | kVMPROTWRITE | kVMPROTEXEC)}});
_vmemArm = new vmem_arm({{_buf,_bufSize,_base, (vmprot)(kVMPROTREAD | kVMPROTWRITE | kVMPROTEXEC)}});

if (!strncmp((char*)&_buf[IBOOT_VERS_STR_OFFSET], "iBoot", sizeof("iBoot")-1)){
retassure(_vers = atoi((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]), "No iBoot version found!\n");
}else{
//iOS 1 iBoot??
loc_t ibootstrloc = memmem("iBoot-", sizeof("iBoot-")-1);
loc_t ibootstrloc = (loc_t)memmem("iBoot-", sizeof("iBoot-")-1);
retassure(ibootstrloc, "No iBoot version found!\n");
const char *ibootstr = (char*)memoryForLoc(ibootstrloc);
retassure(_vers = atoi(ibootstr+6), "No iBoot version found!\n");
Expand All @@ -91,6 +80,7 @@ ibootpatchfinder32_base::~ibootpatchfinder32_base(){
//
}

#pragma mark public
bool ibootpatchfinder32_base::has_kernel_load(){
try {
return (bool) (memstr(KERNELCACHE_PREP_STRING) != 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
namespace tihmstar {
namespace patchfinder {
class ibootpatchfinder32_base : public ibootpatchfinder32{
void init();
public:
ibootpatchfinder32_base(const char *filename);
ibootpatchfinder32_base(const void *buffer, size_t bufSize, bool takeOwnership = false);
Expand Down
6 changes: 0 additions & 6 deletions libpatchfinder/ibootpatchfinder/ibootpatchfinder64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ ibootpatchfinder64::ibootpatchfinder64(bool freeBuf)
//
}

ibootpatchfinder64::ibootpatchfinder64(ibootpatchfinder64 &&mv)
: patchfinder64(std::move(mv))
{
_vers = mv._vers;
}

ibootpatchfinder64 *ibootpatchfinder64::make_ibootpatchfinder64(const char * filename){
bool didConstructSuccessfully = false;
int fd = 0;
Expand Down
86 changes: 54 additions & 32 deletions libpatchfinder/ibootpatchfinder/ibootpatchfinder64_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,29 @@ using namespace tihmstar::libinsn::arm64;
ibootpatchfinder64_base::ibootpatchfinder64_base(const char * filename) :
ibootpatchfinder64(true)
{
int fd = 0;
void *buf = NULL;
int fd = -1;
cleanup([&]{
safeClose(fd);
safeFree(buf);
})
size_t bufSize = 0;
struct stat fs = {};

assure((fd = open(filename, O_RDONLY)) != -1);
assure(!fstat(fd, &fs));
assure((buf = (uint8_t*)malloc( bufSize = fs.st_size)));
assure(read(fd,(void*)buf,bufSize)==bufSize);
assure((_buf = (uint8_t*)malloc(_bufSize = fs.st_size)));
assure(read(fd,(void*)_buf,_bufSize)==_bufSize);

assure(bufSize > 0x1000);
this->make_ibootpatchfinder64(buf, bufSize, true);
buf = NULL;
init();
}

ibootpatchfinder64_base::ibootpatchfinder64_base(const void *buffer, size_t bufSize, bool takeOwnership)
: ibootpatchfinder64(takeOwnership)
{
_bufSize = bufSize;
_buf = (uint8_t*)buffer;
init();
}

void ibootpatchfinder64_base::init(){
assure(_bufSize > 0x1000);

assure(!strncmp((char*)&_buf[IBOOT_VERS_STR_OFFSET], "iBoot", sizeof("iBoot")-1));
Expand All @@ -65,6 +64,7 @@ ibootpatchfinder64_base::ibootpatchfinder64_base(const void *buffer, size_t bufS

_entrypoint = _base = (loc_t)*(uint64_t*)&_buf[iBOOT_BASE_OFFSET];
debug("iBoot base at=0x%016llx\n", _base);
safeDelete(_vmem);
_vmem = new vmem({{_buf,_bufSize,_base, (vmprot)(kVMPROTREAD | kVMPROTWRITE | kVMPROTEXEC)}});
retassure(_vers = atoi((char*)&_buf[IBOOT_VERS_STR_OFFSET+6]), "No iBoot version found!\n");
debug("iBoot-%d inputted\n", _vers);
Expand All @@ -74,6 +74,7 @@ ibootpatchfinder64_base::~ibootpatchfinder64_base(){
//
}

#pragma mark public
bool ibootpatchfinder64_base::has_kernel_load(){
try {
return (bool) (_vmem->memstr(KERNELCACHE_PREP_STRING) != 0);
Expand Down Expand Up @@ -457,6 +458,9 @@ std::vector<patch> ibootpatchfinder64_base::replace_cmd_with_memcpy(const char *

pushINSN(insn::new_immediate_cmp(cPC, 4, 0));
pushINSN(insn::new_immediate_bcond(cPC, shellcode+insnRet*4, insn::cond::NE));
/*
iPhone 5s iOS 12 still uses 0x30+0x28*x formula
*/
pushINSN(insn::new_immediate_ldr_unsigned(cPC, 0x30+0x28*2, 1, 2));
pushINSN(insn::new_immediate_ldr_unsigned(cPC, 0x30+0x28*0, 1, 0));
pushINSN(insn::new_immediate_ldr_unsigned(cPC, 0x30+0x28*1, 1, 1));
Expand Down Expand Up @@ -518,40 +522,58 @@ std::vector<patch> ibootpatchfinder64_base::get_ra1nra1n_patch(){
loc_t findloc = memmem("\x12\x00\x80\xd2", 4);
debug("findloc=0x%016llx\n",findloc);

constexpr const char patch[] = "\xE8\x03\x1D\xAA\xE9\x03\x1D\xAA\x1B\x01\xC0\xD2\x1B\x00\xA3\xF2\xFD\x03\x1B\xAA";

patches.push_back({findloc,patch,sizeof(patch)-1});
auto iter = _vmem->getIter(findloc);
while (++iter != insn::mov && iter().rd() != 30){
retassure(iter() != insn::ret, "got unexpected ret!");
}
uint8_t srcreg = iter().rm();

findloc-=4;
pushINSN(insn::new_register_mov(findloc+=4, 0, 8, srcreg));
pushINSN(insn::new_register_mov(findloc+=4, 0, 9, srcreg));
/*
0x7000 iOS 12 buffers the ramdisk at 0x818000000. If we write ra1nra1n there, the ramdisk gets corrupted
*/
pushINSN(insn::new_immediate_movz(findloc+=4, 0x8, 27, 32));
pushINSN(insn::new_immediate_movk(findloc+=4, 0x2000, 27, 16));
pushINSN(insn::new_register_mov(findloc+=4, 0, 29, 27));


/*
Disable bzero above 0x818000000
*/

loc_t findloc2 = memmem("\x23\x74\x0b\xd5", 4);
debug("findloc2=0x%016llx\n",findloc2);

loc_t bzero = find_bof(findloc2);
debug("bzero=0x%016llx\n",bzero);

int shellcodesize = 10*sizeof(uint32_t); //commitment

loc_t shellcode = findnops(shellcodesize/4);
debug("shellcode=0x%016llx\n",shellcode);
uint32_t shellcode_insn_cnt = 10; //commitment
loc_t shellcode = findnops((shellcode_insn_cnt/2)+1, true, 0x00000000);
debug("shellcode=0x%016llx",shellcode);

pushINSN(insn::new_immediate_b(bzero, shellcode));

constexpr const char patch2[] = "\x03\x01\xC0\xD2\x03\x00\xA3\xF2\x1F\x00\x03\xEB\xA8\x00\x00\x54\x22\x00\x00\x8B\x5F\x00\x03\xEB\x43\x00\x00\x54\xC0\x03\x1F\xD6";
patches.push_back({shellcode,patch2,sizeof(patch2)-1});
shellcodesize -= sizeof(patch2)-1;

loc_t aftershellcode = shellcode+sizeof(patch2)-1;
debug("aftershellcode=0x%016llx\n",aftershellcode);

#define cPC (shellcode+(insnNum++)*4)
int insnNum = 0;
uint32_t shellend = 8;

pushINSN(insn::new_immediate_movz(cPC, 0x8, 3, 32));
pushINSN(insn::new_immediate_movk(cPC, 0x1800, 3, 16));
pushINSN(insn::new_register_cmp(cPC, 0, 0, 3, -1));
pushINSN(insn::new_immediate_bcond(cPC, shellcode+shellend*4, insn::HI));
pushINSN(insn::new_register_add(cPC, 0, 1, 0, 2));
pushINSN(insn::new_register_cmp(cPC, 0, 2, 3, -1));
pushINSN(insn::new_immediate_bcond(cPC, shellcode+shellend*4, insn::CC));
pushINSN(insn::new_general_br(cPC, 30));
assure(shellend == insnNum);
uint32_t backUpProloge = (uint32_t)deref(bzero);
patches.push_back({shellcode+insnNum*4, &backUpProloge, 4});insnNum++;
pushINSN(insn::new_immediate_b(cPC, (int64_t)bzero+4));
assure(insnNum == shellcode_insn_cnt);
#undef cPC

patches.push_back({aftershellcode, &backUpProloge, 4});
aftershellcode +=4;
shellcodesize -=4;

pushINSN(insn::new_immediate_b(aftershellcode, (int64_t)bzero+4));
shellcodesize -=4;

assure(shellcodesize >=0);
return patches;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
namespace tihmstar {
namespace patchfinder {
class ibootpatchfinder64_base : public ibootpatchfinder64{
void init();
public:
ibootpatchfinder64_base(const char *filename);
ibootpatchfinder64_base(const void *buffer, size_t bufSize, bool takeOwnership = false);
Expand Down
Loading

0 comments on commit 7f982dd

Please sign in to comment.