├── .github
├── FUNDING.yml
└── workflows
│ └── build.yml
├── .gitignore
├── COPYING
├── Makefile.am
├── NEWS
├── README.md
├── autogen.sh
├── configure.ac
├── git-version-gen
├── include
├── Makefile.am
└── libirecovery.h
├── m4
└── as-compiler-flag.m4
├── src
├── Makefile.am
├── libirecovery-1.0.pc.in
└── libirecovery.c
├── tools
├── Makefile.am
└── irecovery.c
└── udev
├── 39-libirecovery.rules.in
└── Makefile.am
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: nikias
2 | patreon: nikias
3 | custom: ["https://www.paypal.me/NikiasBassen"]
4 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | schedule:
6 | - cron: '0 0 1 * *'
7 |
8 | jobs:
9 | build-linux-ubuntu:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: install dependencies
13 | run: |
14 | sudo apt-get update
15 | sudo apt-get install libusb-1.0-0-dev
16 | - name: prepare environment
17 | run: |
18 | echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
19 | - name: fetch libplist
20 | uses: dawidd6/action-download-artifact@v6
21 | with:
22 | github_token: ${{secrets.GITHUB_TOKEN}}
23 | workflow: build.yml
24 | name: libplist-latest_${{env.target_triplet}}
25 | repo: libimobiledevice/libplist
26 | - name: fetch libimobiledevice-glue
27 | uses: dawidd6/action-download-artifact@v6
28 | with:
29 | github_token: ${{secrets.GITHUB_TOKEN}}
30 | workflow: build.yml
31 | name: libimobiledevice-glue-latest_${{env.target_triplet}}
32 | repo: libimobiledevice/libimobiledevice-glue
33 | - name: install external dependencies
34 | run: |
35 | mkdir extract
36 | for I in *.tar; do
37 | tar -C extract -xvf $I
38 | done
39 | sudo cp -r extract/* /
40 | sudo ldconfig
41 | - uses: actions/checkout@v4
42 | - name: autogen
43 | run: ./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig LDFLAGS="-Wl,-rpath=/usr/local/lib"
44 | - name: make
45 | run: make
46 | - name: make install
47 | run: sudo make install
48 | - name: prepare artifact
49 | run: |
50 | mkdir -p dest
51 | DESTDIR=`pwd`/dest make install
52 | tar -C dest -cf libirecovery.tar --strip-components 1 .
53 | - name: publish artifact
54 | uses: actions/upload-artifact@v4
55 | with:
56 | name: libirecovery-latest_${{env.target_triplet}}
57 | path: libirecovery.tar
58 | build-macOS:
59 | runs-on: macOS-latest
60 | steps:
61 | - name: install dependencies
62 | run: |
63 | if test -x "`which port`"; then
64 | sudo port install libtool autoconf automake pkgconfig
65 | else
66 | brew install libtool autoconf automake pkgconfig
67 | fi
68 | shell: bash
69 | - name: fetch libplist
70 | uses: dawidd6/action-download-artifact@v6
71 | with:
72 | github_token: ${{secrets.GITHUB_TOKEN}}
73 | workflow: build.yml
74 | name: libplist-latest_macOS
75 | repo: libimobiledevice/libplist
76 | - name: fetch libimobiledevice-glue
77 | uses: dawidd6/action-download-artifact@v6
78 | with:
79 | github_token: ${{secrets.GITHUB_TOKEN}}
80 | workflow: build.yml
81 | name: libimobiledevice-glue-latest_macOS
82 | repo: libimobiledevice/libimobiledevice-glue
83 | - name: install external dependencies
84 | run: |
85 | mkdir extract
86 | for I in *.tar; do
87 | tar -C extract -xvf $I
88 | done
89 | sudo cp -r extract/* /
90 | - uses: actions/checkout@v4
91 | - name: autogen
92 | run: |
93 | SDKDIR=`xcrun --sdk macosx --show-sdk-path`
94 | TESTARCHS="arm64 x86_64"
95 | USEARCHS=
96 | for ARCH in $TESTARCHS; do
97 | if echo "int main(int argc, char **argv) { return 0; }" |clang -arch $ARCH -o /dev/null -isysroot $SDKDIR -x c - 2>/dev/null; then
98 | USEARCHS="$USEARCHS -arch $ARCH"
99 | fi
100 | done
101 | export CFLAGS="$USEARCHS -isysroot $SDKDIR"
102 | echo "Using CFLAGS: $CFLAGS"
103 | ./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
104 | - name: make
105 | run: make
106 | - name: make install
107 | run: sudo make install
108 | - name: prepare artifact
109 | run: |
110 | mkdir -p dest
111 | DESTDIR=`pwd`/dest make install
112 | tar -C dest -cf libirecovery.tar --strip-components 1 .
113 | - name: publish artifact
114 | uses: actions/upload-artifact@v4
115 | with:
116 | name: libirecovery-latest_macOS
117 | path: libirecovery.tar
118 | build-windows:
119 | runs-on: windows-latest
120 | defaults:
121 | run:
122 | shell: msys2 {0}
123 | strategy:
124 | fail-fast: false
125 | matrix:
126 | include: [
127 | { msystem: MINGW64, arch: x86_64 },
128 | { msystem: MINGW32, arch: i686 }
129 | ]
130 | steps:
131 | - uses: msys2/setup-msys2@v2
132 | with:
133 | msystem: ${{ matrix.msystem }}
134 | release: false
135 | update: false
136 | install: >-
137 | base-devel
138 | git
139 | mingw-w64-${{ matrix.arch }}-gcc
140 | mingw-w64-${{ matrix.arch }}-pkg-config
141 | make
142 | libtool
143 | autoconf
144 | automake-wrapper
145 | - name: prepare environment
146 | run: |
147 | dest=`echo ${{ matrix.msystem }} |tr [:upper:] [:lower:]`
148 | echo "dest=$dest" >> $GITHUB_ENV
149 | echo "target_triplet=`gcc -dumpmachine`" >> $GITHUB_ENV
150 | - name: fetch libplist
151 | uses: dawidd6/action-download-artifact@v6
152 | with:
153 | github_token: ${{secrets.GITHUB_TOKEN}}
154 | workflow: build.yml
155 | name: libplist-latest_${{ matrix.arch }}-${{ env.dest }}
156 | repo: libimobiledevice/libplist
157 | - name: fetch libimobiledevice-glue
158 | uses: dawidd6/action-download-artifact@v6
159 | with:
160 | github_token: ${{secrets.GITHUB_TOKEN}}
161 | workflow: build.yml
162 | name: libimobiledevice-glue-latest_${{ matrix.arch }}-${{ env.dest }}
163 | repo: libimobiledevice/libimobiledevice-glue
164 | - name: install external dependencies
165 | run: |
166 | mkdir extract
167 | for I in *.tar; do
168 | tar -C extract -xvf $I
169 | done
170 | cp -r extract/* /
171 | - uses: actions/checkout@v4
172 | - name: autogen
173 | run: ./autogen.sh CC=gcc CXX=g++
174 | - name: make
175 | run: make
176 | - name: make install
177 | run: make install
178 | - name: prepare artifact
179 | run: |
180 | mkdir -p dest
181 | DESTDIR=`pwd`/dest make install
182 | tar -C dest -cf libirecovery.tar ${{ env.dest }}
183 | - name: publish artifact
184 | uses: actions/upload-artifact@v4
185 | with:
186 | name: libirecovery-latest_${{ matrix.arch }}-${{ env.dest }}
187 | path: libirecovery.tar
188 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.[oa]
2 | *~
3 | *.po
4 | *.lo
5 | *.la
6 | autom4te.cache/*
7 | *.in
8 | */.deps/*
9 | m4/*
10 | *.dll
11 | *.so
12 | *.dylib
13 | *.patch
14 | aclocal.m4
15 | config.h
16 | config.log
17 | config.sub
18 | config.guess
19 | config.status
20 | configure
21 | depcomp
22 | install-sh
23 | compile
24 | main
25 | ltmain.sh
26 | missing
27 | mkinstalldirs
28 | libtool
29 | *Makefile
30 | stamp-h1
31 | src/.libs
32 | *.pc
33 | tools/.libs/*
34 | tools/irecovery
35 | .irecovery
36 | udev/39-libirecovery.rules
37 | .idea
38 | .vscode
39 | .DS_Store
40 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | [This is the first released version of the Lesser GPL. It also counts
10 | as the successor of the GNU Library Public License, version 2, hence
11 | the version number 2.1.]
12 |
13 | Preamble
14 |
15 | The licenses for most software are designed to take away your
16 | freedom to share and change it. By contrast, the GNU General Public
17 | Licenses are intended to guarantee your freedom to share and change
18 | free software--to make sure the software is free for all its users.
19 |
20 | This license, the Lesser General Public License, applies to some
21 | specially designated software packages--typically libraries--of the
22 | Free Software Foundation and other authors who decide to use it. You
23 | can use it too, but we suggest you first think carefully about whether
24 | this license or the ordinary General Public License is the better
25 | strategy to use in any particular case, based on the explanations below.
26 |
27 | When we speak of free software, we are referring to freedom of use,
28 | not price. Our General Public Licenses are designed to make sure that
29 | you have the freedom to distribute copies of free software (and charge
30 | for this service if you wish); that you receive source code or can get
31 | it if you want it; that you can change the software and use pieces of
32 | it in new free programs; and that you are informed that you can do
33 | these things.
34 |
35 | To protect your rights, we need to make restrictions that forbid
36 | distributors to deny you these rights or to ask you to surrender these
37 | rights. These restrictions translate to certain responsibilities for
38 | you if you distribute copies of the library or if you modify it.
39 |
40 | For example, if you distribute copies of the library, whether gratis
41 | or for a fee, you must give the recipients all the rights that we gave
42 | you. You must make sure that they, too, receive or can get the source
43 | code. If you link other code with the library, you must provide
44 | complete object files to the recipients, so that they can relink them
45 | with the library after making changes to the library and recompiling
46 | it. And you must show them these terms so they know their rights.
47 |
48 | We protect your rights with a two-step method: (1) we copyright the
49 | library, and (2) we offer you this license, which gives you legal
50 | permission to copy, distribute and/or modify the library.
51 |
52 | To protect each distributor, we want to make it very clear that
53 | there is no warranty for the free library. Also, if the library is
54 | modified by someone else and passed on, the recipients should know
55 | that what they have is not the original version, so that the original
56 | author's reputation will not be affected by problems that might be
57 | introduced by others.
58 |
59 | Finally, software patents pose a constant threat to the existence of
60 | any free program. We wish to make sure that a company cannot
61 | effectively restrict the users of a free program by obtaining a
62 | restrictive license from a patent holder. Therefore, we insist that
63 | any patent license obtained for a version of the library must be
64 | consistent with the full freedom of use specified in this license.
65 |
66 | Most GNU software, including some libraries, is covered by the
67 | ordinary GNU General Public License. This license, the GNU Lesser
68 | General Public License, applies to certain designated libraries, and
69 | is quite different from the ordinary General Public License. We use
70 | this license for certain libraries in order to permit linking those
71 | libraries into non-free programs.
72 |
73 | When a program is linked with a library, whether statically or using
74 | a shared library, the combination of the two is legally speaking a
75 | combined work, a derivative of the original library. The ordinary
76 | General Public License therefore permits such linking only if the
77 | entire combination fits its criteria of freedom. The Lesser General
78 | Public License permits more lax criteria for linking other code with
79 | the library.
80 |
81 | We call this license the "Lesser" General Public License because it
82 | does Less to protect the user's freedom than the ordinary General
83 | Public License. It also provides other free software developers Less
84 | of an advantage over competing non-free programs. These disadvantages
85 | are the reason we use the ordinary General Public License for many
86 | libraries. However, the Lesser license provides advantages in certain
87 | special circumstances.
88 |
89 | For example, on rare occasions, there may be a special need to
90 | encourage the widest possible use of a certain library, so that it becomes
91 | a de-facto standard. To achieve this, non-free programs must be
92 | allowed to use the library. A more frequent case is that a free
93 | library does the same job as widely used non-free libraries. In this
94 | case, there is little to gain by limiting the free library to free
95 | software only, so we use the Lesser General Public License.
96 |
97 | In other cases, permission to use a particular library in non-free
98 | programs enables a greater number of people to use a large body of
99 | free software. For example, permission to use the GNU C Library in
100 | non-free programs enables many more people to use the whole GNU
101 | operating system, as well as its variant, the GNU/Linux operating
102 | system.
103 |
104 | Although the Lesser General Public License is Less protective of the
105 | users' freedom, it does ensure that the user of a program that is
106 | linked with the Library has the freedom and the wherewithal to run
107 | that program using a modified version of the Library.
108 |
109 | The precise terms and conditions for copying, distribution and
110 | modification follow. Pay close attention to the difference between a
111 | "work based on the library" and a "work that uses the library". The
112 | former contains code derived from the library, whereas the latter must
113 | be combined with the library in order to run.
114 |
115 | GNU LESSER GENERAL PUBLIC LICENSE
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117 |
118 | 0. This License Agreement applies to any software library or other
119 | program which contains a notice placed by the copyright holder or
120 | other authorized party saying it may be distributed under the terms of
121 | this Lesser General Public License (also called "this License").
122 | Each licensee is addressed as "you".
123 |
124 | A "library" means a collection of software functions and/or data
125 | prepared so as to be conveniently linked with application programs
126 | (which use some of those functions and data) to form executables.
127 |
128 | The "Library", below, refers to any such software library or work
129 | which has been distributed under these terms. A "work based on the
130 | Library" means either the Library or any derivative work under
131 | copyright law: that is to say, a work containing the Library or a
132 | portion of it, either verbatim or with modifications and/or translated
133 | straightforwardly into another language. (Hereinafter, translation is
134 | included without limitation in the term "modification".)
135 |
136 | "Source code" for a work means the preferred form of the work for
137 | making modifications to it. For a library, complete source code means
138 | all the source code for all modules it contains, plus any associated
139 | interface definition files, plus the scripts used to control compilation
140 | and installation of the library.
141 |
142 | Activities other than copying, distribution and modification are not
143 | covered by this License; they are outside its scope. The act of
144 | running a program using the Library is not restricted, and output from
145 | such a program is covered only if its contents constitute a work based
146 | on the Library (independent of the use of the Library in a tool for
147 | writing it). Whether that is true depends on what the Library does
148 | and what the program that uses the Library does.
149 |
150 | 1. You may copy and distribute verbatim copies of the Library's
151 | complete source code as you receive it, in any medium, provided that
152 | you conspicuously and appropriately publish on each copy an
153 | appropriate copyright notice and disclaimer of warranty; keep intact
154 | all the notices that refer to this License and to the absence of any
155 | warranty; and distribute a copy of this License along with the
156 | Library.
157 |
158 | You may charge a fee for the physical act of transferring a copy,
159 | and you may at your option offer warranty protection in exchange for a
160 | fee.
161 |
162 | 2. You may modify your copy or copies of the Library or any portion
163 | of it, thus forming a work based on the Library, and copy and
164 | distribute such modifications or work under the terms of Section 1
165 | above, provided that you also meet all of these conditions:
166 |
167 | a) The modified work must itself be a software library.
168 |
169 | b) You must cause the files modified to carry prominent notices
170 | stating that you changed the files and the date of any change.
171 |
172 | c) You must cause the whole of the work to be licensed at no
173 | charge to all third parties under the terms of this License.
174 |
175 | d) If a facility in the modified Library refers to a function or a
176 | table of data to be supplied by an application program that uses
177 | the facility, other than as an argument passed when the facility
178 | is invoked, then you must make a good faith effort to ensure that,
179 | in the event an application does not supply such function or
180 | table, the facility still operates, and performs whatever part of
181 | its purpose remains meaningful.
182 |
183 | (For example, a function in a library to compute square roots has
184 | a purpose that is entirely well-defined independent of the
185 | application. Therefore, Subsection 2d requires that any
186 | application-supplied function or table used by this function must
187 | be optional: if the application does not supply it, the square
188 | root function must still compute square roots.)
189 |
190 | These requirements apply to the modified work as a whole. If
191 | identifiable sections of that work are not derived from the Library,
192 | and can be reasonably considered independent and separate works in
193 | themselves, then this License, and its terms, do not apply to those
194 | sections when you distribute them as separate works. But when you
195 | distribute the same sections as part of a whole which is a work based
196 | on the Library, the distribution of the whole must be on the terms of
197 | this License, whose permissions for other licensees extend to the
198 | entire whole, and thus to each and every part regardless of who wrote
199 | it.
200 |
201 | Thus, it is not the intent of this section to claim rights or contest
202 | your rights to work written entirely by you; rather, the intent is to
203 | exercise the right to control the distribution of derivative or
204 | collective works based on the Library.
205 |
206 | In addition, mere aggregation of another work not based on the Library
207 | with the Library (or with a work based on the Library) on a volume of
208 | a storage or distribution medium does not bring the other work under
209 | the scope of this License.
210 |
211 | 3. You may opt to apply the terms of the ordinary GNU General Public
212 | License instead of this License to a given copy of the Library. To do
213 | this, you must alter all the notices that refer to this License, so
214 | that they refer to the ordinary GNU General Public License, version 2,
215 | instead of to this License. (If a newer version than version 2 of the
216 | ordinary GNU General Public License has appeared, then you can specify
217 | that version instead if you wish.) Do not make any other change in
218 | these notices.
219 |
220 | Once this change is made in a given copy, it is irreversible for
221 | that copy, so the ordinary GNU General Public License applies to all
222 | subsequent copies and derivative works made from that copy.
223 |
224 | This option is useful when you wish to copy part of the code of
225 | the Library into a program that is not a library.
226 |
227 | 4. You may copy and distribute the Library (or a portion or
228 | derivative of it, under Section 2) in object code or executable form
229 | under the terms of Sections 1 and 2 above provided that you accompany
230 | it with the complete corresponding machine-readable source code, which
231 | must be distributed under the terms of Sections 1 and 2 above on a
232 | medium customarily used for software interchange.
233 |
234 | If distribution of object code is made by offering access to copy
235 | from a designated place, then offering equivalent access to copy the
236 | source code from the same place satisfies the requirement to
237 | distribute the source code, even though third parties are not
238 | compelled to copy the source along with the object code.
239 |
240 | 5. A program that contains no derivative of any portion of the
241 | Library, but is designed to work with the Library by being compiled or
242 | linked with it, is called a "work that uses the Library". Such a
243 | work, in isolation, is not a derivative work of the Library, and
244 | therefore falls outside the scope of this License.
245 |
246 | However, linking a "work that uses the Library" with the Library
247 | creates an executable that is a derivative of the Library (because it
248 | contains portions of the Library), rather than a "work that uses the
249 | library". The executable is therefore covered by this License.
250 | Section 6 states terms for distribution of such executables.
251 |
252 | When a "work that uses the Library" uses material from a header file
253 | that is part of the Library, the object code for the work may be a
254 | derivative work of the Library even though the source code is not.
255 | Whether this is true is especially significant if the work can be
256 | linked without the Library, or if the work is itself a library. The
257 | threshold for this to be true is not precisely defined by law.
258 |
259 | If such an object file uses only numerical parameters, data
260 | structure layouts and accessors, and small macros and small inline
261 | functions (ten lines or less in length), then the use of the object
262 | file is unrestricted, regardless of whether it is legally a derivative
263 | work. (Executables containing this object code plus portions of the
264 | Library will still fall under Section 6.)
265 |
266 | Otherwise, if the work is a derivative of the Library, you may
267 | distribute the object code for the work under the terms of Section 6.
268 | Any executables containing that work also fall under Section 6,
269 | whether or not they are linked directly with the Library itself.
270 |
271 | 6. As an exception to the Sections above, you may also combine or
272 | link a "work that uses the Library" with the Library to produce a
273 | work containing portions of the Library, and distribute that work
274 | under terms of your choice, provided that the terms permit
275 | modification of the work for the customer's own use and reverse
276 | engineering for debugging such modifications.
277 |
278 | You must give prominent notice with each copy of the work that the
279 | Library is used in it and that the Library and its use are covered by
280 | this License. You must supply a copy of this License. If the work
281 | during execution displays copyright notices, you must include the
282 | copyright notice for the Library among them, as well as a reference
283 | directing the user to the copy of this License. Also, you must do one
284 | of these things:
285 |
286 | a) Accompany the work with the complete corresponding
287 | machine-readable source code for the Library including whatever
288 | changes were used in the work (which must be distributed under
289 | Sections 1 and 2 above); and, if the work is an executable linked
290 | with the Library, with the complete machine-readable "work that
291 | uses the Library", as object code and/or source code, so that the
292 | user can modify the Library and then relink to produce a modified
293 | executable containing the modified Library. (It is understood
294 | that the user who changes the contents of definitions files in the
295 | Library will not necessarily be able to recompile the application
296 | to use the modified definitions.)
297 |
298 | b) Use a suitable shared library mechanism for linking with the
299 | Library. A suitable mechanism is one that (1) uses at run time a
300 | copy of the library already present on the user's computer system,
301 | rather than copying library functions into the executable, and (2)
302 | will operate properly with a modified version of the library, if
303 | the user installs one, as long as the modified version is
304 | interface-compatible with the version that the work was made with.
305 |
306 | c) Accompany the work with a written offer, valid for at
307 | least three years, to give the same user the materials
308 | specified in Subsection 6a, above, for a charge no more
309 | than the cost of performing this distribution.
310 |
311 | d) If distribution of the work is made by offering access to copy
312 | from a designated place, offer equivalent access to copy the above
313 | specified materials from the same place.
314 |
315 | e) Verify that the user has already received a copy of these
316 | materials or that you have already sent this user a copy.
317 |
318 | For an executable, the required form of the "work that uses the
319 | Library" must include any data and utility programs needed for
320 | reproducing the executable from it. However, as a special exception,
321 | the materials to be distributed need not include anything that is
322 | normally distributed (in either source or binary form) with the major
323 | components (compiler, kernel, and so on) of the operating system on
324 | which the executable runs, unless that component itself accompanies
325 | the executable.
326 |
327 | It may happen that this requirement contradicts the license
328 | restrictions of other proprietary libraries that do not normally
329 | accompany the operating system. Such a contradiction means you cannot
330 | use both them and the Library together in an executable that you
331 | distribute.
332 |
333 | 7. You may place library facilities that are a work based on the
334 | Library side-by-side in a single library together with other library
335 | facilities not covered by this License, and distribute such a combined
336 | library, provided that the separate distribution of the work based on
337 | the Library and of the other library facilities is otherwise
338 | permitted, and provided that you do these two things:
339 |
340 | a) Accompany the combined library with a copy of the same work
341 | based on the Library, uncombined with any other library
342 | facilities. This must be distributed under the terms of the
343 | Sections above.
344 |
345 | b) Give prominent notice with the combined library of the fact
346 | that part of it is a work based on the Library, and explaining
347 | where to find the accompanying uncombined form of the same work.
348 |
349 | 8. You may not copy, modify, sublicense, link with, or distribute
350 | the Library except as expressly provided under this License. Any
351 | attempt otherwise to copy, modify, sublicense, link with, or
352 | distribute the Library is void, and will automatically terminate your
353 | rights under this License. However, parties who have received copies,
354 | or rights, from you under this License will not have their licenses
355 | terminated so long as such parties remain in full compliance.
356 |
357 | 9. You are not required to accept this License, since you have not
358 | signed it. However, nothing else grants you permission to modify or
359 | distribute the Library or its derivative works. These actions are
360 | prohibited by law if you do not accept this License. Therefore, by
361 | modifying or distributing the Library (or any work based on the
362 | Library), you indicate your acceptance of this License to do so, and
363 | all its terms and conditions for copying, distributing or modifying
364 | the Library or works based on it.
365 |
366 | 10. Each time you redistribute the Library (or any work based on the
367 | Library), the recipient automatically receives a license from the
368 | original licensor to copy, distribute, link with or modify the Library
369 | subject to these terms and conditions. You may not impose any further
370 | restrictions on the recipients' exercise of the rights granted herein.
371 | You are not responsible for enforcing compliance by third parties with
372 | this License.
373 |
374 | 11. If, as a consequence of a court judgment or allegation of patent
375 | infringement or for any other reason (not limited to patent issues),
376 | conditions are imposed on you (whether by court order, agreement or
377 | otherwise) that contradict the conditions of this License, they do not
378 | excuse you from the conditions of this License. If you cannot
379 | distribute so as to satisfy simultaneously your obligations under this
380 | License and any other pertinent obligations, then as a consequence you
381 | may not distribute the Library at all. For example, if a patent
382 | license would not permit royalty-free redistribution of the Library by
383 | all those who receive copies directly or indirectly through you, then
384 | the only way you could satisfy both it and this License would be to
385 | refrain entirely from distribution of the Library.
386 |
387 | If any portion of this section is held invalid or unenforceable under any
388 | particular circumstance, the balance of the section is intended to apply,
389 | and the section as a whole is intended to apply in other circumstances.
390 |
391 | It is not the purpose of this section to induce you to infringe any
392 | patents or other property right claims or to contest validity of any
393 | such claims; this section has the sole purpose of protecting the
394 | integrity of the free software distribution system which is
395 | implemented by public license practices. Many people have made
396 | generous contributions to the wide range of software distributed
397 | through that system in reliance on consistent application of that
398 | system; it is up to the author/donor to decide if he or she is willing
399 | to distribute software through any other system and a licensee cannot
400 | impose that choice.
401 |
402 | This section is intended to make thoroughly clear what is believed to
403 | be a consequence of the rest of this License.
404 |
405 | 12. If the distribution and/or use of the Library is restricted in
406 | certain countries either by patents or by copyrighted interfaces, the
407 | original copyright holder who places the Library under this License may add
408 | an explicit geographical distribution limitation excluding those countries,
409 | so that distribution is permitted only in or among countries not thus
410 | excluded. In such case, this License incorporates the limitation as if
411 | written in the body of this License.
412 |
413 | 13. The Free Software Foundation may publish revised and/or new
414 | versions of the Lesser General Public License from time to time.
415 | Such new versions will be similar in spirit to the present version,
416 | but may differ in detail to address new problems or concerns.
417 |
418 | Each version is given a distinguishing version number. If the Library
419 | specifies a version number of this License which applies to it and
420 | "any later version", you have the option of following the terms and
421 | conditions either of that version or of any later version published by
422 | the Free Software Foundation. If the Library does not specify a
423 | license version number, you may choose any version ever published by
424 | the Free Software Foundation.
425 |
426 | 14. If you wish to incorporate parts of the Library into other free
427 | programs whose distribution conditions are incompatible with these,
428 | write to the author to ask for permission. For software which is
429 | copyrighted by the Free Software Foundation, write to the Free
430 | Software Foundation; we sometimes make exceptions for this. Our
431 | decision will be guided by the two goals of preserving the free status
432 | of all derivatives of our free software and of promoting the sharing
433 | and reuse of software generally.
434 |
435 | NO WARRANTY
436 |
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446 |
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456 | DAMAGES.
457 |
458 | END OF TERMS AND CONDITIONS
459 |
460 | How to Apply These Terms to Your New Libraries
461 |
462 | If you develop a new library, and you want it to be of the greatest
463 | possible use to the public, we recommend making it free software that
464 | everyone can redistribute and change. You can do so by permitting
465 | redistribution under these terms (or, alternatively, under the terms of the
466 | ordinary General Public License).
467 |
468 | To apply these terms, attach the following notices to the library. It is
469 | safest to attach them to the start of each source file to most effectively
470 | convey the exclusion of warranty; and each file should have at least the
471 | "copyright" line and a pointer to where the full notice is found.
472 |
473 | <one line to give the library's name and a brief idea of what it does.>
474 | Copyright (C) <year> <name of author>
475 |
476 | This library is free software; you can redistribute it and/or
477 | modify it under the terms of the GNU Lesser General Public
478 | License as published by the Free Software Foundation; either
479 | version 2.1 of the License, or (at your option) any later version.
480 |
481 | This library is distributed in the hope that it will be useful,
482 | but WITHOUT ANY WARRANTY; without even the implied warranty of
483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 | Lesser General Public License for more details.
485 |
486 | You should have received a copy of the GNU Lesser General Public
487 | License along with this library; if not, write to the Free Software
488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
489 |
490 | Also add information on how to contact you by electronic and paper mail.
491 |
492 | You should also get your employer (if you work as a programmer) or your
493 | school, if any, to sign a "copyright disclaimer" for the library, if
494 | necessary. Here is a sample; alter the names:
495 |
496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498 |
499 | <signature of Ty Coon>, 1 April 1990
500 | Ty Coon, President of Vice
501 |
502 | That's all there is to it!
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | AUTOMAKE_OPTIONS = foreign
2 | ACLOCAL_AMFLAGS = -I m4
3 | SUBDIRS = src include tools udev
4 |
5 | EXTRA_DIST = \
6 | README.md \
7 | git-version-gen
8 |
9 | dist-hook:
10 | @if ! git diff --quiet; then echo "Uncommitted changes present; not releasing"; exit 1; fi
11 | echo $(VERSION) > $(distdir)/.tarball-version
12 |
13 | DISTCHECK_CONFIGURE_FLAGS = \
14 | --with-udevrulesdir=$dc_install_base/$(udevrulesdir)
15 |
--------------------------------------------------------------------------------
/NEWS:
--------------------------------------------------------------------------------
1 | Version 1.3.1
2 | ~~~~~~~~~~~~~
3 |
4 | * Device database changes:
5 | - Support iPad Pro M5 family devices
6 | - Support Apple Vision Pro M5
7 | - Support MacBook Pro 14-inch M5
8 |
9 | * Bug Fixes:
10 | Fix: array initialization compatibility with MSVC
11 |
12 |
13 | Version 1.3.0
14 | ~~~~~~~~~~~~~
15 |
16 | * Changes:
17 | - Switch to better initializer strategy
18 | - Allow building without readline support for the irecovery tool
19 | - Added support for iOS 1 and iOS 2 recovery mode (Linux, macOS)
20 |
21 | * Device database changes:
22 | - Support iPhone 17 family devices
23 | - Support Watch 11 / SE3 / Ultra3 models
24 | - Support March 2025 iPad and Mac models
25 | - Support iPhone 16e
26 | - Support November 2024 Mac models
27 | - Support iPad mini (A17 Pro)
28 |
29 | * Bug Fixes:
30 | - IOKit: Fix race condition when trying to delete runloop before it even started
31 |
32 |
33 | Version 1.2.1
34 | ~~~~~~~~~~~~~
35 |
36 | * Changes:
37 | - Make sure IRECV_DEVICE_REMOVE event has the mode set the device was in
38 | - KIS: Add some retry loops around open/set config/set interface operations
39 |
40 | * Device database changes:
41 | - Support Apple Watch Series 10 and iPhone 16 models
42 | - Add iPad Air (M2) and iPad Pro (M4) models
43 |
44 | * Bug Fixes:
45 | - Windows: Fix crash due to access to uninitialized data
46 |
47 |
48 | Version 1.2.0
49 | ~~~~~~~~~~~~~
50 |
51 | * Changes:
52 | - Allow building --without-tools
53 | - Add KIS (aka Debug USB) support for macOS, Linux, and Windows
54 | (Windows note: requires up-to-date AppleMobileDeviceSupport64.msi package installed)
55 | - Add Port DFU support (restore procedure is handled externally)
56 | - irecovery: Print detailed mode for -q and -m commands
57 | - Overall code cleanup and de-duplication
58 | - Windows-specific code cleanup and improvements
59 |
60 | * Device database changes:
61 | - Add Mac Pro, Mac Studio (M2) and MacBook Air (M2) models
62 | - Add iPhone 15 family
63 | - Add Apple Watch Series 9 and Ultra 2 models
64 | - Add November 2023 iMac and MacBook Pro models
65 | - Add support for Apple Vision Pro (RealityDevice14,1)
66 |
67 | * Bug Fixes:
68 | - A few minor Windows-specific bug fixes
69 |
70 | Version 1.1.0
71 | ~~~~~~~~~~~~~
72 |
73 | * Changes:
74 | - Remove duplicated thread/collection code and use new libimobiledevice-glue instead
75 | - Add new `irecv_send_command_breq` (for M1 restoring)
76 | - Add new `setenvnp` command
77 | - Add support for iPad 8 and iPad Air 4 models
78 | - Add all current Apple Watch models (device lookup)
79 | - Add support for HomePod and HomePod mini (device lookup)
80 | - Add support for Apple Silicon/M1 Macs (device lookup) and remaining T2/iBridge devices
81 | - Add iMac 24-inch M1 models
82 | - Add iPad Pro 11-inch (3rd gen) and iPad Pro 12.9-inch (5th gen) devices
83 | - Add Apple TV 4K (2nd gen)
84 | - Add iPhone 13 family
85 | - Add 9th gen iPad devices
86 | - Add 6th gen iPad mini
87 | - Add Apple Watch Series 7
88 | - Add MacBook Pro 2021 models (device lookup)
89 | - Add iPad Air (5th gen)
90 | - Add iPhone SE (3rd gen)
91 | - Add Mac Studio
92 | - Add Studio Display (device lookup)
93 | - Add device ID for macOS 12 Apple Silicon VMs
94 | - Add M2 MacBook models
95 | - Add iPhone 14 family
96 | - Add Apple Watch SE 2, Series 8 and Ultra family
97 | - Add iPad (10th gen)
98 | - Add iPad Pro 11-inch (4th gen) and iPad Pro 12.9-inch (6th gen)
99 | - Add Apple TV 4K 3rd gen
100 | - Add January 2023 Macs and 2nd generation HomePod models
101 | - [Windows] Add support for newer drivers
102 | - irecovery: Add new "--devices" option to list internal device data
103 | - irecovery: Output product, model and marketing name for device information
104 |
105 | * Bug Fixes:
106 | - Send a ZLP in recovery mode if the buffer size is a multiple of 512
107 | - Make sure DEVICE_ADD events are sent to additional event listeners
108 | - [Windows] Use ANSI versions for SetupDI and CreateFile API to prevent errors when compiling with unicode support
109 | - irecovery: Fix sending certain commands
110 |
111 | Version 1.0.0
112 | ~~~~~~~~~~~~~
113 |
114 | * Changes:
115 | - Output basic device information after connecting
116 | - Remove obsolete "in-tree" copy of libusb-1.0
117 | - Improve source code directory structure
118 | - Clean up and update of build system files
119 | - Major code refactoring
120 | - Add getters to retrieve device model information
121 | - Change exploit related wording to more accurate limera1n
122 | - Various improvements/fixes for win32 build
123 | - Add support for latest device models
124 | - Fix some memory leaks
125 | - Add requirement for autoconf 2.64
126 | - Support IOKit on OSX (removes dependency on libusb)
127 | - Add DFU mode error handling
128 | - Add udev rules to allow non-root device access
129 | - Support ECID in hex or decimal format
130 | - Fix various compiler warnings
131 | - Add device add/remove event subscription interface
132 | - Convert README to markdown
133 | - Print PWND string if present
134 | - Add support for Apple T2 processors
135 | - Allow compiling without USB functionality
136 | - Support checkra1n DFU mode devices
137 | - Allow toggling debug level using "LIBIRECOVERY_DEBUG_LEVEL" environment
138 | variable
139 | - Add long argument name variants to irecovery
140 | - Add new "--version" argument to irecovery
141 | - Add support for Apple Watch 1st gen devices
142 | - Add support for missing iPad4,3 model and fix wrong device information
143 | iPad7 variants
144 | - Improve README.md with project description, installation, contributing and
145 | usage sections
146 | - Rename library and all related files by adding an API version resulting
147 | in "libirecovery-1.0"
148 |
149 | Version 0.1.1
150 | ~~~~~~~~~~~~~
151 |
152 | * Changes:
153 | - Add serial number and imei getters
154 | - Improve USB communication stability
155 | - Add support for WTF mode
156 | - Add option to target device by ECID
157 | - Add nonce getter
158 | - Improve win32 device detection and mingw compatibility
159 | - Add support for new device models
160 | - Switch to autotools build system instead of plain Makefile
161 | - Expose control and bulk transfer methods in public interface
162 | - Improve maintainability of device model information
163 | - Change license to LGPL 2.1
164 |
165 | Version 0.1.0
166 | ~~~~~~~~~~~~~
167 |
168 | * Changes:
169 | - Implement initial interface and device communication
170 | - Add basic irecovery tool
171 | - Setup build system
172 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # libirecovery
2 |
3 | *The libirecovery library allows communication with iBoot/iBSS of iOS devices
4 | via USB.*
5 |
6 | 
7 |
8 | ## Table of Contents
9 | - [Features](#features)
10 | - [Building](#building)
11 | - [Prerequisites](#prerequisites)
12 | - [Linux (Debian/Ubuntu based)](#linux-debianubuntu-based)
13 | - [macOS](#macos)
14 | - [Windows](#windows)
15 | - [Configuring the source tree](#configuring-the-source-tree)
16 | - [Building and installation](#building-and-installation)
17 | - [Usage](#usage)
18 | - [Contributing](#contributing)
19 | - [Links](#links)
20 | - [License](#license)
21 | - [Credits](#credits)
22 |
23 | ## Features
24 |
25 | libirecovery is a cross-platform library which implements communication to
26 | iBoot/iBSS found on Apple's iOS devices via USB. A command-line utility named
27 | `irecovery` is also provided.
28 |
29 | This is a fork of an older version from former openjailbreak.org and is meant to
30 | be used with [idevicerestore](https://github.com/libimobiledevice/idevicerestore.git/) from the [libimobiledevice](https://github.com/libimobiledevice/) project.
31 |
32 | ## Building
33 |
34 | ### Prerequisites
35 |
36 | You need to have a working compiler (gcc/clang) and development environent
37 | available. This project uses autotools for the build process, allowing to
38 | have common build steps across different platforms.
39 | Only the prerequisites differ and they are described in this section.
40 |
41 | libirecovery requires [libimobiledevice-glue](https://github.com/libimobiledevice/libimobiledevice-glue).
42 | Some platforms already provide it as a package.
43 | Check the [Building](https://github.com/libimobiledevice/libimobiledevice-glue?tab=readme-ov-file#building)
44 | section of the README on how to build it.
45 |
46 | #### Linux (Debian/Ubuntu based)
47 |
48 | * Install all required dependencies and build tools:
49 | ```shell
50 | sudo apt-get install \
51 | build-essential \
52 | pkg-config \
53 | checkinstall \
54 | git \
55 | autoconf \
56 | automake \
57 | libtool-bin \
58 | libimobiledevice-glue-dev \
59 | libreadline-dev \
60 | libusb-1.0-0-dev
61 | ```
62 |
63 | In case libimobiledevice-glue-dev is not available, you can manually build and install it. See note above.
64 |
65 | #### macOS
66 |
67 | * Make sure the Xcode command line tools are installed. Then, use either [MacPorts](https://www.macports.org/)
68 | or [Homebrew](https://brew.sh/) to install `automake`, `autoconf`, `libtool`, etc.
69 |
70 | Using MacPorts:
71 | ```shell
72 | sudo port install libtool autoconf automake pkgconfig libimobiledevice-glue
73 | ```
74 |
75 | Using Homebrew:
76 | ```shell
77 | brew install libtool autoconf automake pkg-config libimobiledevice-glue
78 | ```
79 |
80 | #### Windows
81 |
82 | * Using [MSYS2](https://www.msys2.org/) is the official way of compiling this project on Windows. Download the MSYS2 installer
83 | and follow the installation steps.
84 |
85 | It is recommended to use the _MSYS2 MinGW 64-bit_ shell. Run it and make sure the required dependencies are installed:
86 |
87 | ```shell
88 | pacman -S base-devel \
89 | git \
90 | mingw-w64-x86_64-gcc \
91 | make \
92 | libtool \
93 | autoconf \
94 | automake-wrapper \
95 | pkg-config \
96 | mingw-w64-x86_64-libimobiledevice-glue \
97 | mingw-w64-x86_64-readline
98 | ```
99 | NOTE: You can use a different shell and different compiler according to your needs. Adapt the above command accordingly.
100 |
101 | ### Configuring the source tree
102 |
103 | You can build the source code from a git checkout, or from a `.tar.bz2` release tarball from [Releases](https://github.com/libimobiledevice/libirecovery/releases).
104 | Before we can build it, the source tree has to be configured for building. The steps depend on where you got the source from.
105 |
106 | Since libirecovery depends on other packages, you should set the pkg-config environment variable `PKG_CONFIG_PATH`
107 | accordingly. Make sure to use a path with the same prefix as the dependencies. If they are installed in `/usr/local` you would do
108 |
109 | ```shell
110 | export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
111 | ```
112 |
113 | * **From git**
114 |
115 | If you haven't done already, clone the actual project repository and change into the directory.
116 | ```shell
117 | git clone https://github.com/libimobiledevice/libirecovery
118 | cd libirecovery
119 | ```
120 |
121 | Configure the source tree for building:
122 | ```shell
123 | ./autogen.sh
124 | ```
125 |
126 | * **From release tarball (.tar.bz2)**
127 |
128 | When using an official [release tarball](https://github.com/libimobiledevice/libirecovery/releases) (`libirecovery-x.y.z.tar.bz2`)
129 | the procedure is slightly different.
130 |
131 | Extract the tarball:
132 | ```shell
133 | tar xjf libirecovery-x.y.z.tar.bz2
134 | cd libirecovery-x.y.z
135 | ```
136 |
137 | Configure the source tree for building:
138 | ```shell
139 | ./configure
140 | ```
141 |
142 | Both `./configure` and `./autogen.sh` (which generates and calls `configure`) accept a few options, for example `--prefix` to allow
143 | building for a different target folder. You can simply pass them like this:
144 |
145 | ```shell
146 | ./autogen.sh --prefix=/usr/local
147 | ```
148 | or
149 | ```shell
150 | ./configure --prefix=/usr/local
151 | ```
152 |
153 | Once the command is successful, the last few lines of output will look like this:
154 | ```
155 | [...]
156 | config.status: creating config.h
157 | config.status: executing depfiles commands
158 | config.status: executing libtool commands
159 |
160 | Configuration for libirecovery 1.2.0:
161 | -------------------------------------------
162 |
163 | Install prefix: .........: /usr/local
164 | USB backend: ............: IOKit
165 |
166 | Now type 'make' to build libirecovery 1.2.0,
167 | and then 'make install' for installation.
168 | ```
169 |
170 | ### Building and installation
171 |
172 | If you followed all the steps successfully, and `autogen.sh` or `configure` did not print any errors,
173 | you are ready to build the project. This is simply done with
174 |
175 | ```shell
176 | make
177 | ```
178 |
179 | If no errors are emitted you are ready for installation. Depending on whether
180 | the current user has permissions to write to the destination directory or not,
181 | you would either run
182 | ```shell
183 | make install
184 | ```
185 | _OR_
186 | ```shell
187 | sudo make install
188 | ```
189 |
190 | If you are on Linux, you want to run `sudo ldconfig` after installation to
191 | make sure the installed libraries are made available.
192 |
193 | ## Usage
194 |
195 | First of all attach your device to your machine. Make sure your device is not
196 | in normal mode. You can use the `ideviceenterrecovery` application from
197 | [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice.git/)
198 | to let your device boot into recovery mode if you need it.
199 |
200 | Then simply run:
201 | ```shell
202 | irecovery --shell
203 | ```
204 |
205 | This connects to your device and opens a simple shell to interact with the
206 | device.
207 |
208 | For instance to make your device boot into normal mode again use:
209 | ```shell
210 | setenv auto-boot true
211 | saveenv
212 | reboot
213 | ```
214 |
215 | Please consult the usage information or manual page for a full documentation of
216 | available command line options:
217 | ```shell
218 | irecovery --help
219 | man irecovery
220 | ```
221 |
222 | ## Contributing
223 |
224 | We welcome contributions from anyone and are grateful for every pull request!
225 |
226 | If you'd like to contribute, please fork the `master` branch, change, commit and
227 | send a pull request for review. Once approved it can be merged into the main
228 | code base.
229 |
230 | If you plan to contribute larger changes or a major refactoring, please create a
231 | ticket first to discuss the idea upfront to ensure less effort for everyone.
232 |
233 | Please make sure your contribution adheres to:
234 | * Try to follow the code style of the project
235 | * Commit messages should describe the change well without being too short
236 | * Try to split larger changes into individual commits of a common domain
237 | * Use your real name and a valid email address for your commits
238 |
239 | ## Links
240 |
241 | * Homepage: https://libimobiledevice.org/
242 | * Repository: https://github.com/libimobiledevice/libirecovery.git
243 | * Repository (Mirror): https://git.libimobiledevice.org/libirecovery.git
244 | * Issue Tracker: https://github.com/libimobiledevice/libirecovery/issues
245 | * Mailing List: https://lists.libimobiledevice.org/mailman/listinfo/libimobiledevice-devel
246 | * Twitter: https://twitter.com/libimobiledev
247 |
248 | ## License
249 |
250 | This project is licensed under the [GNU Lesser General Public License v2.1](https://www.gnu.org/licenses/lgpl-2.1.en.html),
251 | also included in the repository in the `COPYING` file.
252 |
253 | ## Credits
254 |
255 | Apple, iPhone, iPad, iPod, iPod Touch, Apple TV, Apple Watch, Mac, iOS,
256 | iPadOS, tvOS, watchOS, and macOS are trademarks of Apple Inc.
257 |
258 | This project is an independent software library and has not been authorized,
259 | sponsored, or otherwise approved by Apple Inc.
260 |
261 | README Updated on: 2025-09-10
262 |
--------------------------------------------------------------------------------
/autogen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | olddir=`pwd`
4 | srcdir=`dirname $0`
5 | test -z "$srcdir" && srcdir=.
6 |
7 | (
8 | cd "$srcdir"
9 |
10 | gprefix=`which glibtoolize 2>&1 >/dev/null`
11 | if [ $? -eq 0 ]; then
12 | glibtoolize --force
13 | else
14 | libtoolize --force
15 | fi
16 | aclocal -I m4
17 | autoheader
18 | automake --add-missing
19 | autoconf
20 |
21 | cd "$olddir"
22 | )
23 |
24 | if [ -z "$NOCONFIGURE" ]; then
25 | $srcdir/configure "$@"
26 | fi
27 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # -*- Autoconf -*-
2 | # Process this file with autoconf to produce a configure script.
3 |
4 | AC_PREREQ(2.68)
5 | AC_INIT([libirecovery], [m4_esyscmd(./git-version-gen $RELEASE_VERSION)], [https://github.com/libimobiledevice/libirecovery/issues], [], [https://libimobiledevice.org])
6 | AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip check-news])
7 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
8 | AC_CONFIG_SRCDIR([src/])
9 | AC_CONFIG_HEADERS([config.h])
10 | AC_CONFIG_MACRO_DIR([m4])
11 |
12 | dnl libtool versioning
13 | # +1 : 0 : +1 == adds new functions to the interface
14 | # +1 : 0 : 0 == changes or removes functions (changes include both
15 | # changes to the signature and the semantic)
16 | # ? :+1 : ? == just internal changes
17 | # CURRENT : REVISION : AGE
18 | LIBIRECOVERY_SO_VERSION=6:2:1
19 |
20 | dnl Minimum package versions
21 | LIBUSB_VERSION=1.0.3
22 | LIMD_GLUE_VERSION=1.2.0
23 |
24 | AC_SUBST(LIBIRECOVERY_SO_VERSION)
25 | AC_SUBST(LIMD_GLUE_VERSION)
26 |
27 | # Checks for programs.
28 | AC_PROG_CC
29 | #AC_PROG_CXX
30 | AM_PROG_CC_C_O
31 | LT_INIT
32 |
33 | # Checks for libraries.
34 | PKG_CHECK_MODULES(limd_glue, libimobiledevice-glue-1.0 >= $LIMD_GLUE_VERSION)
35 |
36 | # Checks for header files.
37 | AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
38 |
39 | # Checks for typedefs, structures, and compiler characteristics.
40 | AC_C_CONST
41 | AC_TYPE_SIZE_T
42 | AC_TYPE_SSIZE_T
43 | AC_TYPE_UINT16_T
44 | AC_TYPE_UINT32_T
45 | AC_TYPE_UINT8_T
46 |
47 | # Checks for library functions.
48 | AC_CHECK_FUNCS([strdup strerror strcasecmp strndup malloc realloc calloc])
49 |
50 | # Check additional platform flags
51 | AC_MSG_CHECKING([for platform-specific build settings])
52 | case ${host_os} in
53 | darwin*)
54 | AC_MSG_RESULT([${host_os}])
55 | AC_CHECK_HEADER(CoreFoundation/CoreFoundation.h, [
56 | AC_CHECK_HEADER(IOKit/usb/IOUSBLib.h, [
57 | GLOBAL_LDFLAGS+=" -framework IOKit -framework CoreFoundation"
58 | have_iokit=yes
59 | ], [])
60 | ], [])
61 | ;;
62 | mingw32*)
63 | AC_MSG_RESULT([${host_os}])
64 | GLOBAL_LDFLAGS+=" -static-libgcc -lkernel32 -lsetupapi"
65 | win32=true
66 | ;;
67 | cygwin*)
68 | AC_MSG_RESULT([${host_os}])
69 | CC=gcc-3
70 | CFLAGS+=" -mno-cygwin"
71 | GLOBAL_LDFLAGS+=" -static-libgcc -lkernel32 -lsetupapi"
72 | win32=true
73 | ;;
74 | *)
75 | AC_MSG_RESULT([${host_os}])
76 | ;;
77 | esac
78 | AM_CONDITIONAL(WIN32, test x$win32 = xtrue)
79 |
80 | AC_ARG_WITH([tools],
81 | [AS_HELP_STRING([--with-tools], [Build irecovery tools. [default=yes]])],
82 | [],
83 | [with_tools=yes])
84 |
85 | AS_IF([test "x$with_tools" = "xyes"], [
86 | have_readline=no
87 | AC_DEFINE(BUILD_TOOLS, 1, [Define if we are building irecovery tools])
88 | AC_CHECK_HEADERS([readline/readline.h],
89 | [AC_DEFINE(HAVE_READLINE, 1, [Define if readline is available])
90 | have_readline=yes],
91 | [AC_MSG_NOTICE([NOTE: Building without readline support. If you want readline support, install its development package.])]
92 | )
93 | AM_CONDITIONAL(HAVE_READLINE, test "x$have_readline" = "xyes")
94 | ])
95 | AM_CONDITIONAL(BUILD_TOOLS, test "x$with_tools" = "xyes")
96 |
97 | AC_ARG_WITH([dummy],
98 | [AS_HELP_STRING([--with-dummy], [Use no USB driver at all [default=no]. This is only useful if you just want to query the device list by product type or hardware model. All other operations are no-ops or will return IRECV_E_UNSUPPORTED.])],
99 | [],
100 | [with_dummy=no])
101 |
102 | AS_IF([test "x$have_iokit" = "xyes"], [
103 | AC_ARG_WITH([iokit],
104 | [AS_HELP_STRING([--with-iokit], [Use IOKit instead of libusb on OS X [default=yes]])],
105 | [],
106 | [with_iokit=yes])
107 | ]
108 | )
109 |
110 | AS_IF([test "x$with_dummy" = "xyes"], [
111 | AC_DEFINE(USE_DUMMY, 1, [Define if we are using dummy USB driver])
112 | USB_BACKEND="dummy"
113 | ], [
114 | AS_IF([test "x$with_iokit" = "xyes" && test "x$have_iokit" = "xyes"], [
115 | AC_DEFINE(HAVE_IOKIT, 1, [Define if we have IOKit])
116 | USB_BACKEND="IOKit"
117 | ], [
118 | AS_IF([test "x$win32" = "xtrue"], [
119 | USB_BACKEND="win32 native (setupapi)"
120 | ], [
121 | PKG_CHECK_MODULES(libusb, libusb-1.0 >= $LIBUSB_VERSION)
122 | USB_BACKEND="libusb `$PKG_CONFIG --modversion libusb-1.0`"
123 | LIBUSB_REQUIRED="libusb-1.0 >= $LIBUSB_VERSION"
124 | AC_SUBST(LIBUSB_REQUIRED)
125 | ])
126 | ])
127 | ])
128 |
129 | AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith -Wwrite-strings -Wswitch-default -Wno-unused-parameter -fvisibility=hidden")
130 |
131 | if test "x$enable_static" = "xyes" -a "x$enable_shared" = "xno"; then
132 | GLOBAL_CFLAGS+=" -DIRECV_STATIC"
133 | fi
134 |
135 | AC_SUBST(GLOBAL_CFLAGS)
136 | AC_SUBST(GLOBAL_LDFLAGS)
137 |
138 | # check for large file support
139 | AC_SYS_LARGEFILE
140 |
141 | AC_ARG_WITH([udev],
142 | AS_HELP_STRING([--with-udev],
143 | [Configure and install udev rules file for DFU/Recovery mode devices]),
144 | [],
145 | [if $($PKG_CONFIG --exists udev); then with_udev=yes; else with_udev=no; fi])
146 |
147 | AC_ARG_WITH([udevrulesdir],
148 | AS_HELP_STRING([--with-udevrulesdir=DIR],
149 | [Directory for udev rules (implies --with-udev)]),
150 | [with_udev=yes],
151 | [with_udevrulesdir=auto])
152 |
153 | AC_ARG_WITH([udevrule],
154 | AS_HELP_STRING([--with-udevrule="RULE"],
155 | [udev activation rule (implies --with-udev)]),
156 | [with_udev=yes],
157 | [with_udevrule=auto])
158 |
159 | if test "x$with_udev" = "xyes"; then
160 | if test "x$with_udevrule" = "xauto"; then
161 | for I in plugdev storage disk staff; do
162 | if grep $I /etc/group >/dev/null; then
163 | USEGROUP=$I
164 | break
165 | fi
166 | done
167 | if test "x$USEGROUP" != "x"; then
168 | if ! groups |grep $USEGROUP >/dev/null; then
169 | AC_MSG_WARN([The group '$USEGROUP' was determined to be used for the udev rule, but the current user is not member of this group.])
170 | fi
171 | else
172 | AC_MSG_ERROR([Could not determine an appropriate user group for the udev activation rule.
173 | Please manually specify a udev activation rule using --with-udevrule=<RULE>
174 | Example: --with-udevrule="OWNER=\\"root\\", GROUP=\\"myusergroup\\", MODE=\\"0660\\""])
175 | fi
176 | with_udevrule="OWNER=\"root\", GROUP=\"$USEGROUP\", MODE=\"0660\""
177 | fi
178 |
179 | if test "x$with_udevrulesdir" = "xauto"; then
180 | udevdir=$($PKG_CONFIG --silence-errors --variable=udevdir udev)
181 | if test "x$udevdir" != "x"; then
182 | with_udevrulesdir=$udevdir"/rules.d"
183 | else
184 | with_udevrulesdir="\${prefix}/lib/udev/rules.d"
185 | AC_MSG_WARN([Could not determine default udev rules directory. Using $with_udevrulesdir.])
186 | fi
187 | fi
188 |
189 | AC_SUBST([udev_activation_rule], [$with_udevrule])
190 | AC_SUBST([udevrulesdir], [$with_udevrulesdir])
191 | fi
192 | AM_CONDITIONAL(WITH_UDEV, test "x$with_udev" = "xyes")
193 |
194 | m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
195 |
196 | AC_CONFIG_FILES([
197 | Makefile
198 | src/Makefile
199 | src/libirecovery-1.0.pc
200 | udev/39-libirecovery.rules
201 | include/Makefile
202 | tools/Makefile
203 | udev/Makefile
204 | ])
205 | AC_OUTPUT
206 |
207 | echo "
208 | Configuration for $PACKAGE $VERSION:
209 | -------------------------------------------
210 |
211 | Install prefix: .........: $prefix
212 | USB backend: ............: $USB_BACKEND
213 | Build tools: ............: $with_tools
214 |
215 | Now type 'make' to build $PACKAGE $VERSION,
216 | and then 'make install' for installation.
217 | "
218 |
--------------------------------------------------------------------------------
/git-version-gen:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | SRCDIR=`dirname $0`
3 | if test -n "$1"; then
4 | VER=$1
5 | else
6 | if test -r "${SRCDIR}/.git" && test -x "`which git`" ; then
7 | git update-index -q --refresh
8 | if ! VER=`git describe --tags --dirty 2>/dev/null`; then
9 | COMMIT=`git rev-parse --short HEAD`
10 | DIRTY=`git diff --quiet HEAD || echo "-dirty"`
11 | VER=`sed -n '1,/RE/s/Version \(.*\)/\1/p' ${SRCDIR}/NEWS`-git-${COMMIT}${DIRTY}
12 | fi
13 | else
14 | if test -f "${SRCDIR}/.tarball-version"; then
15 | VER=`cat "${SRCDIR}/.tarball-version"`
16 | fi
17 | fi
18 | fi
19 | VER=`printf %s "$VER" | head -n1`
20 | printf %s "$VER"
21 |
--------------------------------------------------------------------------------
/include/Makefile.am:
--------------------------------------------------------------------------------
1 | nobase_dist_include_HEADERS = libirecovery.h
--------------------------------------------------------------------------------
/include/libirecovery.h:
--------------------------------------------------------------------------------
1 | /*
2 | * libirecovery.h
3 | * Communication to iBoot/iBSS on Apple iOS devices via USB
4 | *
5 | * Copyright (c) 2012-2023 Nikias Bassen <nikias@gmx.li>
6 | * Copyright (c) 2012-2013 Martin Szulecki <m.szulecki@libimobiledevice.org>
7 | * Copyright (c) 2010 Chronic-Dev Team
8 | * Copyright (c) 2010 Joshua Hill
9 | *
10 | * All rights reserved. This program and the accompanying materials
11 | * are made available under the terms of the GNU Lesser General Public License
12 | * (LGPL) version 2.1 which accompanies this distribution, and is available at
13 | * http://www.gnu.org/licenses/lgpl-2.1.html
14 | *
15 | * This library is distributed in the hope that it will be useful,
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | * Lesser General Public License for more details.
19 | */
20 |
21 | #ifndef LIBIRECOVERY_H
22 | #define LIBIRECOVERY_H
23 |
24 | #ifdef __cplusplus
25 | extern "C" {
26 | #endif
27 |
28 | #include <stdint.h>
29 |
30 | #ifndef IRECV_API
31 | #ifdef IRECV_STATIC
32 | #define IRECV_API
33 | #elif defined(_WIN32)
34 | #define IRECV_API __declspec(dllimport)
35 | #else
36 | #define IRECV_API
37 | #endif
38 | #endif
39 |
40 | enum irecv_mode {
41 | IRECV_K_RECOVERY_MODE_1 = 0x1280,
42 | IRECV_K_RECOVERY_MODE_2 = 0x1281,
43 | IRECV_K_RECOVERY_MODE_3 = 0x1282,
44 | IRECV_K_RECOVERY_MODE_4 = 0x1283,
45 | IRECV_K_WTF_MODE = 0x1222,
46 | IRECV_K_DFU_MODE = 0x1227,
47 | IRECV_K_PORT_DFU_MODE = 0xf014
48 | };
49 |
50 | typedef enum {
51 | IRECV_E_SUCCESS = 0,
52 | IRECV_E_NO_DEVICE = -1,
53 | IRECV_E_OUT_OF_MEMORY = -2,
54 | IRECV_E_UNABLE_TO_CONNECT = -3,
55 | IRECV_E_INVALID_INPUT = -4,
56 | IRECV_E_FILE_NOT_FOUND = -5,
57 | IRECV_E_USB_UPLOAD = -6,
58 | IRECV_E_USB_STATUS = -7,
59 | IRECV_E_USB_INTERFACE = -8,
60 | IRECV_E_USB_CONFIGURATION = -9,
61 | IRECV_E_PIPE = -10,
62 | IRECV_E_TIMEOUT = -11,
63 | IRECV_E_UNSUPPORTED = -254,
64 | IRECV_E_UNKNOWN_ERROR = -255
65 | } irecv_error_t;
66 |
67 | typedef enum {
68 | IRECV_RECEIVED = 1,
69 | IRECV_PRECOMMAND = 2,
70 | IRECV_POSTCOMMAND = 3,
71 | IRECV_CONNECTED = 4,
72 | IRECV_DISCONNECTED = 5,
73 | IRECV_PROGRESS = 6
74 | } irecv_event_type;
75 |
76 | typedef struct {
77 | int size;
78 | const char* data;
79 | double progress;
80 | irecv_event_type type;
81 | } irecv_event_t;
82 |
83 | struct irecv_device {
84 | const char* product_type;
85 | const char* hardware_model;
86 | unsigned int board_id;
87 | unsigned int chip_id;
88 | const char* display_name;
89 | };
90 | typedef struct irecv_device* irecv_device_t;
91 |
92 | struct irecv_device_info {
93 | unsigned int cpid;
94 | unsigned int cprv;
95 | unsigned int cpfm;
96 | unsigned int scep;
97 | unsigned int bdid;
98 | uint64_t ecid;
99 | unsigned int ibfl;
100 | char* srnm;
101 | char* imei;
102 | char* srtg;
103 | char* serial_string;
104 | unsigned char* ap_nonce;
105 | unsigned int ap_nonce_size;
106 | unsigned char* sep_nonce;
107 | unsigned int sep_nonce_size;
108 | uint16_t pid;
109 | unsigned int have_cpid : 1;
110 | unsigned int have_cprv : 1;
111 | unsigned int have_cpfm : 1;
112 | unsigned int have_scep : 1;
113 | unsigned int have_bdid : 1;
114 | unsigned int have_ecid : 1;
115 | unsigned int have_ibfl : 1;
116 | };
117 |
118 | typedef enum {
119 | IRECV_DEVICE_ADD = 1,
120 | IRECV_DEVICE_REMOVE = 2
121 | } irecv_device_event_type;
122 |
123 | typedef struct {
124 | irecv_device_event_type type;
125 | enum irecv_mode mode;
126 | struct irecv_device_info *device_info;
127 | } irecv_device_event_t;
128 |
129 | typedef struct irecv_client_private irecv_client_private;
130 | typedef irecv_client_private* irecv_client_t;
131 |
132 | enum {
133 | IRECV_SEND_OPT_NONE = 0,
134 | IRECV_SEND_OPT_DFU_NOTIFY_FINISH = (1 << 0),
135 | IRECV_SEND_OPT_DFU_FORCE_ZLP = (1 << 1),
136 | IRECV_SEND_OPT_DFU_SMALL_PKT = (1 << 2)
137 | };
138 |
139 | /* library */
140 | IRECV_API void irecv_set_debug_level(int level);
141 | IRECV_API const char* irecv_strerror(irecv_error_t error);
142 |
143 | IRECV_API const char* irecv_version();
144 |
145 | /* device connectivity */
146 | IRECV_API irecv_error_t irecv_open_with_ecid(irecv_client_t* client, uint64_t ecid);
147 | IRECV_API irecv_error_t irecv_open_with_ecid_and_attempts(irecv_client_t* pclient, uint64_t ecid, int attempts);
148 | IRECV_API irecv_error_t irecv_reset(irecv_client_t client);
149 | IRECV_API irecv_error_t irecv_close(irecv_client_t client);
150 | IRECV_API irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause);
151 |
152 | /* misc */
153 | IRECV_API irecv_error_t irecv_receive(irecv_client_t client);
154 | IRECV_API irecv_error_t irecv_execute_script(irecv_client_t client, const char* script);
155 | IRECV_API irecv_error_t irecv_reset_counters(irecv_client_t client);
156 | IRECV_API irecv_error_t irecv_finish_transfer(irecv_client_t client);
157 | IRECV_API irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client);
158 |
159 | /* usb helpers */
160 | IRECV_API irecv_error_t irecv_usb_set_configuration(irecv_client_t client, int configuration);
161 | IRECV_API irecv_error_t irecv_usb_set_interface(irecv_client_t client, int usb_interface, int usb_alt_interface);
162 | IRECV_API int irecv_usb_control_transfer(irecv_client_t client, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, unsigned char *data, uint16_t w_length, unsigned int timeout);
163 | IRECV_API int irecv_usb_bulk_transfer(irecv_client_t client, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout);
164 | IRECV_API int irecv_usb_interrupt_transfer(irecv_client_t client, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout);
165 |
166 | /* events */
167 | typedef void(*irecv_device_event_cb_t)(const irecv_device_event_t* event, void *user_data);
168 | typedef struct irecv_device_event_context* irecv_device_event_context_t;
169 | IRECV_API irecv_error_t irecv_device_event_subscribe(irecv_device_event_context_t *context, irecv_device_event_cb_t callback, void *user_data);
170 | IRECV_API irecv_error_t irecv_device_event_unsubscribe(irecv_device_event_context_t context);
171 | typedef int(*irecv_event_cb_t)(irecv_client_t client, const irecv_event_t* event);
172 | IRECV_API irecv_error_t irecv_event_subscribe(irecv_client_t client, irecv_event_type type, irecv_event_cb_t callback, void *user_data);
173 | IRECV_API irecv_error_t irecv_event_unsubscribe(irecv_client_t client, irecv_event_type type);
174 |
175 | /* I/O */
176 | IRECV_API irecv_error_t irecv_send_file(irecv_client_t client, const char* filename, unsigned int options);
177 | IRECV_API irecv_error_t irecv_send_command(irecv_client_t client, const char* command);
178 | IRECV_API irecv_error_t irecv_send_command_breq(irecv_client_t client, const char* command, uint8_t b_request);
179 | IRECV_API irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, unsigned int options);
180 | IRECV_API irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length);
181 |
182 | /* commands */
183 | IRECV_API irecv_error_t irecv_saveenv(irecv_client_t client);
184 | IRECV_API irecv_error_t irecv_getenv(irecv_client_t client, const char* variable, char** value);
185 | IRECV_API irecv_error_t irecv_setenv(irecv_client_t client, const char* variable, const char* value);
186 | IRECV_API irecv_error_t irecv_setenv_np(irecv_client_t client, const char* variable, const char* value);
187 | IRECV_API irecv_error_t irecv_reboot(irecv_client_t client);
188 | IRECV_API irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value);
189 |
190 | /* device information */
191 | IRECV_API irecv_error_t irecv_get_mode(irecv_client_t client, int* mode);
192 | IRECV_API const struct irecv_device_info* irecv_get_device_info(irecv_client_t client);
193 |
194 | /* device database queries */
195 | IRECV_API irecv_device_t irecv_devices_get_all(void);
196 | IRECV_API irecv_error_t irecv_devices_get_device_by_client(irecv_client_t client, irecv_device_t* device);
197 | IRECV_API irecv_error_t irecv_devices_get_device_by_product_type(const char* product_type, irecv_device_t* device);
198 | IRECV_API irecv_error_t irecv_devices_get_device_by_hardware_model(const char* hardware_model, irecv_device_t* device);
199 |
200 | #ifdef __cplusplus
201 | }
202 | #endif
203 |
204 | #endif
205 |
--------------------------------------------------------------------------------
/m4/as-compiler-flag.m4:
--------------------------------------------------------------------------------
1 | dnl as-compiler-flag.m4 0.1.0
2 |
3 | dnl autostars m4 macro for detection of compiler flags
4 |
5 | dnl David Schleef <ds@schleef.org>
6 |
7 | dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $
8 |
9 | dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
10 | dnl Tries to compile with the given CFLAGS.
11 | dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
12 | dnl and ACTION-IF-NOT-ACCEPTED otherwise.
13 |
14 | AC_DEFUN([AS_COMPILER_FLAG],
15 | [
16 | AC_MSG_CHECKING([to see if compiler understands $1])
17 |
18 | save_CFLAGS="$CFLAGS"
19 | CFLAGS="$CFLAGS $1"
20 |
21 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], [flag_ok=yes], [flag_ok=no])
22 | CFLAGS="$save_CFLAGS"
23 |
24 | if test "X$flag_ok" = Xyes ; then
25 | m4_ifvaln([$2],[$2])
26 | true
27 | else
28 | m4_ifvaln([$3],[$3])
29 | true
30 | fi
31 | AC_MSG_RESULT([$flag_ok])
32 | ])
33 |
34 | dnl AS_COMPILER_FLAGS(VAR, FLAGS)
35 | dnl Tries to compile with the given CFLAGS.
36 |
37 | AC_DEFUN([AS_COMPILER_FLAGS],
38 | [
39 | list=$2
40 | flags_supported=""
41 | flags_unsupported=""
42 | AC_MSG_CHECKING([for supported compiler flags])
43 | for each in $list
44 | do
45 | save_CFLAGS="$CFLAGS"
46 | CFLAGS="$CFLAGS $each"
47 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], [flag_ok=yes], [flag_ok=no])
48 | CFLAGS="$save_CFLAGS"
49 |
50 | if test "X$flag_ok" = Xyes ; then
51 | flags_supported="$flags_supported $each"
52 | else
53 | flags_unsupported="$flags_unsupported $each"
54 | fi
55 | done
56 | AC_MSG_RESULT([$flags_supported])
57 | if test "X$flags_unsupported" != X ; then
58 | AC_MSG_WARN([unsupported compiler flags: $flags_unsupported])
59 | fi
60 | $1="$1 $flags_supported"
61 | ])
62 |
63 |
--------------------------------------------------------------------------------
/src/Makefile.am:
--------------------------------------------------------------------------------
1 | AM_CPPFLAGS = -I$(top_srcdir)/include
2 |
3 | AM_CFLAGS = \
4 | $(GLOBAL_CFLAGS) \
5 | $(LFS_CFLAGS) \
6 | $(limd_glue_CFLAGS) \
7 | $(libusb_CFLAGS)
8 |
9 | AM_LDFLAGS = \
10 | $(GLOBAL_LDFLAGS) \
11 | $(limd_glue_LIBS) \
12 | $(libusb_LIBS)
13 |
14 | lib_LTLIBRARIES = libirecovery-1.0.la
15 | libirecovery_1_0_la_CFLAGS = $(AM_CFLAGS)
16 | libirecovery_1_0_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBIRECOVERY_SO_VERSION) -no-undefined
17 | libirecovery_1_0_la_SOURCES = libirecovery.c
18 |
19 | if WIN32
20 | libirecovery_1_0_la_LDFLAGS += -avoid-version
21 | endif
22 |
23 | pkgconfigdir = $(libdir)/pkgconfig
24 | pkgconfig_DATA = libirecovery-1.0.pc
25 |
--------------------------------------------------------------------------------
/src/libirecovery-1.0.pc.in:
--------------------------------------------------------------------------------
1 | prefix=@prefix@
2 | exec_prefix=@exec_prefix@
3 | libdir=@libdir@
4 | includedir=@includedir@
5 |
6 | Name: @PACKAGE_NAME@
7 | Description: A library to communicate with iBoot/iBSS on iOS devices via USB
8 | Version: @PACKAGE_VERSION@
9 | Libs: -L${libdir} -lirecovery-1.0
10 | Cflags: -I${includedir}
11 | Requires.private: libimobiledevice-glue-1.0 >= @LIMD_GLUE_VERSION@ @LIBUSB_REQUIRED@
12 |
--------------------------------------------------------------------------------
/tools/Makefile.am:
--------------------------------------------------------------------------------
1 | if BUILD_TOOLS
2 | AM_CPPFLAGS = -I$(top_srcdir)/include
3 |
4 | AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS)
5 | AM_LDFLAGS = $(libusb_LIBS)
6 |
7 | bin_PROGRAMS = irecovery
8 |
9 | irecovery_SOURCES = irecovery.c
10 | irecovery_CFLAGS = $(AM_CFLAGS)
11 | irecovery_LDFLAGS = $(AM_LDFLAGS)
12 | if HAVE_READLINE
13 | irecovery_LDFLAGS += -lreadline
14 | endif
15 | irecovery_LDADD = $(top_builddir)/src/libirecovery-1.0.la
16 | endif
17 |
--------------------------------------------------------------------------------
/tools/irecovery.c:
--------------------------------------------------------------------------------
1 | /*
2 | * irecovery.c
3 | * Software frontend for iBoot/iBSS communication with iOS devices
4 | *
5 | * Copyright (c) 2012-2023 Nikias Bassen <nikias@gmx.li>
6 | * Copyright (c) 2012-2015 Martin Szulecki <martin.szulecki@libimobiledevice.org>
7 | * Copyright (c) 2010-2011 Chronic-Dev Team
8 | * Copyright (c) 2010-2011 Joshua Hill
9 | * Copyright (c) 2008-2011 Nicolas Haunold
10 | *
11 | * All rights reserved. This program and the accompanying materials
12 | * are made available under the terms of the GNU Lesser General Public License
13 | * (LGPL) version 2.1 which accompanies this distribution, and is available at
14 | * http://www.gnu.org/licenses/lgpl-2.1.html
15 | *
16 | * This library is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 | * Lesser General Public License for more details.
20 | */
21 |
22 | #ifdef HAVE_CONFIG_H
23 | #include "config.h"
24 | #endif
25 |
26 | #define TOOL_NAME "irecovery"
27 |
28 | #include <stdio.h>
29 | #include <stdlib.h>
30 | #include <unistd.h>
31 | #include <string.h>
32 | #include <getopt.h>
33 | #include <inttypes.h>
34 | #include <ctype.h>
35 | #include <libirecovery.h>
36 | #ifdef HAVE_READLINE
37 | #include <readline/readline.h>
38 | #include <readline/history.h>
39 | #else
40 | #ifndef _WIN32
41 | #include <termios.h>
42 | #endif
43 | #endif
44 |
45 | #ifdef _WIN32
46 | #include <windows.h>
47 | #include <conio.h>
48 | #define sleep(n) Sleep(1000 * n)
49 | #endif
50 |
51 | #define FILE_HISTORY_PATH ".irecovery"
52 | #define debug(...) if (verbose) fprintf(stderr, __VA_ARGS__)
53 |
54 | enum {
55 | kNoAction,
56 | kResetDevice,
57 | kStartShell,
58 | kSendCommand,
59 | kSendFile,
60 | kSendExploit,
61 | kSendScript,
62 | kShowMode,
63 | kRebootToNormalMode,
64 | kQueryInfo,
65 | kListDevices
66 | };
67 |
68 | static unsigned int quit = 0;
69 | static unsigned int verbose = 0;
70 |
71 | void print_progress_bar(double progress);
72 | int received_cb(irecv_client_t client, const irecv_event_t* event);
73 | int progress_cb(irecv_client_t client, const irecv_event_t* event);
74 | int precommand_cb(irecv_client_t client, const irecv_event_t* event);
75 | int postcommand_cb(irecv_client_t client, const irecv_event_t* event);
76 |
77 | static void shell_usage()
78 | {
79 | printf("Usage:\n");
80 | printf(" /upload FILE\t\tsend FILE to device\n");
81 | printf(" /limera1n [FILE]\trun limera1n exploit and send optional payload from FILE\n");
82 | printf(" /deviceinfo\t\tprint device information (ECID, IMEI, etc.)\n");
83 | printf(" /help\t\t\tshow this help\n");
84 | printf(" /exit\t\t\texit interactive shell\n");
85 | }
86 |
87 | static const char* mode_to_str(int mode)
88 | {
89 | switch (mode) {
90 | case IRECV_K_RECOVERY_MODE_1:
91 | case IRECV_K_RECOVERY_MODE_2:
92 | case IRECV_K_RECOVERY_MODE_3:
93 | case IRECV_K_RECOVERY_MODE_4:
94 | return "Recovery";
95 | break;
96 | case IRECV_K_DFU_MODE:
97 | return "DFU";
98 | break;
99 | case IRECV_K_PORT_DFU_MODE:
100 | return "Port DFU";
101 | break;
102 | case IRECV_K_WTF_MODE:
103 | return "WTF";
104 | break;
105 | default:
106 | return "Unknown";
107 | break;
108 | }
109 | }
110 |
111 | static void buffer_read_from_filename(const char *filename, char **buffer, uint64_t *length)
112 | {
113 | FILE *f;
114 | uint64_t size;
115 |
116 | *length = 0;
117 |
118 | f = fopen(filename, "rb");
119 | if (!f) {
120 | return;
121 | }
122 |
123 | fseek(f, 0, SEEK_END);
124 | size = ftell(f);
125 | rewind(f);
126 |
127 | if (size == 0) {
128 | fclose(f);
129 | return;
130 | }
131 |
132 | *buffer = (char*)malloc(sizeof(char)*(size+1));
133 | fread(*buffer, sizeof(char), size, f);
134 | fclose(f);
135 |
136 | *length = size;
137 | }
138 |
139 | static void print_hex(unsigned char *buf, size_t len)
140 | {
141 | size_t i;
142 | for (i = 0; i < len; i++) {
143 | printf("%02x", buf[i]);
144 | }
145 | }
146 |
147 | static void print_device_info(irecv_client_t client)
148 | {
149 | int ret, mode;
150 | irecv_device_t device = NULL;
151 | const struct irecv_device_info *devinfo = irecv_get_device_info(client);
152 | if (devinfo) {
153 | printf("CPID: 0x%04x\n", devinfo->cpid);
154 | printf("CPRV: 0x%02x\n", devinfo->cprv);
155 | printf("BDID: 0x%02x\n", devinfo->bdid);
156 | printf("ECID: 0x%016" PRIx64 "\n", devinfo->ecid);
157 | printf("CPFM: 0x%02x\n", devinfo->cpfm);
158 | printf("SCEP: 0x%02x\n", devinfo->scep);
159 | printf("IBFL: 0x%02x\n", devinfo->ibfl);
160 | printf("SRTG: %s\n", (devinfo->srtg) ? devinfo->srtg : "N/A");
161 | printf("SRNM: %s\n", (devinfo->srnm) ? devinfo->srnm : "N/A");
162 | printf("IMEI: %s\n", (devinfo->imei) ? devinfo->imei : "N/A");
163 | printf("NONC: ");
164 | if (devinfo->ap_nonce) {
165 | print_hex(devinfo->ap_nonce, devinfo->ap_nonce_size);
166 | } else {
167 | printf("N/A");
168 | }
169 | printf("\n");
170 | printf("SNON: ");
171 | if (devinfo->sep_nonce) {
172 | print_hex(devinfo->sep_nonce, devinfo->sep_nonce_size);
173 | } else {
174 | printf("N/A");
175 | }
176 | printf("\n");
177 | char* p = strstr(devinfo->serial_string, "PWND:[");
178 | if (p) {
179 | p+=6;
180 | char* pend = strchr(p, ']');
181 | if (pend) {
182 | printf("PWND: %.*s\n", (int)(pend-p), p);
183 | }
184 | }
185 | } else {
186 | printf("Could not get device info?!\n");
187 | }
188 |
189 | ret = irecv_get_mode(client, &mode);
190 | if (ret == IRECV_E_SUCCESS) {
191 | switch (devinfo->pid) {
192 | case 0x1881:
193 | printf("MODE: DFU via Debug USB (KIS)\n");
194 | break;
195 | default:
196 | printf("MODE: %s\n", mode_to_str(mode));
197 | break;
198 | }
199 | }
200 |
201 | irecv_devices_get_device_by_client(client, &device);
202 | if (device) {
203 | printf("PRODUCT: %s\n", device->product_type);
204 | printf("MODEL: %s\n", device->hardware_model);
205 | printf("NAME: %s\n", device->display_name);
206 | }
207 | }
208 |
209 | static void print_devices()
210 | {
211 | struct irecv_device *devices = irecv_devices_get_all();
212 | struct irecv_device *device = NULL;
213 | int i = 0;
214 |
215 | for (i = 0; devices[i].product_type != NULL; i++) {
216 | device = &devices[i];
217 |
218 | printf("%s %s 0x%02x 0x%04x %s\n", device->product_type, device->hardware_model, device->board_id, device->chip_id, device->display_name);
219 | }
220 | }
221 |
222 | static int _is_breq_command(const char* cmd)
223 | {
224 | return (
225 | !strcmp(cmd, "go")
226 | || !strcmp(cmd, "bootx")
227 | || !strcmp(cmd, "reboot")
228 | || !strcmp(cmd, "memboot")
229 | );
230 | }
231 |
232 | static void parse_command(irecv_client_t client, unsigned char* command, unsigned int size)
233 | {
234 | char* cmd = strdup((char*)command);
235 | char* action = strtok(cmd, " ");
236 |
237 | if (!strcmp(cmd, "/exit")) {
238 | quit = 1;
239 | } else if (!strcmp(cmd, "/help")) {
240 | shell_usage();
241 | } else if (!strcmp(cmd, "/upload")) {
242 | char* filename = strtok(NULL, " ");
243 | debug("Uploading file %s\n", filename);
244 | if (filename != NULL) {
245 | irecv_send_file(client, filename, 0);
246 | }
247 | } else if (!strcmp(cmd, "/deviceinfo")) {
248 | print_device_info(client);
249 | } else if (!strcmp(cmd, "/limera1n")) {
250 | char* filename = strtok(NULL, " ");
251 | debug("Sending limera1n payload %s\n", filename);
252 | if (filename != NULL) {
253 | irecv_send_file(client, filename, 0);
254 | }
255 | irecv_trigger_limera1n_exploit(client);
256 | } else if (!strcmp(cmd, "/execute")) {
257 | char* filename = strtok(NULL, " ");
258 | debug("Executing script %s\n", filename);
259 | if (filename != NULL) {
260 | char* buffer = NULL;
261 | uint64_t buffer_length = 0;
262 | buffer_read_from_filename(filename, &buffer, &buffer_length);
263 | if (buffer) {
264 | buffer[buffer_length] = '\0';
265 | irecv_execute_script(client, buffer);
266 | free(buffer);
267 | } else {
268 | printf("Could not read file '%s'\n", filename);
269 | }
270 | }
271 | } else {
272 | printf("Unsupported command %s. Use /help to get a list of available commands.\n", cmd);
273 | }
274 |
275 | free(action);
276 | }
277 |
278 | static void load_command_history()
279 | {
280 | #ifdef HAVE_READLINE
281 | read_history(FILE_HISTORY_PATH);
282 | #endif
283 | }
284 |
285 | static void append_command_to_history(const char* cmd)
286 | {
287 | #ifdef HAVE_READLINE
288 | add_history(cmd);
289 | write_history(FILE_HISTORY_PATH);
290 | #endif
291 | }
292 |
293 | #ifndef HAVE_READLINE
294 | #ifdef _WIN32
295 | #define BS_CC '\b'
296 | #else
297 | #define BS_CC 0x7f
298 | #define getch getchar
299 | #endif
300 | static void get_input(char *buf, int maxlen)
301 | {
302 | int len = 0;
303 | int c;
304 |
305 | while ((c = getch())) {
306 | if ((c == '\r') || (c == '\n')) {
307 | break;
308 | }
309 | if (isprint(c)) {
310 | if (len < maxlen-1)
311 | buf[len++] = c;
312 | } else if (c == BS_CC) {
313 | if (len > 0) {
314 | fputs("\b \b", stdout);
315 | len--;
316 | }
317 | }
318 | }
319 | buf[len] = 0;
320 | }
321 | #endif
322 |
323 | static void init_shell(irecv_client_t client)
324 | {
325 | irecv_error_t error = 0;
326 | load_command_history();
327 | irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
328 | irecv_event_subscribe(client, IRECV_RECEIVED, &received_cb, NULL);
329 | irecv_event_subscribe(client, IRECV_PRECOMMAND, &precommand_cb, NULL);
330 | irecv_event_subscribe(client, IRECV_POSTCOMMAND, &postcommand_cb, NULL);
331 | while (!quit) {
332 | error = irecv_receive(client);
333 | if (error != IRECV_E_SUCCESS) {
334 | debug("%s\n", irecv_strerror(error));
335 | break;
336 | }
337 | #ifdef HAVE_READLINE
338 | char* cmd = readline("> ");
339 | #else
340 | char cmdbuf[4096];
341 | const char* cmd = &cmdbuf[0];
342 | printf("> ");
343 | fflush(stdout);
344 | get_input(cmdbuf, sizeof(cmdbuf));
345 | #endif
346 | if (cmd && *cmd) {
347 | if (_is_breq_command(cmd)) {
348 | error = irecv_send_command_breq(client, cmd, 1);
349 | } else {
350 | error = irecv_send_command(client, cmd);
351 | }
352 | if (error != IRECV_E_SUCCESS) {
353 | quit = 1;
354 | }
355 |
356 | append_command_to_history(cmd);
357 | }
358 | #ifdef HAVE_READLINE
359 | free(cmd);
360 | #endif
361 | }
362 | }
363 |
364 | int received_cb(irecv_client_t client, const irecv_event_t* event)
365 | {
366 | if (event->type == IRECV_RECEIVED) {
367 | int i = 0;
368 | int size = event->size;
369 | const char* data = event->data;
370 | for (i = 0; i < size; i++) {
371 | printf("%c", data[i]);
372 | }
373 | }
374 |
375 | return 0;
376 | }
377 |
378 | int precommand_cb(irecv_client_t client, const irecv_event_t* event)
379 | {
380 | if (event->type == IRECV_PRECOMMAND) {
381 | if (event->data[0] == '/') {
382 | parse_command(client, (unsigned char*)event->data, event->size);
383 | return -1;
384 | }
385 | }
386 |
387 | return 0;
388 | }
389 |
390 | int postcommand_cb(irecv_client_t client, const irecv_event_t* event)
391 | {
392 | char* value = NULL;
393 | char* action = NULL;
394 | char* command = NULL;
395 | char* argument = NULL;
396 | irecv_error_t error = IRECV_E_SUCCESS;
397 |
398 | if (event->type == IRECV_POSTCOMMAND) {
399 | command = strdup(event->data);
400 | action = strtok(command, " ");
401 | if (!strcmp(action, "getenv")) {
402 | argument = strtok(NULL, " ");
403 | error = irecv_getenv(client, argument, &value);
404 | if (error != IRECV_E_SUCCESS) {
405 | debug("%s\n", irecv_strerror(error));
406 | free(command);
407 | return error;
408 | }
409 | printf("%s\n", value);
410 | free(value);
411 | }
412 |
413 | if (!strcmp(action, "reboot")) {
414 | quit = 1;
415 | }
416 | }
417 |
418 | free(command);
419 |
420 | return 0;
421 | }
422 |
423 | int progress_cb(irecv_client_t client, const irecv_event_t* event)
424 | {
425 | if (event->type == IRECV_PROGRESS) {
426 | print_progress_bar(event->progress);
427 | }
428 |
429 | return 0;
430 | }
431 |
432 | void print_progress_bar(double progress)
433 | {
434 | int i = 0;
435 |
436 | if (progress < 0) {
437 | return;
438 | }
439 |
440 | if (progress > 100) {
441 | progress = 100;
442 | }
443 |
444 | printf("\r[");
445 |
446 | for (i = 0; i < 50; i++) {
447 | if (i < progress / 2) {
448 | printf("=");
449 | } else {
450 | printf(" ");
451 | }
452 | }
453 |
454 | printf("] %3.1f%%", progress);
455 |
456 | fflush(stdout);
457 |
458 | if (progress == 100) {
459 | printf("\n");
460 | }
461 | }
462 |
463 | static void print_usage(int argc, char **argv)
464 | {
465 | char *name = NULL;
466 | name = strrchr(argv[0], '/');
467 | printf("Usage: %s [OPTIONS]\n", (name ? name + 1: argv[0]));
468 | printf("\n");
469 | printf("Interact with an iOS device in DFU or recovery mode.\n");
470 | printf("\n");
471 | printf("OPTIONS:\n");
472 | printf(" -i, --ecid ECID\tconnect to specific device by its ECID\n");
473 | printf(" -c, --command CMD\trun CMD on device\n");
474 | printf(" -m, --mode\t\tprint current device mode\n");
475 | printf(" -f, --file FILE\tsend file to device\n");
476 | printf(" -k, --payload FILE\tsend limera1n usb exploit payload from FILE\n");
477 | printf(" -r, --reset\t\treset client\n");
478 | printf(" -n, --normal\t\treboot device into normal mode (exit recovery loop)\n");
479 | printf(" -e, --script FILE\texecutes recovery script from FILE\n");
480 | printf(" -s, --shell\t\tstart an interactive shell\n");
481 | printf(" -q, --query\t\tquery device info\n");
482 | printf(" -a, --devices\t\tlist information for all known devices\n");
483 | printf(" -v, --verbose\t\tenable verbose output, repeat for higher verbosity\n");
484 | printf(" -h, --help\t\tprints this usage information\n");
485 | printf(" -V, --version\t\tprints version information\n");
486 | printf("\n");
487 | printf("Homepage: <" PACKAGE_URL ">\n");
488 | printf("Bug Reports: <" PACKAGE_BUGREPORT ">\n");
489 | }
490 |
491 | int main(int argc, char* argv[])
492 | {
493 | static struct option longopts[] = {
494 | { "ecid", required_argument, NULL, 'i' },
495 | { "command", required_argument, NULL, 'c' },
496 | { "mode", no_argument, NULL, 'm' },
497 | { "file", required_argument, NULL, 'f' },
498 | { "payload", required_argument, NULL, 'k' },
499 | { "reset", no_argument, NULL, 'r' },
500 | { "normal", no_argument, NULL, 'n' },
501 | { "script", required_argument, NULL, 'e' },
502 | { "shell", no_argument, NULL, 's' },
503 | { "query", no_argument, NULL, 'q' },
504 | { "devices", no_argument, NULL, 'a' },
505 | { "verbose", no_argument, NULL, 'v' },
506 | { "help", no_argument, NULL, 'h' },
507 | { "version", no_argument, NULL, 'V' },
508 | { NULL, 0, NULL, 0 }
509 | };
510 | int i = 0;
511 | int opt = 0;
512 | int action = kNoAction;
513 | uint64_t ecid = 0;
514 | int mode = -1;
515 | char* argument = NULL;
516 | irecv_error_t error = 0;
517 |
518 | char* buffer = NULL;
519 | uint64_t buffer_length = 0;
520 |
521 | if (argc == 1) {
522 | print_usage(argc, argv);
523 | return 0;
524 | }
525 |
526 | while ((opt = getopt_long(argc, argv, "i:vVhrsmnc:f:e:k:qa", longopts, NULL)) > 0) {
527 | switch (opt) {
528 | case 'i':
529 | if (optarg) {
530 | char* tail = NULL;
531 | ecid = strtoull(optarg, &tail, 0);
532 | if (tail && (tail[0] != '\0')) {
533 | ecid = 0;
534 | }
535 | if (ecid == 0) {
536 | fprintf(stderr, "ERROR: Could not parse ECID from argument '%s'\n", optarg);
537 | return -1;
538 | }
539 | }
540 | break;
541 |
542 | case 'v':
543 | verbose += 1;
544 | break;
545 |
546 | case 'h':
547 | print_usage(argc, argv);
548 | return 0;
549 |
550 | case 'm':
551 | action = kShowMode;
552 | break;
553 |
554 | case 'n':
555 | action = kRebootToNormalMode;
556 | break;
557 |
558 | case 'r':
559 | action = kResetDevice;
560 | break;
561 |
562 | case 's':
563 | action = kStartShell;
564 | break;
565 |
566 | case 'f':
567 | action = kSendFile;
568 | argument = optarg;
569 | break;
570 |
571 | case 'c':
572 | action = kSendCommand;
573 | argument = optarg;
574 | break;
575 |
576 | case 'k':
577 | action = kSendExploit;
578 | argument = optarg;
579 | break;
580 |
581 | case 'e':
582 | action = kSendScript;
583 | argument = optarg;
584 | break;
585 |
586 | case 'q':
587 | action = kQueryInfo;
588 | break;
589 |
590 | case 'a':
591 | action = kListDevices;
592 | print_devices();
593 | return 0;
594 |
595 | case 'V':
596 | printf("%s %s", TOOL_NAME, PACKAGE_VERSION);
597 | #ifdef HAVE_READLINE
598 | printf(" (readline)");
599 | #endif
600 | printf("\n");
601 | return 0;
602 |
603 | default:
604 | fprintf(stderr, "Unknown argument\n");
605 | return -1;
606 | }
607 | }
608 |
609 | if (action == kNoAction) {
610 | fprintf(stderr, "ERROR: Missing action option\n");
611 | print_usage(argc, argv);
612 | return -1;
613 | }
614 |
615 | if (verbose)
616 | irecv_set_debug_level(verbose);
617 |
618 | irecv_client_t client = NULL;
619 | for (i = 0; i <= 5; i++) {
620 | debug("Attempting to connect... \n");
621 |
622 | irecv_error_t err = irecv_open_with_ecid(&client, ecid);
623 | if (err == IRECV_E_UNSUPPORTED) {
624 | fprintf(stderr, "ERROR: %s\n", irecv_strerror(err));
625 | return -1;
626 | }
627 | else if (err != IRECV_E_SUCCESS)
628 | sleep(1);
629 | else
630 | break;
631 |
632 | if (i == 5) {
633 | fprintf(stderr, "ERROR: %s\n", irecv_strerror(err));
634 | return -1;
635 | }
636 | }
637 |
638 | irecv_device_t device = NULL;
639 | irecv_devices_get_device_by_client(client, &device);
640 | if (device)
641 | debug("Connected to %s, model %s, cpid 0x%04x, bdid 0x%02x\n", device->product_type, device->hardware_model, device->chip_id, device->board_id);
642 |
643 | const struct irecv_device_info *devinfo = irecv_get_device_info(client);
644 |
645 | switch (action) {
646 | case kResetDevice:
647 | irecv_reset(client);
648 | break;
649 |
650 | case kSendFile:
651 | irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
652 | error = irecv_send_file(client, argument, IRECV_SEND_OPT_DFU_NOTIFY_FINISH);
653 | debug("%s\n", irecv_strerror(error));
654 | break;
655 |
656 | case kSendCommand:
657 | if (devinfo->pid == 0x1881) {
658 | printf("Shell is not available in Debug USB (KIS) mode.\n");
659 | break;
660 | }
661 | if (_is_breq_command(argument)) {
662 | error = irecv_send_command_breq(client, argument, 1);
663 | } else {
664 | error = irecv_send_command(client, argument);
665 | }
666 | debug("%s\n", irecv_strerror(error));
667 | break;
668 |
669 | case kSendExploit:
670 | if (devinfo->pid == 0x1881) {
671 | printf("Shell is not available in Debug USB (KIS) mode.\n");
672 | break;
673 | }
674 | if (argument != NULL) {
675 | irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
676 | error = irecv_send_file(client, argument, 0);
677 | if (error != IRECV_E_SUCCESS) {
678 | debug("%s\n", irecv_strerror(error));
679 | break;
680 | }
681 | }
682 | error = irecv_trigger_limera1n_exploit(client);
683 | debug("%s\n", irecv_strerror(error));
684 | break;
685 |
686 | case kStartShell:
687 | if (devinfo->pid == 0x1881) {
688 | printf("This feature is not supported in Debug USB (KIS) mode.\n");
689 | break;
690 | }
691 | init_shell(client);
692 | break;
693 |
694 | case kSendScript:
695 | if (devinfo->pid == 0x1881) {
696 | printf("This feature is not supported in Debug USB (KIS) mode.\n");
697 | break;
698 | }
699 | buffer_read_from_filename(argument, &buffer, &buffer_length);
700 | if (buffer) {
701 | buffer[buffer_length] = '\0';
702 |
703 | error = irecv_execute_script(client, buffer);
704 | if (error != IRECV_E_SUCCESS) {
705 | debug("%s\n", irecv_strerror(error));
706 | }
707 |
708 | free(buffer);
709 | } else {
710 | fprintf(stderr, "Could not read file '%s'\n", argument);
711 | }
712 | break;
713 |
714 | case kShowMode: {
715 | irecv_get_mode(client, &mode);
716 | printf("%s Mode", mode_to_str(mode));
717 | if (devinfo->pid == 0x1881) {
718 | printf(" via Debug USB (KIS)");
719 | }
720 | printf("\n");
721 | break;
722 | }
723 | case kRebootToNormalMode:
724 | if (devinfo->pid == 0x1881) {
725 | printf("This feature is not supported in Debug USB (KIS) mode.\n");
726 | break;
727 | }
728 | error = irecv_setenv(client, "auto-boot", "true");
729 | if (error != IRECV_E_SUCCESS) {
730 | debug("%s\n", irecv_strerror(error));
731 | break;
732 | }
733 |
734 | error = irecv_saveenv(client);
735 | if (error != IRECV_E_SUCCESS) {
736 | debug("%s\n", irecv_strerror(error));
737 | break;
738 | }
739 |
740 | error = irecv_reboot(client);
741 | if (error != IRECV_E_SUCCESS) {
742 | debug("%s\n", irecv_strerror(error));
743 | } else {
744 | debug("%s\n", irecv_strerror(error));
745 | }
746 | break;
747 |
748 | case kQueryInfo:
749 | print_device_info(client);
750 | break;
751 |
752 | default:
753 | fprintf(stderr, "Unknown action\n");
754 | break;
755 | }
756 |
757 | irecv_close(client);
758 |
759 | return 0;
760 | }
761 |
--------------------------------------------------------------------------------
/udev/39-libirecovery.rules.in:
--------------------------------------------------------------------------------
1 | # Handle iOS devices in DFU and Recovery mode - for use with libirecovery
2 |
3 | # Change group and permissions of iOS devices in DFU, legacy WTF, and Recovery mode
4 | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="122[27]|128[0-3]", @udev_activation_rule@
5 |
6 | # Handle checkra1n DFU mode
7 | ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1338", @udev_activation_rule@
8 |
9 |
--------------------------------------------------------------------------------
/udev/Makefile.am:
--------------------------------------------------------------------------------
1 | if WITH_UDEV
2 | edit = \
3 | $(SED) -r \
4 | -e 's|@udev_activation_rule[@]|$(udev_activation_rule)|g' \
5 | < lt; > $@ || rm $@
6 |
7 | udevrules_DATA = \
8 | 39-libirecovery.rules
9 |
10 | 39-libirecovery.rules: 39-libirecovery.rules.in
11 | $(edit)
12 |
13 | EXTRA_DIST = \
14 | 39-libirecovery.rules.in
15 |
16 | MAINTAINERCLEANFILES = \
17 | 39-libirecovery.rules
18 |
19 | CLEANFILES = \
20 | 39-libirecovery.rules
21 | endif
22 |
--------------------------------------------------------------------------------