mirror of
https://github.com/bkerler/edl.git
synced 2025-04-02 02:00:03 -04:00
Merge remote-tracking branch 'upstream/master'
Signed-off-by: yangshiguang <yangshiguang@xiaomi.com>
This commit is contained in:
commit
9cdb99644d
74 changed files with 3425 additions and 807 deletions
.gitignoreenableadbfastpwnfastpwn.exefhloaderparsepyproject.tomlqc_diagrequirements.txtsetup.pysierrakeygensierrakeygen_README.md
Drivers
51-edl.rules
LICENSEREADME.mdboottodownloadedlWindows
edlclient
Config
Library
Connection
Modules
asmtools.pycryptutils.pyfirehose.pyfirehose_client.pygpt.pyhdlc.pyloader_db.pymemparse.pynand_config.pysahara.pysahara_defs.pysparse.pystreaming.pystreaming_client.pystreaming_defs.pyutils.pyxmlparser.pyTools
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -103,3 +103,5 @@ venv.bak/
|
|||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
edl_config.json
|
|
@ -2,6 +2,10 @@
|
|||
# Qualcomm EDL
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="9008", MODE="0666", GROUP="plugdev"
|
||||
|
||||
# Sony EDL
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0fce", ATTRS{idProduct}=="9dde", MODE="0666", GROUP="plugdev"
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0fce", ATTRS{idProduct}=="ade5", MODE="0666", GROUP="plugdev"
|
||||
|
||||
# Qualcomm Memory Debug
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="9006", MODE="0666", GROUP="plugdev"
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,4 +0,0 @@
|
|||
[ViewState]
|
||||
Mode=
|
||||
Vid=
|
||||
FolderType=Generic
|
|
@ -1,19 +0,0 @@
|
|||
<!--
|
||||
Summary of the DPInst XML Elements:
|
||||
http://msdn.microsoft.com/en-us/library/windows/hardware/ff553383%28v=vs.85%29.aspx
|
||||
|
||||
Enabling Language Customization:
|
||||
http://msdn.microsoft.com/en-us/library/windows/hardware/ff544886%28v=vs.85%29.aspx
|
||||
|
||||
Customizing the Items That Appear on the Wizard Pages:
|
||||
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540265%28v=vs.85%29.aspx
|
||||
|
||||
Dpinst.xml Example:
|
||||
http://msdn.microsoft.com/en-us/library/windows/hardware/ff544778%28v=vs.85%29.aspx
|
||||
-->
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<dpinst>
|
||||
<forceIfDriverIsNotBetter>1</forceIfDriverIsNotBetter>
|
||||
<installAllOrNone>1</installAllOrNone>
|
||||
</dpinst>
|
Binary file not shown.
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
Set oShell = CreateObject("WScript.Shell")
|
||||
oShell.Run("""dpinst64.exe """ & "/SW")
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
Set oShell = CreateObject("WScript.Shell")
|
||||
oShell.Run("""dpscat.exe""")
|
|
@ -1,2 +0,0 @@
|
|||
Set oShell = CreateObject("WScript.Shell")
|
||||
oShell.Run("""dpinst64.exe /SW""")
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Drivers/Windows/libusb-1.0.26-binaries.7z
Normal file
BIN
Drivers/Windows/libusb-1.0.26-binaries.7z
Normal file
Binary file not shown.
BIN
Drivers/Windows/zadig-2.8.exe
Normal file
BIN
Drivers/Windows/zadig-2.8.exe
Normal file
Binary file not shown.
687
LICENSE
687
LICENSE
|
@ -1,21 +1,674 @@
|
|||
MIT License
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (c) 2018 Bjoern Kerler
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Preamble
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
37
README.md
37
README.md
|
@ -1,5 +1,9 @@
|
|||
# Qualcomm Sahara / Firehose Attack Client / Diag Tools
|
||||
(c) B. Kerler 2018-2022
|
||||
(c) B. Kerler 2018-2024
|
||||
Licensed under GPLv3 license.
|
||||
|
||||
# Be aware that if you use anything from this repository in any (including) compiled form, you need to opensource your code as well !
|
||||
# Violating against the GPLv3 license will enforce me to stop developing these opensource tools.
|
||||
|
||||
## Why
|
||||
|
||||
|
@ -7,6 +11,10 @@
|
|||
- Because attacking firehose is kewl
|
||||
- Because memory dumping helps to find issues :)
|
||||
|
||||
## QC Sahara V3 additional information for newer QC devices
|
||||
- For newer qc phones, loader autodetection doesn't work anymore as the sahara loader doesn't offer a way to read the pkhash anymore
|
||||
- Thus, for Sahara V3, you need to give a valid loader via --loader option !
|
||||
|
||||
### Use LiveDVD (everything ready to go, based on Ubuntu):
|
||||
User: user, Password:user (based on Ubuntu 22.04 LTS)
|
||||
|
||||
|
@ -16,6 +24,14 @@ User: user, Password:user (based on Ubuntu 22.04 LTS)
|
|||
|
||||
## Installation
|
||||
|
||||
#### Grab files and install
|
||||
```
|
||||
git clone https://github.com/bkerler/edl
|
||||
cd edl
|
||||
git submodule update --init --recursive
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
### Linux (Debian/Ubuntu/Mint/etc):
|
||||
```bash
|
||||
# Debian/Ubuntu/Mint/etc
|
||||
|
@ -37,10 +53,12 @@ cd edl
|
|||
git submodule update --init --recursive
|
||||
sudo cp Drivers/51-edl.rules /etc/udev/rules.d
|
||||
sudo cp Drivers/50-android.rules /etc/udev/rules.d
|
||||
python setup.py build
|
||||
sudo python setup.py install
|
||||
python3 setup.py build
|
||||
sudo python3 setup.py install
|
||||
```
|
||||
|
||||
If you have SELinux enabled, you may need to set it to permissive mode temporarily to prevent permission issues. SELinux is commonly used by RedHat-like distros (for example, RHEL, Fedora, and CentOS). You can set it to permissive run-time until next boot with `sudo setenforce 0`.
|
||||
|
||||
### macOS:
|
||||
```bash
|
||||
brew install libusb git
|
||||
|
@ -48,8 +66,8 @@ brew install libusb git
|
|||
git clone https://github.com/bkerler/edl.git
|
||||
cd edl
|
||||
git submodule update --init --recursive
|
||||
python setup.py build
|
||||
sudo python setup.py install
|
||||
python3 setup.py build
|
||||
sudo python3 setup.py install
|
||||
```
|
||||
|
||||
### Windows:
|
||||
|
@ -58,13 +76,6 @@ sudo python setup.py install
|
|||
- If you install python from microsoft store, "python setup.py install" will fail, but that step isn't required.
|
||||
- WIN+R ```cmd```
|
||||
|
||||
#### Grab files and install
|
||||
```
|
||||
git clone https://github.com/bkerler/edl
|
||||
cd edl
|
||||
git submodule update --init --recursive
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
#### Get latest UsbDk 64-Bit
|
||||
- Install normal QC 9008 Serial Port driver (or use default Windows COM Port one, make sure no exclamation is seen)
|
||||
|
@ -246,7 +257,7 @@ For Oneplus 6T, enter *#801#* on dialpad, set Engineer Mode and Serial to on and
|
|||
- Oneplus 3T/5/6T/7T/8/8t/9/Nord CE/N10/N100 (Read-Only), BQ X, BQ X5, BQ X2, Gigaset ME Pure, ZTE MF210, ZTE MF920V, Sierra Wireless EM7455, Netgear MR1100-10EUS, Netgear MR5100
|
||||
- SIMCOM SIM8905E
|
||||
|
||||
Published under MIT license
|
||||
Published under GPLv3 license
|
||||
Additional license limitations: No use in commercial products without prior permit.
|
||||
|
||||
Enjoy !
|
||||
|
|
1
boottodownload
Symbolic link
1
boottodownload
Symbolic link
|
@ -0,0 +1 @@
|
|||
edlclient/Tools/boottodwnload
|
176
edl
176
edl
|
@ -1,6 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
# Qualcomm Sahara / Firehose Client (c) B.Kerler 2018-2021
|
||||
# Licensed under MIT License
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
"""
|
||||
Usage:
|
||||
edl -h | --help
|
||||
|
@ -9,14 +14,14 @@ Usage:
|
|||
edl [--debugmode] [--portname=portname] [--serial]
|
||||
edl [--gpt-num-part-entries=number] [--gpt-part-entry-size=number] [--gpt-part-entry-start-lba=number] [--portname=portname] [--serial]
|
||||
edl [--memory=memtype] [--skipstorageinit] [--maxpayload=bytes] [--sectorsize==bytes] [--portname=portname] [--serial]
|
||||
edl server [--tcpport=portnumber] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl memorydump [--partitions=partnames] [--debugmode] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl printgpt [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl gpt <directory> [--memory=memtype] [--lun=lun] [--genxml] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl r <partitionname> <filename> [--memory=memtype] [--sectorsize==bytes] [--lun=lun] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl rl <directory> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skip=partnames] [--genxml] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl rf <filename> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl rs <start_sector> <sectors> <filename> [--lun=lun] [--sectorsize==bytes] [--memory=memtype] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl server [--tcpport=portnumber] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl memorydump [--partitions=partnames] [--debugmode] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--serial_number=serial_number]
|
||||
edl printgpt [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl gpt <directory> [--memory=memtype] [--lun=lun] [--genxml] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl r <partitionname> <filename> [--memory=memtype] [--sectorsize==bytes] [--lun=lun] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl rl <directory> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skip=partnames] [--genxml] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl rf <filename> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl rs <start_sector> <sectors> <filename> [--lun=lun] [--sectorsize==bytes] [--memory=memtype] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl w <partitionname> <filename> [--partitionfilename=filename] [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skipwrite] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl wl <directory> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skip=partnames] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl wf <filename> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
|
@ -24,7 +29,7 @@ Usage:
|
|||
edl e <partitionname> [--memory=memtype] [--skipwrite] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl es <start_sector> <sectors> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skipwrite] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl ep <partitionname> <sectors> [--memory=memtype] [--skipwrite] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl footer <filename> [--memory=memtype] [--lun=lun] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl footer <filename> [--memory=memtype] [--lun=lun] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl peek <offset> <length> <filename> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl peekhex <offset> <length> [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl peekdword <offset> [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
|
@ -38,17 +43,18 @@ Usage:
|
|||
edl secureboot [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl pbl <filename> [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl qfp <filename> [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl getstorageinfo [--loader=filename] [--memory=memtype] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl setbootablestoragedrive <lun> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl setactiveslot <slot> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl send <command> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl xml <xmlfile> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl rawxml <xmlstring> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl reset [--resetmode=mode] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl nop [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial]
|
||||
edl getstorageinfo [--loader=filename] [--memory=memtype] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl setbootablestoragedrive <lun> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl getactiveslot [--memory=memtype] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl setactiveslot <slot> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl send <command> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl xml <xmlfile> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl rawxml <xmlstring> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl reset [--resetmode=mode] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl nop [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--skipstorageinit] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl modules <command> <options> [--memory=memtype] [--lun=lun] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value] [--portname=portname] [--serial]
|
||||
edl provision <xmlfile> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl qfil <rawprogram> <patch> <imagedir> [--loader=filename] [--memory=memtype] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial]
|
||||
edl provision <xmlfile> [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
edl qfil <rawprogram> <patch> <imagedir> [--loader=filename] [--memory=memtype] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--portname=portname] [--serial] [--devicemodel=value]
|
||||
|
||||
Description:
|
||||
server # Run tcp/ip server
|
||||
|
@ -96,8 +102,8 @@ Description:
|
|||
|
||||
Options:
|
||||
--loader=filename Use specific EDL loader, disable autodetection [default: None]
|
||||
--vid=vid Set usb vendor image_id used for EDL [default: -1]
|
||||
--pid=pid Set usb product image_id used for EDL [default: -1]
|
||||
--vid=vid Set usb vendor id used for EDL [default: -1]
|
||||
--pid=pid Set usb product id used for EDL [default: -1]
|
||||
--lun=lun Set lun to read/write from (UFS memory only)
|
||||
--maxpayload=bytes Set the maximum payload for EDL [default: 0x100000]
|
||||
--sectorsize=bytes Set default sector size
|
||||
|
@ -142,13 +148,13 @@ from binascii import hexlify
|
|||
|
||||
args = docopt(__doc__, version='3')
|
||||
|
||||
print("Qualcomm Sahara / Firehose Client V3.60 (c) B.Kerler 2018-2022.")
|
||||
print("Qualcomm Sahara / Firehose Client V3.62 (c) B.Kerler 2018-2023.")
|
||||
|
||||
|
||||
def parse_cmd(rargs):
|
||||
cmds = ["server", "printgpt", "gpt", "r", "rl", "rf", "rs", "w", "wl", "wf", "ws", "e", "es", "ep", "footer",
|
||||
"peek", "peekhex", "peekdword", "peekqword", "memtbl", "poke", "pokehex", "pokedword", "pokeqword",
|
||||
"memcpy", "secureboot", "pbl", "qfp", "getstorageinfo", "setbootablestoragedrive", "setactiveslot",
|
||||
"memcpy", "secureboot", "pbl", "qfp", "getstorageinfo", "setbootablestoragedrive", "getactiveslot", "setactiveslot",
|
||||
"send", "xml", "rawxml", "reset", "nop", "modules", "memorydump", "provision", "qfil"]
|
||||
for cmd in cmds:
|
||||
if rargs[cmd]:
|
||||
|
@ -187,8 +193,9 @@ class main(metaclass=LogBase):
|
|||
self.sahara = None
|
||||
self.vid = None
|
||||
self.pid = None
|
||||
self.serial_number = None
|
||||
|
||||
def doconnect(self, loop):
|
||||
def doconnect(self, loop) -> dict:
|
||||
while not self.cdc.connected:
|
||||
self.cdc.connected = self.cdc.connect(portname=self.portname)
|
||||
if not self.cdc.connected:
|
||||
|
@ -226,32 +233,13 @@ class main(metaclass=LogBase):
|
|||
self.cdc.close()
|
||||
sys.exit()
|
||||
|
||||
def handle_streaming(self, mode):
|
||||
self.cdc.timeout = None
|
||||
sahara_info = self.sahara.streaminginfo()
|
||||
if sahara_info:
|
||||
mode, resp = self.sahara.connect()
|
||||
if mode == "sahara":
|
||||
mode = self.sahara.upload_loader()
|
||||
if "enprg" in self.sahara.programmer.lower():
|
||||
mode = "load_enandprg"
|
||||
elif "nprg" in self.sahara.programmer.lower():
|
||||
mode = "load_nandprg"
|
||||
elif mode != "":
|
||||
mode = "load_" + mode
|
||||
if "load_" in mode:
|
||||
time.sleep(0.3)
|
||||
else:
|
||||
print("Error, couldn't find suitable enprg/nprg loader :(")
|
||||
self.exit()
|
||||
return mode
|
||||
|
||||
def run(self):
|
||||
if is_windows():
|
||||
proper_driver = console_cmd(r'reg query HKLM\HARDWARE\DEVICEMAP\SERIALCOMM')
|
||||
if re.findall(r'QCUSB', str(proper_driver)):
|
||||
self.warning(f'Please first install libusb_win32 driver from Zadig')
|
||||
|
||||
mode = ""
|
||||
loop = 0
|
||||
vid = int(args["--vid"], 16)
|
||||
pid = int(args["--pid"], 16)
|
||||
|
@ -282,7 +270,9 @@ class main(metaclass=LogBase):
|
|||
if self.serial:
|
||||
self.cdc = serial_class(loglevel=self.__logger.level, portconfig=portconfig)
|
||||
else:
|
||||
self.cdc = usb_class(portconfig=portconfig, loglevel=self.__logger.level)
|
||||
if args["--serial_number"]:
|
||||
self.serial_number = args["--serial_number"]
|
||||
self.cdc = usb_class(portconfig=portconfig, loglevel=self.__logger.level, serial_number=self.serial_number)
|
||||
|
||||
self.sahara = sahara(self.cdc, loglevel=self.__logger.level)
|
||||
|
||||
|
@ -295,58 +285,64 @@ class main(metaclass=LogBase):
|
|||
self.sahara.programmer = loader
|
||||
|
||||
self.info("Waiting for the device")
|
||||
resp = None
|
||||
self.cdc.timeout = 1500
|
||||
conninfo = self.doconnect(loop)
|
||||
mode = conninfo["mode"]
|
||||
if not "data" in conninfo:
|
||||
version = 2
|
||||
else:
|
||||
version = conninfo["data"].version
|
||||
if mode == "sahara":
|
||||
cmd = conninfo["cmd"]
|
||||
data = conninfo["data"]
|
||||
if cmd == cmd_t.SAHARA_HELLO_REQ:
|
||||
if data.mode == sahara_mode_t.SAHARA_MODE_MEMORY_DEBUG:
|
||||
if args["memorydump"] or self.cdc.pid==0x900E:
|
||||
time.sleep(0.5)
|
||||
print("Device is in memory dump mode, dumping memory")
|
||||
if args["--partitions"]:
|
||||
self.sahara.debug_mode(args["--partitions"].split(","))
|
||||
else:
|
||||
self.sahara.debug_mode()
|
||||
self.exit()
|
||||
else:
|
||||
print("Device is in streaming mode, uploading loader")
|
||||
self.cdc.timeout = None
|
||||
sahara_info = self.sahara.streaminginfo()
|
||||
if sahara_info:
|
||||
sahara_connect = self.sahara.connect()
|
||||
if len(sahara_connect) == 3:
|
||||
mode, cmd, resp = sahara_connect
|
||||
if "data" in conninfo:
|
||||
data = conninfo["data"]
|
||||
if data.mode == sahara_mode_t.SAHARA_MODE_MEMORY_DEBUG:
|
||||
if args["memorydump"] or self.cdc.pid == 0x900E:
|
||||
time.sleep(0.5)
|
||||
print("Device is in memory dump mode, dumping memory")
|
||||
if args["--partitions"]:
|
||||
self.sahara.debug_mode(args["--partitions"].split(","),version=version)
|
||||
else:
|
||||
mode, resp = sahara_connect
|
||||
if mode == "sahara":
|
||||
mode = self.sahara.upload_loader()
|
||||
if "enprg" in self.sahara.programmer.lower():
|
||||
mode = "load_enandprg"
|
||||
elif "nprg" in self.sahara.programmer.lower():
|
||||
mode = "load_nandprg"
|
||||
elif mode != "":
|
||||
mode = "load_" + mode
|
||||
if "load_" in mode:
|
||||
time.sleep(0.3)
|
||||
self.sahara.debug_mode(version=version)
|
||||
self.exit()
|
||||
else:
|
||||
print("Device is in streaming mode, uploading loader")
|
||||
self.cdc.timeout = None
|
||||
sahara_info = self.sahara.streaminginfo()
|
||||
if sahara_info:
|
||||
sahara_connect = self.sahara.connect()
|
||||
if len(sahara_connect) == 3:
|
||||
mode, cmd, resp = sahara_connect
|
||||
else:
|
||||
print("Error, couldn't find suitable enprg/nprg loader :(")
|
||||
self.exit()
|
||||
else:
|
||||
sahara_info = self.sahara.cmd_info()
|
||||
if sahara_info is not None:
|
||||
resp = self.sahara.connect()
|
||||
mode = resp["mode"]
|
||||
if "data" in resp:
|
||||
data = resp["data"]
|
||||
if mode == "sahara":
|
||||
mode = self.sahara.upload_loader()
|
||||
mode, resp = sahara_connect
|
||||
if mode == "sahara":
|
||||
mode = self.sahara.upload_loader(version=version)
|
||||
if "enprg" in self.sahara.programmer.lower():
|
||||
mode = "load_enandprg"
|
||||
elif "nprg" in self.sahara.programmer.lower():
|
||||
mode = "load_nandprg"
|
||||
elif mode != "":
|
||||
mode = "load_" + mode
|
||||
if "load_" in mode:
|
||||
time.sleep(0.3)
|
||||
else:
|
||||
print("Error, couldn't find suitable enprg/nprg loader :(")
|
||||
self.exit()
|
||||
else:
|
||||
print("Error on sahara handshake, resetting.")
|
||||
self.sahara.cmd_reset()
|
||||
sys.exit(1)
|
||||
sahara_info = self.sahara.cmd_info(version=version)
|
||||
if sahara_info is not None:
|
||||
resp = self.sahara.connect()
|
||||
mode = resp["mode"]
|
||||
if "data" in resp:
|
||||
data = resp["data"]
|
||||
if mode == "sahara":
|
||||
mode = self.sahara.upload_loader(version=version)
|
||||
else:
|
||||
print("Error on sahara handshake, resetting.")
|
||||
self.sahara.cmd_reset()
|
||||
sys.exit(1)
|
||||
if mode == "error":
|
||||
print("Connection detected, quiting.")
|
||||
sys.exit(1)
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
vendor = {
|
||||
0x0000: "Qualcomm ",
|
||||
0x0001: "Foxconn/Sony ",
|
||||
|
@ -37,11 +45,11 @@ vendor = {
|
|||
}
|
||||
|
||||
root_cert_hash = {
|
||||
"secboot_sha2_pss_subca1" : "afca69d4235117e5bfc21467068b20df85e0115d7413d5821883a6d244961581",
|
||||
"secboot_sha2_pss_subca2" : "d40eee56f3194665574109a39267724ae7944134cd53cb767e293d3c40497955bc8a4519ff992b031fadc6355015ac87",
|
||||
"old" : "cc3153a80293939b90d02d3bf8b23e0292e452fef662c74998421adad42a380f",
|
||||
"new" : "7be49b72f9e4337223ccb84d6eccca4e61ce16e3602ac2008cb18b75babe6d09",
|
||||
"mdm9x60_tel" : "36c886068d9a6634e9c55185044344e9e756dcc3b5960874942c7a1a1550dee0"
|
||||
"secboot_sha2_pss_subca1": "afca69d4235117e5bfc21467068b20df85e0115d7413d5821883a6d244961581",
|
||||
"secboot_sha2_pss_subca2": "d40eee56f3194665574109a39267724ae7944134cd53cb767e293d3c40497955bc8a4519ff992b031fadc6355015ac87",
|
||||
"old": "cc3153a80293939b90d02d3bf8b23e0292e452fef662c74998421adad42a380f",
|
||||
"secboot_sha2_root": "7be49b72f9e4337223ccb84d6eccca4e61ce16e3602ac2008cb18b75babe6d09",
|
||||
"mdm9x60_tel": "36c886068d9a6634e9c55185044344e9e756dcc3b5960874942c7a1a1550dee0"
|
||||
}
|
||||
|
||||
msmids = {
|
||||
|
@ -51,45 +59,59 @@ msmids = {
|
|||
0x9780E1: "IPQ4018",
|
||||
0x9790E1: "IPQ4019",
|
||||
0x0160E1: "QCA4020",
|
||||
0x9680E1: "APQ8009",
|
||||
0x9680E1: "APQ8009", # Snapdragon 212
|
||||
0x7060E1: "APQ8016",
|
||||
0x8100E1: "APQ806x",
|
||||
0x9D00E1: "APQ8076",
|
||||
0x08A0E1: "APQ807x",
|
||||
0x9000E1: "APQ8084",
|
||||
0x9010E1: "APQ8084", # SnapDragon 805
|
||||
0x9630E1: "APQ8092",
|
||||
0x9410E1: "APQ8094", # Snapdragon 810
|
||||
0x0940E1: "MSM8905",
|
||||
0x9600E1: "MSM8909", # SnapDragon 210
|
||||
0x9600E1: "MSM8909", # SnapDragon 210
|
||||
0x0510E1: "MSM8909W",
|
||||
0x7050E1: "MSM8916", # SnapDragon 410
|
||||
0x0560E1: "MSM8917",
|
||||
0x0520E1: "APQ8009W", # wear3100
|
||||
0x0960E1: "SDX24", # 0x60020100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit
|
||||
0x0970E1: "SDX24M", # 0x60020100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit
|
||||
0x7050E1: "MSM8916", # SnapDragon 410
|
||||
0x0560E1: "MSM8917", # Snapdragon 425
|
||||
0x0860E1: "MSM8920",
|
||||
0x91B0E1: "MSM8929", # SnapDragon 415
|
||||
0x04F0E1: "MSM8937",
|
||||
0x90B0E1: "MSM8939", # SnapDragon 610
|
||||
0x90B0E1: "MSM8939", # SnapDragon 615
|
||||
0x90C0E1: "APQ8036",
|
||||
0x90D0E1: "APQ8039",
|
||||
0x0500E1: "APQ8037",
|
||||
0x90D0E1: "APQ8039", # Snapdragon 615
|
||||
0x06B0E1: "MSM8940",
|
||||
0x9720E1: "MSM8952", # SnapDragon 652
|
||||
0x0460E1: "MSM8953", # 8053lat
|
||||
0x0660E1: "APQ8053",
|
||||
0x0460E1: "MSM8953", # Snapdragon 636
|
||||
0x0660E1: "APQ8053", # SnapDragon 652
|
||||
0x9900E1: "MSM8976", # SnapDragon 652
|
||||
0x9690E1: "MSM8992", # SnapDragon 82x
|
||||
0x9690E1: "MSM8992", # SnapDragon 808
|
||||
0x9400E1: "MSM8994", # SnapDragon 808
|
||||
0x9470E1: "MSM8996", # SnapDragon 820
|
||||
0x06F0E1: "MSM8996AU",
|
||||
0x0630E1: "MSM8996AU",
|
||||
0x05E0E1: "MSM8998_SDM835",
|
||||
0x94B0E1: "MSM9055",
|
||||
0x7F00E1: "MDM8225",
|
||||
0x7F30E1: "MDM8225M",
|
||||
0x9730E1: "MDM9206_MDM9607tx",
|
||||
0x9530E1: "MDM9245M",
|
||||
0x9200E1: "MDM9635", #Snapdragon X7
|
||||
0x04A0E1: "MDM9607",
|
||||
0x9670E1: "MDM9609",
|
||||
0x8090E1: "MDM9916",
|
||||
0x80B0E1: "MDM9955",
|
||||
0x9210E1: "MDM9x35",
|
||||
0x9500E1: "MDM9x40",
|
||||
0x9540E1: "MDM9x45",
|
||||
0x03A0E1: "MDM9x50",
|
||||
0x7F50E1: "MDM9x25",
|
||||
0x0320E1: "MDM9250", # MDM9x50
|
||||
0x03A0E1: "MDM9x50", # MDM8650
|
||||
0x7F50E1: "MDM9x25", # Snapdragon X5
|
||||
0x7F40E1: "MDM9625", # Snapdragon X5
|
||||
0x7F10E1: "MSM9225_1", # Snapdragon X5
|
||||
0x0320E1: "MDM9250", # MDM9x50, Snapdragon X16
|
||||
0x0340E1: "MDM9255", # MDM9x55
|
||||
0x0390E1: "MDM9350", # MDM9x50
|
||||
0x03B0E1: "MDM9x55",
|
||||
|
@ -102,18 +124,19 @@ msmids = {
|
|||
0x16A0E1: "FSM10051",
|
||||
0x16B0E1: "FSM10056",
|
||||
0x1530E1: "ipq5018",
|
||||
0x1610E1: "olympic",
|
||||
0x1720E1: "olympic_hybrid",
|
||||
0x0C50E1: "sda439",
|
||||
0x1610E1: "olympic_v1", # snapdragon 439, 0x6016 soc_hw, 0x8FCFD000 sec 32Bit, 0x8fff7000 dbg 32bit
|
||||
0x1720E1: "olympic_v1_hybrid",
|
||||
0x1060E1: "qm215",
|
||||
0x0BE0E1: "SDM429",
|
||||
0x0BF0E1: "SDM439",
|
||||
0x09A0E1: "SDM450",
|
||||
0x0AC0E1: "SDM630", #0x30070x00
|
||||
0x0AC0E1: "SDM630", # 0x30070x00
|
||||
0x0BA0E1: "SDM632",
|
||||
0x0BB0E1: "SDA632",
|
||||
0x08C0E1: "SDM660", # 0x30060000 soc_hw_version
|
||||
0x07B0E1: "SDX50M", # 0x soc_hw_version,
|
||||
0x0E50E1: "SDX55:CD90-PG591", # 0x600b0100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit
|
||||
0x0E50E1: "SDX55:CD90-PG591", # 0x600b0100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit
|
||||
0x0CF0E1: "SDX55M:CD90-PH809", # 0x600b0100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit, # Netgear MR5100, sdxprairie
|
||||
0x1250E1: "SA515M",
|
||||
|
||||
|
@ -130,33 +153,43 @@ msmids = {
|
|||
0x0DB0E1: "SDM710",
|
||||
0x0AA0E1: "QCS605",
|
||||
0x0ED0E1: "SXR1120",
|
||||
0x0EA0E1: "SXR1130",
|
||||
0x0EA0E1: "SXR1130", # QC VR/AR
|
||||
0x08E0E1: "SDA845",
|
||||
0x1A60E1: "WCN7850", # hamilton, soc_hw 0x40170000,
|
||||
0x1A70E1: "WCN7851", # hamilton, soc_hw 0x40170000
|
||||
|
||||
# d40eee56f3194665574109a39267724ae7944134cd53cb767e293d3c40497955
|
||||
# d40eee56f3194665574109a39267724ae7944134cd53cb767e293d3c40497955bc8a4519ff992b031fadc6355015ac87 pk-hash/root-cert
|
||||
0x1260E1: "IPQ6018",
|
||||
0x1070E1: "MDM9205", # 0x20130100
|
||||
0x1450E1: "agatti", # soc_vers 0x9003
|
||||
0x13F0E1: "bitra_SDM", # soc_vers 0x6012 SDM690
|
||||
0x1410E1: "bitra_SDA",
|
||||
0x1590E1: "cedros", # soc_vers 0x6017
|
||||
0x1360E1: "kamorta", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1370E1: "kamorta_P", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1730E1: "kamorta_IoT_modem", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1740E1: "kamorta_IoT_APQ", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1350E1: "lahaina", # soc_vers 0x600F sm8350, SDM875
|
||||
0x1070E1: "MDM9205", # 0x20130100
|
||||
0x1450E1: "agatti_mdm", # soc_vers 0x9003
|
||||
0x14F0E1: "agatti",
|
||||
0x1850E1: "agatti_mdm_iot",
|
||||
0x1860E1: "qcs2290", # qcs_agatti_apq
|
||||
0x13F0E1: "bitra_SDM", # soc_vers 0x6012 SDM690
|
||||
0x1410E1: "bitra_SDA", # Snapdragon 690 5G, smp_bitra
|
||||
0x1590E1: "cedros", # soc_vers 0x6017
|
||||
0x1360E1: "kamorta", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1370E1: "kamorta_P", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1730E1: "kamorta_IoT_modem", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1740E1: "kamorta_IoT_APQ", # soc_vers 0x9002 SnapDragon 460 SM4350
|
||||
0x1C70E1: "kamorta_qrb",
|
||||
0x1B80E1: "divar", # Snapdragon 680 4G SM6225 Codename Divar, soc_vers 0x9007, 0x45FFF000 sec.elf 64 bit, 0x10000000 dbgpolicy 64 bit
|
||||
0x1350E1: "lahaina", # sd888, soc_vers 0x600F sm8350, SDM875
|
||||
0x1520E1: "lahaina", # sd888
|
||||
0x19E0E1: "lahaina", # vordonisi
|
||||
0x1A40E1: "Vordonisi",
|
||||
0x1420E1: "lahaina_premier",
|
||||
0x14A0E1: "SC8280X", # soc_vers 0x6014, makena
|
||||
0x14A0E1: "SC8280X", # soc_vers 0x6014, makena
|
||||
0x14B0E1: "SA8295P",
|
||||
0x14C0E1: "SA8540P",
|
||||
0x16F0E1: "mannar", # soc_vers 0x9004
|
||||
0x16E0E1: "mannar_P", # soc_vers 0x9004
|
||||
0x1470E1: "moselle", # soc_vers 0x4014
|
||||
0x14C0E1: "SA8540P", # Makena Adas
|
||||
0x16F0E1: "mannar", # soc_vers 0x9004, SnapDragon 480 5G SM4350
|
||||
0x16E0E1: "mannar_P", # soc_vers 0x9004
|
||||
0x1470E1: "moselle", # soc_vers 0x4014
|
||||
0x10A0E1: "nicobar", # 0x90010100 soc_hw_version, 0x45FFF000 sec.elf 64Bit, 0x101FF000 dbgpolicy, 64Bit
|
||||
0x1750E1: "nicobar_IoT_modem", # 0x90010100 soc_hw_version, 0x45FFF000 sec.elf 64Bit, 0x101FF000 dbgpolicy, 64Bit
|
||||
0x1760E1: "nicobar_IoT_APQ", # 0x90010100 soc_hw_version, 0x45FFF000 sec.elf 64Bit, 0x101FF000 dbgpolicy, 64Bit
|
||||
0x10B0E1: "QCN9000", # soc_vers 0x400D
|
||||
0x10B0E1: "QCN9000", # soc_vers 0x400D
|
||||
0x10C0E1: "QCN9001",
|
||||
0x1150E1: "QCN9002",
|
||||
0x10D0E1: "QCN9003",
|
||||
|
@ -164,83 +197,134 @@ msmids = {
|
|||
0x10F0E1: "QCN9011",
|
||||
0x1110E1: "QCN9012",
|
||||
0x1140E1: "QCN9013",
|
||||
0x0E30E1: "qcs401", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0E40E1: "qcs403", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x1040E1: "qcs404", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0E30E1: "qcs401", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0E40E1: "qcs403", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x1040E1: "qcs404", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0AF0E1: "qcs405", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0EB0E1: "qcs407", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0400E1: "rennell_cb", # soc_vers 0x600E7T A11 CB
|
||||
0x12A0E1: "rennell",
|
||||
0x12B0E1: "rennell_premier",
|
||||
0x1490E1: "rennell_v1.1",
|
||||
0x1630E1: "sd7250",
|
||||
0x11E0E1: "saipan", # 0x600D0100 soc_hw_version, 0x808FF000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit, SM7250 Snapdragon 765G
|
||||
0x0950E1: "SM6150", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0EB0E1: "qcs407", # 0x20140000 soc_hw_version, 0x863DB000 sec.elf 64Bit, 0x863DE000 dbgpolicy, 64Bit
|
||||
0x0400E1: "rennell_cb", # soc_vers 0x600E7T A11 CB
|
||||
0x12A0E1: "rennell", # Snapdragon 720G, rennell_sm
|
||||
0x12B0E1: "rennell_premier", # Snapdragon 720G, rennell_smp
|
||||
0x1490E1: "rennell_v1.1", # Snapdragon 720G rennell_sm_ab
|
||||
0x1630E1: "sd7250", # Snapdragon 750G, bitra_h
|
||||
0x11E0E1: "saipan", # 0x600D0100 soc_hw_version, 0x808FF000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit, SM7250 Snapdragon 765G
|
||||
0x1430E1: "saipan", # saipan module
|
||||
0x0950E1: "SM6150", # Snapdragon 675, 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0EC0E1: "SM6150p", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0F50E1: "SM6155", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0F50E1: "SM6155", # SA6155, 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x100EE0E1: "SM6155p", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x000EE0E1: "SA6155p", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0011C0E1: "QCS610", # Qualcomm Vision Intelligence
|
||||
0x1011C0E1: "SM6150_IoT_High", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x001290E1: "SM6150_IoT_Low", # 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x001290E1: "SM6150_IoT_Low", # QCS410, 0x60070100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0E60E1: "SM7150", # 0x600C0100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0A50E1: "SM8150", # SDM855 Hana 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0A60E1: "SM8150p", # SDM855p Hana 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0C30E1: "SM8250:CD90-PH805-1A", # Kona, 0x60080100 soc_hw_version, 0x808FF000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit
|
||||
0x0CE0E1: "SM8250:CD90-PH806-1A", # Kona 0x60080100 soc_hw_version, 0x808FF000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit
|
||||
0x0B80E1: "sc8180x", # Snapdragon 8CX, soc_vers 0x6006
|
||||
0x1560E1: "SM8250", # HDK 8250
|
||||
0x0A50E1: "SM8150", # SDM855 Hana 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0A60E1: "SM8150p", # SDA855 Hana 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0CB0E1: "SDM855A",
|
||||
0x0C30E1: "SM8250:CD90-PH805-1A", # Snapdragon 865, Kona, 0x60080100 soc_hw_version, 0x808FF000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit
|
||||
0x0CE0E1: "SM8250:CD90-PH806-1A", # Snapdragon 865, Kona 0x60080100 soc_hw_version, 0x808FF000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit
|
||||
0x0B80E1: "sc8180x", # Snapdragon 8CX, soc_vers 0x6006, 0x85FFD000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit
|
||||
0x1230E1: "sa8189P", # Snapdragon 8CX, automotive, soc_vers 0x6006, 0x85FFD000 sec.elf 64Bit, 0x1C000000 dbgpolicy, 64Bit
|
||||
0x1560E1: "SM8250", # HDK 8250 / QCS820
|
||||
0x1510E1: "SA2150p",
|
||||
0x14D0E1: "SDM662", # sm6115, bengal
|
||||
0x18A0E1: "fraser", #soc_vers 0x600D
|
||||
0x1920E1: "sm7325", #soc_vers 0x6018
|
||||
0x1930E1: "sc7280", #soc_vers 0x6018
|
||||
0x1940E1: "sc7295", #soc_vers 0x6018
|
||||
0x18B0E1: "qtang2", #soc_vers 0x7001
|
||||
0x12C0E1: "sc7180", #soc_vers 0x600E
|
||||
0x14D0E1: "SDM662", # sm6115, bengal
|
||||
0x18A0E1: "fraser", # soc_vers 0x600D
|
||||
0x1920E1: "sm7325", # soc_vers 0x6018
|
||||
0x1930E1: "sc7280", # soc_vers 0x6018
|
||||
0x1940E1: "sc7295", # soc_vers 0x6018
|
||||
0x18B0E1: "qtang2", # soc_vers 0x7001
|
||||
0x12C0E1: "sc7180", # soc_vers 0x600E, 0x1C000000 dbgpolicy 32Bit
|
||||
0x1A90E1: "strait", # 0x90060100 soc_hw_version, 0x10000000 dbgpolicy 64Bit, 0x808FF000 sec.elf 64Bit
|
||||
|
||||
# Unknown root hash
|
||||
0x0B70E1: "SDM850",
|
||||
0x0960E1: "SDX24", # 0x60020100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit
|
||||
0x0970E1: "SDX24M", # 0x60020100 soc_hw_version, 0x8fff7000 dbgpolicy 32Bit, 0x8FCFD000 sec.elf 64Bit
|
||||
0x0E70E1: "SM7150p", # 0x600C0100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0E80E1: "SA8155", # 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0E90E1: "SA8155p", # 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x1440E1: "chitwan", # soc_vers 0x6013
|
||||
0x0E70E1: "SM7150p", # SnapDragon 730, 0x600C0100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0E80E1: "SA8155", # Snapdragon 855+, 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x0E90E1: "SA8155p", # SDA855A, 0x60030100 soc_hw_version, 0x85FFF000 sec.elf 64Bit, 0x1C1FF000 dbgpolicy, 64Bit
|
||||
0x1440E1: "chitwan", # soc_vers 0x6013
|
||||
0x6220E1: "MSM7227A",
|
||||
0x8040E1: "APQ8026",
|
||||
0x0550E1: "APQ8017",
|
||||
0x90F0E1: "APQ8037",
|
||||
0x9770E1: "APQ8052",
|
||||
0x9F00E1: "APQ8056",
|
||||
0x9F00E1: "APQ8056", # Snapdragon 650
|
||||
0x9120E1: "APQ8062",
|
||||
0x7190E1: "APQ8064",
|
||||
0x9300E1: "APQ8092",
|
||||
0x0640E1: "APQ8096SG",
|
||||
0x0620E1: "APQ8098",
|
||||
0x8110E1: "MSM8210",
|
||||
0x8140E1: "MSM8212",
|
||||
0x8120E1: "MSM8610",
|
||||
0x0590E1: "MSM8217",
|
||||
0x7BE0E1: "MSM8274_AA",
|
||||
0x8120E1: "MSM8610", # SnapDragon 200
|
||||
0x8160E1: "MSM8112", # SnapDragon 200
|
||||
0x8170E1: "MSM8510", # Snapdragon 200
|
||||
0x8100E1: "MSM8110", # Snapdragon 200
|
||||
0x8130E1: "MSM8810", # Snapdragon 200
|
||||
0x8080E1: "MSM8512", # Snapdragon 200
|
||||
0x8150E1: "MSM8612",
|
||||
0x8010E1: "MSM8626",
|
||||
0x8050E1: "MSM8926", # SnapDragon 400
|
||||
0x9180E1: "MSM8928", # SnapDragon 400
|
||||
0x8050E1: "MSM8926", # SnapDragon 400
|
||||
0x9180E1: "MSM8928", # SnapDragon 400
|
||||
0x9170E1: "MSM8628", # SnapDragon 400
|
||||
0x7210E1: "MSM8930",
|
||||
0x72C0E1: "MSM8960",
|
||||
0x9B00E1: "MSM8956", # SnapDragon 652
|
||||
0x9B00E1: "MSM8956", # SnapDragon 652
|
||||
0x9100E1: "MSM8962",
|
||||
0x7B00E1: "MSM8974", # Snapdragon 800
|
||||
0x7B30E1: "MSM8974A",
|
||||
0x7B00E1: "MSM8974", # Snapdragon 800
|
||||
0x7BD0E1: "MSM8674_AA", # Snapdragon 800
|
||||
0x7B30E1: "APQ8074", # APQ8074
|
||||
0x7B40E1: "MSM8974AB",
|
||||
0x7B80E1: "MSM8974Pro",
|
||||
0x7BC0E1: "MSM8974ABv3",
|
||||
0x6B10E1: "MSM8974AC",
|
||||
0x05F0E1: "MSM8996Pro", # SnapDragon 821
|
||||
0x05F0E1: "MSM8996Pro", # SnapDragon 821, MSM8996SG
|
||||
0x06C0E1: "MSM8997",
|
||||
0x0480E1: "MDM9207",
|
||||
0x0CC0E1: "SDM636",
|
||||
0x0930E1: "SDA670", # 0x60040100 soc_hw_version
|
||||
#0x0930E1: "SDA835", # 0x30020000 => HW_ID1 3002000000290022
|
||||
# 0x0930E1: "SDA835", # 0x30020000 => HW_ID1 3002000000290022
|
||||
0x08B0E1: "SDM845", # Napali 0x60000100 => HW_ID1 6000000000010000
|
||||
#SDM840 NapaliQ ?
|
||||
#SDM640 Talos ?
|
||||
0x19E0E1: "lahaina",
|
||||
0x0520e1: "Wear3100"
|
||||
# SDM840 NapaliQ ?
|
||||
# SDM640 Talos ?
|
||||
# SM6375 ?
|
||||
0x1970E1: "qcm6490",
|
||||
0x1980E1: "qcs6490",
|
||||
0x9820E1: "msm8976", # Snapdragon 652
|
||||
0x8060E1: "msm8326", # Snapdragon S4
|
||||
0x9640E1: "msm8992", # Snapdragon 808
|
||||
0x7B50E1: "msm8674_pro", # Snapdragon 801
|
||||
0x80D0E1: "fsm9915",
|
||||
0x9110E1: "msm8262",
|
||||
0x0BC0E1: "sda630",
|
||||
0x0F20E1: "sa4155p",
|
||||
0x0EF0E1: "sdm660",
|
||||
0x8030E1: "msm8126",
|
||||
0x9130E1: "apq8028", #Snapdragon 400
|
||||
0x0B90E1: "sda450",
|
||||
0x05A0E1: "msm8617", #Snapdragon 425
|
||||
0x13D0E1: "qcm2150",
|
||||
0x8020E1: "msm8526",
|
||||
0x80A0E1: "fsm9965",
|
||||
0x80F0E1: "fsm9900",
|
||||
0x9140E1: "msm8128",
|
||||
0x9160E1: "msm8528", # Snapdragon 400
|
||||
0x08F0E1: "sdm830", # Snapdragon 830
|
||||
0x09D0E1: "sda658", # Snapdragon 660/658
|
||||
0x08D0E1: "sdm658",
|
||||
0x9830E1: "apq8076", # Snapdragon 652
|
||||
0x80C0E1: "fsm9950",
|
||||
0x80E0E1: "fsm9910",
|
||||
0x15A0E1: "qrb516",
|
||||
0x8000E1: "msm8226",
|
||||
0x0D90E1: "qca6390",
|
||||
0x9D70E1: "msm8229",
|
||||
0x90E0E1: "msm8236",
|
||||
0x9660E1: "mdm9309",
|
||||
0x04E0E1: "apq8096au",
|
||||
0x9570E1: "msm8239", # Snapdragon 615
|
||||
|
||||
}
|
||||
|
||||
sochw = {
|
||||
|
@ -256,7 +340,7 @@ sochw = {
|
|||
0x400B: "QCN7605,QCA6595,QCN7606",
|
||||
0x400D: "QCN9000,QCN9001,QCN9002,QCN9003,QCN9010,QCN9011,QCN9012,QCN9013",
|
||||
0x4014: "moselle",
|
||||
|
||||
0x4017: "WCN7850,WCN7851",
|
||||
#: "SDM632",
|
||||
#: "SDA632",
|
||||
#: "SDM636",
|
||||
|
@ -278,28 +362,30 @@ sochw = {
|
|||
0x600F: "lahaina",
|
||||
0x6012: "bitra_SDM",
|
||||
0x6013: "chitwan",
|
||||
0x6014: "SC8280X,SA8295P,SA8540P", #makena
|
||||
0x6016: "olympic,olympic_hybrid",
|
||||
0x6014: "SC8280X,SA8295P,SA8540P", # makena
|
||||
0x6016: "olympic_v1,olympic_v1_hybrid",
|
||||
0x6017: "cedros",
|
||||
0x6018: "sm7325,sc7280,sc7295", #kodiak
|
||||
0x6018: "sm7325,sc7280,sc7295", # kodiak
|
||||
0x7001: "qtang2",
|
||||
0x7200: "SDM662",
|
||||
0x9001: "nicobar,nicobar_IoT_APQ,nicobar_IoT_modem",
|
||||
0x9002: "kamorta,kamorta_P,kamorta_IoT_APQ,kamorta_IoT_modem",
|
||||
0x9003: "agatti",
|
||||
0x9004: "mannar,mannar_P"
|
||||
0x9002: "kamorta,kamorta_P,kamorta_IoT_APQ,kamorta_IoT_modem,sm6225",
|
||||
0x9003: "agatti,agatti_mdm_iot,agatti_mdm,qcs2290",
|
||||
0x9004: "mannar,mannar_P",
|
||||
0x9006: "strait",
|
||||
0x9007: "divar"
|
||||
}
|
||||
|
||||
secgen=[
|
||||
secgen = [
|
||||
# BOOT_ROM_BASE_PHYS, SECURITY_CONTROL_BASE_PHYS, MEMORY_MAP
|
||||
[[], [0x01900000, 0x100000], []],
|
||||
[[],[0x01e20000,0x1000],[]],
|
||||
[[0xFC010000, 0x18000], [0xFC4B8000, 0x60F0], [0x200000, 0x24000]],
|
||||
[[0x100000, 0x1ffb0], [0x70000, 0x6158], [0x200000, 0x24000]],
|
||||
[[0x100000, 0x1ffb0], [0x00058000, 0x1000], [0x200000, 0x24000]],
|
||||
[[0x100000, 0x1ffb0], [0x000A0000, 0x6FFF], [0x200000, 0x24000]],
|
||||
[[0x100000, 0x1ffb0], [0x00700000, 0x6158], [0x200000, 0x24000]],
|
||||
[[0x300000, 0x3c000], [0x00780000, 0x10000], [0x14009003, 0x24000]],
|
||||
[[], [0x01e20000, 0x1000], []],
|
||||
[[0xFC010000, 0x18000], [0xFC4B8000, 0x60F0], [0x200000, 0x18000]],
|
||||
[[0x100000, 0x1ffb0], [0x70000, 0x6158], [0x200000, 0x18000]],
|
||||
[[0x100000, 0x1ffb0], [0x00058000, 0x1000], [0x200000, 0x18000]],
|
||||
[[0x100000, 0x1ffb0], [0x000A0000, 0x6FFF], [0x200000, 0x18000]],
|
||||
[[0x100000, 0x1ffb0], [0x00700000, 0x6158], [0x200000, 0x18000]],
|
||||
[[0x300000, 0x3c000], [0x00780000, 0x10000], [0x14009003, 0x18000]],
|
||||
[[0x300000, 0x3c000], [0x01B40000, 0x10000], []],
|
||||
]
|
||||
|
||||
|
@ -320,6 +406,7 @@ infotbl = {
|
|||
"MSM8974AB": secgen[2],
|
||||
"MSM8974ABv3": secgen[2],
|
||||
"MSM8974AC": secgen[2],
|
||||
"APQ8074": secgen[2],
|
||||
"MSM8992": secgen[2],
|
||||
"MSM8994": secgen[2],
|
||||
"MDM9x25": secgen[2],
|
||||
|
@ -408,9 +495,9 @@ infotbl = {
|
|||
"SM6150": secgen[7],
|
||||
"SM6150p": secgen[7],
|
||||
"SM6150_IoT_High": secgen[7],
|
||||
"SM6150_IoT_Low" : secgen[7],
|
||||
"SM6155" : secgen[7],
|
||||
"SM6155p" : secgen[7],
|
||||
"SM6150_IoT_Low": secgen[7],
|
||||
"SM6155": secgen[7],
|
||||
"SM6155p": secgen[7],
|
||||
"SM7150": secgen[7],
|
||||
"SM7150p": secgen[7],
|
||||
"SM8150": secgen[7],
|
||||
|
@ -434,15 +521,23 @@ infotbl = {
|
|||
"rennell_v1.1": secgen[7],
|
||||
"sc7180": secgen[7],
|
||||
"sd7250": secgen[7],
|
||||
"olympic_v1": secgen[7], # secgen 8 as well
|
||||
"olympic_v1_hybrid": secgen[7], # secgen 8 as well
|
||||
"WCN7850": secgen[7],
|
||||
"WCN7851": secgen[7],
|
||||
|
||||
"nicobar": secgen[8],
|
||||
"nicobar_IoT_APQ": secgen[8],
|
||||
"nicobar_IoT_modem": secgen[8],
|
||||
"agatti": secgen[8],
|
||||
"agatti_mdm": secgen[8],
|
||||
"agatti_mdm_iot": secgen[8],
|
||||
"qcs2290": secgen[8],
|
||||
"kamorta": secgen[8],
|
||||
"kamorta_P": secgen[8],
|
||||
"kamorta_IoT_modem": secgen[8],
|
||||
"kamorta_IoT_APQ": secgen[8],
|
||||
"divar": secgen[8],
|
||||
"SDM662": secgen[8],
|
||||
"sm7235": secgen[8],
|
||||
"sc7280": secgen[8],
|
||||
|
@ -450,10 +545,7 @@ infotbl = {
|
|||
"SC8280X": secgen[8],
|
||||
"SA8295P": secgen[8],
|
||||
"SA8540P": secgen[8],
|
||||
"olympic": secgen[8],
|
||||
"olympic_hybrid": secgen[8],
|
||||
"lahaina": secgen[8]
|
||||
|
||||
"strait": secgen[8],
|
||||
|
||||
# "MSM7227A": [[], [], []],
|
||||
# "MSM8210": [[], [0xFC4B8000,0x6FFF], []],
|
||||
|
@ -464,6 +556,7 @@ infotbl = {
|
|||
# "MSM8928": [[], [], []],
|
||||
}
|
||||
|
||||
|
||||
class memory_type:
|
||||
nand = 0
|
||||
emmc = 1
|
||||
|
@ -487,6 +580,7 @@ class memory_type:
|
|||
"MSM8974AB": emmc,
|
||||
"MSM8974ABv3": emmc,
|
||||
"MSM8974AC": emmc,
|
||||
"APQ8074": emmc,
|
||||
"MSM8992": emmc,
|
||||
"MSM8994": emmc,
|
||||
"MDM9x25": emmc,
|
||||
|
@ -602,15 +696,20 @@ class memory_type:
|
|||
"sc7180": ufs,
|
||||
"sd7250": ufs,
|
||||
"SA2150p": emmc,
|
||||
|
||||
"nicobar": ufs,
|
||||
"agatti": ufs,
|
||||
"agatti": emmc,
|
||||
"agatti_mdm": emmc,
|
||||
"agatti_mdm_iot": emmc,
|
||||
"qcs2290": emmc,
|
||||
"kamorta": ufs,
|
||||
"kamorta_P": ufs,
|
||||
"kamorta_IoT_APQ": emmc,
|
||||
"kamorta_IoT_modem": emmc,
|
||||
"divar": ufs,
|
||||
"SDM662": emmc,
|
||||
|
||||
"strait": ufs,
|
||||
"WCN7850": emmc,
|
||||
"WCN7851": emmc,
|
||||
# "MSM7227A": [[], [], []],
|
||||
# "MSM8210": [[], [0xFC4B8000,0x6FFF], []],
|
||||
# "MSM8212": [[], [], []],
|
||||
|
@ -638,6 +737,7 @@ secureboottbl = {
|
|||
"APQ8076": 0x000a01d0,
|
||||
"APQ8084": 0xFC4B83F8,
|
||||
"APQ8092": 0xFC4B83F8,
|
||||
"APQ8094": 0xFC4B83F8,
|
||||
"APQ8098": 0x00780350,
|
||||
"MSM8226": 0xFC4B83E8,
|
||||
"MSM8610": 0xFC4B83E8,
|
||||
|
@ -657,6 +757,7 @@ secureboottbl = {
|
|||
"MSM8953": 0x000a01d0,
|
||||
"MSM8956": 0x000a01d0,
|
||||
"MSM8974": 0xFC4B83F8,
|
||||
"APQ8074": 0xFC4B83F8,
|
||||
"MSM8974AB": 0xFC4B83F8,
|
||||
"MSM8974ABv3": 0xFC4B83F8,
|
||||
"MSM8974AC": 0xFC4B83F8,
|
||||
|
@ -691,7 +792,7 @@ secureboottbl = {
|
|||
"SDA632": 0x000a01d0,
|
||||
"SDM636": 0x00780350,
|
||||
"SDM660": 0x00780350,
|
||||
"SDM670": 0x00780350, # Warlock
|
||||
"SDM670": 0x00780350, # Warlock
|
||||
"SDA670": 0x00780350,
|
||||
"SDM710": 0x00780350,
|
||||
"QCS605": 0x00780350,
|
||||
|
@ -699,13 +800,13 @@ secureboottbl = {
|
|||
"SXR1130": 0x00780350,
|
||||
"SDM845": 0x00780350,
|
||||
"SDA845": 0x00780350,
|
||||
"SDX24" : 0x00780390,
|
||||
"SDX24": 0x00780390,
|
||||
"SDX24M": 0x00780390,
|
||||
"SDX50M": 0x000a01e0,
|
||||
"SDX55:CD90-PG591": 0x007805E8,
|
||||
"SDX55:CD90-PH809": 0x007805E8,
|
||||
"SDX55M" : 0x007804D0,
|
||||
"SA515M" : 0x007804D0,
|
||||
"SDX55:CD90-PG591": 0x007805E8,
|
||||
"SDX55:CD90-PH809": 0x007805E8,
|
||||
"SDX55M": 0x007804D0,
|
||||
"SA515M": 0x007804D0,
|
||||
"SM6150": 0x00780360,
|
||||
"SM6150p": 0x00780360,
|
||||
"SM6155": 0x00780360,
|
||||
|
@ -720,6 +821,7 @@ secureboottbl = {
|
|||
"SM8250:CD90-PH805-1A": 0x007805E8,
|
||||
"SM8250:CD90-PH806-1A": 0x007805E8,
|
||||
"agatti": 0x01B40458,
|
||||
"qcs2290": 0x01B40458,
|
||||
"bitra": 0x007804D8,
|
||||
"bitra_SDM": 0x007804D8,
|
||||
"bitra_SDA": 0x007804D8,
|
||||
|
@ -740,15 +842,16 @@ secureboottbl = {
|
|||
"kamorta_P": 0x01B40458,
|
||||
"kamorta_IoT_APQ": 0x01B40458,
|
||||
"kamorta_IoT_modem": 0x01B40458,
|
||||
"divar": 0x01B40458,
|
||||
"SDM662": 0x01B40458,
|
||||
"lahaina": 0x780668,
|
||||
"lahaina_premier": 0x780668,
|
||||
"mannar": 0x01B40458,
|
||||
"mannar_P": 0x01B40458,
|
||||
"qm215": 0x000a01d0,
|
||||
"rennell":0x000780498,
|
||||
"rennell_premier":0x000780498,
|
||||
"rennell_V1.1":0x000780498,
|
||||
"rennell": 0x000780498,
|
||||
"rennell_premier": 0x000780498,
|
||||
"rennell_V1.1": 0x000780498,
|
||||
"sc7180": 0x000780498
|
||||
# "MSM7227A":[[], [], []],
|
||||
# "MSM8210": [[], [], []],
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
default_ids = [
|
||||
[0x05c6, 0x9008, -1],
|
||||
[0x0fce, 0x9dde, -1],
|
||||
[0x0fce, 0xade5, -1],
|
||||
[0x05c6, 0x900e, -1],
|
||||
[0x05c6, 0x9025, -1],
|
||||
[0x1199, 0x9062, -1],
|
||||
|
@ -15,6 +25,8 @@ default_diag_vid_pid = [
|
|||
[0x1199, 0x9091, -1], # Sierra Wireless
|
||||
[0x0846, 0x68e2, 2], # Netgear
|
||||
[0x05C6, 0x9008, -1], # QC EDL
|
||||
[0x0fce, 0x9dde, -1], # SONY EDL
|
||||
[0x0fce, 0xade5, -1], # SONY EDL
|
||||
[0x05C6, 0x676C, 0], # QC Handset
|
||||
[0x05c6, 0x901d, 0], # QC Android "setprop sys.usb.config diag,adb"
|
||||
[0x19d2, 0x0016, -1], # ZTE Diag
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import serial
|
||||
import serial.tools.list_ports
|
||||
import inspect
|
||||
import traceback
|
||||
from binascii import hexlify
|
||||
from edlclient.Library.utils import *
|
||||
try:
|
||||
from edlclient.Library.utils import *
|
||||
except:
|
||||
from Library.utils import *
|
||||
|
||||
class DeviceClass(metaclass=LogBase):
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2022
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import os.path
|
||||
import time
|
||||
import sys
|
||||
|
@ -20,8 +24,13 @@ import serial.tools.list_ports
|
|||
import inspect
|
||||
import traceback
|
||||
from binascii import hexlify
|
||||
from edlclient.Library.utils import *
|
||||
from edlclient.Library.Connection.devicehandler import DeviceClass
|
||||
try:
|
||||
from edlclient.Library.utils import *
|
||||
from edlclient.Library.Connection.devicehandler import DeviceClass
|
||||
except:
|
||||
from Library.utils import *
|
||||
from Library.Connection.devicehandler import DeviceClass
|
||||
|
||||
|
||||
class serial_class(DeviceClass):
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import io
|
||||
import logging
|
||||
|
||||
|
@ -9,17 +13,22 @@ import usb.util
|
|||
import time
|
||||
import inspect
|
||||
import array
|
||||
from edlclient.Library.utils import is_windows
|
||||
import usb.backend.libusb0
|
||||
if not is_windows():
|
||||
import usb.backend.libusb1
|
||||
from enum import Enum
|
||||
from binascii import hexlify
|
||||
from ctypes import c_void_p, c_int
|
||||
from edlclient.Library.utils import *
|
||||
try:
|
||||
from edlclient.Library.utils import *
|
||||
except:
|
||||
from Library.utils import *
|
||||
if not is_windows():
|
||||
import usb.backend.libusb1
|
||||
from struct import pack, calcsize
|
||||
import traceback
|
||||
from edlclient.Library.Connection.devicehandler import DeviceClass
|
||||
try:
|
||||
from edlclient.Library.Connection.devicehandler import DeviceClass
|
||||
except:
|
||||
from Library.Connection.devicehandler import DeviceClass
|
||||
USB_DIR_OUT = 0 # to device
|
||||
USB_DIR_IN = 0x80 # to host
|
||||
|
||||
|
@ -40,6 +49,8 @@ USB_RECIP_OTHER = 0x03
|
|||
USB_RECIP_PORT = 0x04
|
||||
USB_RECIP_RPIPE = 0x05
|
||||
|
||||
MAX_USB_BULK_BUFFER_SIZE = 16384
|
||||
|
||||
tag = 0
|
||||
|
||||
CDC_CMDS = {
|
||||
|
@ -57,8 +68,9 @@ CDC_CMDS = {
|
|||
|
||||
class usb_class(DeviceClass):
|
||||
|
||||
def __init__(self, loglevel=logging.INFO, portconfig=None, devclass=-1):
|
||||
def __init__(self, loglevel=logging.INFO, portconfig=None, devclass=-1, serial_number=None):
|
||||
super().__init__(loglevel, portconfig, devclass)
|
||||
self.serial_number = serial_number
|
||||
self.load_windows_dll()
|
||||
self.EP_IN = None
|
||||
self.EP_OUT = None
|
||||
|
@ -210,9 +222,13 @@ class usb_class(DeviceClass):
|
|||
for dev in devices:
|
||||
for usbid in self.portconfig:
|
||||
if dev.idProduct == usbid[1] and dev.idVendor == usbid[0]:
|
||||
if self.serial_number is not None:
|
||||
if dev.serial_number != self.serial_number:
|
||||
continue
|
||||
self.device = dev
|
||||
self.vid = dev.idVendor
|
||||
self.pid = dev.idProduct
|
||||
self.serial_number = dev.serial_number
|
||||
self.interface = usbid[2]
|
||||
break
|
||||
if self.device is not None:
|
||||
|
@ -322,7 +338,8 @@ class usb_class(DeviceClass):
|
|||
|
||||
def write(self, command, pktsize=None):
|
||||
if pktsize is None:
|
||||
pktsize = self.EP_OUT.wMaxPacketSize
|
||||
#pktsize = self.EP_OUT.wMaxPacketSize
|
||||
pktsize = MAX_USB_BULK_BUFFER_SIZE
|
||||
if isinstance(command, str):
|
||||
command = bytes(command, 'utf-8')
|
||||
pos = 0
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import argparse
|
||||
from edlclient.Library.Connection.usblib import *
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import logging
|
||||
from edlclient.Library.utils import LogBase
|
||||
|
@ -23,9 +27,12 @@ class generic(metaclass=LogBase):
|
|||
if res[0]:
|
||||
lun = res[1]
|
||||
rpartition = res[2]
|
||||
offsettopatch = 0x7FFFF
|
||||
sector = rpartition.sector + (offsettopatch // self.fh.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
offset = offsettopatch % self.fh.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if rpartition.sectors <= (0x8000//self.fh.cfg.SECTOR_SIZE_IN_BYTES):
|
||||
offsettopatch = 0x7FFF
|
||||
sector, offset = self.fh.calc_offset(rpartition.sector, offsettopatch)
|
||||
else:
|
||||
offsettopatch = 0x7FFFF
|
||||
sector, offset = self.fh.calc_offset(rpartition.sector, offsettopatch)
|
||||
if enable:
|
||||
value = 0x1
|
||||
else:
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import logging
|
||||
from edlclient.Library.utils import LogBase
|
||||
|
@ -8,24 +12,32 @@ from edlclient.Library.utils import LogBase
|
|||
try:
|
||||
from edlclient.Library.Modules.generic import generic
|
||||
except ImportError as e:
|
||||
print(e)
|
||||
generic = None
|
||||
pass
|
||||
|
||||
try:
|
||||
from edlclient.Library.Modules.oneplus import oneplus
|
||||
except ImportError as e:
|
||||
print(e)
|
||||
oneplus = None
|
||||
pass
|
||||
|
||||
try:
|
||||
from edlclient.Library.Modules.xiaomi import xiaomi
|
||||
except ImportError as e:
|
||||
print(e)
|
||||
xiaomi = None
|
||||
pass
|
||||
|
||||
try:
|
||||
from edlclient.Library.Modules.nothing import nothing
|
||||
except ImportError as e:
|
||||
nothing = None
|
||||
pass
|
||||
|
||||
class modules(metaclass=LogBase):
|
||||
def __init__(self, fh, serial, supported_functions, loglevel, devicemodel, args):
|
||||
def __init__(self, fh, serial:int, supported_functions, loglevel, devicemodel:str, args):
|
||||
self.fh = fh
|
||||
self.args = args
|
||||
self.serial = serial
|
||||
|
@ -43,17 +55,20 @@ class modules(metaclass=LogBase):
|
|||
try:
|
||||
self.generic = generic(fh=self.fh, serial=self.serial, args=self.args, loglevel=loglevel)
|
||||
except Exception as e:
|
||||
self.error(e)
|
||||
pass
|
||||
self.ops = None
|
||||
try:
|
||||
self.ops = oneplus(fh=self.fh, projid=self.devicemodel, serial=self.serial,
|
||||
supported_functions=self.supported_functions, args=self.args, loglevel=loglevel)
|
||||
except Exception as e:
|
||||
self.error(e)
|
||||
pass
|
||||
self.xiaomi = None
|
||||
try:
|
||||
self.xiaomi = xiaomi(fh=self.fh)
|
||||
except Exception as e:
|
||||
self.error(e)
|
||||
pass
|
||||
|
||||
def addpatch(self):
|
||||
|
@ -87,7 +102,7 @@ class modules(metaclass=LogBase):
|
|||
else:
|
||||
options[args[i]] = True
|
||||
if command == "":
|
||||
print("Valid commands are:\noemunlock\n")
|
||||
print("Valid commands are:\noemunlock, ops\n")
|
||||
return False
|
||||
if self.generic is not None and command == "oemunlock":
|
||||
if "enable" in options:
|
||||
|
@ -98,3 +113,46 @@ class modules(metaclass=LogBase):
|
|||
self.error("Unknown mode given. Available are: enable, disable.")
|
||||
return False
|
||||
return self.generic.oem_unlock(enable)
|
||||
elif self.ops is not None and command == "ops":
|
||||
if self.devicemodel is not None:
|
||||
enable = False
|
||||
partition = "param"
|
||||
if "enable" in options:
|
||||
enable = True
|
||||
elif "disable" in options:
|
||||
enable = False
|
||||
else:
|
||||
self.error("Unknown mode given. Available are: enable, disable.")
|
||||
return False
|
||||
res = self.fh.detect_partition(self.args, partition)
|
||||
if res[0]:
|
||||
lun = res[1]
|
||||
rpartition = res[2]
|
||||
paramdata = self.fh.cmd_read_buffer(lun, rpartition.sector, rpartition.sectors, False)
|
||||
if paramdata.data == b"":
|
||||
self.error("Error on reading param partition.")
|
||||
return False
|
||||
wdata = self.ops.enable_ops(paramdata.data, enable,self.devicemodel,self.serial)
|
||||
if wdata is not None:
|
||||
self.ops.run()
|
||||
if self.fh.cmd_program_buffer(lun, rpartition.sector, wdata, False):
|
||||
self.info("Successfully set mode")
|
||||
return True
|
||||
else:
|
||||
self.error("Error on writing param partition")
|
||||
return False
|
||||
else:
|
||||
self.error("No param info generated, did you provide the devicemodel ?")
|
||||
return False
|
||||
else:
|
||||
fpartitions = res[1]
|
||||
self.error(f"Error: Couldn't detect partition: {partition}\nAvailable partitions:")
|
||||
for lun in fpartitions:
|
||||
for rpartition in fpartitions[lun]:
|
||||
if self.args["--memory"].lower() == "emmc":
|
||||
self.error("\t" + rpartition)
|
||||
else:
|
||||
self.error(lun + ":\t" + rpartition)
|
||||
else:
|
||||
self.error("A devicemodel is needed for this command")
|
||||
return False
|
||||
|
|
65
edlclient/Library/Modules/nothing.py
Normal file
65
edlclient/Library/Modules/nothing.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import hashlib
|
||||
import logging
|
||||
import random
|
||||
|
||||
from edlclient.Library.utils import LogBase
|
||||
|
||||
|
||||
class nothing(metaclass=LogBase):
|
||||
def __init__(self, fh, projid="22111", serial=123456, ATOBuild=0, Flash_Mode=0, cf=0, supported_functions=None,
|
||||
loglevel=logging.INFO):
|
||||
self.fh = fh
|
||||
self.projid = projid
|
||||
#self.projid == "22111":
|
||||
self.hashverify = "16386b4035411a770b12507b2e30297c0c5471230b213e6a1e1e701c6a425150"
|
||||
self.serial = serial
|
||||
self.supported_functions = supported_functions
|
||||
self.__logger.setLevel(loglevel)
|
||||
if loglevel == logging.DEBUG:
|
||||
logfilename = "log.txt"
|
||||
fh = logging.FileHandler(logfilename)
|
||||
self.__logger.addHandler(fh)
|
||||
|
||||
def generatetoken(self, token1: str = None):
|
||||
if token1 is None:
|
||||
token1 = random.randbytes(32).hex()
|
||||
authresp = token1 + self.projid + ("%x" % self.serial) + self.hashverify
|
||||
token2 = hashlib.sha256(bytes(authresp,'utf-8')).hexdigest()[:64]
|
||||
token3 = self.hashverify
|
||||
return bytes(f"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><data>\n <ntprojectverify token1=\"{token1}\" token2=\"{token2}\" token3=\"{token3}\"/>\n</data>\n",'utf-8')
|
||||
|
||||
|
||||
def ntprojectverify(self):
|
||||
"""
|
||||
Nothing Phone 2
|
||||
"""
|
||||
authcmd = b"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><data>\n <checkntfeature />\n</data>\n"
|
||||
rsp = self.fh.xmlsend(authcmd)
|
||||
if rsp.resp:
|
||||
authresp = self.generatetoken()
|
||||
rsp = self.fh.xmlsend(authresp)
|
||||
if rsp.resp:
|
||||
if b"ACK" in rsp.data:
|
||||
return True
|
||||
if "value" in rsp.resp:
|
||||
if rsp.resp["value"] == "ACK":
|
||||
if 'authenticated' in rsp.log[0].lower() and 'true' in rsp.log[0].lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
nt = nothing(fh=None, projid="22111", serial=1729931115)
|
||||
res=nt.generatetoken(token1="512034500a07154561661e0f371f4a712a0b76074605724c640e301d632b3671")
|
||||
org=b"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><data>\n <ntprojectverify token1=\"512034500a07154561661e0f371f4a712a0b76074605724c640e301d632b3671\" token2=\"1ecd222465436eb8acc0cfc41e90d1e677165c184ea7d9631615014dac88c669\" token3=\"16386b4035411a770b12507b2e30297c0c5471230b213e6a1e1e701c6a425150\"/>\n</data>\n"
|
||||
if res!=org:
|
||||
print("Error !")
|
||||
print(res)
|
||||
print(nt.generatetoken())
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
"""
|
||||
Usage:
|
||||
|
@ -20,7 +24,7 @@ import random
|
|||
from struct import pack
|
||||
import logging
|
||||
from edlclient.Library.utils import LogBase
|
||||
|
||||
from edlclient.Library.Modules.oneplus_param import paramtools
|
||||
try:
|
||||
from edlclient.Library.cryptutils import cryptutils
|
||||
except Exception as e:
|
||||
|
@ -75,7 +79,7 @@ deviceconfig = {
|
|||
|
||||
# OP Nord, avicii
|
||||
"20801": dict(version=2, cm="eacf50e7", param_mode=0),
|
||||
|
||||
|
||||
# OP N10 5G Metro, billie8t
|
||||
"20885": dict(version=3, cm="3a403a71", param_mode=1),
|
||||
# OP N10 5G Global, billie8
|
||||
|
@ -87,7 +91,7 @@ deviceconfig = {
|
|||
|
||||
# OP N100 Metro, billie2t
|
||||
"20880": dict(version=3, cm="6ccf5913", param_mode=1),
|
||||
# OP N100 Global, billie2
|
||||
# OP N100 Global, billie2
|
||||
"20881": dict(version=3, cm="fa9ff378", param_mode=1),
|
||||
# OP N100 TMO, billie2t
|
||||
"20882": dict(version=3, cm="4ca1e84e", param_mode=1),
|
||||
|
@ -124,10 +128,10 @@ deviceconfig = {
|
|||
|
||||
|
||||
class oneplus(metaclass=LogBase):
|
||||
def __init__(self, fh, projid="18825", serial=123456, ATOBuild=0, Flash_Mode=0, cf=0, supported_functions=None,
|
||||
def __init__(self, fh, projid:str="18825", serial=123456, ATOBuild=0, Flash_Mode=0, cf=0, supported_functions=None,
|
||||
args=None, loglevel=logging.INFO):
|
||||
self.fh = fh
|
||||
self.__logger=self.__logger
|
||||
self.__logger = self.__logger
|
||||
self.args = args
|
||||
self.ATOBuild = ATOBuild
|
||||
self.Flash_Mode = Flash_Mode
|
||||
|
@ -155,7 +159,15 @@ class oneplus(metaclass=LogBase):
|
|||
logfilename = "log.txt"
|
||||
filehandler = logging.FileHandler(logfilename)
|
||||
self.__logger.addHandler(filehandler)
|
||||
self.ops_parm = None
|
||||
try:
|
||||
if projid in deviceconfig:
|
||||
mode = deviceconfig[projid]["param_mode"]
|
||||
self.ops_parm = paramtools(mode=mode, serial=serial)
|
||||
else:
|
||||
self.ops_parm = paramtools(mode=0, serial=serial)
|
||||
except ImportError as e:
|
||||
self.__logger.error(str(e))
|
||||
self.ops_parm = None
|
||||
self.ops = self.convert_projid(fh, projid, serial)
|
||||
|
||||
def getprodkey(self, projid):
|
||||
|
@ -187,10 +199,11 @@ class oneplus(metaclass=LogBase):
|
|||
exit(0)
|
||||
elif version == 3:
|
||||
if cm is not None:
|
||||
oneplus2(fh, cm, serial, pk, prodkey, self.ATOBuild, self.Flash_Mode, self.cf)
|
||||
return oneplus2(fh, cm, serial, pk, prodkey, self.ATOBuild, self.Flash_Mode, self.cf)
|
||||
else:
|
||||
assert "Device is not supported"
|
||||
exit(0)
|
||||
assert "Unknown projid:"+str(projid)
|
||||
return None
|
||||
|
||||
def run(self):
|
||||
|
@ -212,21 +225,26 @@ class oneplus(metaclass=LogBase):
|
|||
if self.ops.setprojmodel_verify:
|
||||
return self.ops.setprojmodel_verify(pk, token)
|
||||
|
||||
def setswprojmodel_verify(self, pk, token, device_timestamp):
|
||||
def setswprojmodel_verify(self, pk, token):
|
||||
if self.ops.setswprojmodel_verify:
|
||||
return self.ops.setswprojmodel_verify(pk, token, device_timestamp)
|
||||
return self.ops.setswprojmodel_verify(pk, token)
|
||||
|
||||
def program_verify(self, pk, token, tokendata):
|
||||
if self.ops.program_verify:
|
||||
return self.ops.program_verify(pk, token, tokendata)
|
||||
|
||||
def generatetoken(self, program=False, device_timestamp="123456789"):
|
||||
return self.ops.generatetoken(program=program, device_timestamp=device_timestamp)
|
||||
def generatetoken(self, program=False):
|
||||
return self.ops.generatetoken(program=program)
|
||||
|
||||
def demacia(self):
|
||||
if self.ops.demacia():
|
||||
return self.ops.demacia()
|
||||
|
||||
def enable_ops(self, data, enable, projid, serial):
|
||||
if self.ops_parm is not None:
|
||||
return self.ops_parm.enable_ops(data, enable)
|
||||
return None
|
||||
|
||||
def addpatch(self):
|
||||
if "setprojmodel" in self.supported_functions or "setswprojmodel" in self.supported_functions:
|
||||
pk, token = self.ops.generatetoken(True)
|
||||
|
@ -292,7 +310,7 @@ class oneplus1:
|
|||
data = "<?xml version=\"1.0\" ?>\n<data>\n<demacia token=\"" + token + "\" pk=\"" + pk + "\" />\n</data>"
|
||||
return data
|
||||
|
||||
def generatetoken(self, program=False, device_timestamp=None):
|
||||
def generatetoken(self, program=False):
|
||||
timestamp = str(int(time.time()))
|
||||
ha = cryptutils().hash()
|
||||
h1 = self.prodkey + self.ModelVerifyPrjName + self.random_postfix
|
||||
|
@ -411,6 +429,7 @@ class oneplus1:
|
|||
class oneplus2(metaclass=LogBase):
|
||||
def __init__(self, fh, ModelVerifyPrjName="20889", serial=123456, pk="", prodkey="", ATOBuild=0, Flash_Mode=0,
|
||||
cf=0, loglevel=logging.INFO):
|
||||
self.device_timestamp = None
|
||||
self.ModelVerifyPrjName = ModelVerifyPrjName
|
||||
self.pk = pk
|
||||
self.fh = fh
|
||||
|
@ -427,10 +446,10 @@ class oneplus2(metaclass=LogBase):
|
|||
fh = logging.FileHandler(logfilename)
|
||||
self.__logger.addHandler(fh)
|
||||
|
||||
def crypt_token(self, data, pk, device_timestamp, decrypt=False):
|
||||
def crypt_token(self, data, pk, device_timestamp:int, decrypt=False):
|
||||
aes = cryptutils().aes()
|
||||
aeskey = b"\x46\xA5\x97\x30\xBB\x0D\x41\xE8" + bytes(pk, 'utf-8') + \
|
||||
pack("<Q", int(device_timestamp, 10)) # we get this using setprocstart
|
||||
pack("<Q", device_timestamp) # we get this using setprocstart
|
||||
aesiv = b"\xDC\x91\x0D\x88\xE3\xC6\xEE\x65\xF0\xC7\x44\xB4\x02\x30\xCE\x40"
|
||||
if decrypt:
|
||||
cdata = unhexlify(data)
|
||||
|
@ -445,7 +464,7 @@ class oneplus2(metaclass=LogBase):
|
|||
rdata = hexlify(result)
|
||||
return rdata.upper().decode('utf-8')
|
||||
|
||||
def generatetoken(self, program=False, device_timestamp=None): # setswprojmodel
|
||||
def generatetoken(self, program=False): # setswprojmodel
|
||||
timestamp = str(int(time.time()))
|
||||
ha = cryptutils().hash()
|
||||
h1 = self.prodkey + self.ModelVerifyPrjName + self.random_postfix
|
||||
|
@ -464,7 +483,7 @@ class oneplus2(metaclass=LogBase):
|
|||
for item in items:
|
||||
data += item + ","
|
||||
data = data[:-1]
|
||||
token = self.crypt_token(data, self.pk, device_timestamp)
|
||||
token = self.crypt_token(data, self.pk, self.device_timestamp)
|
||||
return self.pk, token
|
||||
|
||||
def run(self, flag):
|
||||
|
@ -475,7 +494,9 @@ class oneplus2(metaclass=LogBase):
|
|||
return False
|
||||
data = res.decode('utf-8')
|
||||
device_timestamp = data[data.rfind("device_timestamp"):].split("\"")[1]
|
||||
pk, token = self.generatetoken(False, device_timestamp)
|
||||
self.device_timestamp = int(device_timestamp)
|
||||
print(self.device_timestamp)
|
||||
pk, token = self.generatetoken(False)
|
||||
res = self.fh.cmd_send(f"setswprojmodel token=\"{token}\" pk=\"{pk}\"")
|
||||
if not b"model_check=\"0\"" in res or not b"auth_token_verify=\"0\"" in res:
|
||||
print("Setswprojmodel failed.")
|
||||
|
@ -483,10 +504,10 @@ class oneplus2(metaclass=LogBase):
|
|||
return False
|
||||
return True
|
||||
|
||||
def setswprojmodel_verify(self, pk, token, device_timestamp):
|
||||
def setswprojmodel_verify(self, pk, token):
|
||||
self.pk = pk
|
||||
ha = cryptutils().hash()
|
||||
items = self.crypt_token(token, pk, device_timestamp, True)
|
||||
items = self.crypt_token(token, pk, self.device_timestamp, True)
|
||||
info = ["ModelVerifyPrjName", "random_postfix", "ModelVerifyHashToken", "ato_build_state", "flash_mode",
|
||||
"Version", "soc_sn", "cf", "timestamp", "secret"]
|
||||
i = 0
|
||||
|
@ -550,10 +571,11 @@ def main():
|
|||
serial = args["--serial"]
|
||||
device_timestamp = args["--ts"]
|
||||
op2 = oneplus(None, projid="20889", serial=serial, ATOBuild=0, Flash_Mode=0, cf=0)
|
||||
op2.ops.device_timestamp = int(device_timestamp)
|
||||
# 20889 OP N10 5G Europe
|
||||
print(f"./edl.py rawxml \"<?xml version=\\\"1.0\\\" ?><data><setprocstart /></data>\"")
|
||||
# Response should be : <?xml version="1.0" ?><data><response value=1 device_timestamp="%llu" /></data>
|
||||
pk, token = op2.generatetoken(False, device_timestamp)
|
||||
pk, token = op2.generatetoken(False)
|
||||
print(
|
||||
f"./edl.py rawxml \"<?xml version=\\\"1.0\\\" ?><data><setswprojmodel " +
|
||||
f"token=\\\"{token}\\\" pk=\\\"{pk}\\\" /></data>\" --debugmode")
|
||||
|
@ -587,9 +609,10 @@ def main():
|
|||
projid = args["--projid"][0]
|
||||
device_timestamp = args["--ts"]
|
||||
op = oneplus(None, projid=projid, serial=123456)
|
||||
op.ops.device_timestamp = int(device_timestamp)
|
||||
token = args["<token>"]
|
||||
pk = args["<pk>"]
|
||||
op.setswprojmodel_verify(pk, token, device_timestamp)
|
||||
op.setswprojmodel_verify(pk, token)
|
||||
|
||||
|
||||
def test_setswprojmodel_verify():
|
||||
|
@ -599,8 +622,9 @@ def test_setswprojmodel_verify():
|
|||
op = oneplus(None, projid=projid, serial=123456)
|
||||
data = deviceresp.decode('utf-8')
|
||||
device_timestamp = data[data.rfind("device_timestamp"):].split("\"")[1]
|
||||
pk, token = op.generatetoken(False, device_timestamp)
|
||||
if not op.setswprojmodel_verify(pk, token, device_timestamp):
|
||||
op.ops.device_timestamp = int(device_timestamp)
|
||||
pk, token = op.generatetoken(False)
|
||||
if not op.setswprojmodel_verify(pk, token):
|
||||
assert "Setswprojmodel error"
|
||||
|
||||
|
||||
|
|
989
edlclient/Library/Modules/oneplus_param.py
Executable file
989
edlclient/Library/Modules/oneplus_param.py
Executable file
|
@ -0,0 +1,989 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
"""
|
||||
Usage:
|
||||
oneplus_param.py param <filename> [--mode=mode] [--serial=serial]
|
||||
oneplus_param.py ops <filename> [--mode=mode] [--serial=serial]
|
||||
oneplus_param.py gencode <imei>
|
||||
oneplus_param.py setparam <filename> <sid> <offset> <value> [--mode=mode] [--serial=serial]
|
||||
"""
|
||||
import hashlib
|
||||
import zlib
|
||||
from enum import Enum
|
||||
from struct import calcsize, pack, unpack
|
||||
|
||||
try:
|
||||
from edlclient.Library.cryptutils import cryptutils
|
||||
except ImportError as e:
|
||||
import os, sys, inspect
|
||||
|
||||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
sys.path.insert(0, parent_dir)
|
||||
try:
|
||||
from cryptutils import cryptutils
|
||||
except ImportError as e:
|
||||
print(str(e))
|
||||
from binascii import unhexlify, hexlify
|
||||
|
||||
|
||||
class sid(Enum):
|
||||
PARAM_SID_PRODUCT = 0,
|
||||
PARAM_SID_CONFIG = 1,
|
||||
PARAM_SID_LCD = 2,
|
||||
PARAM_SID_TP = 3,
|
||||
PARAM_SID_TP_KPD = 4,
|
||||
PARAM_SID_CAMERA = 5,
|
||||
PARAM_SID_SENSORS = 6,
|
||||
PARAM_SID_BATTERY = 7,
|
||||
PARAM_SID_RTC = 8,
|
||||
PARAM_SID_CRASH_RECORD = 9,
|
||||
PARAM_SID_SALEINFO = 0xA,
|
||||
PARAM_SID_MISC = 0xB,
|
||||
PARAM_SID_DOWNLOAD = 0xC,
|
||||
PARAM_SID_PHONE_HISTORY = 0xD,
|
||||
PARAM_SID_DL_USERINFO = 0xE,
|
||||
PARAM_SID_ENC_SECRECY = 0x12C,
|
||||
PARAM_SID_ENC_CARRIER = 0x130,
|
||||
PARAM_SID_ENC_MOBID = 0x134,
|
||||
PARAM_SID_ENC_CVE = 0x138,
|
||||
PARAM_SID_INVALID = -1
|
||||
|
||||
'''
|
||||
CUSTOM_TYPE.NONE = new CUSTOM_TYPE("NONE", 0);
|
||||
CUSTOM_TYPE.JCC = new CUSTOM_TYPE("JCC", 1); French edition
|
||||
CUSTOM_TYPE.SW = new CUSTOM_TYPE("SW", 2); Star Wars
|
||||
CUSTOM_TYPE.AVG = new CUSTOM_TYPE("AVG", 3); Avengers
|
||||
CUSTOM_TYPE.MCL = new CUSTOM_TYPE("MCL", 4); McLaren
|
||||
CUSTOM_TYPE.OPR_RETAIL = new CUSTOM_TYPE("OPR_RETAIL", 5);
|
||||
CUSTOM_TYPE.CYB = new CUSTOM_TYPE("CYB", 6); Cyberpunk
|
||||
CUSTOM_TYPE v0 = new CUSTOM_TYPE("CMCC", 7); China Mobile
|
||||
'''
|
||||
'''
|
||||
SW_TYPE.DEFAULT = new SW_TYPE("DEFAULT", 0);
|
||||
SW_TYPE.O2 = new SW_TYPE("O2", 1);
|
||||
SW_TYPE.H2 = new SW_TYPE("H2", 2);
|
||||
SW_TYPE.IN = new SW_TYPE("IN", 3);
|
||||
SW_TYPE.EU = new SW_TYPE("EU", 4);
|
||||
SW_TYPE.TMO = new SW_TYPE("TMO", 5);
|
||||
SW_TYPE.SPRINT = new SW_TYPE("SPRINT", 6);
|
||||
SW_TYPE.VERIZON = new SW_TYPE("VERIZON", 7);
|
||||
SW_TYPE.ATT = new SW_TYPE("ATT", 8);
|
||||
SW_TYPE v0 = new SW_TYPE("C532", 9);
|
||||
|
||||
'''
|
||||
'''
|
||||
CUSTOM_BACK_COVER_TYPE.NONE = new CUSTOM_BACK_COVER_TYPE("NONE", 0);
|
||||
CUSTOM_BACK_COVER_TYPE.LCH = new CUSTOM_BACK_COVER_TYPE("LCH", 1);
|
||||
CUSTOM_BACK_COVER_TYPE.MYH = new CUSTOM_BACK_COVER_TYPE("MYH", 2);
|
||||
CUSTOM_BACK_COVER_TYPE.YYB = new CUSTOM_BACK_COVER_TYPE("YYB", 3);
|
||||
CUSTOM_BACK_COVER_TYPE.HPH = new CUSTOM_BACK_COVER_TYPE("HPH", 4);
|
||||
CUSTOM_BACK_COVER_TYPE.DGZ = new CUSTOM_BACK_COVER_TYPE("DGZ", 5);
|
||||
CUSTOM_BACK_COVER_TYPE.OPGY = new CUSTOM_BACK_COVER_TYPE("OPGY", 6);
|
||||
CUSTOM_BACK_COVER_TYPE.OPBL = new CUSTOM_BACK_COVER_TYPE("OPBL", 7);
|
||||
CUSTOM_BACK_COVER_TYPE.OPGL = new CUSTOM_BACK_COVER_TYPE("OPGL", 8);
|
||||
CUSTOM_BACK_COVER_TYPE.OPRD = new CUSTOM_BACK_COVER_TYPE("OPRD", 9);
|
||||
CUSTOM_BACK_COVER_TYPE.OPHDBL = new CUSTOM_BACK_COVER_TYPE("OPHDBL", 10);
|
||||
CUSTOM_BACK_COVER_TYPE.OPHDSL = new CUSTOM_BACK_COVER_TYPE("OPHDSL", 11);
|
||||
CUSTOM_BACK_COVER_TYPE.OPHDMCL = new CUSTOM_BACK_COVER_TYPE("OPHDMCL", 12);
|
||||
CUSTOM_BACK_COVER_TYPE.OPHDAGBL = new CUSTOM_BACK_COVER_TYPE("OPHDAGBL", 13);
|
||||
CUSTOM_BACK_COVER_TYPE.OPINBLK = new CUSTOM_BACK_COVER_TYPE("OPINBLK", 14);
|
||||
CUSTOM_BACK_COVER_TYPE.OPINGRN = new CUSTOM_BACK_COVER_TYPE("OPINGRN", 15);
|
||||
CUSTOM_BACK_COVER_TYPE.OPINBLU = new CUSTOM_BACK_COVER_TYPE("OPINBLU", 16);
|
||||
CUSTOM_BACK_COVER_TYPE.OPINGRD = new CUSTOM_BACK_COVER_TYPE("OPINGRD", 17);
|
||||
CUSTOM_BACK_COVER_TYPE.OPINIB = new CUSTOM_BACK_COVER_TYPE("OPINIB", 18);
|
||||
CUSTOM_BACK_COVER_TYPE.OPAVICGRIR = new CUSTOM_BACK_COVER_TYPE("OPAVICGRIR", 19);
|
||||
CUSTOM_BACK_COVER_TYPE.OPAVICBLIC = new CUSTOM_BACK_COVER_TYPE("OPAVICBLIC", 20);
|
||||
CUSTOM_BACK_COVER_TYPE.OPAVICGRFR = new CUSTOM_BACK_COVER_TYPE("OPAVICGRFR", 21);
|
||||
CUSTOM_BACK_COVER_TYPE.OPKEBABGD = new CUSTOM_BACK_COVER_TYPE("OPKEBABGD", 22);
|
||||
CUSTOM_BACK_COVER_TYPE.OPKEBABBG = new CUSTOM_BACK_COVER_TYPE("OPKEBABBG", 23);
|
||||
CUSTOM_BACK_COVER_TYPE.OPKEBABSG = new CUSTOM_BACK_COVER_TYPE("OPKEBABSG", 24);
|
||||
CUSTOM_BACK_COVER_TYPE.OPN1MB = new CUSTOM_BACK_COVER_TYPE("OPN1MB", 25);
|
||||
CUSTOM_BACK_COVER_TYPE v0 = new CUSTOM_BACK_COVER_TYPE("OPN2GB", 26);
|
||||
|
||||
'''
|
||||
|
||||
|
||||
class paramtools():
|
||||
paramitems = {
|
||||
sid.PARAM_SID_PRODUCT.value[0]: {
|
||||
0x18: ["8c", "project_name"],
|
||||
0x20: ["I", "hw_version"],
|
||||
0x24: ["I", "rf_version"],
|
||||
0x28: ["16c", "rf_config_str"],
|
||||
0x38: ["I", "operator_num"],
|
||||
0x3C: ["10c", "operator_str"],
|
||||
0x4C: ["B", "Length PCBA_number"],
|
||||
0x4D: ["27c", "pcba_number"],
|
||||
0x68: ["I", "boot_aging_count"],
|
||||
0x6C: ["48c", "ota_info"],
|
||||
0x9C: ["80c", "firmware_info"],
|
||||
0xEC: ["32c", "build_info"],
|
||||
0x10C: ["I", "unknown_dword"],
|
||||
0x1A0: ["I", "OemCheckResetDevInfo"] # if 1, then reset dev info. if 2, then do below, wth is this ?
|
||||
},
|
||||
sid.PARAM_SID_CONFIG.value[0]: {
|
||||
0x18: ["B", "dump_enable"],
|
||||
},
|
||||
sid.PARAM_SID_CRASH_RECORD.value[0]: {
|
||||
0x18: ["I", "crash_record_count"],
|
||||
0x1c: ["20c", "Crash log 1"],
|
||||
0x30: ["20c", "Crash log 2"],
|
||||
0x44: ["20c", "Crash log 3"],
|
||||
0x58: ["20c", "Crash log 4"],
|
||||
0x6c: ["20c", "Crash log 5"],
|
||||
0x80: ["20c", "Crash log 6"],
|
||||
0x94: ["20c", "Crash log 7"],
|
||||
0xa8: ["20c", "Crash log 8"],
|
||||
0xbc: ["20c", "Crash log 9"],
|
||||
0xd0: ["20c", "Crash log 10"],
|
||||
0xe4: ["20c", "Crash log 11"],
|
||||
0xf8: ["20c", "Crash log 12"],
|
||||
0x10c: ["20c", "Crash log 13"],
|
||||
0x120: ["20c", "Crash log 14"],
|
||||
0x134: ["20c", "Crash log 15"],
|
||||
0x15c: ["I", "restart_08_count"],
|
||||
0x160: ["I", "restart_other_count"]
|
||||
},
|
||||
sid.PARAM_SID_SALEINFO.value[0]: { # 0xA, Param_saleinfo, PARAM_SID_SALEINFO
|
||||
0x18: ["I", "is_rooted"],
|
||||
0x1c: ["I", "root_time"],
|
||||
0x20: ["16c", "flash_0"],
|
||||
0x30: ["16c", "flash_1"],
|
||||
0x40: ["16c", "flash_2"],
|
||||
0x50: ["16c", "erase_0"],
|
||||
0x60: ["16c", "erase_1"],
|
||||
0x70: ["16c", "erase_2"],
|
||||
0x80: ["I", "is_angela"],
|
||||
# adb shell am start -n com.android.engineeringmode/.qualcomm.DiagEnabled --es "code" "angela"
|
||||
# adb shell am start -n com.oneplus.factorymode/.qualcomm.DiagEnabled --es "code" "angela"
|
||||
# disable: "setprop persist.sys.adb.engineermode 0" and "setprop persist.sys.adbroot 0" or call code *#8011#
|
||||
0x88: ["I", "Unknown flag"],
|
||||
0x8c: ["I", "Unknown value"],
|
||||
0x90: ["I", "Unknown flag"],
|
||||
},
|
||||
sid.PARAM_SID_MISC.value[0]: { # 0xB
|
||||
0x20: ["I", "Misc flag 1"],
|
||||
0x24: ["44c", "Misc log a_1"],
|
||||
0x50: ["I", "Misc flag a_2"],
|
||||
0x54: ["44c", "Misc log a_2"],
|
||||
0x80: ["I", "Misc flag a_3"],
|
||||
0x84: ["44c", "Misc log a_3"],
|
||||
0xb0: ["I", "Misc flag a_4"],
|
||||
0xb4: ["44c", "Misc log a_4"],
|
||||
0xe4: ["I", "Misc flag b_1"],
|
||||
0xe8: ["44c", "Misc log b_1"],
|
||||
0x114: ["I", "Misc flag b_2"],
|
||||
0x118: ["44c", "Misc log b_2"],
|
||||
0x144: ["I", "Misc flag b_3"],
|
||||
0x148: ["44c", "Misc log b_3"],
|
||||
0x174: ["I", "Misc flag b_4"],
|
||||
0x178: ["44c", "Misc log b_4"],
|
||||
0x1a8: ["I", "Misc flag c_1"],
|
||||
0x1ac: ["44c", "Misc log c_1"],
|
||||
0x1d8: ["I", "Misc flag c_2"],
|
||||
0x1dc: ["44c", "Misc log c_2"],
|
||||
0x208: ["I", "Misc flag c_3"],
|
||||
0x20c: ["44c", "Misc log c_3"],
|
||||
0x238: ["I", "Misc flag c_4"],
|
||||
0x23c: ["44c", "Misc log c_4"],
|
||||
},
|
||||
sid.PARAM_SID_DOWNLOAD.value[0]: { # 0xC
|
||||
0x18: ["24c", "Unknown date"],
|
||||
0x30: ["B", "SMT_Download_Status"],
|
||||
0x32: ["B", "Unknown flag"],
|
||||
0x33: ["B", "Unknown flag"],
|
||||
0x38: ["32c", "Unknown string_1"],
|
||||
0xd8: ["24c", "Unknown date_1"],
|
||||
0xF0: ["B", "Upgrade_Download_Status_1"],
|
||||
0xF2: ["B", "Unknown flag_1"],
|
||||
|
||||
0xF8: ["32c", "Unknown string_2"],
|
||||
0x118: ["24c", "Unknown date_2"],
|
||||
0x130: ["B", "Upgrade_Download_Status_2"],
|
||||
0x132: ["B", "Unknown flag_2"],
|
||||
|
||||
0x138: ["32c", "Unknown string_3"],
|
||||
0x158: ["24c", "Unknown date_3"],
|
||||
0x170: ["B", "Upgrade_Download_Status_3"],
|
||||
0x172: ["B", "Unknown flag_3"],
|
||||
|
||||
0x178: ["32c", "Unknown string_4"],
|
||||
0x188: ["24c", "Unknown date_4"],
|
||||
|
||||
0x198: ["I", "boot_stage"],
|
||||
0x19C: ["I", "data_stage"],
|
||||
0x1A0: ["B", "reset_devinfo"], # OemCheckResetRevInfo
|
||||
0x1A4: ["B", "intranet_3t"],
|
||||
0x1A8: ["B", "bootmode_3t"]
|
||||
},
|
||||
|
||||
sid.PARAM_SID_PHONE_HISTORY.value[0]: { # 0xD
|
||||
0x24: ["I", "Update_Count"],
|
||||
0x28: ["I", "Unlock_Count"],
|
||||
0x2c: ["I", "Unknown value"],
|
||||
0x30: ["I", "param_poweroff_count"],
|
||||
0x34: ["I", "abl_tamper"],
|
||||
},
|
||||
|
||||
sid.PARAM_SID_DL_USERINFO.value[0]: { # 0xE
|
||||
0x20: ["32c", "Computername_1"],
|
||||
0x40: ["32c", "Username_1"],
|
||||
0x60: ["I", "Flag_1"],
|
||||
0x68: ["20c", "IP_1"],
|
||||
0x7C: ["I", "Chksum_1_0"],
|
||||
0xA0: ["32c", "Computername_2"],
|
||||
0xC0: ["32c", "Username_2"],
|
||||
0xE0: ["I", "Flag_2"],
|
||||
0xE8: ["20c", "IP_2"],
|
||||
0xFC: ["I", "Chksum_2"],
|
||||
0x120: ["32c", "Computername_2"],
|
||||
0x140: ["32c", "Username_2"],
|
||||
0x160: ["I", "Flag_2"],
|
||||
0x168: ["20c", "IP_2"],
|
||||
0x17C: ["I", "Chksum_2"],
|
||||
0x1A0: ["32c", "Computername_3"],
|
||||
0x1C0: ["32c", "Username_3"],
|
||||
0x1E0: ["I", "Flag_3"],
|
||||
0x1E8: ["20c", "IP_3"],
|
||||
0x1FC: ["I", "Chksum_3"],
|
||||
},
|
||||
|
||||
0xB0: {
|
||||
0x2b4: ["128B", "Unknown"]
|
||||
},
|
||||
|
||||
sid.PARAM_SID_ENC_SECRECY.value[0]: { # 0x12C
|
||||
0x80: ["I", "intranet"], # Allows factory commands via fastboot ops, *#808# engineermode
|
||||
# dumpsys secrecy dump (persist)
|
||||
# fastboot ops 4F50040TR18FTR7FSTD5F01
|
||||
# fastboot ops help
|
||||
0x84: ["I", "boottype"], # 0xA9E:"sdebug"; 0xB7:"debug";0xA0:"auto";0x0:"normal"
|
||||
0x88: ["I", "ONLINE_CFG_TEST_ENV"],
|
||||
0x8C: ["I", "TargetSWID"],
|
||||
0x90: ["I", "AgingFlag"]
|
||||
},
|
||||
|
||||
sid.PARAM_SID_ENC_CARRIER.value[0]: { # 0x130
|
||||
0xA0: ["I", "CustFlag"],
|
||||
0xA4: ["I", "CustFlagMigrationPlaintext"],
|
||||
0xA8: ["I", "carrier_id"],
|
||||
0xAC: ["I", "carrier_init_flag"]
|
||||
},
|
||||
sid.PARAM_SID_ENC_MOBID.value[0]: {
|
||||
0x80: ["16c", "mobid/imei/meid1"],
|
||||
0x90: ["I", "mobid/imei_flag"],
|
||||
0x94: ["I", "Recondition flag (RCF)"],
|
||||
0x98: ["19c", "Unknown date1"],
|
||||
0xB0: ["19c", "Unknown date2"],
|
||||
0xC8: ["19c", "Unknown date3"],
|
||||
0xE0: ["8c", "Unknown_value_000000"],
|
||||
0xE8: ["16c", "mobid/imei/meid2"],
|
||||
0xF0: ["I", "mobid/meid flag"],
|
||||
0xF8: ["I", "Unknown flag"]
|
||||
},
|
||||
sid.PARAM_SID_ENC_CVE.value[0]: {
|
||||
0x80: ["16c", "CVE_SystemBlob_A"],
|
||||
0x90: ["16c", "CVE_VendorBlob_A"],
|
||||
0xA0: ["16c", "CVE_SystemBlob_B"],
|
||||
0xB0: ["16c", "CVE_VendorBlob_B"],
|
||||
0xC0: ["16c", "CVE_Current_BootImg_A"],
|
||||
0xD0: ["16c", "CVE_Current_BootImg_B"],
|
||||
0xE0: ["I", "PWD Index 1"],
|
||||
0xE4: ["40c", "PWD Hash 1"],
|
||||
0x114: ["40c", "PWD Hash 2"],
|
||||
0x144: ["40c", "PWD Hash 3"],
|
||||
0x174: ["40c", "PWD Hash 4"],
|
||||
0x1a4: ["I", "PWD Index 2"],
|
||||
0x1a8: ["40c", "PWD Hash 1"],
|
||||
0x1d8: ["40c", "PWD Hash 2"],
|
||||
0x208: ["40c", "PWD Hash 3"],
|
||||
0x238: ["40c", "PWD Hash 4"],
|
||||
0x268: ["I", "PWD Index 3"],
|
||||
0x26c: ["40c", "PWD Hash 1"],
|
||||
0x29c: ["40c", "PWD Hash 2"],
|
||||
0x2cc: ["40c", "PWD Hash 3"],
|
||||
0x2fc: ["40c", "PWD Hash 4"],
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self, mode, serial):
|
||||
self.aes_iv = unhexlify("562E17996D093D28DDB3BA695A2E6F58")
|
||||
self.aes_key = unhexlify("3030304F6E65506C7573383138303030")
|
||||
if mode==1:
|
||||
derivedkey=bytes.fromhex("a9264fbf8a"+("%08x"%serial)+"6b4487ea")[:0x1A]
|
||||
derivedkey=hashlib.sha256(derivedkey).digest()[:16]
|
||||
self.aes_key = derivedkey
|
||||
|
||||
def getparam(self, offset, sidindex):
|
||||
if sidindex & 0x1FF in self.paramitems:
|
||||
siditems = self.paramitems[sidindex & 0x1FF]
|
||||
if offset in siditems:
|
||||
return siditems[offset]
|
||||
return None
|
||||
|
||||
def decryptsid(self, data):
|
||||
aes = cryptutils().aes()
|
||||
hash = cryptutils().hash()
|
||||
header = data[:4 + 1 + 1]
|
||||
magic, hv, cv = unpack("<IBB", header)
|
||||
updatecounter = data[0x10]
|
||||
if magic != 0xA0AD646A:
|
||||
return None, None, None, None
|
||||
|
||||
enchash = data[0x80:0x90]
|
||||
encdata = data[0x400:0x400 + 0xC00]
|
||||
genenchash = hash.md5(encdata)
|
||||
if genenchash != enchash:
|
||||
print(
|
||||
f"Generated hash doesn't match encrypted hash:\n{hexlify(genenchash).decode('utf-8')}\n{hexlify(enchash).decode('utf-8')}")
|
||||
return None, None, None, None
|
||||
decdata = aes.aes_cbc(self.aes_key, self.aes_iv, encdata)
|
||||
dechash = decdata[:16]
|
||||
itemdata = decdata[-0xB80:]
|
||||
gendechash = hash.md5(itemdata)
|
||||
if gendechash != dechash:
|
||||
print(
|
||||
f"Generated hash doesn't match decrypted hash:\n{hexlify(gendechash).decode('utf-8')}\n{hexlify(dechash).decode('utf-8')}")
|
||||
return None, None, None, None
|
||||
return itemdata, hv, cv, updatecounter
|
||||
|
||||
def encryptsid(self, itemdata, hv, cv, updatecounter):
|
||||
aes = cryptutils().aes()
|
||||
hash = cryptutils().hash()
|
||||
magic = 0xA0AD646A
|
||||
siddata = bytearray(b"\x00" * 0x1000)
|
||||
siddata[:4 + 1 + 1] = pack("<IBB", magic, hv, cv)
|
||||
siddata[0x10] = updatecounter + 1
|
||||
|
||||
header = bytearray(b"\00" * 0x80)
|
||||
gendechash = hash.md5(itemdata)
|
||||
header[0:16] = gendechash
|
||||
decdata = header + itemdata
|
||||
encdata = aes.aes_cbc(self.aes_key, self.aes_iv, decdata, False)
|
||||
genenchash = hash.md5(encdata)
|
||||
|
||||
siddata[0x80:0x90] = genenchash
|
||||
siddata[0x400:0x400 + 0xC00] = encdata
|
||||
return siddata
|
||||
|
||||
def parse_encrypted(self, rdata, sid):
|
||||
data = rdata[(sid * 0x400):(sid * 0x400) + 0x1000]
|
||||
itemdata, hv, cv, updatecounter = self.decryptsid(data)
|
||||
if itemdata != None:
|
||||
itemdata = bytearray(itemdata)
|
||||
print(
|
||||
f"Offset {hex(sid * 0x400)}: hv {hex(hv)}, cv {hex(cv)}, increase_enc_update_counter {hex(updatecounter)}.")
|
||||
i = 0
|
||||
while i < len(itemdata):
|
||||
offset = i + 0x80
|
||||
param = self.getparam(offset, sid)
|
||||
if param is None:
|
||||
if i + 4 < len(itemdata):
|
||||
value = unpack("<I", itemdata[i:i + 4])[0]
|
||||
if value != 0x0:
|
||||
print(f"Encrypted SID_Index {hex(sid)}, Offset {hex(offset)}: {hex(value)}")
|
||||
|
||||
i += 4
|
||||
else:
|
||||
length = self.parse_data(i, itemdata, offset, param, sid, True)
|
||||
i += length
|
||||
if length % 4:
|
||||
i += 4 - (length % 4)
|
||||
print()
|
||||
|
||||
def parse_encrypted_fields(self, rdata):
|
||||
for sid in range(0x12c, 0x139):
|
||||
self.parse_encrypted(rdata, sid)
|
||||
# Backup
|
||||
"""
|
||||
for sid in range(0x32c, 0x339):
|
||||
self.parse_encrypted(rdata, sid)
|
||||
"""
|
||||
|
||||
def parse_decrypted_fields(self, rdata):
|
||||
for pos in range(0x0, 0x40000, 0x400):
|
||||
if pos >= len(rdata):
|
||||
break
|
||||
data = rdata[pos:pos + 0x18]
|
||||
fm = data[0:0x10].replace(b'\x00', b'').decode('utf-8')
|
||||
if fm != "":
|
||||
print()
|
||||
print(f"Offset {hex(pos)}: Field {fm}")
|
||||
itemlength = unpack("<I", data[0x14:0x18])[0]
|
||||
if itemlength == 0x0:
|
||||
itemlength = 0x400
|
||||
itemdata = rdata[pos + 0x18:pos + 0x18 + itemlength]
|
||||
i = 0
|
||||
while (i < len(itemdata) - 0x22):
|
||||
sidindex = (pos // 0x400) & 0x1FF
|
||||
offset = i + 0x18
|
||||
# if sidindex==0x334 and offset==0x80:
|
||||
# print(hexlify(itemdata).decode('utf-8'))
|
||||
param = self.getparam(offset, sidindex)
|
||||
if param is None:
|
||||
if itemdata[i] != 0:
|
||||
if i + 4 < len(itemdata):
|
||||
value = unpack("<I", itemdata[i:i + 4])[0]
|
||||
if value != 0x0:
|
||||
print(f"SID_Index {hex(sidindex)}, Offset {hex(offset)}: {hex(value)}")
|
||||
i += 4
|
||||
else:
|
||||
i += 1
|
||||
else:
|
||||
length = self.parse_data(i, itemdata, offset, param, sidindex)
|
||||
i += length
|
||||
if length > 4:
|
||||
if (length % 4):
|
||||
i += 4 - (length % 4)
|
||||
|
||||
def parse_data(self, i, itemdata, offset, param, sidindex, encrypted=False):
|
||||
stype = param[0]
|
||||
name = param[1]
|
||||
length = calcsize(stype)
|
||||
item = itemdata[i:i + length]
|
||||
content = unpack(stype, item)
|
||||
try:
|
||||
content = "\"" + b"".join(content).replace(b'\x00', b'').decode('utf-8') + "\""
|
||||
except:
|
||||
if len(content) == 1:
|
||||
content = hex(content[0])
|
||||
else:
|
||||
tm = ""
|
||||
for item in content:
|
||||
if item == 0:
|
||||
break
|
||||
tm += hex(item)
|
||||
content = tm
|
||||
offsetstr = hex(offset)
|
||||
while len(offsetstr) < 5:
|
||||
offsetstr = offsetstr[:2] + "0" + offsetstr[2:]
|
||||
while len(name) < 30:
|
||||
name = name + " "
|
||||
if "PWD Hash" in name:
|
||||
items = content.split(" ")
|
||||
pwdhash = items[0][1:9]+"00000000000000000000000000000000000000000000000000000000"
|
||||
valid = "True" if items[1] != "-1" else "False"
|
||||
flag = items[2]
|
||||
date = items[3] + " "+ items[4][:-1]
|
||||
content = f"{date} ({valid},{flag}): {pwdhash}"
|
||||
ff = f"SID_Index {hex(sidindex)}, Offset {offsetstr}: {name}: {content}"
|
||||
if encrypted:
|
||||
ff = "Encrypted " + ff
|
||||
else:
|
||||
ff = f"SID_Index {hex(sidindex)}, Offset {offsetstr}: {name}: {content}"
|
||||
if encrypted:
|
||||
ff = "Encrypted " + ff
|
||||
print(ff)
|
||||
return length
|
||||
|
||||
def setparamvalue(self, data, sid, offset, value):
|
||||
if sid > 0x100:
|
||||
rdata = data[sid * 0x400:(sid * 0x400) + 0x1000]
|
||||
itemdata, hv, cv, updatecounter = self.decryptsid(rdata)
|
||||
if itemdata is not None:
|
||||
itemdata = bytearray(itemdata)
|
||||
if isinstance(value, int):
|
||||
itemdata[offset - 0x80:(offset + 4) - 0x80] = pack("<I", value)
|
||||
elif isinstance(value, bytearray):
|
||||
itemdata[offset - 0x80:(offset + len(value)) - 0x80] = value
|
||||
# itemdata[0x84-0x80:(0x84+4)-0x80]=pack("<I",0xB7) #devkmsg_enable
|
||||
mdata = self.encryptsid(itemdata, hv, cv, updatecounter)
|
||||
data = bytearray(data)
|
||||
data[sid * 0x400:(sid * 0x400) + 0x1000] = mdata
|
||||
# data[(sid+0x200) * 0x400:((sid+0x200) * 0x400) + 0x1000] = mdata
|
||||
else:
|
||||
rdata = data[sid * 0x400:(sid * 0x400) + 0x1000]
|
||||
data = bytearray(data)
|
||||
rdata = bytearray(rdata)
|
||||
if isinstance(value, int):
|
||||
rdata[offset:offset + 4] = pack("<I", value)
|
||||
elif isinstance(value, bytearray):
|
||||
rdata[offset:(offset + len(value))] = value
|
||||
data[sid * 0x400:(sid * 0x400) + 0x1000] = rdata
|
||||
return data
|
||||
|
||||
def gencode(self, inparray):
|
||||
res = []
|
||||
for input in inparray:
|
||||
m = hashlib.sha1()
|
||||
m.update(bytes("ONEPLUS_" + input, 'utf-8'))
|
||||
hash = m.hexdigest().lower()
|
||||
crcdata = hex(zlib.crc32(bytes(hash, 'utf-8')))[2:]
|
||||
while len(crcdata) < 8:
|
||||
crcdata = '0' + crcdata
|
||||
res.append(crcdata)
|
||||
return res
|
||||
|
||||
def enable_ops(self, data, enable):
|
||||
sid = 0x12C
|
||||
offset = 0x80 # intranet
|
||||
if enable:
|
||||
value = 0x3
|
||||
else:
|
||||
value = 0x0
|
||||
return self.setparamvalue(data, sid, offset, value)
|
||||
|
||||
|
||||
'''
|
||||
ONEPLUS_358240051111110 => sha1 = 99e489e03107817f14ac06a1bb52de3455423542 => CRC32 ->
|
||||
ecec6492
|
||||
ONEPLUS_YOU_CAN_PASS_NOW => sha1 = 9db4b7338e254669b8c703e77cbc9f119ade7fa6 => CRC32 -> 79707450 (wenn < 8, dann fill mit 0)
|
||||
'''
|
||||
'''
|
||||
com.android.engineeringmode.encrypt
|
||||
|
||||
3439 = oem.cust.flag 1 = French custom edition
|
||||
9339 = oem.cust.flag 2 = Indian edition
|
||||
3392 = oem.cust.flag 0 = Normal edition
|
||||
7668 = com.android.engineeringmode.manualtest.CheckRootStatusActivity
|
||||
5646 = com.android.engineeringmode.manualtest.DecryptActivity
|
||||
838 = com.android.engineeringmode.manualtest.CheckRootStatusActivity
|
||||
|
||||
com.oneplus.factorymode.CommonCommands
|
||||
com.oem.engineermode.DoShellCommond
|
||||
if(!arg18.getAction().equals(v1.mAction) && !arg18.getAction().equals(v1.na)) {
|
||||
if((arg18.getAction().equals(v1.doshellcommond)) && ("get_config_params".equals(v0.getStringExtra("shell_cmd")))) {
|
||||
adb shell am start -n com.oem.engineermode.DoShellCommond --es "shell_cmd" "get_config_params"
|
||||
|
||||
action android:name
|
||||
adb shell am start -n com.android.engineeringmode/.qualcomm.DiagEnabled --es "code" "Angela"
|
||||
79a6a933dfc9b1975e444d4e8481c64c771d8ab40b7ac72f8bc1a1bca1718bef
|
||||
|
||||
android.provider.Telephony.SECRET_CODE
|
||||
*#66# com.android.engineeringmode.IMeiAndPcbCheck
|
||||
*#99# com.android.engineeringmode.KeepSrceenOn
|
||||
*#008# com.android.engineeringmode.LanguageSwitchToChineseActivity
|
||||
*#268# com.android.engineeringmode.qualcomm.QualCommActivity
|
||||
*#391# com.android.engineeringmode.SwitchSoftwareVersion
|
||||
*#789# com.android.engineeringmode.qualcomm.ClearTelcelnetlock
|
||||
*#800# com.android.engineeringmode.qualcomm.LogSwitch
|
||||
*#800# com.oem.oemlogkit.OEMLogKitMainActivity
|
||||
*#801# com.android.engineeringmode.qualcomm.DiagEnabled
|
||||
*#802# com.android.engineeringmode.gps.GpsActivity
|
||||
*#803# com.android.engineeringmode.wifitest.WifiSettings
|
||||
*#804# com.android.engineeringmode.NetworkSearch
|
||||
*#805# com.android.engineeringmode.bluetoothtest.BluetoothTest
|
||||
*#806# com.android.engineeringmode.autoaging.AutoAgingMainListActivity
|
||||
*#807# com.android.engineeringmode.autotest.AutoTest
|
||||
*#808# com.android.engineeringmode.EngineerModeMain
|
||||
*#808# com.android.engineeringmode.manualtest.ManualTest
|
||||
*#809# com.android.engineeringmode.echotest.EchoTest
|
||||
*#810# com.android.engineeringmode.SwitchSetupWizardActivity
|
||||
*#814# com.android.engineeringmode.TDSNetworkSearch
|
||||
*#818# com.android.engineeringmode.NetworkSearch_New
|
||||
*#820# com.android.engineeringmode.DeleteNoNeedFilesActivity
|
||||
*#824# com.android.engineeringmode.WCDMANetworkSearch
|
||||
*#834# com.android.engineeringmode.LTENetworkSearch
|
||||
*#838# com.android.engineeringmode.NetworkSearch_New
|
||||
*#845# com.android.engineeringmode.wifitest.WifiApSettings
|
||||
*#888# com.android.engineeringmode.PcbShow
|
||||
*#899# com.oneplus.factorymode.aftersale.ChooseBackCoverColor
|
||||
*#900# com.android.engineeringmode.BackCameraAdjusting
|
||||
*#911# com.android.engineeringmode.PowerOff (Warning: Does factory reset)
|
||||
*#912# com.android.engineeringmode.qualcomm.RecoverTelcelnetlock
|
||||
*#912# com.android.engineeringmode.RebootManager
|
||||
*#928# com.android.engineeringmode.wifitest.WifiFTMActivity
|
||||
*#1234# com.android.engineeringmode.SHOW_ONEPLUS_VERSION
|
||||
*#4321# com.android.engineeringmode.LanguageSwitchToZimbabweService
|
||||
*#6776# com.android.engineeringmode.CheckSoftwareInfo
|
||||
*#7327# com.oem.rftoolkit.RfToolkitCustomerService
|
||||
*#7328# com.oem.rftoolkit.RfToolkitAgingTest
|
||||
*#7332# com.oem.rftoolkit.RfToolkitFactory
|
||||
*#8011# com.android.engineeringmode.NoUI
|
||||
*#8017# com.android.engineeringmode.wifitest.WifiAdbHelper
|
||||
*#8019# com.android.engineeringmode.wifitest.WifiSocketHelper
|
||||
*#8020# com.android.engineeringmode.wifitest.WifiAdbHelper
|
||||
*##*8110# com.android.engineeringmode.qualcomm.OtaSwitch
|
||||
*#8668# com.oneplus.activation.action.STOP_ACTIVATION
|
||||
*#8669# com.oneplus.activation.action.START_ACTIVATION
|
||||
*#8778# com.android.engineeringmode.manualtest.MasterClear
|
||||
*#8888# com.android.engineeringmode.manualtest.MasterClear
|
||||
*#9886# com.oneplus.screensaver.off
|
||||
*#9889# com.oneplus.screensaver.on
|
||||
*#10000# com.android.engineeringmode.MarkResultShow
|
||||
*#12345# com.android.activation.action.STOP_SERVICE
|
||||
*#3954391# Switch activated
|
||||
*##*37847# com.android.engineeringmode.manualtest.DeviceListActivity
|
||||
*#2288379# com.android.engineeringmode.BatteryExtraInfo
|
||||
*#36446337# com.android.engineeringmode.EngineeringMode
|
||||
*#6776001# set_language en_US
|
||||
*#6776007# set_language ru_RU
|
||||
*#67760052# set_language es_MX
|
||||
*#67760055# set_language pt_BR
|
||||
*#67760066# set_language th_TH
|
||||
*#67760062# set_language in_IN
|
||||
*#67760084# set_language vi_VI
|
||||
*#67760086# set_language zh_CN
|
||||
*#67760886# set_language zh_TW
|
||||
*#67760044# com.android.engineeringmode.LanguageSwitchToEnglishActivity
|
||||
*#67766776# com.android.engineeringmode.oneplusConnectionADBActivity
|
||||
*#677667764482# com.android.engineeringmode.UserAgentSwitchService
|
||||
*#*#5646#*#* com.android.engineeringmode.manualtest.DecryptActivity
|
||||
*#*#7668#*#* com.android.engineeringmode.manualtest.CheckRootStatusActivity
|
||||
*#3439# = oem.cust.flag=1
|
||||
*#9339# = oem.cust.flag=2
|
||||
*#3392# = oem.cust.flag=0
|
||||
|
||||
fastboot ops 4F50040TR18FTR7FSTD5F01
|
||||
fastboot ops help
|
||||
|
||||
fastboot ops 4F50040TR18FTR7FSTD5F01
|
||||
fastboot ops devkmsg on
|
||||
fastboot ops boottype debug
|
||||
|
||||
|
||||
(bootloader) ops android_log_all
|
||||
(bootloader) ops kernel_log_all
|
||||
(bootloader) ops devkmsg
|
||||
(bootloader) ops boottype [normal, debug, sdebug]
|
||||
(bootloader) ops set_cust
|
||||
(bootloader) ops force_adb
|
||||
(bootloader) ops qeaging_data_img
|
||||
(bootloader) ops unmount tempfs
|
||||
(bootloader) ops mount tempfs
|
||||
(bootloader) ops enable_dm_verity
|
||||
(bootloader) ops disable_dm_verity
|
||||
(bootloader) ops boot_mode [rf,ftm,wlan,normal]
|
||||
(bootloader) ops selinux
|
||||
(bootloader) ops dump
|
||||
(bootloader) ops help
|
||||
(bootloader) ops datafs
|
||||
(bootloader) ops unforce_training
|
||||
(bootloader) ops force_training
|
||||
(bootloader) ops reboot-bootloader
|
||||
(bootloader) ops reboot-shutdown
|
||||
(bootloader) ops kmemleak undetect
|
||||
(bootloader) ops kmemleak detect
|
||||
(bootloader) ops unconsole
|
||||
(bootloader) ops console
|
||||
(bootloader) oem get_unlock_code
|
||||
(bootloader) oem lock
|
||||
(bootloader) oem unlock
|
||||
(bootloader) download:
|
||||
(bootloader) getvar:
|
||||
(bootloader) reboot-bootloader
|
||||
(bootloader) reboot
|
||||
(bootloader) continue
|
||||
(bootloader) oem device-info
|
||||
(bootloader) oem select-display-panel
|
||||
(bootloader) oem off-mode-charge
|
||||
(bootloader) oem disable-charger-screen
|
||||
(bootloader) oem enable-charger-screen
|
||||
(bootloader) boot
|
||||
(bootloader) flashing lock
|
||||
(bootloader) flashing unlock
|
||||
(bootloader) flashing get_unlock_ability
|
||||
(bootloader) set_active
|
||||
(bootloader) erase:
|
||||
(bootloader) flash:
|
||||
(bootloader) Varlist
|
||||
|
||||
(bootloader) hw-revision:20001
|
||||
(bootloader) unlocked:no
|
||||
(bootloader) off-mode-charge:1
|
||||
(bootloader) charger-screen-enabled:1
|
||||
(bootloader) battery-soc-ok:yes
|
||||
(bootloader) battery-voltage:4360
|
||||
(bootloader) version-baseband:
|
||||
(bootloader) version-bootloader:
|
||||
(bootloader) erase-block-size: 0x1000
|
||||
(bootloader) logical-block-size: 0x1000
|
||||
(bootloader) variant:SDM UFS
|
||||
(bootloader) partition-type:fsc:raw
|
||||
(bootloader) partition-size:fsc: 0x20000
|
||||
(bootloader) partition-type:fsg:raw
|
||||
(bootloader) partition-size:fsg: 0x200000
|
||||
(bootloader) partition-type:modemst2:raw
|
||||
(bootloader) partition-size:modemst2: 0x200000
|
||||
(bootloader) partition-type:modemst1:raw
|
||||
(bootloader) partition-size:modemst1: 0x200000
|
||||
(bootloader) partition-type:ALIGN_TO_128K_2:raw
|
||||
(bootloader) partition-size:ALIGN_TO_128K_2: 0x1A000
|
||||
(bootloader) partition-type:ImageFv:raw
|
||||
(bootloader) partition-size:ImageFv: 0x200000
|
||||
(bootloader) partition-type:logdump:raw
|
||||
(bootloader) partition-size:logdump: 0x4000000
|
||||
(bootloader) partition-type:sti:raw
|
||||
(bootloader) partition-size:sti: 0x200000
|
||||
(bootloader) partition-type:logfs:raw
|
||||
(bootloader) partition-size:logfs: 0x800000
|
||||
(bootloader) partition-type:toolsfv:raw
|
||||
(bootloader) partition-size:toolsfv: 0x100000
|
||||
(bootloader) partition-type:limits:raw
|
||||
(bootloader) partition-size:limits: 0x1000
|
||||
(bootloader) partition-type:splash:raw
|
||||
(bootloader) partition-size:splash: 0x20A4000
|
||||
(bootloader) partition-type:spunvm:raw
|
||||
(bootloader) partition-size:spunvm: 0x800000
|
||||
(bootloader) partition-type:msadp:raw
|
||||
(bootloader) partition-size:msadp: 0x40000
|
||||
(bootloader) partition-type:apdp:raw
|
||||
(bootloader) partition-size:apdp: 0x40000
|
||||
(bootloader) partition-type:dip:raw
|
||||
(bootloader) partition-size:dip: 0x100000
|
||||
(bootloader) partition-type:devinfo:raw
|
||||
(bootloader) partition-size:devinfo: 0x1000
|
||||
(bootloader) partition-type:sec:raw
|
||||
(bootloader) partition-size:sec: 0x4000
|
||||
(bootloader) partition-type:op1:raw
|
||||
(bootloader) partition-size:op1: 0x6400000
|
||||
(bootloader) partition-type:aging:raw
|
||||
(bootloader) partition-size:aging: 0x4000000
|
||||
(bootloader) partition-type:minidump:raw
|
||||
(bootloader) partition-size:minidump: 0x6400000
|
||||
(bootloader) partition-type:fw_ufs8_b:raw
|
||||
(bootloader) partition-size:fw_ufs8_b: 0x200000
|
||||
(bootloader) partition-type:fw_ufs7_b:raw
|
||||
(bootloader) partition-size:fw_ufs7_b: 0x200000
|
||||
(bootloader) partition-type:fw_ufs6_b:raw
|
||||
(bootloader) partition-size:fw_ufs6_b: 0x200000
|
||||
(bootloader) partition-type:fw_ufs5_b:raw
|
||||
(bootloader) partition-size:fw_ufs5_b: 0x200000
|
||||
(bootloader) partition-type:fw_ufs4_b:raw
|
||||
(bootloader) partition-size:fw_ufs4_b: 0x200000
|
||||
(bootloader) partition-type:fw_ufs3_b:raw
|
||||
(bootloader) partition-size:fw_ufs3_b: 0x200000
|
||||
(bootloader) partition-type:fw_4u1ea_b:raw
|
||||
(bootloader) partition-size:fw_4u1ea_b: 0x200000
|
||||
(bootloader) partition-type:fw_4j1ed_b:raw
|
||||
(bootloader) partition-size:fw_4j1ed_b: 0x200000
|
||||
(bootloader) partition-type:LOGO_b:raw
|
||||
(bootloader) partition-size:LOGO_b: 0x1000000
|
||||
(bootloader) partition-type:storsec_b:raw
|
||||
(bootloader) partition-size:storsec_b: 0x20000
|
||||
(bootloader) partition-type:dtbo_b:raw
|
||||
(bootloader) partition-size:dtbo_b: 0x800000
|
||||
(bootloader) partition-type:vbmeta_b:raw
|
||||
(bootloader) partition-size:vbmeta_b: 0x10000
|
||||
(bootloader) partition-type:vendor_b:raw
|
||||
(bootloader) partition-size:vendor_b: 0x40000000
|
||||
(bootloader) partition-type:qupfw_b:raw
|
||||
(bootloader) partition-size:qupfw_b: 0x10000
|
||||
(bootloader) partition-type:devcfg_b:raw
|
||||
(bootloader) partition-size:devcfg_b: 0x20000
|
||||
(bootloader) partition-type:cmnlib64_b:raw
|
||||
(bootloader) partition-size:cmnlib64_b: 0x80000
|
||||
(bootloader) partition-type:cmnlib_b:raw
|
||||
(bootloader) partition-size:cmnlib_b: 0x80000
|
||||
(bootloader) partition-type:boot_b:raw
|
||||
(bootloader) partition-size:boot_b: 0x4000000
|
||||
(bootloader) partition-type:keymaster_b:raw
|
||||
(bootloader) partition-size:keymaster_b: 0x80000
|
||||
(bootloader) partition-type:dsp_b:raw
|
||||
(bootloader) partition-size:dsp_b: 0x2000000
|
||||
(bootloader) partition-type:abl_b:raw
|
||||
(bootloader) partition-size:abl_b: 0x800000
|
||||
(bootloader) partition-type:mdtp_b:raw
|
||||
(bootloader) partition-size:mdtp_b: 0x2000000
|
||||
(bootloader) partition-type:mdtpsecapp_b:raw
|
||||
(bootloader) partition-size:mdtpsecapp_b: 0x400000
|
||||
(bootloader) partition-type:bluetooth_b:raw
|
||||
(bootloader) partition-size:bluetooth_b: 0x100000
|
||||
(bootloader) partition-type:modem_b:raw
|
||||
(bootloader) partition-size:modem_b: 0x7800000
|
||||
(bootloader) partition-type:hyp_b:raw
|
||||
(bootloader) partition-size:hyp_b: 0x80000
|
||||
(bootloader) partition-type:tz_b:raw
|
||||
(bootloader) partition-size:tz_b: 0x200000
|
||||
(bootloader) partition-type:aop_b:raw
|
||||
(bootloader) partition-size:aop_b: 0x80000
|
||||
(bootloader) partition-type:fw_ufs8_a:raw
|
||||
(bootloader) partition-size:fw_ufs8_a: 0x200000
|
||||
(bootloader) partition-type:fw_ufs7_a:raw
|
||||
(bootloader) partition-size:fw_ufs7_a: 0x200000
|
||||
(bootloader) partition-type:fw_ufs6_a:raw
|
||||
(bootloader) partition-size:fw_ufs6_a: 0x200000
|
||||
(bootloader) partition-type:fw_ufs5_a:raw
|
||||
(bootloader) partition-size:fw_ufs5_a: 0x200000
|
||||
(bootloader) partition-type:fw_ufs4_a:raw
|
||||
(bootloader) partition-size:fw_ufs4_a: 0x200000
|
||||
(bootloader) partition-type:fw_ufs3_a:raw
|
||||
(bootloader) partition-size:fw_ufs3_a: 0x200000
|
||||
(bootloader) partition-type:fw_4u1ea_a:raw
|
||||
(bootloader) partition-size:fw_4u1ea_a: 0x200000
|
||||
(bootloader) partition-type:fw_4j1ed_a:raw
|
||||
(bootloader) partition-size:fw_4j1ed_a: 0x200000
|
||||
(bootloader) partition-type:LOGO_a:raw
|
||||
(bootloader) partition-size:LOGO_a: 0x1000000
|
||||
(bootloader) partition-type:storsec_a:raw
|
||||
(bootloader) partition-size:storsec_a: 0x20000
|
||||
(bootloader) partition-type:dtbo_a:raw
|
||||
(bootloader) partition-size:dtbo_a: 0x800000
|
||||
(bootloader) partition-type:vbmeta_a:raw
|
||||
(bootloader) partition-size:vbmeta_a: 0x10000
|
||||
(bootloader) partition-type:vendor_a:raw
|
||||
(bootloader) partition-size:vendor_a: 0x40000000
|
||||
(bootloader) partition-type:qupfw_a:raw
|
||||
(bootloader) partition-size:qupfw_a: 0x10000
|
||||
(bootloader) partition-type:devcfg_a:raw
|
||||
(bootloader) partition-size:devcfg_a: 0x20000
|
||||
(bootloader) partition-type:cmnlib64_a:raw
|
||||
(bootloader) partition-size:cmnlib64_a: 0x80000
|
||||
(bootloader) partition-type:cmnlib_a:raw
|
||||
(bootloader) partition-size:cmnlib_a: 0x80000
|
||||
(bootloader) partition-type:boot_a:raw
|
||||
(bootloader) partition-size:boot_a: 0x4000000
|
||||
(bootloader) partition-type:keymaster_a:raw
|
||||
(bootloader) partition-size:keymaster_a: 0x80000
|
||||
(bootloader) partition-type:dsp_a:raw
|
||||
(bootloader) partition-size:dsp_a: 0x2000000
|
||||
(bootloader) partition-type:abl_a:raw
|
||||
(bootloader) partition-size:abl_a: 0x800000
|
||||
(bootloader) partition-type:mdtp_a:raw
|
||||
(bootloader) partition-size:mdtp_a: 0x2000000
|
||||
(bootloader) partition-type:mdtpsecapp_a:raw
|
||||
(bootloader) partition-size:mdtpsecapp_a: 0x400000
|
||||
(bootloader) partition-type:bluetooth_a:raw
|
||||
(bootloader) partition-size:bluetooth_a: 0x100000
|
||||
(bootloader) partition-type:modem_a:raw
|
||||
(bootloader) partition-size:modem_a: 0x7800000
|
||||
(bootloader) partition-type:hyp_a:raw
|
||||
(bootloader) partition-size:hyp_a: 0x80000
|
||||
(bootloader) partition-type:tz_a:raw
|
||||
(bootloader) partition-size:tz_a: 0x200000
|
||||
(bootloader) partition-type:aop_a:raw
|
||||
(bootloader) partition-size:aop_a: 0x80000
|
||||
(bootloader) partition-type:ddr:raw
|
||||
(bootloader) partition-size:ddr: 0x100000
|
||||
(bootloader) partition-type:cdt:raw
|
||||
(bootloader) partition-size:cdt: 0x20000
|
||||
(bootloader) partition-type:ALIGN_TO_128K_1:raw
|
||||
(bootloader) partition-size:ALIGN_TO_128K_1: 0x1A000
|
||||
(bootloader) partition-type:xbl_config_b:raw
|
||||
(bootloader) partition-size:xbl_config_b: 0x20000
|
||||
(bootloader) partition-type:xbl_b:raw
|
||||
(bootloader) partition-size:xbl_b: 0x380000
|
||||
(bootloader) partition-type:xbl_config_a:raw
|
||||
(bootloader) partition-size:xbl_config_a: 0x20000
|
||||
(bootloader) partition-type:xbl_a:raw
|
||||
(bootloader) partition-size:xbl_a: 0x380000
|
||||
(bootloader) partition-type:userdata:ext4
|
||||
(bootloader) partition-size:userdata: 0x1B800BB000
|
||||
(bootloader) partition-type:odm_b:raw
|
||||
(bootloader) partition-size:odm_b: 0x6400000
|
||||
(bootloader) partition-type:odm_a:raw
|
||||
(bootloader) partition-size:odm_a: 0x6400000
|
||||
(bootloader) partition-type:system_b:ext4
|
||||
(bootloader) partition-size:system_b: 0xB2C00000
|
||||
(bootloader) partition-type:system_a:ext4
|
||||
(bootloader) partition-size:system_a: 0xB2C00000
|
||||
(bootloader) partition-type:config:raw
|
||||
(bootloader) partition-size:config: 0x80000
|
||||
(bootloader) partition-type:reserve2:raw
|
||||
(bootloader) partition-size:reserve2: 0xFD0000
|
||||
(bootloader) partition-type:reserve1:raw
|
||||
(bootloader) partition-size:reserve1: 0x7E8000
|
||||
(bootloader) partition-type:oem_stanvbk:raw
|
||||
(bootloader) partition-size:oem_stanvbk: 0xA00000
|
||||
(bootloader) partition-type:oem_dycnvbk:raw
|
||||
(bootloader) partition-size:oem_dycnvbk: 0xA00000
|
||||
(bootloader) partition-type:op2:raw
|
||||
(bootloader) partition-size:op2: 0x10000000
|
||||
(bootloader) partition-type:frp:raw
|
||||
(bootloader) partition-size:frp: 0x80000
|
||||
(bootloader) partition-type:keystore:raw
|
||||
(bootloader) partition-size:keystore: 0x80000
|
||||
(bootloader) partition-type:param:raw
|
||||
(bootloader) partition-size:param: 0x100000
|
||||
(bootloader) partition-type:misc:raw
|
||||
(bootloader) partition-size:misc: 0x100000
|
||||
(bootloader) partition-type:persist:raw
|
||||
(bootloader) partition-size:persist: 0x2000000
|
||||
(bootloader) partition-type:ssd:raw
|
||||
(bootloader) partition-size:ssd: 0x2000
|
||||
(bootloader) has-slot:modem:yes
|
||||
(bootloader) has-slot:system:yes
|
||||
(bootloader) current-slot:b
|
||||
(bootloader) has-slot:boot:yes
|
||||
(bootloader) slot-retry-count:b:6
|
||||
(bootloader) slot-unbootable:b:no
|
||||
(bootloader) slot-successful:b:yes
|
||||
(bootloader) slot-retry-count:a:6
|
||||
(bootloader) slot-unbootable:a:no
|
||||
(bootloader) slot-successful:a:yes
|
||||
(bootloader) slot-count:2
|
||||
(bootloader) secure:yes
|
||||
(bootloader) serialno:45751efa
|
||||
(bootloader) product:sdm845
|
||||
(bootloader) max-download-size:536870912
|
||||
(bootloader) kernel:uefi
|
||||
|
||||
25d52959
|
||||
|
||||
am broadcast -n com.oneplus.factorymode/.EngineerModeActionReceiver -a android.provider.Telephony.SECRET_CODE -d android_secret_code://5646
|
||||
|
||||
am broadcast -n com.oneplus.factorymode/.EngineerModeActionReceiver -a com.android.engineeringmode.encrypt
|
||||
|
||||
am broadcast -n com.oneplus.factorymode/.EngineerModeActionReceiver -a
|
||||
com.oem.engineermode.StartOEMLogMain
|
||||
|
||||
IMEI:866241047809937
|
||||
'''
|
||||
|
||||
|
||||
def main():
|
||||
from docopt import docopt
|
||||
args = docopt(__doc__, version='oneplus 1.1')
|
||||
# filename="param_jacob_7pro.bin"
|
||||
# filename="chris/param.bin"
|
||||
if args["param"]:
|
||||
filename = args["<filename>"]
|
||||
mode = args["--mode"]
|
||||
serial = args["--serial"]
|
||||
param = paramtools(mode,serial)
|
||||
with open(filename, 'rb') as rf:
|
||||
data = rf.read()
|
||||
param.parse_decrypted_fields(data)
|
||||
print("\nEncrypted Values:\n-----------------\n")
|
||||
param.parse_encrypted_fields(data)
|
||||
# with open(filename + ".patched", 'wb') as wf:
|
||||
# wf.write(param.setfactoryflags(data))
|
||||
elif args["ops"]:
|
||||
filename = args["<filename>"]
|
||||
mode = args["--mode"]
|
||||
serial = args["--serial"]
|
||||
param = paramtools(mode,serial)
|
||||
with open(filename, 'rb') as rf:
|
||||
data = rf.read()
|
||||
with open(filename + ".patched", 'wb') as wf:
|
||||
try:
|
||||
data = param.setparamvalue(data, 0x12C, 0x80, 0x3) # >= Oneplus 5
|
||||
except:
|
||||
pass
|
||||
data = param.setparamvalue(data, 0xC, 0x1A4, 0x1) # < Oneplus 5
|
||||
wf.write(data)
|
||||
elif args["setparam"]:
|
||||
filename = args["<filename>"]
|
||||
sid = int(args["<sid>"], 16)
|
||||
offset = int(args["<offset>"], 16)
|
||||
value = int(args["<value>"], 16)
|
||||
mode = args["--mode"]
|
||||
serial = args["--serial"]
|
||||
param = paramtools(mode,serial)
|
||||
with open(filename, 'rb') as rf:
|
||||
data = rf.read()
|
||||
with open(filename + ".patched", 'wb') as wf:
|
||||
wf.write(param.setparamvalue(data, sid, offset, value))
|
||||
elif args["gencode"]:
|
||||
imei = args["<imei>"]
|
||||
mode = 0
|
||||
serial = None
|
||||
param = paramtools(mode,serial)
|
||||
print("oneplus Factory qr code generator (c) B. Kerler 2019\nGPLv3 License\n----------------------")
|
||||
print("Code : *#*#5646#*#* , *#808#, *#36446337# = com.android.engineeringmode.manualtest.DecryptActivity")
|
||||
results = param.gencode([imei, "YOU_CAN_PASS_NOW"])
|
||||
import qrcode
|
||||
img = qrcode.make("op_eng://" + results[0])
|
||||
print("Code : " + results[0])
|
||||
img.save(imei + ".png")
|
||||
print("Image written as " + imei + ".png")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import logging
|
||||
from edlclient.Library.utils import LogBase
|
||||
|
@ -31,15 +35,15 @@ class xiaomi(metaclass=LogBase):
|
|||
|
||||
def edl_auth(self):
|
||||
"""
|
||||
Poco F1, Redmi 5 Pro, 6 Pro, 7 Pro, 7A, 8, 8A, 8A Dual, 8A Pro, Y2, S2
|
||||
Redmi A1, Poco F1, Redmi 5 Pro, 6 Pro, 7 Pro, 7A, 8, 8A, 8A Dual, 8A Pro, Y2, S2
|
||||
"""
|
||||
authcmd = b"<?xml version=\"1.0\" ?><data> <sig TargetName=\"sig\" size_in_bytes=\"256\" verbose=\"1\"/></data>"
|
||||
rsp = self.fh.xmlsend(authcmd)
|
||||
if rsp[0]:
|
||||
if rsp.resp:
|
||||
rsp = self.fh.xmlsend(self.xiaomi_authdata)
|
||||
if len(rsp) > 1:
|
||||
if rsp[0]:
|
||||
if b"EDL Authenticated" in rsp[2] or b"ACK" in rsp[2]:
|
||||
return True
|
||||
return True
|
||||
if rsp.resp:
|
||||
if "value" in rsp.resp:
|
||||
if rsp.resp["value"]=="ACK":
|
||||
if 'authenticated' in rsp.log[0].lower() and 'true' in rsp.log[0].lower():
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
from capstone import *
|
||||
from keystone import *
|
||||
from binascii import unhexlify
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2019
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import hashlib
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util import Counter
|
||||
from Crypto.Hash import CMAC
|
||||
from Crypto.Util.number import long_to_bytes, bytes_to_long
|
||||
from Cryptodome.Cipher import AES
|
||||
from Cryptodome.Util import Counter
|
||||
from Cryptodome.Hash import CMAC
|
||||
from Cryptodome.Util.number import long_to_bytes, bytes_to_long
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2019
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import binascii
|
||||
import io
|
||||
import os.path
|
||||
import platform
|
||||
import re
|
||||
import time
|
||||
|
@ -12,10 +17,28 @@ from struct import unpack
|
|||
from binascii import hexlify
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
from edlclient.Library.Modules.nothing import nothing
|
||||
from edlclient.Library.utils import *
|
||||
from edlclient.Library.gpt import gpt
|
||||
from edlclient.Library.gpt import gpt, AB_FLAG_OFFSET, AB_PARTITION_ATTR_SLOT_ACTIVE, MAX_PRIORITY, PART_ATT_PRIORITY_BIT
|
||||
from edlclient.Library.gpt import PART_ATT_PRIORITY_VAL, PART_ATT_ACTIVE_VAL, PART_ATT_MAX_RETRY_COUNT_VAL, PART_ATT_SUCCESSFUL_VAL, PART_ATT_UNBOOTABLE_VAL
|
||||
from edlclient.Library.sparse import QCSparse
|
||||
from edlclient.Library.utils import progress
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
rq = Queue()
|
||||
|
||||
def writedata(filename, rq):
|
||||
pos = 0
|
||||
with open(filename, "wb") as wf:
|
||||
while True:
|
||||
data = rq.get()
|
||||
if data is None:
|
||||
break
|
||||
pos += len(data)
|
||||
wf.write(data)
|
||||
rq.task_done()
|
||||
|
||||
|
||||
class response:
|
||||
|
@ -191,7 +214,13 @@ class firehose(metaclass=LogBase):
|
|||
self.nandparttbl = None
|
||||
self.nandpart = nand_partition(parent=self, printer=print)
|
||||
|
||||
def detect_partition(self, arguments, partitionname):
|
||||
def detect_partition(self, arguments, partitionname, send_full=False):
|
||||
if arguments is None:
|
||||
arguments = {
|
||||
"--gpt-num-part-entries" : 0,
|
||||
"--gpt-part-entry-size" : 0,
|
||||
"--gpt-part-entry-start-lba" : 0
|
||||
}
|
||||
fpartitions = {}
|
||||
for lun in self.luns:
|
||||
lunname = "Lun" + str(lun)
|
||||
|
@ -203,7 +232,7 @@ class firehose(metaclass=LogBase):
|
|||
break
|
||||
else:
|
||||
if partitionname in guid_gpt.partentries:
|
||||
return [True, lun, guid_gpt.partentries[partitionname]]
|
||||
return [True, lun, data, guid_gpt] if send_full else [True, lun, guid_gpt.partentries[partitionname]]
|
||||
for part in guid_gpt.partentries:
|
||||
fpartitions[lunname].append(part)
|
||||
return [False, fpartitions]
|
||||
|
@ -267,7 +296,7 @@ class firehose(metaclass=LogBase):
|
|||
if resp["rawmode"] == "false":
|
||||
if status:
|
||||
log = self.xml.getlog(rdata)
|
||||
return response(resp=status, data=resp, log=log)
|
||||
return response(resp=status, data=rdata, log=log)
|
||||
else:
|
||||
error = self.xml.getlog(rdata)
|
||||
return response(resp=status, error=error, data=resp, log=error)
|
||||
|
@ -304,7 +333,7 @@ class firehose(metaclass=LogBase):
|
|||
|
||||
def cmd_reset(self, mode="reset"):
|
||||
if mode is None:
|
||||
mode = "poweroff"
|
||||
mode = "reset"
|
||||
data = "<?xml version=\"1.0\" ?><data><power value=\"" + mode + "\"/></data>"
|
||||
val = self.xmlsend(data)
|
||||
try:
|
||||
|
@ -340,7 +369,7 @@ class firehose(metaclass=LogBase):
|
|||
def cmd_nop(self):
|
||||
data = "<?xml version=\"1.0\" ?><data><nop /></data>"
|
||||
resp = self.xmlsend(data, True)
|
||||
self.debug(resp.hex())
|
||||
self.debug(resp.data.hex())
|
||||
info = b""
|
||||
tmp = None
|
||||
while tmp != b"":
|
||||
|
@ -607,6 +636,7 @@ class firehose(metaclass=LogBase):
|
|||
return True
|
||||
|
||||
def cmd_read(self, physical_partition_number, start_sector, num_partition_sectors, filename, display=True):
|
||||
global rq
|
||||
self.lasterror = b""
|
||||
progbar = progress(self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
if display:
|
||||
|
@ -614,52 +644,56 @@ class firehose(metaclass=LogBase):
|
|||
f"\nReading from physical partition {str(physical_partition_number)}, " +
|
||||
f"sector {str(start_sector)}, sectors {str(num_partition_sectors)}")
|
||||
|
||||
with open(file=filename, mode="wb", buffering=self.cfg.MaxPayloadSizeFromTargetInBytes) as wr:
|
||||
data = f"<?xml version=\"1.0\" ?><data><read SECTOR_SIZE_IN_BYTES=\"{self.cfg.SECTOR_SIZE_IN_BYTES}\"" + \
|
||||
f" num_partition_sectors=\"{num_partition_sectors}\"" + \
|
||||
f" physical_partition_number=\"{physical_partition_number}\"" + \
|
||||
f" start_sector=\"{start_sector}\"/>\n</data>"
|
||||
data = f"<?xml version=\"1.0\" ?><data><read SECTOR_SIZE_IN_BYTES=\"{self.cfg.SECTOR_SIZE_IN_BYTES}\"" + \
|
||||
f" num_partition_sectors=\"{num_partition_sectors}\"" + \
|
||||
f" physical_partition_number=\"{physical_partition_number}\"" + \
|
||||
f" start_sector=\"{start_sector}\"/>\n</data>"
|
||||
|
||||
rsp = self.xmlsend(data, self.skipresponse)
|
||||
self.cdc.xmlread = False
|
||||
time.sleep(0.01)
|
||||
if not rsp.resp:
|
||||
if display:
|
||||
self.error(rsp.error)
|
||||
return b""
|
||||
else:
|
||||
bytestoread = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
total = bytestoread
|
||||
show_progress = progbar.show_progress
|
||||
usb_read = self.cdc.read
|
||||
progbar.show_progress(prefix="Read", pos=0, total=total, display=display)
|
||||
while bytestoread > 0:
|
||||
if self.cdc.is_serial:
|
||||
maxsize = self.cfg.MaxPayloadSizeFromTargetInBytes
|
||||
else:
|
||||
maxsize = 5 * 1024 * 1024
|
||||
size = min(maxsize, bytestoread)
|
||||
data = usb_read(size)
|
||||
if len(data) > 0:
|
||||
wr.write(data)
|
||||
bytestoread -= len(data)
|
||||
show_progress(prefix="Read", pos=total - bytestoread, total=total, display=display)
|
||||
self.cdc.xmlread = True
|
||||
wd = self.wait_for_data()
|
||||
info = self.xml.getlog(wd)
|
||||
rsp = self.xml.getresponse(wd)
|
||||
if "value" in rsp:
|
||||
if rsp["value"] != "ACK":
|
||||
rsp = self.xmlsend(data, self.skipresponse)
|
||||
self.cdc.xmlread = False
|
||||
time.sleep(0.01)
|
||||
if not rsp.resp:
|
||||
if display:
|
||||
self.error(rsp.error)
|
||||
return b""
|
||||
else:
|
||||
bytestoread = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
total = bytestoread
|
||||
show_progress = progbar.show_progress
|
||||
usb_read = self.cdc.read
|
||||
progbar.show_progress(prefix="Read", pos=0, total=total, display=display)
|
||||
worker = Thread(target=writedata, args=(filename, rq), daemon=True)
|
||||
worker.start()
|
||||
while bytestoread > 0:
|
||||
if self.cdc.is_serial:
|
||||
maxsize = self.cfg.MaxPayloadSizeFromTargetInBytes
|
||||
else:
|
||||
maxsize = 5 * 1024 * 1024
|
||||
size = min(maxsize, bytestoread)
|
||||
data = usb_read(size)
|
||||
if len(data) > 0:
|
||||
rq.put(data)
|
||||
bytestoread -= len(data)
|
||||
show_progress(prefix="Read", pos=total - bytestoread, total=total, display=display)
|
||||
rq.put(None)
|
||||
worker.join(60)
|
||||
self.cdc.xmlread = True
|
||||
wd = self.wait_for_data()
|
||||
info = self.xml.getlog(wd)
|
||||
rsp = self.xml.getresponse(wd)
|
||||
if "value" in rsp:
|
||||
if rsp["value"] != "ACK":
|
||||
if bytestoread!=0:
|
||||
self.error(f"Error:")
|
||||
for line in info:
|
||||
self.error(line)
|
||||
self.lasterror += bytes(line + "\n", "utf-8")
|
||||
return False
|
||||
else:
|
||||
if display:
|
||||
self.error(f"Error:{rsp[2]}")
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
if display:
|
||||
self.error(f"Error:{rsp[2]}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def cmd_read_buffer(self, physical_partition_number, start_sector, num_partition_sectors, display=True):
|
||||
self.lasterror = b""
|
||||
|
@ -720,13 +754,13 @@ class firehose(metaclass=LogBase):
|
|||
resp = rsp["value"] == "ACK"
|
||||
return response(resp=resp, data=resData, error=rsp[2]) # Do not remove, needed for oneplus
|
||||
|
||||
def get_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba):
|
||||
def get_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba, start_sector=1):
|
||||
try:
|
||||
resp = self.cmd_read_buffer(lun, 0, 2, False)
|
||||
resp = self.cmd_read_buffer(lun, 0, 1, False)
|
||||
except Exception as err:
|
||||
self.debug(str(err))
|
||||
self.skipresponse = True
|
||||
resp = self.cmd_read_buffer(lun, 0, 2, False)
|
||||
resp = self.cmd_read_buffer(lun, 0, 1, False)
|
||||
|
||||
if not resp.resp:
|
||||
for line in resp.error:
|
||||
|
@ -734,6 +768,7 @@ class firehose(metaclass=LogBase):
|
|||
return None, None
|
||||
data = resp.data
|
||||
magic = unpack("<I", data[0:4])[0]
|
||||
data += self.cmd_read_buffer(lun, start_sector, 1, False).data
|
||||
if magic == 0x844bdcd1:
|
||||
self.info("Nand storage detected.")
|
||||
self.info("Scanning for partition table ...")
|
||||
|
@ -768,22 +803,22 @@ class firehose(metaclass=LogBase):
|
|||
loglevel=self.__logger.level
|
||||
)
|
||||
try:
|
||||
header = guid_gpt.parseheader(data, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
sectorsize = self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
header = guid_gpt.parseheader(data, sectorsize)
|
||||
if header.signature == b"EFI PART":
|
||||
gptsize = (header.part_entry_start_lba * self.cfg.SECTOR_SIZE_IN_BYTES) + (
|
||||
header.num_part_entries * header.part_entry_size)
|
||||
sectors = gptsize // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if gptsize % self.cfg.SECTOR_SIZE_IN_BYTES != 0:
|
||||
part_table_size = header.num_part_entries * header.part_entry_size
|
||||
sectors = part_table_size // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if part_table_size % self.cfg.SECTOR_SIZE_IN_BYTES != 0:
|
||||
sectors += 1
|
||||
if sectors == 0:
|
||||
return None, None
|
||||
if sectors > 64:
|
||||
sectors = 64
|
||||
data = self.cmd_read_buffer(lun, 0, sectors, False)
|
||||
data += self.cmd_read_buffer(lun, header.part_entry_start_lba, sectors, False).data
|
||||
if data == b"":
|
||||
return None, None
|
||||
guid_gpt.parse(data.data, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
return data.data, guid_gpt
|
||||
guid_gpt.parse(data, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
return data, guid_gpt
|
||||
else:
|
||||
return None, None
|
||||
except Exception as err:
|
||||
|
@ -848,7 +883,7 @@ class firehose(metaclass=LogBase):
|
|||
'''
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><data><response value=\"ACK\" MinVersionSupported=\"1\"" \
|
||||
"MemoryName=\"eMMC\" MaxPayloadSizeFromTargetInBytes=\"4096\" MaxPayloadSizeToTargetInBytes=\"1048576\" " \
|
||||
"MaxPayloadSizeToTargetInBytesSupported=\"1048576\" MaxXMLSizeInBytes=\"4096\" Version=\"1\"
|
||||
"MaxPayloadSizeToTargetInBytesSupported=\"1048576\" MaxXMLSizeInBytes=\"4096\" Version=\"1\"
|
||||
TargetName=\"8953\" />" \
|
||||
"</data>"
|
||||
'''
|
||||
|
@ -1008,6 +1043,15 @@ class firehose(metaclass=LogBase):
|
|||
self.cfg.SECTOR_SIZE_IN_BYTES = 4096
|
||||
return self.configure(0)
|
||||
self.parse_storage()
|
||||
for function in self.supported_functions:
|
||||
if function == "checkntfeature":
|
||||
if type(self.devicemodel)==list:
|
||||
self.devicemodel=self.devicemodel[0]
|
||||
self.nothing = nothing(fh=self, projid=self.devicemodel, serial=self.serial,
|
||||
supported_functions=self.supported_functions,
|
||||
loglevel=self.loglevel)
|
||||
if self.nothing is not None:
|
||||
self.nothing.ntprojectverify()
|
||||
self.luns = self.getluns(self.args)
|
||||
return True
|
||||
|
||||
|
@ -1104,6 +1148,8 @@ class firehose(metaclass=LogBase):
|
|||
if "chip serial num" in line.lower():
|
||||
try:
|
||||
serial = line.split("0x")[1][:-1]
|
||||
if ")" in serial:
|
||||
serial=serial[:serial.rfind(")")]
|
||||
self.serial = int(serial, 16)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
self.debug(str(err))
|
||||
|
@ -1136,7 +1182,8 @@ class firehose(metaclass=LogBase):
|
|||
try:
|
||||
if os.path.exists(self.cfg.programmer):
|
||||
data = open(self.cfg.programmer, "rb").read()
|
||||
for cmd in [b"demacia", b"setprojmodel", b"setswprojmodel", b"setprocstart", b"SetNetType"]:
|
||||
for cmd in [b"demacia", b"setprojmodel", b"setswprojmodel", b"setprocstart", b"SetNetType",
|
||||
b"checkntfeature"]:
|
||||
if cmd in data:
|
||||
self.supported_functions.append(cmd.decode('utf-8'))
|
||||
state = {
|
||||
|
@ -1144,7 +1191,19 @@ class firehose(metaclass=LogBase):
|
|||
"programmer": self.cfg.programmer,
|
||||
"serial": self.serial
|
||||
}
|
||||
open("edl_config.json", "w").write(json.dumps(state))
|
||||
if os.path.exists("edl_config.json"):
|
||||
data = json.loads(open("edl_config.json","rb").read().decode('utf-8'))
|
||||
if "serial" in data and data["serial"]!=state["serial"]:
|
||||
open("edl_config.json", "w").write(json.dumps(state))
|
||||
else:
|
||||
self.supported_functions = data["supported_functions"]
|
||||
self.cfg.programmer = data["programmer"]
|
||||
else:
|
||||
open("edl_config.json", "w").write(json.dumps(state))
|
||||
if "001920e101cf0000_fa2836525c2aad8a_fhprg.bin" in self.cfg.programmer:
|
||||
self.devicemodel = '20111'
|
||||
elif "000b80e100020000_467f3020c4cc788d_fhprg.bin" in self.cfg.programmer:
|
||||
self.devicemodel = '22111'
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -1262,41 +1321,204 @@ class firehose(metaclass=LogBase):
|
|||
return None
|
||||
|
||||
def cmd_setactiveslot(self, slot: str):
|
||||
# flags: 0x3a for inactive and 0x6f for active boot partition
|
||||
def set_flags(flags, active, is_boot):
|
||||
new_flags = flags
|
||||
if active:
|
||||
if is_boot:
|
||||
#new_flags |= (PART_ATT_PRIORITY_VAL | PART_ATT_ACTIVE_VAL | PART_ATT_MAX_RETRY_COUNT_VAL)
|
||||
#new_flags &= (~PART_ATT_SUCCESSFUL_VAL & ~PART_ATT_UNBOOTABLE_VAL)
|
||||
new_flags = 0x6f << (AB_FLAG_OFFSET*8)
|
||||
else:
|
||||
new_flags |= AB_PARTITION_ATTR_SLOT_ACTIVE << (AB_FLAG_OFFSET*8)
|
||||
else:
|
||||
if is_boot:
|
||||
#new_flags &= (~PART_ATT_PRIORITY_VAL & ~PART_ATT_ACTIVE_VAL)
|
||||
#new_flags |= ((MAX_PRIORITY-1) << PART_ATT_PRIORITY_BIT)
|
||||
new_flags = 0x3a << (AB_FLAG_OFFSET*8)
|
||||
else:
|
||||
new_flags &= ~(AB_PARTITION_ATTR_SLOT_ACTIVE << (AB_FLAG_OFFSET*8))
|
||||
return new_flags
|
||||
|
||||
def patch_helper(gpt_data_a, gpt_data_b, guid_gpt_a, guid_gpt_b, partition_a, partition_b, slot_a_status, slot_b_status, is_boot):
|
||||
part_entry_size = guid_gpt_a.header.part_entry_size
|
||||
|
||||
rf_a = BytesIO(gpt_data_a)
|
||||
rf_b = BytesIO(gpt_data_b)
|
||||
|
||||
entryoffset_a = partition_a.entryoffset - ((guid_gpt_a.header.part_entry_start_lba - 2) * guid_gpt_a.sectorsize)
|
||||
entryoffset_b = partition_b.entryoffset - ((guid_gpt_b.header.part_entry_start_lba - 2) * guid_gpt_b.sectorsize)
|
||||
rf_a.seek(entryoffset_a)
|
||||
rf_b.seek(entryoffset_b)
|
||||
|
||||
sdata_a = rf_a.read(part_entry_size)
|
||||
sdata_b = rf_b.read(part_entry_size)
|
||||
|
||||
partentry_a = gpt.gpt_partition(sdata_a)
|
||||
partentry_b = gpt.gpt_partition(sdata_b)
|
||||
|
||||
partentry_a.flags = set_flags(partentry_a.flags, slot_a_status, is_boot)
|
||||
partentry_b.flags = set_flags(partentry_b.flags, slot_b_status, is_boot)
|
||||
partentry_a.type, partentry_b.type = partentry_b.type, partentry_a.type
|
||||
|
||||
pdata_a, pdata_b = partentry_a.create(), partentry_b.create()
|
||||
return pdata_a, partition_a.entryoffset, pdata_b, partition_b.entryoffset
|
||||
|
||||
def cmd_patch_multiple(lun, start_sector, byte_offset, patch_data):
|
||||
offset = 0
|
||||
size_each_patch = 8 if len(patch_data) % 8 == 0 else 4
|
||||
unpack_fmt = "<I" if size_each_patch == 4 else "<Q"
|
||||
write_size = len(patch_data)
|
||||
for i in range(0, write_size, size_each_patch):
|
||||
pdata_subset = int(unpack(unpack_fmt, patch_data[offset:offset+size_each_patch])[0])
|
||||
self.cmd_patch( lun, start_sector, byte_offset + offset, pdata_subset, size_each_patch, True)
|
||||
offset += size_each_patch
|
||||
return True
|
||||
|
||||
def update_gpt_info(guid_gpt_a, guid_gpt_b, partitionname_a, partitionname_b,
|
||||
gpt_data_a, gpt_data_b, slot_a_status, slot_b_status, lun_a, lun_b
|
||||
):
|
||||
part_a = guid_gpt_a.partentries[partitionname_a]
|
||||
part_b = guid_gpt_b.partentries[partitionname_b]
|
||||
|
||||
is_boot = False
|
||||
if partitionname_a == "boot_a":
|
||||
is_boot = True
|
||||
pdata_a, poffset_a, pdata_b, poffset_b = patch_helper(
|
||||
gpt_data_a, gpt_data_b,
|
||||
guid_gpt_a, guid_gpt_b,
|
||||
part_a, part_b,
|
||||
slot_a_status, slot_b_status,
|
||||
is_boot
|
||||
)
|
||||
|
||||
if gpt_data_a and gpt_data_b:
|
||||
entryoffset_a = poffset_a - ((guid_gpt_a.header.part_entry_start_lba - 2) * guid_gpt_a.sectorsize)
|
||||
gpt_data_a[entryoffset_a : entryoffset_a + len(pdata_a)] = pdata_a
|
||||
new_gpt_data_a = guid_gpt_a.fix_gpt_crc(gpt_data_a)
|
||||
|
||||
entryoffset_b = poffset_b - ((guid_gpt_b.header.part_entry_start_lba - 2) * guid_gpt_b.sectorsize)
|
||||
gpt_data_b[entryoffset_b : entryoffset_b + len(pdata_b)] = pdata_b
|
||||
new_gpt_data_b = guid_gpt_b.fix_gpt_crc(gpt_data_b)
|
||||
|
||||
start_sector_patch_a = poffset_a // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
byte_offset_patch_a = poffset_a % self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
cmd_patch_multiple(lun_a, start_sector_patch_a, byte_offset_patch_a, pdata_a)
|
||||
|
||||
if lun_a != lun_b:
|
||||
start_sector_hdr_a = guid_gpt_a.header.current_lba
|
||||
headeroffset_a = guid_gpt_a.sectorsize # gptData: mbr + gpt header + part array
|
||||
new_hdr_a = new_gpt_data_a[headeroffset_a : headeroffset_a+guid_gpt_a.header.header_size]
|
||||
cmd_patch_multiple(lun_a, start_sector_hdr_a, 0, new_hdr_a)
|
||||
|
||||
start_sector_patch_b = poffset_b // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
byte_offset_patch_b = poffset_b % self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
cmd_patch_multiple(lun_b, start_sector_patch_b, byte_offset_patch_b, pdata_b)
|
||||
|
||||
start_sector_hdr_b = guid_gpt_b.header.current_lba
|
||||
headeroffset_b = guid_gpt_b.sectorsize
|
||||
new_hdr_b = new_gpt_data_b[headeroffset_b : headeroffset_b+guid_gpt_b.header.header_size]
|
||||
cmd_patch_multiple(lun_b, start_sector_hdr_b, 0, new_hdr_b)
|
||||
return True
|
||||
return False
|
||||
|
||||
def ensure_gpt_hdr_consistency(guid_gpt, backup_guid_gpt, gpt_data, backup_gpt_data):
|
||||
headeroffset = guid_gpt.sectorsize
|
||||
prim_corrupted, backup_corrupted = False, False
|
||||
|
||||
prim_hdr = gpt_data[headeroffset : headeroffset + guid_gpt.header.header_size]
|
||||
test_hdr = guid_gpt.fix_gpt_crc(gpt_data)[headeroffset : headeroffset + guid_gpt.header.header_size]
|
||||
prim_hdr_crc, test_hdr_crc = prim_hdr[0x10 : 0x10 + 4], test_hdr[0x10 : 0x10 + 4]
|
||||
prim_part_table_crc, test_part_table_crc = prim_hdr[0x58 : 0x58 + 4], test_hdr[0x58 : 0x58 + 4]
|
||||
prim_corrupted = prim_hdr_crc != test_hdr_crc or prim_part_table_crc != test_part_table_crc
|
||||
|
||||
backup_hdr = backup_gpt_data[headeroffset : headeroffset + backup_guid_gpt.header.header_size]
|
||||
test_hdr = backup_guid_gpt.fix_gpt_crc(backup_gpt_data)[headeroffset : headeroffset + backup_guid_gpt.header.header_size]
|
||||
backup_hdr_crc, test_hdr_crc = backup_hdr[0x10 : 0x10 + 4], test_hdr[0x10 : 0x10 + 4]
|
||||
backup_part_table_crc, test_part_table_crc = backup_hdr[0x58 : 0x58 + 4], test_hdr[0x58 : 0x58 + 4]
|
||||
backup_corrupted = backup_hdr_crc != test_hdr_crc or backup_part_table_crc != test_part_table_crc
|
||||
|
||||
prim_backup_consistent = prim_part_table_crc == backup_part_table_crc
|
||||
if prim_corrupted or not prim_backup_consistent:
|
||||
if backup_corrupted:
|
||||
self.error("both are gpt headers are corrupted, cannot recover")
|
||||
return False, None, None
|
||||
gpt_data[2*guid_gpt.sectorsize:] = backup_gpt_data[2*backup_guid_gpt.sectorsize:]
|
||||
gpt_data = guid_gpt.fix_gpt_crc(gpt_data)
|
||||
elif backup_corrupted or not prim_backup_consistent:
|
||||
backup_gpt_data[2*backup_guid_gpt.sectorsize:] = gpt_data[2*guid_gpt.sectorsize:]
|
||||
backup_gpt_data = backup_guid_gpt.fix_gpt_crc(backup_gpt_data)
|
||||
return True, gpt_data, backup_gpt_data
|
||||
|
||||
if slot.lower() not in ["a", "b"]:
|
||||
self.error("Only slots a or b are accepted. Aborting.")
|
||||
return False
|
||||
partslots = {}
|
||||
slot_a_status = None
|
||||
if slot == "a":
|
||||
partslots["_a"] = True
|
||||
partslots["_b"] = False
|
||||
slot_a_status = True
|
||||
elif slot == "b":
|
||||
partslots["_a"] = True
|
||||
partslots["_b"] = False
|
||||
slot_a_status = False
|
||||
slot_b_status = not slot_a_status
|
||||
fpartitions = {}
|
||||
for lun in self.luns:
|
||||
lunname = "Lun" + str(lun)
|
||||
fpartitions[lunname] = []
|
||||
data, guid_gpt = self.get_gpt(lun, int(0), int(0), int(0))
|
||||
if guid_gpt is None:
|
||||
break
|
||||
else:
|
||||
for partitionname in guid_gpt.partentries:
|
||||
gp = gpt()
|
||||
slot = partitionname.lower()[-2:]
|
||||
if "_a" in slot or "_b" in slot:
|
||||
pdata, poffset = gp.patch(data, partitionname, active=partslots[slot])
|
||||
data[poffset:poffset + len(pdata)] = pdata
|
||||
wdata = gp.fix_gpt_crc(data)
|
||||
if wdata is not None:
|
||||
start_sector_patch = poffset // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
byte_offset_patch = poffset % self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
headeroffset = gp.header.current_lba * gp.sectorsize
|
||||
start_sector_hdr = headeroffset // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
header = wdata[start_sector_hdr:start_sector_hdr + gp.header.header_size]
|
||||
self.cmd_patch(lun, start_sector_patch, byte_offset_patch, pdata, len(pdata), True)
|
||||
self.cmd_patch(lun, headeroffset, 0, header, len(pdata), True)
|
||||
return True
|
||||
return False
|
||||
try:
|
||||
for lun_a in self.luns:
|
||||
lunname = "Lun" + str(lun_a)
|
||||
fpartitions[lunname] = []
|
||||
check_gpt_hdr = False
|
||||
gpt_data_a, guid_gpt_a = self.get_gpt(lun_a, int(0), int(0), int(0))
|
||||
backup_gpt_data_a, backup_guid_gpt_a = self.get_gpt(lun_a, 0, 0 , 0, guid_gpt_a.header.backup_lba)
|
||||
if guid_gpt_a is None:
|
||||
break
|
||||
else:
|
||||
for partitionname_a in guid_gpt_a.partentries:
|
||||
slot = partitionname_a.lower()[-2:]
|
||||
if slot == "_a":
|
||||
partitionname_b = partitionname_a[:-1] + "b"
|
||||
if partitionname_b in guid_gpt_a.partentries:
|
||||
lun_b = lun_a
|
||||
gpt_data_b = gpt_data_a
|
||||
guid_gpt_b = guid_gpt_a
|
||||
backup_gpt_data_b = backup_gpt_data_a
|
||||
backup_guid_gpt_b = backup_guid_gpt_a
|
||||
else:
|
||||
resp = self.detect_partition(arguments=None,
|
||||
partitionname=partitionname_b,
|
||||
send_full=True)
|
||||
if not resp[0]:
|
||||
self.error(f"Cannot find partition {partitionname_b}")
|
||||
return False
|
||||
_, lun_b, gpt_data_b, guid_gpt_b = resp
|
||||
backup_gpt_data_b, backup_guid_gpt_b = self.get_gpt(lun_b, 0, 0 , 0, guid_gpt_b.header.backup_lba)
|
||||
|
||||
if not check_gpt_hdr and partitionname_a[:3] != "xbl": # xbl partition don't need check consistency
|
||||
sts, gpt_data_a, backup_gpt_data_a = ensure_gpt_hdr_consistency(guid_gpt_a, backup_guid_gpt_a, gpt_data_a, backup_gpt_data_a)
|
||||
if not sts:
|
||||
return False
|
||||
if lun_a != lun_b:
|
||||
sts, gpt_data_b, backup_gpt_data_b = ensure_gpt_hdr_consistency(guid_gpt_b, backup_guid_gpt_b, gpt_data_b, backup_gpt_data_b)
|
||||
if not sts:
|
||||
return False
|
||||
check_gpt_hdr = True
|
||||
|
||||
update_gpt_info(guid_gpt_a, guid_gpt_b,
|
||||
partitionname_a, partitionname_b,
|
||||
gpt_data_a, gpt_data_b,
|
||||
slot_a_status, slot_b_status,
|
||||
lun_a, lun_b)
|
||||
|
||||
# TODO: this updates the backup gpt header, but is it needed, since it is updated when xbl loads
|
||||
#update_gpt_info(backup_guid_gpt_a, backup_guid_gpt_b,
|
||||
# partitionname_a, partitionname_b,
|
||||
# backup_gpt_data_a, backup_gpt_data_b,
|
||||
# slot_a_status, slot_b_status,
|
||||
# lun_a, lun_b)
|
||||
|
||||
except Exception as err:
|
||||
self.error(str(err))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def cmd_test(self, cmd):
|
||||
token = "1234"
|
||||
|
@ -1415,12 +1637,12 @@ class firehose(metaclass=LogBase):
|
|||
data = f"<?xml version=\"1.0\" ?><data><peek address64=\"{address}\" " + \
|
||||
f"size_in_bytes=\"{SizeInBytes}\" /></data>\n"
|
||||
'''
|
||||
<?xml version="1.0" encoding="UTF-8" ?><data><log value="Using address 00100000" /></data>
|
||||
<?xml version="1.0" encoding="UTF-8" ?><data><log value="0x22 0x00 0x00 0xEA 0x70 0x00 0x00 0xEA 0x74 0x00
|
||||
0x00 0xEA 0x78 0x00 0x00 0xEA 0x7C 0x00 0x00 0xEA 0x80 0x00 0x00 0xEA 0x84 0x00 0x00 0xEA 0x88 0x00 0x00
|
||||
0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA
|
||||
0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE
|
||||
0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF
|
||||
<?xml version="1.0" encoding="UTF-8" ?><data><log value="Using address 00100000" /></data>
|
||||
<?xml version="1.0" encoding="UTF-8" ?><data><log value="0x22 0x00 0x00 0xEA 0x70 0x00 0x00 0xEA 0x74 0x00
|
||||
0x00 0xEA 0x78 0x00 0x00 0xEA 0x7C 0x00 0x00 0xEA 0x80 0x00 0x00 0xEA 0x84 0x00 0x00 0xEA 0x88 0x00 0x00
|
||||
0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA
|
||||
0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE
|
||||
0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF
|
||||
0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF " /></data>
|
||||
'''
|
||||
try:
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2019
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -12,6 +16,7 @@ from edlclient.Library.firehose import firehose
|
|||
from edlclient.Library.xmlparser import xmlparser
|
||||
from edlclient.Library.utils import do_tcp_server
|
||||
from edlclient.Library.utils import LogBase, getint
|
||||
from edlclient.Library.gpt import AB_FLAG_OFFSET, AB_PARTITION_ATTR_SLOT_ACTIVE
|
||||
from edlclient.Config.qualcomm_config import memory_type
|
||||
from edlclient.Config.qualcomm_config import infotbl, msmids, secureboottbl, sochw
|
||||
import fnmatch
|
||||
|
@ -132,10 +137,11 @@ class firehose_client(metaclass=LogBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def find_bootable_partition(self, rawprogram):
|
||||
def find_bootable_partition(self, imagedir, rawprogram):
|
||||
part = -1
|
||||
for xml in rawprogram:
|
||||
with open(xml, "r") as fl:
|
||||
filename = os.path.join(imagedir, xml)
|
||||
with open(filename, "r") as fl:
|
||||
for evt, elem in ET.iterparse(fl, events=["end"]):
|
||||
if elem.tag == "program":
|
||||
label = elem.get("label")
|
||||
|
@ -201,13 +207,15 @@ class firehose_client(metaclass=LogBase):
|
|||
int(options["--gpt-part-entry-start-lba"]))
|
||||
if guid_gpt is None:
|
||||
break
|
||||
with open(sfilename, "wb") as write_handle:
|
||||
write_handle.write(data)
|
||||
#with open(sfilename, "wb") as write_handle:
|
||||
# #write_handle.write(data)
|
||||
# pass
|
||||
|
||||
self.printer(f"Dumped GPT from Lun {str(lun)} to {sfilename}")
|
||||
sfilename = os.path.join(directory, f"gpt_backup{str(lun)}.bin")
|
||||
with open(sfilename, "wb") as write_handle:
|
||||
write_handle.write(data[self.firehose.cfg.SECTOR_SIZE_IN_BYTES * 2:])
|
||||
#with open(sfilename, "wb") as write_handle:
|
||||
# #write_handle.write(data[self.firehose.cfg.SECTOR_SIZE_IN_BYTES * 2:])
|
||||
# pass
|
||||
self.printer(f"Dumped Backup GPT from Lun {str(lun)} to {sfilename}")
|
||||
if genxml:
|
||||
guid_gpt.generate_rawprogram(lun, self.firehose.cfg.SECTOR_SIZE_IN_BYTES, directory)
|
||||
|
@ -634,6 +642,29 @@ class firehose_client(metaclass=LogBase):
|
|||
return False
|
||||
else:
|
||||
return self.firehose.cmd_setbootablestoragedrive(int(options["<lun>"]))
|
||||
elif cmd == "getactiveslot":
|
||||
res = self.firehose.detect_partition(options, "boot_a", send_full=True)
|
||||
if res[0]:
|
||||
lun = res[1]
|
||||
prim_guid_gpt = res[3]
|
||||
_, backup_guid_gpt = self.firehose.get_gpt(lun, 0, 0, 0, prim_guid_gpt.header.backup_lba)
|
||||
partition = backup_guid_gpt.partentries["boot_a"]
|
||||
active = ((partition.flags >> (AB_FLAG_OFFSET*8))&0xFF) & AB_PARTITION_ATTR_SLOT_ACTIVE == AB_PARTITION_ATTR_SLOT_ACTIVE
|
||||
if active:
|
||||
self.printer("Current active slot: a")
|
||||
return True
|
||||
res = self.firehose.detect_partition(options, "boot_b", send_full=True)
|
||||
if res[0]:
|
||||
lun = res[1]
|
||||
prim_guid_gpt = res[3]
|
||||
_, backup_guid_gpt = self.firehose.get_gpt(lun, 0, 0, 0, prim_guid_gpt.header.backup_lba)
|
||||
partition = backup_guid_gpt.partentries["boot_b"]
|
||||
active = ((partition.flags >> (AB_FLAG_OFFSET*8))&0xFF) & AB_PARTITION_ATTR_SLOT_ACTIVE == AB_PARTITION_ATTR_SLOT_ACTIVE
|
||||
if active:
|
||||
self.printer("Current active slot: b")
|
||||
return True
|
||||
self.error("Can't detect active slot. Please make sure your device has slot A/B")
|
||||
return False
|
||||
elif cmd == "setactiveslot":
|
||||
if not self.check_param(["<slot>"]):
|
||||
return False
|
||||
|
@ -724,17 +755,17 @@ class firehose_client(metaclass=LogBase):
|
|||
filenames = []
|
||||
if self.firehose.modules is not None:
|
||||
self.firehose.modules.writeprepare()
|
||||
for dirName, subdirList, fileList in os.walk(directory):
|
||||
for fname in fileList:
|
||||
filenames.append(os.path.join(dirName, fname))
|
||||
for fname in filter(os.path.isfile, [ os.path.join(directory, i) for i in os.listdir(directory) ]):
|
||||
filenames.append(fname)
|
||||
for lun in luns:
|
||||
data, guid_gpt = self.firehose.get_gpt(lun, int(options["--gpt-num-part-entries"]),
|
||||
int(options["--gpt-part-entry-size"]),
|
||||
int(options["--gpt-part-entry-start-lba"]))
|
||||
if guid_gpt is None:
|
||||
self.error("Error: Can not fetch GPT table from device, you may need to use `edl w gpt` to write a partition table first.`")
|
||||
break
|
||||
for filename in filenames:
|
||||
partname = filename[filename.rfind("/") + 1:]
|
||||
partname = os.path.basename(filename)
|
||||
if ".bin" in partname[-4:] or ".img" in partname[-4:] or ".mbn" in partname[-4:]:
|
||||
partname = partname[:-4]
|
||||
if partname in skip:
|
||||
|
@ -953,7 +984,8 @@ class firehose_client(metaclass=LogBase):
|
|||
else:
|
||||
self.warning(f"File : {filename} not found.")
|
||||
self.info("[qfil] patching ok")
|
||||
bootable = self.find_bootable_partition(rawprogram)
|
||||
|
||||
bootable = self.find_bootable_partition(imagedir, rawprogram)
|
||||
if bootable != -1:
|
||||
if self.firehose.cmd_setbootablestoragedrive(bootable):
|
||||
self.info("[qfil] partition({partition}) is now bootable\n".format(partition=bootable))
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021 MIT License
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
|
@ -190,6 +194,20 @@ AB_SLOT_ACTIVE = 1
|
|||
AB_SLOT_INACTIVE = 0
|
||||
|
||||
|
||||
PART_ATT_PRIORITY_BIT = 48
|
||||
PART_ATT_ACTIVE_BIT = 50
|
||||
PART_ATT_MAX_RETRY_CNT_BIT = 51
|
||||
MAX_PRIORITY = 3
|
||||
PART_ATT_SUCCESS_BIT = 54
|
||||
PART_ATT_UNBOOTABLE_BIT = 55
|
||||
|
||||
PART_ATT_PRIORITY_VAL = 0x3 << PART_ATT_PRIORITY_BIT
|
||||
PART_ATT_ACTIVE_VAL = 0x1 << PART_ATT_ACTIVE_BIT
|
||||
PART_ATT_MAX_RETRY_COUNT_VAL = 0x7 << PART_ATT_MAX_RETRY_CNT_BIT
|
||||
PART_ATT_SUCCESSFUL_VAL = 0x1 << PART_ATT_SUCCESS_BIT
|
||||
PART_ATT_UNBOOTABLE_VAL = 0x1 << PART_ATT_UNBOOTABLE_BIT
|
||||
|
||||
|
||||
class gpt(metaclass=LogBase):
|
||||
class gpt_header:
|
||||
def __init__(self, data):
|
||||
|
@ -220,7 +238,7 @@ class gpt(metaclass=LogBase):
|
|||
self.name = sh.string(72)
|
||||
|
||||
def create(self):
|
||||
val = pack("16s16sQQQ72s", self.type, self.unique, self.first_lba, self.last_lba, self.flags, self.name)
|
||||
val = pack("<16s16sQQQ72s", self.type, self.unique, self.first_lba, self.last_lba, self.flags, self.name)
|
||||
return val
|
||||
|
||||
class efi_type(Enum):
|
||||
|
@ -343,7 +361,7 @@ class gpt(metaclass=LogBase):
|
|||
if self.part_entry_start_lba != 0:
|
||||
start = self.part_entry_start_lba
|
||||
else:
|
||||
start = self.header.part_entry_start_lba * sectorsize
|
||||
start = 2 * sectorsize # mbr + header + part_table
|
||||
|
||||
entrysize = self.header.part_entry_size
|
||||
self.partentries = {}
|
||||
|
@ -376,7 +394,7 @@ class gpt(metaclass=LogBase):
|
|||
pa.sector = partentry.first_lba
|
||||
pa.sectors = partentry.last_lba - partentry.first_lba + 1
|
||||
pa.flags = partentry.flags
|
||||
pa.entryoffset = start + (idx * entrysize)
|
||||
pa.entryoffset = (self.header.part_entry_start_lba * sectorsize) + (idx * entrysize)
|
||||
type = int(unpack("<I", partentry.type[0:0x4])[0])
|
||||
try:
|
||||
pa.type = self.efi_type(type).name
|
||||
|
@ -386,7 +404,7 @@ class gpt(metaclass=LogBase):
|
|||
if pa.type == "EFI_UNUSED":
|
||||
continue
|
||||
self.partentries[pa.name]=pa
|
||||
self.totalsectors = self.header.last_usable_lba + 34
|
||||
self.totalsectors = self.header.first_usable_lba + self.header.last_usable_lba
|
||||
return True
|
||||
|
||||
def print(self):
|
||||
|
@ -478,37 +496,11 @@ class gpt(metaclass=LogBase):
|
|||
res = self.print_gptfile(os.path.join("TestFiles", "gpt_sm8180x.bin"))
|
||||
assert res, "GPT Partition wasn't decoded properly"
|
||||
|
||||
def patch(self, data:bytes, partitionname="boot", active: bool = True):
|
||||
try:
|
||||
rf = BytesIO(data)
|
||||
for sectorsize in [512, 4096]:
|
||||
result = self.parse(data, sectorsize)
|
||||
if result:
|
||||
for rname in self.partentries:
|
||||
if partitionname.lower() == rname.lower():
|
||||
partition = self.partentries[rname]
|
||||
rf.seek(partition.entryoffset)
|
||||
sdata = rf.read(self.header.part_entry_size)
|
||||
partentry = self.gpt_partition(sdata)
|
||||
flags = partentry.flags
|
||||
if active:
|
||||
flags |= AB_PARTITION_ATTR_SLOT_ACTIVE << (AB_FLAG_OFFSET*8)
|
||||
else:
|
||||
flags |= AB_PARTITION_ATTR_UNBOOTABLE << (AB_FLAG_OFFSET*8)
|
||||
partentry.flags = flags
|
||||
pdata = partentry.create()
|
||||
return pdata, partition.entryoffset
|
||||
break
|
||||
return None, None
|
||||
except Exception as e:
|
||||
self.error(str(e))
|
||||
return None, None
|
||||
|
||||
def fix_gpt_crc(self, data):
|
||||
partentry_size = self.header.num_part_entries * self.header.part_entry_size
|
||||
partentry_offset = self.header.part_entry_start_lba * self.sectorsize
|
||||
partentry_offset = 2 * self.sectorsize
|
||||
partdata = data[partentry_offset:partentry_offset + partentry_size]
|
||||
headeroffset = self.header.current_lba * self.sectorsize
|
||||
headeroffset = self.sectorsize
|
||||
headerdata = bytearray(data[headeroffset:headeroffset + self.header.header_size])
|
||||
headerdata[0x58:0x58 + 4] = pack("<I", crc32(partdata))
|
||||
headerdata[0x10:0x10 + 4] = pack("<I", 0)
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2019
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import logging
|
||||
from binascii import hexlify
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2022
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import binascii
|
||||
import time
|
||||
import os
|
||||
|
@ -11,8 +15,12 @@ from struct import unpack, pack
|
|||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
sys.path.insert(0, parent_dir)
|
||||
from edlclient.Library.utils import read_object, print_progress, rmrf, LogBase
|
||||
from edlclient.Config.qualcomm_config import sochw, msmids, root_cert_hash
|
||||
try:
|
||||
from edlclient.Library.utils import read_object, print_progress, rmrf, LogBase
|
||||
from edlclient.Config.qualcomm_config import sochw, msmids, root_cert_hash
|
||||
except:
|
||||
from Library.utils import read_object, print_progress, rmrf, LogBase
|
||||
from Config.qualcomm_config import sochw, msmids, root_cert_hash
|
||||
|
||||
class loader_utils(metaclass=LogBase):
|
||||
def __init__(self, loglevel=logging.INFO):
|
||||
|
@ -43,7 +51,15 @@ class loader_utils(metaclass=LogBase):
|
|||
try:
|
||||
hwid = filename.split("_")[0].lower()
|
||||
msmid = hwid[:8]
|
||||
try:
|
||||
int(msmid,16)
|
||||
except:
|
||||
continue
|
||||
devid = hwid[8:]
|
||||
if devid == '':
|
||||
continue
|
||||
if len(filename.split("_"))<2:
|
||||
continue
|
||||
pkhash = filename.split("_")[1].lower()
|
||||
for msmid in self.convertmsmid(msmid):
|
||||
mhwid = msmid + devid
|
||||
|
@ -53,7 +69,7 @@ class loader_utils(metaclass=LogBase):
|
|||
if pkhash not in self.loaderdb[mhwid]:
|
||||
self.loaderdb[mhwid][pkhash] = fn
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self.debug(str(e))
|
||||
self.debug(f"Filename:{filename} => {str(e)}")
|
||||
continue
|
||||
return self.loaderdb
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
import os
|
||||
import pt64
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2019
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import ctypes
|
||||
from enum import Enum
|
||||
from edlclient.Config.qualcomm_config import secgen, secureboottbl
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import binascii
|
||||
import time
|
||||
import os
|
||||
|
@ -94,11 +98,11 @@ class sahara(metaclass=LogBase):
|
|||
self.error(str(e))
|
||||
return {}
|
||||
|
||||
def cmd_hello(self, mode, version_min=1, max_cmd_len=0): # CMD 0x1, RSP 0x2
|
||||
def cmd_hello(self, mode, version_min=1, max_cmd_len=0, version=2): # CMD 0x1, RSP 0x2
|
||||
cmd = cmd_t.SAHARA_HELLO_RSP
|
||||
length = 0x30
|
||||
version = SAHARA_VERSION
|
||||
responsedata = pack("<IIIIIIIIIIII", cmd, length, version, version_min, max_cmd_len, mode, 0, 0, 0, 0, 0, 0)
|
||||
#version = SAHARA_VERSION
|
||||
responsedata = pack("<IIIIIIIIIIII", cmd, length, version, version_min, max_cmd_len, mode, 1, 2, 3, 4, 5, 6)
|
||||
try:
|
||||
self.cdc.write(responsedata)
|
||||
return True
|
||||
|
@ -151,8 +155,8 @@ class sahara(metaclass=LogBase):
|
|||
self.error(str(e))
|
||||
return {"mode": "error"}
|
||||
|
||||
def enter_command_mode(self):
|
||||
if not self.cmd_hello(sahara_mode_t.SAHARA_MODE_COMMAND):
|
||||
def enter_command_mode(self, version=2):
|
||||
if not self.cmd_hello(sahara_mode_t.SAHARA_MODE_COMMAND, version=version):
|
||||
return False
|
||||
res = self.get_rsp()
|
||||
if "cmd" in res:
|
||||
|
@ -175,11 +179,9 @@ class sahara(metaclass=LogBase):
|
|||
|
||||
def cmdexec_get_msm_hwid(self):
|
||||
res = self.cmd_exec(exec_cmd_t.SAHARA_EXEC_CMD_MSM_HW_ID_READ)
|
||||
try:
|
||||
if res is not None:
|
||||
return int.from_bytes(res[:8],'little')
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
self.debug(str(e))
|
||||
return None
|
||||
return None
|
||||
|
||||
def cmdexec_get_pkhash(self):
|
||||
try:
|
||||
|
@ -208,106 +210,111 @@ class sahara(metaclass=LogBase):
|
|||
res = self.cmd_exec(exec_cmd_t.SAHARA_EXEC_CMD_READ_DEBUG_DATA)
|
||||
return res
|
||||
|
||||
def cmd_info(self):
|
||||
if self.enter_command_mode():
|
||||
def cmd_info(self, version):
|
||||
if self.enter_command_mode(version=version):
|
||||
self.serial = self.cmdexec_get_serial_num()
|
||||
self.serials = "{:08x}".format(self.serial)
|
||||
# if self.version>=2.4:
|
||||
# self.sblversion = "{:08x}".format(self.cmdexec_get_sbl_version())
|
||||
if self.programmer == "":
|
||||
if version < 3:
|
||||
self.hwid = self.cmdexec_get_msm_hwid()
|
||||
self.pkhash = self.cmdexec_get_pkhash()
|
||||
|
||||
if self.hwid is not None:
|
||||
self.hwidstr = "{:016x}".format(self.hwid)
|
||||
self.msm_id = int(self.hwidstr[2:8], 16)
|
||||
self.oem_id = int(self.hwidstr[-8:-4], 16)
|
||||
self.model_id = int(self.hwidstr[-4:], 16)
|
||||
self.oem_str = "{:04x}".format(self.oem_id)
|
||||
self.model_id = "{:04x}".format(self.model_id)
|
||||
self.msm_str = "{:08x}".format(self.msm_id)
|
||||
if self.msm_id in msmids:
|
||||
cpustr = f"CPU detected: \"{msmids[self.msm_id]}\"\n"
|
||||
else:
|
||||
cpustr = "Unknown CPU, please send log as issue to https://github.com/bkerler/edl\n"
|
||||
"""
|
||||
if self.version >= 2.4:
|
||||
self.info(f"\n------------------------\n" +
|
||||
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
|
||||
f"OEM_ID:0x{self.oem_str}," +
|
||||
f"MODEL_ID:0x{self.model_id})\n" +
|
||||
f"PK_HASH: 0x{self.pkhash}\n" +
|
||||
f"Serial: 0x{self.serials}\n" +
|
||||
f"SBL Version: 0x{self.sblversion}\n")
|
||||
else:
|
||||
"""
|
||||
self.info(f"\n------------------------\n" +
|
||||
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
|
||||
f"OEM_ID:0x{self.oem_str}," +
|
||||
f"MODEL_ID:0x{self.model_id})\n" +
|
||||
cpustr +
|
||||
f"PK_HASH: 0x{self.pkhash}\n" +
|
||||
f"Serial: 0x{self.serials}\n")
|
||||
if self.programmer == "":
|
||||
if self.hwidstr in self.loaderdb:
|
||||
mt = self.loaderdb[self.hwidstr]
|
||||
unfused = False
|
||||
for rootcert in root_cert_hash:
|
||||
if self.pkhash[0:16] in root_cert_hash[rootcert]:
|
||||
unfused = True
|
||||
break
|
||||
if unfused:
|
||||
self.info("Possibly unfused device detected, so any loader should be fine...")
|
||||
if self.pkhash[0:16] in mt:
|
||||
self.programmer = mt[self.pkhash[0:16]]
|
||||
self.info(f"Trying loader: {self.programmer}")
|
||||
# if self.version>=2.4:
|
||||
# self.sblversion = "{:08x}".format(self.cmdexec_get_sbl_version())
|
||||
if self.hwid is not None:
|
||||
self.hwidstr = "{:016x}".format(self.hwid)
|
||||
self.msm_id = int(self.hwidstr[2:8], 16)
|
||||
self.oem_id = int(self.hwidstr[-8:-4], 16)
|
||||
self.model_id = int(self.hwidstr[-4:], 16)
|
||||
self.oem_str = "{:04x}".format(self.oem_id)
|
||||
self.model_id = "{:04x}".format(self.model_id)
|
||||
self.msm_str = "{:08x}".format(self.msm_id)
|
||||
if self.msm_id in msmids:
|
||||
cpustr = f"CPU detected: \"{msmids[self.msm_id]}\"\n"
|
||||
else:
|
||||
cpustr = "Unknown CPU, please send log as issue to https://github.com/bkerler/edl\n"
|
||||
"""
|
||||
if self.version >= 2.4:
|
||||
self.info(f"\nVersion {hex(version)}\n------------------------\n" +
|
||||
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
|
||||
f"OEM_ID:0x{self.oem_str}," +
|
||||
f"MODEL_ID:0x{self.model_id})\n" +
|
||||
f"PK_HASH: 0x{self.pkhash}\n" +
|
||||
f"Serial: 0x{self.serials}\n" +
|
||||
f"SBL Version: 0x{self.sblversion}\n")
|
||||
else:
|
||||
"""
|
||||
self.info(f"\nVersion {hex(version)}\n------------------------\n" +
|
||||
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
|
||||
f"OEM_ID:0x{self.oem_str}," +
|
||||
f"MODEL_ID:0x{self.model_id})\n" +
|
||||
cpustr +
|
||||
f"PK_HASH: 0x{self.pkhash}\n" +
|
||||
f"Serial: 0x{self.serials}\n")
|
||||
if self.programmer == "":
|
||||
if self.hwidstr in self.loaderdb:
|
||||
mt = self.loaderdb[self.hwidstr]
|
||||
unfused = False
|
||||
for rootcert in root_cert_hash:
|
||||
if self.pkhash[0:16] in root_cert_hash[rootcert]:
|
||||
unfused = True
|
||||
break
|
||||
if unfused:
|
||||
self.info("Possibly unfused device detected, so any loader should be fine...")
|
||||
if self.pkhash[0:16] in mt:
|
||||
self.programmer = mt[self.pkhash[0:16]]
|
||||
self.info(f"Trying loader: {self.programmer}")
|
||||
else:
|
||||
for loader in mt:
|
||||
self.programmer = mt[loader]
|
||||
self.info(f"Possible loader available: {self.programmer}")
|
||||
for loader in mt:
|
||||
self.programmer = mt[loader]
|
||||
self.info(f"Trying loader: {self.programmer}")
|
||||
break
|
||||
elif self.pkhash[0:16] in mt:
|
||||
self.programmer = self.loaderdb[self.hwidstr][self.pkhash[0:16]]
|
||||
self.info(f"Detected loader: {self.programmer}")
|
||||
else:
|
||||
for loader in mt:
|
||||
self.programmer = mt[loader]
|
||||
self.info(f"Possible loader available: {self.programmer}")
|
||||
for loader in mt:
|
||||
self.programmer = mt[loader]
|
||||
for loader in self.loaderdb[self.hwidstr]:
|
||||
self.programmer = self.loaderdb[self.hwidstr][loader]
|
||||
self.info(f"Trying loader: {self.programmer}")
|
||||
break
|
||||
elif self.pkhash[0:16] in mt:
|
||||
self.programmer = self.loaderdb[self.hwidstr][self.pkhash[0:16]]
|
||||
self.info(f"Detected loader: {self.programmer}")
|
||||
else:
|
||||
for loader in self.loaderdb[self.hwidstr]:
|
||||
self.programmer = self.loaderdb[self.hwidstr][loader]
|
||||
self.info(f"Trying loader: {self.programmer}")
|
||||
break
|
||||
# print("Couldn't find a loader for given hwid and pkhash :(")
|
||||
# exit(0)
|
||||
elif self.hwidstr is not None and self.pkhash is not None:
|
||||
msmid = self.hwidstr[:8]
|
||||
found = False
|
||||
for hwidstr in self.loaderdb:
|
||||
if msmid == hwidstr[:8]:
|
||||
if self.pkhash[0:16] in self.loaderdb[hwidstr]:
|
||||
self.programmer = self.loaderdb[hwidstr][self.pkhash[0:16]]
|
||||
self.info(f"Found loader: {self.programmer}")
|
||||
self.cmd_modeswitch(sahara_mode_t.SAHARA_MODE_COMMAND)
|
||||
return True
|
||||
# print("Couldn't find a loader for given hwid and pkhash :(")
|
||||
# exit(0)
|
||||
elif self.hwidstr is not None and self.pkhash is not None:
|
||||
msmid = self.hwidstr[:8]
|
||||
found = False
|
||||
for hwidstr in self.loaderdb:
|
||||
if msmid == hwidstr[:8]:
|
||||
if self.pkhash[0:16] in self.loaderdb[hwidstr]:
|
||||
self.programmer = self.loaderdb[hwidstr][self.pkhash[0:16]]
|
||||
self.info(f"Found loader: {self.programmer}")
|
||||
self.cmd_modeswitch(sahara_mode_t.SAHARA_MODE_COMMAND)
|
||||
return True
|
||||
else:
|
||||
if self.pkhash[0:16] in self.loaderdb[hwidstr]:
|
||||
self.programmer = self.loaderdb[hwidstr][self.pkhash[0:16]]
|
||||
self.info(f"Found possible loader: {self.programmer}")
|
||||
found = True
|
||||
if found:
|
||||
self.cmd_modeswitch(sahara_mode_t.SAHARA_MODE_COMMAND)
|
||||
return True
|
||||
else:
|
||||
if self.pkhash[0:16] in self.loaderdb[hwidstr]:
|
||||
self.programmer = self.loaderdb[hwidstr][self.pkhash[0:16]]
|
||||
self.info(f"Found possible loader: {self.programmer}")
|
||||
found = True
|
||||
if found:
|
||||
self.cmd_modeswitch(sahara_mode_t.SAHARA_MODE_COMMAND)
|
||||
return True
|
||||
self.error(
|
||||
f"Couldn't find a loader for given hwid and pkhash ({self.hwidstr}_{self.pkhash[0:16]}" +
|
||||
"_[FHPRG/ENPRG].bin) :(")
|
||||
return False
|
||||
else:
|
||||
self.error(
|
||||
f"Couldn't find a loader for given hwid and pkhash ({self.hwidstr}_{self.pkhash[0:16]}" +
|
||||
"_[FHPRG/ENPRG].bin) :(")
|
||||
self.error(f"Couldn't find a suitable loader :(")
|
||||
return False
|
||||
else:
|
||||
self.info(f"\nVersion {hex(version)}\n------------------------\n" +
|
||||
f"Serial: 0x{self.serials}\n")
|
||||
if self.programmer=="":
|
||||
self.error("No autodetection of loader possible with sahara version 3 and above :( Aborting.")
|
||||
return False
|
||||
else:
|
||||
self.error(f"Couldn't find a suitable loader :(")
|
||||
return False
|
||||
|
||||
self.cmd_modeswitch(sahara_mode_t.SAHARA_MODE_COMMAND)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def streaminginfo(self):
|
||||
|
@ -430,8 +437,8 @@ class sahara(metaclass=LogBase):
|
|||
self.cmd_reset()
|
||||
return True
|
||||
|
||||
def debug_mode(self, dump_partitions=None):
|
||||
if not self.cmd_hello(sahara_mode_t.SAHARA_MODE_MEMORY_DEBUG):
|
||||
def debug_mode(self, dump_partitions=None, version=2):
|
||||
if not self.cmd_hello(sahara_mode_t.SAHARA_MODE_MEMORY_DEBUG, version=version):
|
||||
return False
|
||||
if os.path.exists("memory"):
|
||||
rmrf("memory")
|
||||
|
@ -479,7 +486,7 @@ class sahara(metaclass=LogBase):
|
|||
num_entries = len(ptbldata) // pktsize
|
||||
partitions = []
|
||||
for id_entry in range(0, num_entries):
|
||||
pd = self.parttbl(ptbldata[id_entry * pktsize:(id_entry * pktsize) + pktsize])
|
||||
pd = self.ch.parttbl(ptbldata[id_entry * pktsize:(id_entry * pktsize) + pktsize])
|
||||
desc = pd.desc.replace(b"\x00", b"").decode('utf-8')
|
||||
filename = pd.filename.replace(b"\x00", b"").decode('utf-8')
|
||||
if dump_partitions and filename not in dump_partitions:
|
||||
|
@ -499,7 +506,7 @@ class sahara(metaclass=LogBase):
|
|||
return False
|
||||
return False
|
||||
|
||||
def upload_loader(self):
|
||||
def upload_loader(self, version):
|
||||
if self.programmer == "":
|
||||
return ""
|
||||
try:
|
||||
|
@ -510,14 +517,14 @@ class sahara(metaclass=LogBase):
|
|||
self.error(str(e))
|
||||
sys.exit()
|
||||
|
||||
if not self.cmd_hello(sahara_mode_t.SAHARA_MODE_IMAGE_TX_PENDING):
|
||||
if not self.cmd_hello(sahara_mode_t.SAHARA_MODE_IMAGE_TX_PENDING, version=version):
|
||||
return ""
|
||||
|
||||
try:
|
||||
datalen = len(programmer)
|
||||
done = False
|
||||
loop = 0
|
||||
while datalen > 0 or done:
|
||||
while datalen >= 0 or done:
|
||||
resp = self.get_rsp()
|
||||
if "cmd" in resp:
|
||||
cmd = resp["cmd"]
|
||||
|
@ -582,6 +589,7 @@ class sahara(metaclass=LogBase):
|
|||
except Exception as e: # pylint: disable=broad-except
|
||||
self.error("Unexpected error on uploading, maybe signature of loader wasn't accepted ?\n" + str(e))
|
||||
return ""
|
||||
return self.mode
|
||||
|
||||
def cmd_modeswitch(self, mode):
|
||||
data = pack("<III", cmd_t.SAHARA_SWITCH_MODE, 0xC, mode)
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
|
||||
from edlclient.Library.utils import structhelper_io
|
||||
from io import BytesIO
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
|
@ -14,6 +18,9 @@ sys.path.insert(0, parent_dir)
|
|||
from edlclient.Library.utils import LogBase, print_progress
|
||||
|
||||
|
||||
MAX_STORE_SIZE = 1024 * 1024 * 1024 * 2 # 2 GBs
|
||||
|
||||
|
||||
class QCSparse(metaclass=LogBase):
|
||||
def __init__(self, filename, loglevel):
|
||||
self.rf = open(filename, 'rb')
|
||||
|
@ -32,6 +39,8 @@ class QCSparse(metaclass=LogBase):
|
|||
self.total_chunks = None
|
||||
self.image_checksum = None
|
||||
|
||||
self.tmp_offset = 0
|
||||
|
||||
self.info = self.__logger.info
|
||||
self.debug = self.__logger.debug
|
||||
self.error = self.__logger.error
|
||||
|
@ -77,20 +86,22 @@ class QCSparse(metaclass=LogBase):
|
|||
chunk_sz = header[2]
|
||||
total_sz = header[3]
|
||||
data_sz = total_sz - 12
|
||||
|
||||
if chunk_type == 0xCAC1:
|
||||
if data_sz != (chunk_sz * self.blk_sz):
|
||||
self.error(
|
||||
"Raw chunk input size (%u) does not match output size (%u)" % (data_sz, chunk_sz * self.blk_sz))
|
||||
return -1
|
||||
else:
|
||||
self.rf.seek(self.rf.tell() + chunk_sz * self.blk_sz)
|
||||
self.rf.seek(self.rf.tell() + data_sz)
|
||||
return chunk_sz * self.blk_sz
|
||||
elif chunk_type == 0xCAC2:
|
||||
if data_sz != 4:
|
||||
self.error("Fill chunk should have 4 bytes of fill, but this has %u" % data_sz)
|
||||
return -1
|
||||
else:
|
||||
return chunk_sz * self.blk_sz // 4
|
||||
self.rf.seek(self.rf.tell() + data_sz)
|
||||
return chunk_sz * self.blk_sz
|
||||
elif chunk_type == 0xCAC3:
|
||||
return chunk_sz * self.blk_sz
|
||||
elif chunk_type == 0xCAC4:
|
||||
|
@ -98,7 +109,7 @@ class QCSparse(metaclass=LogBase):
|
|||
self.error("CRC32 chunk should have 4 bytes of CRC, but this has %u" % data_sz)
|
||||
return -1
|
||||
else:
|
||||
self.rf.seek(self.rf.tell() + 4)
|
||||
self.rf.seek(self.rf.tell() + data_sz)
|
||||
return 0
|
||||
else:
|
||||
self.debug("Unknown chunk type 0x%04X" % chunk_type)
|
||||
|
@ -166,17 +177,20 @@ class QCSparse(metaclass=LogBase):
|
|||
return length
|
||||
|
||||
def read(self, length=None):
|
||||
if self.tmp_offset >= MAX_STORE_SIZE:
|
||||
self.tmpdata = self.tmpdata[self.tmp_offset:]
|
||||
self.tmp_offset = 0
|
||||
if length is None:
|
||||
return self.unsparse()
|
||||
if length <= len(self.tmpdata):
|
||||
tdata = self.tmpdata[:length]
|
||||
self.tmpdata = self.tmpdata[length:]
|
||||
if (self.tmp_offset + length) <= len(self.tmpdata):
|
||||
tdata = self.tmpdata[self.tmp_offset : self.tmp_offset + length]
|
||||
self.tmp_offset += length
|
||||
return tdata
|
||||
while len(self.tmpdata) < length:
|
||||
while (self.tmp_offset + length) > len(self.tmpdata):
|
||||
self.tmpdata.extend(self.unsparse())
|
||||
if length <= len(self.tmpdata):
|
||||
tdata = self.tmpdata[:length]
|
||||
self.tmpdata = self.tmpdata[length:]
|
||||
if (self.tmp_offset + length) <= len(self.tmpdata):
|
||||
tdata = self.tmpdata[self.tmp_offset : self.tmp_offset + length]
|
||||
self.tmp_offset += length
|
||||
return tdata
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
from struct import pack
|
||||
from binascii import unhexlify
|
||||
from edlclient.Library.utils import *
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
class open_mode_type:
|
||||
OPEN_MODE_NONE = 0x00 # Not opened yet
|
||||
OPEN_BOOTLOADER = 0x01 # Bootloader Image
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import sys
|
||||
import logging
|
||||
import logging.config
|
||||
|
@ -145,7 +149,7 @@ class progress:
|
|||
suffix=prefix + ' (Sector 0x%X of 0x%X) %0.2f MB/s' %
|
||||
(pos // self.pagesize,
|
||||
total // self.pagesize,
|
||||
0), bar_length=50)
|
||||
0), bar_length=10)
|
||||
|
||||
if prog > self.prog or prog==100.0:
|
||||
if display:
|
||||
|
@ -179,7 +183,7 @@ class progress:
|
|||
suffix=prefix + f' (Sector 0x%X of 0x%X, {hinfo}) %0.2f MB/s' %
|
||||
(pos // self.pagesize,
|
||||
total // self.pagesize,
|
||||
throughput), bar_length=50)
|
||||
throughput), bar_length=10)
|
||||
self.prog = prog
|
||||
self.progpos = pos
|
||||
self.progtime = t0
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2021
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
|
||||
|
|
1
edlclient/Tools/Config
Symbolic link
1
edlclient/Tools/Config
Symbolic link
|
@ -0,0 +1 @@
|
|||
../Config
|
1
edlclient/Tools/Library
Symbolic link
1
edlclient/Tools/Library
Symbolic link
|
@ -0,0 +1 @@
|
|||
../Library
|
|
@ -1,5 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
# Beagle to EDL Loader (c) B.Kerler 2021
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
# Beagle to EDL Loader
|
||||
|
||||
import os,sys
|
||||
from struct import unpack
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2020 under MIT license
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
# If you want to use in a commercial product, ask me before integrating it
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import time
|
||||
import serial
|
||||
import serial.tools.list_ports
|
||||
import argparse
|
||||
import requests
|
||||
from telnetlib import Telnet
|
||||
from Exscript.protocols.telnetlib import Telnet
|
||||
import usb.core
|
||||
from enum import Enum
|
||||
|
||||
|
@ -53,7 +55,7 @@ class connection(metaclass=LogBase):
|
|||
port = self.detect(port)
|
||||
if port == "":
|
||||
try:
|
||||
self.tn = Telnet("192.168.1.1", 5510, 5)
|
||||
self.tn = Telnet("192.168.1.1", 5510)
|
||||
self.connected = True
|
||||
except:
|
||||
self.connected = False
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2020-2021 under MIT license
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
# If you want to use in a commercial product, ask me before integrating it
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import time
|
||||
from telnetlib import Telnet
|
||||
from Exscript.protocols.telnetlib import Telnet
|
||||
import serial
|
||||
import serial.tools.list_ports
|
||||
import argparse
|
||||
|
@ -18,7 +20,8 @@ except ImportError as e:
|
|||
|
||||
import usb.core
|
||||
from enum import Enum
|
||||
import crypt
|
||||
|
||||
from passlib.hash import md5_crypt
|
||||
|
||||
try:
|
||||
from edlclient.Tools.sierrakeygen import SierraKeygen
|
||||
|
@ -30,15 +33,85 @@ except ImportError:
|
|||
sys.path.insert(0, parent_dir)
|
||||
from sierrakeygen import SierraKeygen
|
||||
|
||||
try:
|
||||
from edlclient.Library.utils import LogBase
|
||||
except Exception as e:
|
||||
import os, sys, inspect
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import colorama
|
||||
|
||||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
sys.path.insert(0, parent_dir)
|
||||
from edlclient.Library.utils import LogBase
|
||||
|
||||
itoa64 = bytearray(b"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
|
||||
def _crypt_to64(s, v, n):
|
||||
out=bytearray()
|
||||
while --n >= 0:
|
||||
out.append(itoa64[v&0x3f])
|
||||
v >>= 6
|
||||
|
||||
|
||||
class ColorFormatter(logging.Formatter):
|
||||
LOG_COLORS = {
|
||||
logging.ERROR: colorama.Fore.RED,
|
||||
logging.DEBUG: colorama.Fore.LIGHTMAGENTA_EX,
|
||||
logging.WARNING: colorama.Fore.YELLOW,
|
||||
}
|
||||
|
||||
def format(self, record, *args, **kwargs):
|
||||
# if the corresponding logger has children, they may receive modified
|
||||
# record, so we want to keep it intact
|
||||
new_record = copy.copy(record)
|
||||
if new_record.levelno in self.LOG_COLORS:
|
||||
pad = ""
|
||||
if new_record.name != "root":
|
||||
print(new_record.name)
|
||||
pad = "[LIB]: "
|
||||
# we want levelname to be in different color, so let's modify it
|
||||
new_record.msg = "{pad}{color_begin}{msg}{color_end}".format(
|
||||
pad=pad,
|
||||
msg=new_record.msg,
|
||||
color_begin=self.LOG_COLORS[new_record.levelno],
|
||||
color_end=colorama.Style.RESET_ALL,
|
||||
)
|
||||
# now we can let standart formatting take care of the rest
|
||||
return super(ColorFormatter, self).format(new_record, *args, **kwargs)
|
||||
|
||||
|
||||
class LogBase(type):
|
||||
debuglevel = logging.root.level
|
||||
|
||||
def __init__(cls, *args):
|
||||
super().__init__(*args)
|
||||
logger_attribute_name = '_' + cls.__name__ + '__logger'
|
||||
logger_debuglevel_name = '_' + cls.__name__ + '__debuglevel'
|
||||
logger_name = '.'.join([c.__name__ for c in cls.mro()[-2::-1]])
|
||||
LOG_CONFIG = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"root": {
|
||||
"()": ColorFormatter,
|
||||
"format": "%(name)s - %(message)s",
|
||||
}
|
||||
},
|
||||
"handlers": {
|
||||
"root": {
|
||||
# "level": cls.__logger.level,
|
||||
"formatter": "root",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stdout",
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"": {
|
||||
"handlers": ["root"],
|
||||
# "level": cls.debuglevel,
|
||||
"propagate": False
|
||||
}
|
||||
},
|
||||
}
|
||||
logging.config.dictConfig(LOG_CONFIG)
|
||||
logger = logging.getLogger(logger_name)
|
||||
|
||||
setattr(cls, logger_attribute_name, logger)
|
||||
setattr(cls, logger_debuglevel_name, cls.debuglevel)
|
||||
|
||||
|
||||
class vendor(Enum):
|
||||
|
@ -110,24 +183,36 @@ class connection:
|
|||
0x04E8: ["Samsung", -1]
|
||||
}
|
||||
mode = "Unknown"
|
||||
for device in self.detectusbdevices():
|
||||
if device.vid == vendor.zte.value:
|
||||
if device.pid == 0x0016:
|
||||
print(f"Detected a {atvendortable[device.vid][0]} device with pid {hex(device.pid)} in AT mode")
|
||||
mode = "AT"
|
||||
break
|
||||
elif device.pid == 0x1403:
|
||||
print(f"Detected a {atvendortable[device.vid][0]} device with pid {hex(device.pid)} in Web mode")
|
||||
mode = "Web"
|
||||
self.ZTE_Web()
|
||||
break
|
||||
elif device.vid == vendor.netgear.value:
|
||||
try:
|
||||
# vid 0846, netgear mr1100, mr5100
|
||||
self.tn = Telnet("192.168.1.1", 5510, 5)
|
||||
self.connected = True
|
||||
except:
|
||||
self.connected = False
|
||||
try:
|
||||
for device in self.detectusbdevices():
|
||||
if device.vid == vendor.zte.value:
|
||||
if device.pid == 0x0016:
|
||||
print(f"Detected a {atvendortable[device.vid][0]} device with pid {hex(device.pid)} in AT mode")
|
||||
mode = "AT"
|
||||
break
|
||||
elif device.pid == 0x1403:
|
||||
print(f"Detected a {atvendortable[device.vid][0]} device with pid {hex(device.pid)} in Web mode")
|
||||
mode = "Web"
|
||||
self.ZTE_Web()
|
||||
break
|
||||
elif device.vid == vendor.netgear.value:
|
||||
try:
|
||||
# vid 0846, netgear mr1100, mr5100
|
||||
self.tn = Telnet("192.168.1.1", 5510)
|
||||
self.connected = True
|
||||
except:
|
||||
self.connected = False
|
||||
except:
|
||||
print("No libusb driver found. Trying Telnet instead.")
|
||||
try:
|
||||
# vid 0846, netgear mr1100, mr5100
|
||||
self.tn = Telnet("192.168.1.1", 5510)
|
||||
self.connected = True
|
||||
except:
|
||||
self.connected = False
|
||||
print("Failed to connect to Telnet.")
|
||||
return
|
||||
pass
|
||||
if mode in ["AT", "Unknown"]:
|
||||
for port in self.getserialports():
|
||||
if port.vid in atvendortable:
|
||||
|
@ -168,8 +253,8 @@ class connection:
|
|||
data = ""
|
||||
while True:
|
||||
tmp = self.tn.read_eager()
|
||||
if tmp != b"":
|
||||
data += tmp.strip().decode('utf-8')
|
||||
if tmp != "":
|
||||
data += tmp.strip()
|
||||
else:
|
||||
break
|
||||
if "ERROR" in data:
|
||||
|
@ -322,7 +407,8 @@ class adbtools(metaclass=LogBase):
|
|||
|
||||
def SierraWireless(self, cn, info, enable):
|
||||
print("Sending at switch command")
|
||||
kg = SierraKeygen(cn)
|
||||
kg = SierraKeygen(cn=cn,devicegeneration=None)
|
||||
kg.detectdevicegeneration()
|
||||
if kg.openlock():
|
||||
if enable:
|
||||
if cn.send('AT!CUSTOM="ADBENABLE",1\r') != -1:
|
||||
|
@ -330,7 +416,7 @@ class adbtools(metaclass=LogBase):
|
|||
kg.openlock()
|
||||
if cn.send('AT!CUSTOM="TELNETENABLE",1\r') != -1:
|
||||
time.sleep(5)
|
||||
tn = Telnet("192.168.1.1", 23, 15)
|
||||
tn = Telnet("192.168.1.1", 23)
|
||||
tn.write(b"adbd &\r\n")
|
||||
info = tn.read_eager()
|
||||
print(info)
|
||||
|
@ -470,12 +556,13 @@ class adbtools(metaclass=LogBase):
|
|||
return False
|
||||
|
||||
def Quectel(self, cn, enable: bool = True):
|
||||
salt = cn.send("AT+QADBKEY?\r")
|
||||
if salt != -1:
|
||||
if len(salt) > 1:
|
||||
salt = salt[1]
|
||||
code = crypt.crypt("SH_adb_quectel", "$1$" + salt)
|
||||
code = code[12:]
|
||||
sn = cn.send("AT+QADBKEY?\r")
|
||||
if sn != -1:
|
||||
if len(sn) > 1:
|
||||
sn = sn[1]
|
||||
cc = md5_crypt(salt="")
|
||||
code = cc.encrypt("SH_adb_quectel", salt=str(sn))
|
||||
code = code[12:28]
|
||||
cn.send("AT+QADBKEY=\"%s\"\r" % code)
|
||||
if enable:
|
||||
if cn.send("AT+QCFG=\"usbcfg\",0x2C7C,0x125,1,1,1,1,1,1,0\r") == -1:
|
||||
|
@ -491,7 +578,7 @@ class adbtools(metaclass=LogBase):
|
|||
|
||||
def main():
|
||||
version = "1.2"
|
||||
info = '\nModem Gimme-ADB ' + version + ' (c) B. Kerler 2020-2021\n-------------------------------------------\n'
|
||||
info = '\nModem Gimme-ADB ' + version + ' (c) B. Kerler 2020-2023\n-------------------------------------------\n'
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description=info)
|
||||
parser.add_argument(
|
||||
'-mode', help='Mode: enable or disable',
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import os
|
||||
import sys
|
||||
from os import walk
|
||||
|
@ -7,12 +13,10 @@ from struct import unpack, pack
|
|||
from shutil import copyfile
|
||||
import os, sys, inspect
|
||||
from io import BytesIO
|
||||
from Library.utils import elf
|
||||
from Library.loader_db import loader_utils
|
||||
from Config.qualcomm_config import vendor
|
||||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(os.path.dirname(current_dir))
|
||||
sys.path.insert(0, parent_dir)
|
||||
from edlclient.Library.utils import elf
|
||||
from edlclient.Library.loader_db import loader_utils
|
||||
from edlclient.Config.qualcomm_config import vendor
|
||||
|
||||
lu=loader_utils()
|
||||
|
||||
|
@ -102,9 +106,54 @@ def extract_hdr(memsection, version, sign_info, mem_section, code_size, signatur
|
|||
len1 = unpack(">H", mem_section[signatureoffset + 2:signatureoffset + 4])[0] + 4
|
||||
casignature2offset = signatureoffset + len1
|
||||
len2 = unpack(">H", mem_section[casignature2offset + 2:casignature2offset + 4])[0] + 4
|
||||
rootsignature3offset = casignature2offset + len2
|
||||
len3 = unpack(">H", mem_section[rootsignature3offset + 2:rootsignature3offset + 4])[0] + 4
|
||||
sign_info.pk_hash = hashlib.sha384(mem_section[rootsignature3offset:rootsignature3offset + len3]).hexdigest()
|
||||
rootsignature3 = mem_section[(casignature2offset + len2):(casignature2offset + len2) + 999999999].split(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff')[0]
|
||||
|
||||
idx = signatureoffset
|
||||
signature = {}
|
||||
while idx != -1:
|
||||
if idx >= len(mem_section):
|
||||
break
|
||||
idx = mem_section.find('\x04\x0B'.encode(), idx)
|
||||
if idx == -1:
|
||||
break
|
||||
length = mem_section[idx + 3]
|
||||
if length > 60:
|
||||
idx += 1
|
||||
continue
|
||||
try:
|
||||
text = mem_section[idx + 4:idx + 4 + length].decode().split(' ')
|
||||
signature[text[2]] = text[1]
|
||||
except:
|
||||
text = ""
|
||||
idx += 1
|
||||
idx = mem_section.find('QC_IMAGE_VERSION_STRING='.encode(), 0)
|
||||
if idx != -1:
|
||||
sign_info.qc_version = grabtext(mem_section[idx + len("QC_IMAGE_VERSION_STRING="):])
|
||||
idx = mem_section.find('OEM_IMAGE_VERSION_STRING='.encode(), 0)
|
||||
if idx != -1:
|
||||
sign_info.oem_version = grabtext(mem_section[idx + len("OEM_IMAGE_VERSION_STRING="):])
|
||||
idx = mem_section.find('IMAGE_VARIANT_STRING='.encode(), 0)
|
||||
if idx != -1:
|
||||
sign_info.image_variant = grabtext(mem_section[idx + len("IMAGE_VARIANT_STRING="):])
|
||||
if "MODEL_ID" in signature:
|
||||
sign_info.model_id = signature["MODEL_ID"]
|
||||
if "OEM_ID" in signature:
|
||||
sign_info.oem_id = signature["OEM_ID"]
|
||||
if "HW_ID" in signature:
|
||||
sign_info.hw_id = signature["HW_ID"]
|
||||
if "SW_ID" in signature:
|
||||
sign_info.sw_id = signature["SW_ID"]
|
||||
if "SW_SIZE" in signature:
|
||||
sign_info.sw_size = signature["SW_SIZE"]
|
||||
if "SHA256" in signature:
|
||||
sign_info.pk_hash = hashlib.sha256(rootsignature3).hexdigest()
|
||||
elif "SHA384" in signature:
|
||||
sign_info.pk_hash = hashlib.sha384(
|
||||
rootsignature3).hexdigest()
|
||||
else:
|
||||
sign_info.pk_hash = hashlib.sha384(
|
||||
rootsignature3).hexdigest()
|
||||
|
||||
except:
|
||||
return None
|
||||
return sign_info
|
||||
|
@ -122,9 +171,8 @@ def extract_old_hdr(signatureoffset, sign_info, mem_section, code_size, signatur
|
|||
len1 = unpack(">H", mem_section[signatureoffset + 2:signatureoffset + 4])[0] + 4
|
||||
casignature2offset = signatureoffset + len1
|
||||
len2 = unpack(">H", mem_section[casignature2offset + 2:casignature2offset + 4])[0] + 4
|
||||
rootsignature3offset = casignature2offset + len2
|
||||
len3 = unpack(">H", mem_section[rootsignature3offset + 2:rootsignature3offset + 4])[0] + 4
|
||||
sign_info.pk_hash = hashlib.sha256(mem_section[rootsignature3offset:rootsignature3offset + len3]).hexdigest()
|
||||
rootsignature3 = mem_section[(casignature2offset + len2):(casignature2offset + len2) + 999999999].split(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff')[0]
|
||||
sign_info.pk_hash = hashlib.sha256(rootsignature3).hexdigest()
|
||||
idx = signatureoffset
|
||||
|
||||
while idx != -1:
|
||||
|
@ -162,12 +210,24 @@ def extract_old_hdr(signatureoffset, sign_info, mem_section, code_size, signatur
|
|||
sign_info.sw_id = signature["SW_ID"]
|
||||
if "SW_SIZE" in signature:
|
||||
sign_info.sw_size = signature["SW_SIZE"]
|
||||
if "SHA256" in signature:
|
||||
sign_info.pk_hash = hashlib.sha256(rootsignature3).hexdigest()
|
||||
elif "SHA384" in signature:
|
||||
sign_info.pk_hash = hashlib.sha384(
|
||||
rootsignature3).hexdigest()
|
||||
return sign_info
|
||||
|
||||
|
||||
def init_loader_db():
|
||||
loaderdb = {}
|
||||
for (dirpath, dirnames, filenames) in os.walk(os.path.join(current_dir,"..","..","Loaders")):
|
||||
loaders=os.path.join(current_dir,"..","..","Loaders")
|
||||
if not os.path.exists(loaders):
|
||||
loaders = os.path.join(current_dir, "Loaders")
|
||||
if not os.path.exists(loaders):
|
||||
print("Couldn't find Loaders directory")
|
||||
return loaderdb
|
||||
|
||||
for (dirpath, dirnames, filenames) in os.walk(loaders):
|
||||
for filename in filenames:
|
||||
file_name = os.path.join(dirpath, filename)
|
||||
found = False
|
||||
|
@ -311,6 +371,7 @@ def main(argv):
|
|||
print("%s has no signature." % filename)
|
||||
copyfile(filename,
|
||||
os.path.join(outputdir, "Unknown", filename[filename.rfind("/") + 1:].lower()))
|
||||
elfpos += 0x30
|
||||
continue
|
||||
if version < 6: # MSM,MDM
|
||||
signatureoffset = memsection.file_start_addr + 0x28 + code_size + signature_size
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Licensed under MIT License, (c) B. Kerler 2018-2021
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2018-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import inspect
|
||||
import argparse
|
||||
import json
|
||||
|
@ -16,12 +19,18 @@ import os, sys
|
|||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(os.path.dirname(current_dir))
|
||||
sys.path.insert(0, parent_dir)
|
||||
|
||||
from edlclient.Library.utils import print_progress, read_object, write_object, LogBase
|
||||
from edlclient.Library.Connection.usblib import usb_class
|
||||
from edlclient.Library.Connection.seriallib import serial_class
|
||||
from edlclient.Library.hdlc import hdlc
|
||||
from edlclient.Config.usb_ids import default_diag_vid_pid
|
||||
try:
|
||||
from Library.utils import print_progress, read_object, write_object, LogBase
|
||||
from Library.Connection.usblib import usb_class
|
||||
from Library.Connection.seriallib import serial_class
|
||||
from Library.hdlc import hdlc
|
||||
from Config.usb_ids import default_diag_vid_pid
|
||||
except:
|
||||
from edlclient.Library.utils import print_progress, read_object, write_object, LogBase
|
||||
from edlclient.Library.Connection.usblib import usb_class
|
||||
from edlclient.Library.Connection.seriallib import serial_class
|
||||
from edlclient.Library.hdlc import hdlc
|
||||
from edlclient.Config.usb_ids import default_diag_vid_pid
|
||||
|
||||
qcerror = {
|
||||
1: "None",
|
||||
|
@ -332,9 +341,14 @@ class qcdiag(metaclass=LogBase):
|
|||
self.__logger.addHandler(fh)
|
||||
import os, inspect
|
||||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(os.path.dirname(current_dir))
|
||||
nvxml = os.path.join(parent_dir, "edlclient", "Config", "nvitems.xml")
|
||||
e = ElementTree.parse(nvxml).getroot()
|
||||
try:
|
||||
parent_dir = os.path.dirname(os.path.dirname(current_dir))
|
||||
nvxml = os.path.join(parent_dir, "edlclient", "Config", "nvitems.xml")
|
||||
e = ElementTree.parse(nvxml).getroot()
|
||||
except:
|
||||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
nvxml = os.path.join(current_dir, "edlclient", "Config", "nvitems.xml")
|
||||
e = ElementTree.parse(nvxml).getroot()
|
||||
for atype in e.findall("nv"):
|
||||
name = atype.get("name")
|
||||
identifier = int(atype.get("id"))
|
||||
|
@ -1141,22 +1155,42 @@ class DiagTools(metaclass=LogBase):
|
|||
self.interface = -1
|
||||
self.vid = None
|
||||
self.pid = None
|
||||
self.serial = args.serial
|
||||
if args.portname is not None:
|
||||
try:
|
||||
self.serial = args.serial
|
||||
except:
|
||||
self.serial = False
|
||||
try:
|
||||
self.portname = args.portname
|
||||
self.serial = True
|
||||
else:
|
||||
except:
|
||||
self.portname = ""
|
||||
|
||||
if args.vid != "":
|
||||
if self.portname is not None and self.portname != "":
|
||||
self.serial = True
|
||||
try:
|
||||
self.vid = int(args.vid, 16)
|
||||
if args.pid != "":
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.pid = int(args.pid, 16)
|
||||
if args.interface != "":
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.interface = int(args.interface, 16)
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.debugmode = args.debugmode
|
||||
except:
|
||||
self.debugmode = False
|
||||
|
||||
if self.vid is not None:
|
||||
self.vid = int(args.vid, 16)
|
||||
if self.pid is not None:
|
||||
self.pid = int(args.pid, 16)
|
||||
|
||||
logfilename = "diag.txt"
|
||||
if args.debugmode:
|
||||
if self.debugmode:
|
||||
if os.path.exists(logfilename):
|
||||
os.remove(logfilename)
|
||||
fh = logging.FileHandler(logfilename)
|
||||
|
|
|
@ -1,24 +1,88 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2019-2020 under MIT license
|
||||
# (c) B.Kerler 2019-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
# If you want to use in a commercial product, ask me before integrating it
|
||||
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
import copy
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
import serial.tools.list_ports
|
||||
from telnetlib import Telnet
|
||||
from Exscript.protocols.telnetlib import Telnet
|
||||
from binascii import hexlify, unhexlify
|
||||
import logging
|
||||
import logging.config
|
||||
import logging.handlers
|
||||
import colorama
|
||||
|
||||
class ColorFormatter(logging.Formatter):
|
||||
LOG_COLORS = {
|
||||
logging.ERROR: colorama.Fore.RED,
|
||||
logging.DEBUG: colorama.Fore.LIGHTMAGENTA_EX,
|
||||
logging.WARNING: colorama.Fore.YELLOW,
|
||||
}
|
||||
|
||||
def format(self, record, *args, **kwargs):
|
||||
# if the corresponding logger has children, they may receive modified
|
||||
# record, so we want to keep it intact
|
||||
new_record = copy.copy(record)
|
||||
if new_record.levelno in self.LOG_COLORS:
|
||||
pad = ""
|
||||
if new_record.name != "root":
|
||||
print(new_record.name)
|
||||
pad = "[LIB]: "
|
||||
# we want levelname to be in different color, so let's modify it
|
||||
new_record.msg = "{pad}{color_begin}{msg}{color_end}".format(
|
||||
pad=pad,
|
||||
msg=new_record.msg,
|
||||
color_begin=self.LOG_COLORS[new_record.levelno],
|
||||
color_end=colorama.Style.RESET_ALL,
|
||||
)
|
||||
# now we can let standart formatting take care of the rest
|
||||
return super(ColorFormatter, self).format(new_record, *args, **kwargs)
|
||||
|
||||
|
||||
class LogBase(type):
|
||||
debuglevel = logging.root.level
|
||||
|
||||
def __init__(cls, *args):
|
||||
super().__init__(*args)
|
||||
logger_attribute_name = '_' + cls.__name__ + '__logger'
|
||||
logger_debuglevel_name = '_' + cls.__name__ + '__debuglevel'
|
||||
logger_name = '.'.join([c.__name__ for c in cls.mro()[-2::-1]])
|
||||
LOG_CONFIG = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
"root": {
|
||||
"()": ColorFormatter,
|
||||
"format": "%(name)s - %(message)s",
|
||||
}
|
||||
},
|
||||
"handlers": {
|
||||
"root": {
|
||||
# "level": cls.__logger.level,
|
||||
"formatter": "root",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stdout",
|
||||
}
|
||||
},
|
||||
"loggers": {
|
||||
"": {
|
||||
"handlers": ["root"],
|
||||
# "level": cls.debuglevel,
|
||||
"propagate": False
|
||||
}
|
||||
},
|
||||
}
|
||||
logging.config.dictConfig(LOG_CONFIG)
|
||||
logger = logging.getLogger(logger_name)
|
||||
|
||||
setattr(cls, logger_attribute_name, logger)
|
||||
setattr(cls, logger_debuglevel_name, cls.debuglevel)
|
||||
|
||||
try:
|
||||
from edlclient.Library.utils import LogBase
|
||||
except Exception as e:
|
||||
import os,inspect
|
||||
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
sys.path.insert(0, parent_dir)
|
||||
from Library.utils import LogBase
|
||||
|
||||
'''
|
||||
C7 = 7 0 0 2 7 5 0
|
||||
|
@ -58,10 +122,12 @@ prodtable = {
|
|||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)"), # EM7565
|
||||
"MDM9x06": dict(openlock=20, openmep=19, opencnd=20, clen=8, init=[7, 3, 0, 1, 5],
|
||||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)"), # WP77xx
|
||||
"SDX55": dict(openlock=22, openmep=21, opencnd=22, clen=8, init=[7, 3, 0, 1, 5], #MR5100
|
||||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)"),
|
||||
"MDM9x15A": dict(openlock=24, openmep=23, opencnd=24, clen=8, init=[7, 3, 0, 1, 5], #AC779S
|
||||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)")
|
||||
"SDX55": dict(openlock=22, openmep=21, opencnd=22, clen=8, init=[7, 3, 0, 1, 5], # MR5100, MR6400 old fw
|
||||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)"),
|
||||
"MDM9x15A": dict(openlock=24, openmep=23, opencnd=24, clen=8, init=[7, 3, 0, 1, 5], # AC779S
|
||||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)"),
|
||||
"SDX65": dict(openlock=25, openmep=21, opencnd=26, clen=8, init=[7, 3, 0, 1, 5], # MR6400 new fw
|
||||
run="resultbuffer[i]=self.SierraAlgo(challenge[i], 4, 2, 1, 0, 3, 2, 0, 0)")
|
||||
}
|
||||
|
||||
infotable = {
|
||||
|
@ -81,68 +147,73 @@ infotable = {
|
|||
"MDM9x15A": ["AC779S"],
|
||||
"MDM9x30": ["EM7455", "MC7455", "EM7430", "MC7430"],
|
||||
"MDM9x30_V1": ["Netgear AC790/MDM9230"],
|
||||
"MDM9x40": ["AC815s", "AC785s", "AC797S", "MR1100"],
|
||||
"MDM9x40": ["MR1100", "AC815s", "AC785s", "AC797S"],
|
||||
"MDM9x50": ["EM7565", "EM7565-9", "EM7511", "EM7411"],
|
||||
"SDX55" : ["MR5100","MR5200","ac797-100eus","MR6400"]
|
||||
"SDX55": ["MR5100", "MR5200", "ac797-100eus", "MR6400"],
|
||||
"SDX65": ["MR6400", "MR6500", "MR6110", "MR6150", "MR6450", "MR6550"]
|
||||
}
|
||||
|
||||
keytable = bytearray([0xF0, 0x14, 0x55, 0x0D, 0x5E, 0xDA, 0x92, 0xB3, 0xA7, 0x6C, 0xCE, 0x84, 0x90, 0xBC, 0x7F, 0xED,
|
||||
# 0 MC8775_H2.0.8.19 !OPENLOCK, !OPENCND .. MC8765V,MC8765,MC8755V,MC8775,MC8775V,MC8775,AC850,
|
||||
# AC860,AC875,AC881,AC881U,AC875, AC340U 1.13.12.14
|
||||
0x61, 0x94, 0xCE, 0xA7, 0xB0, 0xEA, 0x4F, 0x0A, 0x73, 0xC5, 0xC3, 0xA6, 0x5E, 0xEC, 0x1C, 0xE2,
|
||||
keytable = bytearray([0xF0, 0x14, 0x55, 0x0D, 0x5E, 0xDA, 0x92, 0xB3, 0xA7, 0x6C, 0xCE, 0x84, 0x90, 0xBC, 0x7F, 0xED,
|
||||
# 1 MC8775_H2.0.8.19 AC340U, OPENMEP default
|
||||
0x39, 0xC6, 0x7B, 0x04, 0xCA, 0x50, 0x82, 0x1F, 0x19, 0x63, 0x36, 0xDE, 0x81, 0x49, 0xF0, 0xD7,
|
||||
# 2 AC750,AC710,AC7XX,SB750A,SB750,PC7000,AC313u OPENMEP
|
||||
0xDE, 0xA5, 0xAD, 0x2E, 0xBE, 0xE1, 0xC9, 0xEF, 0xCA, 0xF9, 0xFE, 0x1F, 0x17, 0xFE, 0xED, 0x3B,
|
||||
# 3 AC775,PC7200
|
||||
0xFE, 0xD4, 0x40, 0x52, 0x2D, 0x4B, 0x12, 0x5C, 0xE7, 0x0D, 0xF8, 0x79, 0xF8, 0xC0, 0xDD, 0x37,
|
||||
# 4 MC7455_02.30.01.01 OPENMEP
|
||||
0x3B, 0x18, 0x99, 0x6B, 0x57, 0x24, 0x0A, 0xD8, 0x94, 0x6F, 0x8E, 0xD9, 0x90, 0xBC, 0x67, 0x56,
|
||||
# 5 MC7455_02.30.01.01 OPENLOCK
|
||||
0x47, 0x4F, 0x4F, 0x44, 0x4A, 0x4F, 0x42, 0x44, 0x45, 0x43, 0x4F, 0x44, 0x49, 0x4E, 0x47, 0x2E,
|
||||
# 6 SWI9x50 Openmep Key SWI9X50C_01.08.04.00
|
||||
0x4F, 0x4D, 0x41, 0x52, 0x20, 0x44, 0x49, 0x44, 0x20, 0x54, 0x48, 0x49, 0x53, 0x2E, 0x2E, 0x2E,
|
||||
# 7 SWI9x50 Openlock Key SWI9X50C_01.08.04.00
|
||||
0x8F, 0xA5, 0x85, 0x05, 0x5E, 0xCF, 0x44, 0xA0, 0x98, 0x8B, 0x09, 0xE8, 0xBB, 0xC6, 0xF7, 0x65,
|
||||
# 8 MDM8200 Special
|
||||
0x4D, 0x42, 0xD8, 0xC1, 0x25, 0x44, 0xD8, 0xA0, 0x1D, 0x80, 0xC4, 0x52, 0x8E, 0xEC, 0x8B, 0xE3,
|
||||
# 9 SWI9x07 Openlock Key 02.25.02.01
|
||||
0xED, 0xA9, 0xB7, 0x0A, 0xDB, 0x85, 0x3D, 0xC0, 0x92, 0x49, 0x7D, 0x41, 0x9A, 0x91, 0x09, 0xEE,
|
||||
# 10 SWI9x07 Openmep Key 02.25.02.01
|
||||
0x8A, 0x56, 0x03, 0xF0, 0xBB, 0x9C, 0x13, 0xD2, 0x4E, 0xB2, 0x45, 0xAD, 0xC4, 0x0A, 0xE7, 0x52,
|
||||
# 11 NTG9X40C_11.14.08.11 / mdm9x40r11_core AC815s / SWI9x50 MR1100 Openlock Key
|
||||
0x2A, 0xEF, 0x07, 0x2B, 0x19, 0x60, 0xC9, 0x01, 0x8B, 0x87, 0xF2, 0x6E, 0xC1, 0x42, 0xA8, 0x3A,
|
||||
# 12 SWI9x50 MR1100 Openmep Key
|
||||
0x28, 0x55, 0x48, 0x52, 0x24, 0x72, 0x63, 0x37, 0x14, 0x26, 0x37, 0x50, 0xBE, 0xFE, 0x00, 0x00,
|
||||
# 13 SWI9x50 Unknown key
|
||||
0x22, 0x63, 0x48, 0x02, 0x24, 0x72, 0x27, 0x37, 0x19, 0x26, 0x37, 0x50, 0xBE, 0xEF, 0xCA, 0xFE,
|
||||
# 14 SWI9x50,SWI9X06Y IMEI nv key
|
||||
0x98, 0xE1, 0xC1, 0x93, 0xC3, 0xBF, 0xC3, 0x50, 0x8D, 0xA1, 0x35, 0xFE, 0x50, 0x47, 0xB3, 0xC4,
|
||||
# 15 NTG9X35C_02.08.29.00 Openmep Key AC791L/AC790S Old
|
||||
0x61, 0x94, 0xCE, 0xA7, 0xB0, 0xEA, 0x4F, 0x0A, 0x73, 0xC5, 0xC3, 0xA6, 0x5E, 0xEC, 0x1C, 0xE2,
|
||||
# 2 AC750,AC710,AC7XX,SB750A,SB750,PC7000,AC313u OPENMEP
|
||||
0x39, 0xC6, 0x7B, 0x04, 0xCA, 0x50, 0x82, 0x1F, 0x19, 0x63, 0x36, 0xDE, 0x81, 0x49, 0xF0, 0xD7,
|
||||
# 3 AC775,PC7200
|
||||
0xDE, 0xA5, 0xAD, 0x2E, 0xBE, 0xE1, 0xC9, 0xEF, 0xCA, 0xF9, 0xFE, 0x1F, 0x17, 0xFE, 0xED, 0x3B,
|
||||
# 4 MC7455_02.30.01.01 OPENMEP
|
||||
0xFE, 0xD4, 0x40, 0x52, 0x2D, 0x4B, 0x12, 0x5C, 0xE7, 0x0D, 0xF8, 0x79, 0xF8, 0xC0, 0xDD, 0x37,
|
||||
# 5 MC7455_02.30.01.01 OPENLOCK
|
||||
0x3B, 0x18, 0x99, 0x6B, 0x57, 0x24, 0x0A, 0xD8, 0x94, 0x6F, 0x8E, 0xD9, 0x90, 0xBC, 0x67, 0x56,
|
||||
# 6 SWI9x50 Openmep Key SWI9X50C_01.08.04.00
|
||||
0x47, 0x4F, 0x4F, 0x44, 0x4A, 0x4F, 0x42, 0x44, 0x45, 0x43, 0x4F, 0x44, 0x49, 0x4E, 0x47, 0x2E,
|
||||
# 7 SWI9x50 Openlock Key SWI9X50C_01.08.04.00
|
||||
0x4F, 0x4D, 0x41, 0x52, 0x20, 0x44, 0x49, 0x44, 0x20, 0x54, 0x48, 0x49, 0x53, 0x2E, 0x2E, 0x2E,
|
||||
# 8 MDM8200 Special
|
||||
0x8F, 0xA5, 0x85, 0x05, 0x5E, 0xCF, 0x44, 0xA0, 0x98, 0x8B, 0x09, 0xE8, 0xBB, 0xC6, 0xF7, 0x65,
|
||||
# 9 SWI9x07 Openlock Key 02.25.02.01
|
||||
0x4D, 0x42, 0xD8, 0xC1, 0x25, 0x44, 0xD8, 0xA0, 0x1D, 0x80, 0xC4, 0x52, 0x8E, 0xEC, 0x8B, 0xE3,
|
||||
# 10 SWI9x07 Openmep Key 02.25.02.01
|
||||
0xED, 0xA9, 0xB7, 0x0A, 0xDB, 0x85, 0x3D, 0xC0, 0x92, 0x49, 0x7D, 0x41, 0x9A, 0x91, 0x09, 0xEE,
|
||||
# 11 NTG9X40C_11.14.08.11 / mdm9x40r11_core AC815s / SWI9x50 MR1100 Openlock Key
|
||||
0x8A, 0x56, 0x03, 0xF0, 0xBB, 0x9C, 0x13, 0xD2, 0x4E, 0xB2, 0x45, 0xAD, 0xC4, 0x0A, 0xE7, 0x52,
|
||||
# 12 SWI9x50 MR1100 Openmep Key
|
||||
0x2A, 0xEF, 0x07, 0x2B, 0x19, 0x60, 0xC9, 0x01, 0x8B, 0x87, 0xF2, 0x6E, 0xC1, 0x42, 0xA8, 0x3A,
|
||||
# 13 SWI9x50/SWI9x65 Unknown key
|
||||
0x28, 0x55, 0x48, 0x52, 0x24, 0x72, 0x63, 0x37, 0x14, 0x26, 0x37, 0x50, 0xBE, 0xFE, 0x00, 0x00,
|
||||
# 14 SWI9x50,SWI9X06Y,SWI9x65 IMEI nv key
|
||||
0x22, 0x63, 0x48, 0x02, 0x24, 0x72, 0x27, 0x37, 0x19, 0x26, 0x37, 0x50, 0xBE, 0xEF, 0xCA, 0xFE,
|
||||
# 15 NTG9X35C_02.08.29.00 Openmep Key AC791L/AC790S Old
|
||||
0x98, 0xE1, 0xC1, 0x93, 0xC3, 0xBF, 0xC3, 0x50, 0x8D, 0xA1, 0x35, 0xFE, 0x50, 0x47, 0xB3, 0xC4,
|
||||
# 16 NTG9X35C_02.08.29.00 Openmep Key AC791/AC790S, NTGX55_10.25.15.02 MR5100 Alternative, NTG9X40C_30.00.12.00 Alternative
|
||||
0xC5, 0x50, 0x40, 0xDA, 0x23, 0xE8, 0xF4, 0x4C, 0x29, 0xE9, 0x07, 0xDE, 0x24, 0xE5, 0x2C, 0x1D,
|
||||
0x61, 0x94, 0xCE, 0xA7, 0xB0, 0xEA, 0x4F, 0x0A, 0x73, 0xC5, 0xC3, 0xA6, 0x5E, 0xEC, 0x1C, 0xE2,
|
||||
# 17 NTG9X35C_02.08.29.00 Openlock Key AC791/AC790S Old
|
||||
0xF0, 0x14, 0x55, 0x0D, 0x5E, 0xDA, 0x92, 0xB3, 0xA7, 0x6C, 0xCE, 0x84, 0x90, 0xBC, 0x7F, 0xED,
|
||||
0xC5, 0x50, 0x40, 0xDA, 0x23, 0xE8, 0xF4, 0x4C, 0x29, 0xE9, 0x07, 0xDE, 0x24, 0xE5, 0x2C, 0x1D,
|
||||
# 18 NTG9X35C_02.08.29.00 Openlock Key AC791/AC790S, NTGX55_10.25.15.02 MR5100 Alternative, NTG9X40C_30.00.12.00 Alternative
|
||||
0x78, 0x19, 0xC5, 0x6D, 0xC3, 0xD8, 0x25, 0x3E, 0x51, 0x60, 0x8C, 0xA7, 0x32, 0x83, 0x37, 0x9D,
|
||||
0xF0, 0x14, 0x55, 0x0D, 0x5E, 0xDA, 0x92, 0xB3, 0xA7, 0x6C, 0xCE, 0x84, 0x90, 0xBC, 0x7F, 0xED,
|
||||
# 19 SWI9X06Y_02.14.04.00 Openmep Key WP77xx
|
||||
0x12, 0xF0, 0x79, 0x6B, 0x19, 0xC7, 0xF4, 0xEC, 0x50, 0xF3, 0x8C, 0x40, 0x02, 0xC9, 0x43, 0xC8,
|
||||
0x78, 0x19, 0xC5, 0x6D, 0xC3, 0xD8, 0x25, 0x3E, 0x51, 0x60, 0x8C, 0xA7, 0x32, 0x83, 0x37, 0x9D,
|
||||
# 20 SWI9X06Y_02.14.04.00 Openlock Key WP77xx
|
||||
0x49, 0x42, 0xFF, 0x76, 0x8A, 0x95, 0xCF, 0x7B, 0xA3, 0x47, 0x5F, 0xF5, 0x8F, 0xD8, 0x45, 0xE4,
|
||||
0x12, 0xF0, 0x79, 0x6B, 0x19, 0xC7, 0xF4, 0xEC, 0x50, 0xF3, 0x8C, 0x40, 0x02, 0xC9, 0x43, 0xC8,
|
||||
# 21 NTGX55 Openmep Key, NTGX55_10.25.15.02 MR5100, NTG9X40C_30.00.12.00
|
||||
0xF8, 0x1A, 0x3A, 0xCC, 0xAA, 0x2B, 0xA5, 0xE8, 0x8B, 0x53, 0x5A, 0x55, 0xB9, 0x65, 0x57, 0x98,
|
||||
0x49, 0x42, 0xFF, 0x76, 0x8A, 0x95, 0xCF, 0x7B, 0xA3, 0x47, 0x5F, 0xF5, 0x8F, 0xD8, 0x45, 0xE4,
|
||||
# 22 NTGX55 Openlock Key, NTGX55_10.25.15.02 MR5100, NTG9X40C_30.00.12.00
|
||||
0x54, 0xC9, 0xC7, 0xA4, 0x02, 0x1C, 0xB0, 0x11, 0x05, 0x22, 0x39, 0xB7, 0x84, 0xEF, 0x16, 0xCA,
|
||||
0xF8, 0x1A, 0x3A, 0xCC, 0xAA, 0x2B, 0xA5, 0xE8, 0x8B, 0x53, 0x5A, 0x55, 0xB9, 0x65, 0x57, 0x98,
|
||||
# 23 NTG9X15A Openlock Key, NTG9X15A_01.08.02.00
|
||||
0xC7, 0xE6, 0x39, 0xFE, 0x0A, 0xC7, 0xCA, 0x4D, 0x49, 0x8F, 0xD8, 0x55, 0xEB, 0x1A, 0xCD, 0x8A
|
||||
0x54, 0xC9, 0xC7, 0xA4, 0x02, 0x1C, 0xB0, 0x11, 0x05, 0x22, 0x39, 0xB7, 0x84, 0xEF, 0x16, 0xCA,
|
||||
# 24 NTG9X15A Openlock Key, NTG9X15A_01.08.02.00
|
||||
0xC7, 0xE6, 0x39, 0xFE, 0x0A, 0xC7, 0xCA, 0x4D, 0x49, 0x8F, 0xD8, 0x55, 0xEB, 0x1A, 0xCD, 0x8A,
|
||||
# 25 NTGX65 Openlock Key, NTGX65_10.04.13.03
|
||||
0xF2, 0x4A, 0x9A, 0x2C, 0xDA, 0x3D, 0xA5, 0xE2, 0x6B, 0x56, 0x9A, 0x45, 0x29, 0x25, 0x77, 0x9A,
|
||||
# 26 NTGX65 Openadm Key, NTGX65_10.04.13.03
|
||||
0x46, 0x30, 0x33, 0x43, 0x44, 0x36, 0x42, 0x34, 0x41, 0x32, 0x31, 0x32, 0x30, 0x35, 0x39, 0x37
|
||||
])
|
||||
|
||||
|
||||
class SierraGenerator():
|
||||
tbl = bytearray()
|
||||
rtbl = bytearray()
|
||||
devicegeneration = None
|
||||
|
||||
def __init__(self):
|
||||
for _ in range(0, 0x14):
|
||||
|
@ -163,7 +234,7 @@ class SierraGenerator():
|
|||
lockid = prodtable[devicegeneration]["openlock"]
|
||||
clen = prodtable[devicegeneration]["clen"]
|
||||
if len(challenge) < clen:
|
||||
challenge=[0 for _ in range(0, clen - len(challenge))]
|
||||
challenge = [0 for _ in range(0, clen - len(challenge))]
|
||||
|
||||
challengelen = len(challenge)
|
||||
if _type == 0: # lockkey
|
||||
|
@ -179,7 +250,7 @@ class SierraGenerator():
|
|||
return resp
|
||||
|
||||
def selftest(self):
|
||||
test_table=[
|
||||
test_table = [
|
||||
{"challenge": "8101A18AB3C3E66A", "devicegeneration": "MDM9x15", "response": "D1E128FCA8A963ED"},
|
||||
{"challenge": "BE96CBBEE0829BCA", "devicegeneration": "MDM9x40", "response": "1033773720F6EE66"},
|
||||
{"challenge": "BE96CBBEE0829BCA", "devicegeneration": "MDM9x30", "response": "1E02CE6A98B7DD2A"},
|
||||
|
@ -193,7 +264,8 @@ class SierraGenerator():
|
|||
{"challenge": "BE96CBBEE0829BCA", "devicegeneration": "MDM9x30_V1", "response": "6A5E4C9CBCBDA7DC"},
|
||||
{"challenge": "BE96CBBEE0829BCA", "devicegeneration": "MDM9200", "response": "EEDBF8BFF8DAE346"},
|
||||
{"challenge": "20E253156762DACE", "devicegeneration": "SDX55", "response": "03940D7067145323"},
|
||||
{"challenge": "2387885E7D290FEE", "devicegeneration": "MDM9x15A", "response": "DC3E51897BAA9C1E"}
|
||||
{"challenge": "2387885E7D290FEE", "devicegeneration": "MDM9x15A", "response": "DC3E51897BAA9C1E"},
|
||||
{"challenge": "4B1FEF9FD43C6DAA", "devicegeneration": "SDX65", "response":"1253C1B1E447B697"}
|
||||
]
|
||||
for test in test_table:
|
||||
challenge = test["challenge"]
|
||||
|
@ -202,9 +274,9 @@ class SierraGenerator():
|
|||
openlock = self.run(devicegeneration, challenge, 0)
|
||||
padding = " " * (16 - len(devicegeneration))
|
||||
if openlock != response:
|
||||
print(devicegeneration+padding+" FAILED!")
|
||||
print(devicegeneration + padding + " FAILED!")
|
||||
else:
|
||||
print(devicegeneration+padding+" PASSED :)")
|
||||
print(devicegeneration + padding + " PASSED :)")
|
||||
|
||||
def SierraPreInit(self, counter, key, keylen, challengelen, mcount):
|
||||
if counter != 0:
|
||||
|
@ -232,7 +304,7 @@ class SierraGenerator():
|
|||
if keylen == 0 or keylen > 0x20:
|
||||
retval = [0, keylen]
|
||||
elif 1 <= keylen <= 0x20:
|
||||
self.tbl = [(i&0xFF) for i in range(0, 0x100)]
|
||||
self.tbl = [(i & 0xFF) for i in range(0, 0x100)]
|
||||
mcount = 0
|
||||
cl = keylen & 0xffffff00
|
||||
i = 0xFF
|
||||
|
@ -306,13 +378,13 @@ class SierraGenerator():
|
|||
self.rtbl[4] = 0
|
||||
return 1
|
||||
|
||||
def SierraKeygen(self, challenge:bytearray, key: bytearray, challengelen:int, keylen:int):
|
||||
def SierraKeygen(self, challenge: bytearray, key: bytearray, challengelen: int, keylen: int):
|
||||
challenge = challenge
|
||||
resultbuffer=bytearray([0 for _ in range(0, 0x100 + 1)])
|
||||
resultbuffer = bytearray([0 for _ in range(0, 0x100 + 1)])
|
||||
ret, keylen = self.SierraInit(key, keylen)
|
||||
if ret:
|
||||
for i in range(0, challengelen):
|
||||
exec(prodtable[self.devicegeneration]["run"]) # uses challenge
|
||||
exec(prodtable[self.devicegeneration]["run"]) # uses challenge
|
||||
self.SierraFinish()
|
||||
return resultbuffer
|
||||
|
||||
|
@ -326,7 +398,10 @@ class connection:
|
|||
port = self.detect(port)
|
||||
if port == "":
|
||||
self.tn = Telnet(ip, 5510)
|
||||
self.connected = True
|
||||
if self.tn:
|
||||
self.connected = True
|
||||
else:
|
||||
self.connected = False
|
||||
if port != "":
|
||||
self.serial = serial.Serial(port=port, baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1)
|
||||
self.connected = self.serial.is_open
|
||||
|
@ -366,8 +441,8 @@ class connection:
|
|||
data = ""
|
||||
while True:
|
||||
tmp = self.tn.read_eager()
|
||||
if tmp != b"":
|
||||
data += tmp.strip().decode('utf-8')
|
||||
if tmp != "":
|
||||
data += tmp.strip()
|
||||
else:
|
||||
break
|
||||
return data.split("\r\n")
|
||||
|
@ -384,14 +459,15 @@ class connection:
|
|||
self.serial.close()
|
||||
self.connected = False
|
||||
|
||||
|
||||
class SierraKeygen(metaclass=LogBase):
|
||||
def __init__(self,cn,devicegeneration=None):
|
||||
self.cn=cn
|
||||
def __init__(self, cn, devicegeneration=None):
|
||||
self.cn = cn
|
||||
self.keygen = SierraGenerator()
|
||||
if devicegeneration==None:
|
||||
if devicegeneration == None:
|
||||
self.detectdevicegeneration()
|
||||
else:
|
||||
self.devicegeneration=devicegeneration
|
||||
self.devicegeneration = devicegeneration
|
||||
|
||||
def run_selftest(self):
|
||||
print("Running self-test ...")
|
||||
|
@ -410,23 +486,23 @@ class SierraKeygen(metaclass=LogBase):
|
|||
_model = line.split(":")[1].strip()
|
||||
if revision != "":
|
||||
if "9200" in revision:
|
||||
devicegeneration = "MDM9200" #AC762S NTG9200H2_03.05.14.12ap
|
||||
devicegeneration = "MDM9200" # AC762S NTG9200H2_03.05.14.12ap
|
||||
if "9X07" in revision:
|
||||
devicegeneration = "MDM9x07"
|
||||
elif "9X25" in revision:
|
||||
if "NTG9X25C" in revision:
|
||||
devicegeneration = "MDM9200" #AC781S NTG9X25C_01.00.57.00
|
||||
devicegeneration = "MDM9200" # AC781S NTG9X25C_01.00.57.00
|
||||
elif "9X15" in revision:
|
||||
if "NTG9X15A" in revision:
|
||||
devicegeneration = "MDM9x15A" #Aircard 779S
|
||||
devicegeneration = "MDM9x15A" # Aircard 779S
|
||||
elif "NTG9X15C" in revision:
|
||||
devicegeneration = "MDM9200" #AC770S NTG9X15C_01.18.02.00
|
||||
devicegeneration = "MDM9200" # AC770S NTG9X15C_01.18.02.00
|
||||
elif "9X15A" in revision:
|
||||
devicegeneration = "MDM9x15A"
|
||||
else:
|
||||
devicegeneration = "MDM9x15"
|
||||
elif "9X30" in revision:
|
||||
if "NTG9X35C" in revision: #790S NTG9X35C_11.11.15.03
|
||||
if "NTG9X35C" in revision: # 790S NTG9X35C_11.11.15.03
|
||||
devicegeneration = "MDM9x30_V1"
|
||||
else:
|
||||
devicegeneration = "MDM9x30"
|
||||
|
@ -434,26 +510,35 @@ class SierraKeygen(metaclass=LogBase):
|
|||
devicegeneration = "MDM9x40"
|
||||
elif "9X50" in revision:
|
||||
if "NTG9X50" in revision:
|
||||
devicegeneration = "MDM9x40" #MR1100,AC797S NTG9X50C_12.06.03.00
|
||||
devicegeneration = "MDM9x40" # MR1100,AC797S NTG9X50C_12.06.03.00
|
||||
else:
|
||||
devicegeneration = "MDM9x50"
|
||||
elif "9X06" in revision:
|
||||
devicegeneration = "MDM9x06"
|
||||
elif "X55" in revision or "9X40C" in revision:
|
||||
if "NTGX55" in revision: #MR5100 NTGX55_10.25.15.02, MR5200 NTGX55_12.04.12.00
|
||||
devicegeneration = "SDX55"
|
||||
elif "NTGX65" in revision: #MR6400 NTGX65_10.01.41.02
|
||||
if "NTGX55" in revision: # MR5100 NTGX55_10.25.15.02, MR5200 NTGX55_12.04.12.00
|
||||
devicegeneration = "SDX55"
|
||||
devicegeneration = "SDX55"
|
||||
elif "X65" in revision:
|
||||
if "NTGX65" in revision:
|
||||
version = revision[revision.find("_") + 1:revision.find(" ")].split(".")
|
||||
maj = int(version[0]) * 1000000 + int(version[1]) * 10000 + int(version[2]) * 100 + int(
|
||||
version[3])
|
||||
if maj < 10041303:
|
||||
devicegeneration = "SDX55"
|
||||
else: # MR6400 NTGX65_10.04.13.03
|
||||
devicegeneration = "SDX65"
|
||||
# MR6550 NTGX65_12.01.31.00
|
||||
devicegeneration = "SDX65"
|
||||
else:
|
||||
devicegeneration = ""
|
||||
#Missing:
|
||||
# Missing:
|
||||
# SDX24 Sierra
|
||||
# MR2100 NTGX24_10.17.03.00
|
||||
# SDX55 Sierra
|
||||
# AC810S NTG9X40C_11.14.08.16
|
||||
# AC800S NTG9X40C_11.14.07.00
|
||||
self.devicegeneration=devicegeneration
|
||||
self.devicegeneration = devicegeneration
|
||||
else:
|
||||
print("Error on getting ATI modem response. Wrong port? Aborting.")
|
||||
self.cn.close()
|
||||
|
@ -461,9 +546,9 @@ class SierraKeygen(metaclass=LogBase):
|
|||
|
||||
def openlock(self):
|
||||
print("Device generation detected: " + self.devicegeneration)
|
||||
#print("Sending AT!ENTERCND=\"A710\" request.")
|
||||
#info = self.cn.send("AT!ENTERCND=\"A710\"")
|
||||
#if info == -1:
|
||||
# print("Sending AT!ENTERCND=\"A710\" request.")
|
||||
# info = self.cn.send("AT!ENTERCND=\"A710\"")
|
||||
# if info == -1:
|
||||
# print("Uhoh ... invalid entercnd password. Aborting ...")
|
||||
# return
|
||||
print("Sending AT!OPENLOCK? request")
|
||||
|
@ -472,7 +557,7 @@ class SierraKeygen(metaclass=LogBase):
|
|||
if info != -1:
|
||||
if len(info) > 2:
|
||||
challenge = info[1]
|
||||
print("Received challenge: "+info[1])
|
||||
print("Received challenge: " + info[1])
|
||||
else:
|
||||
print("Error on AT!OPENLOCK? request. Aborting.")
|
||||
return False
|
||||
|
@ -489,10 +574,11 @@ class SierraKeygen(metaclass=LogBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main(args):
|
||||
version = "1.5"
|
||||
info = 'Sierra Wireless Generator ' + version + ' (c) B. Kerler 2019-2021'
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,description=info)
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description=info)
|
||||
|
||||
parser.add_argument(
|
||||
'-openlock', '-l',
|
||||
|
@ -546,10 +632,10 @@ def main(args):
|
|||
print(info)
|
||||
print("------------------------------------------------------------\n")
|
||||
print("Usage: ./sierrakeygen.py [-l,-m,-c] [challenge] -d [devicegeneration]")
|
||||
print("Example: ./sierrakeygen.py.py -l BE96CBBEE0829BCA -d MDM9200")
|
||||
print("or: ./sierrakeygen.py.py -u for auto unlock")
|
||||
print("or: ./sierrakeygen.py.py -u -p [portname] for auto unlock with given portname")
|
||||
print("or: ./sierrakeygen.py.py -s for self-test")
|
||||
print("Example: ./sierrakeygen.py -l BE96CBBEE0829BCA -d MDM9200")
|
||||
print("or: ./sierrakeygen.py -u for auto unlock")
|
||||
print("or: ./sierrakeygen.py -u -p [portname] for auto unlock with given portname")
|
||||
print("or: ./sierrakeygen.py -s for self-test")
|
||||
print("Supported devicegenerations :")
|
||||
for key in infotable:
|
||||
info = f"\t{key}:\t\t"
|
||||
|
@ -569,14 +655,14 @@ def main(args):
|
|||
print("You need to specific a device generation as well. Option -d")
|
||||
exit(0)
|
||||
if devicegeneration == "":
|
||||
devicegeneration=None
|
||||
devicegeneration = None
|
||||
if args.selftest:
|
||||
kg=SierraKeygen(None,"selftest")
|
||||
kg = SierraKeygen(None, "selftest")
|
||||
kg.run_selftest()
|
||||
elif args.unlock:
|
||||
cn = connection(args.port, args.ip)
|
||||
if cn.connected:
|
||||
kg=SierraKeygen(cn,devicegeneration)
|
||||
kg = SierraKeygen(cn, devicegeneration)
|
||||
if kg.devicegeneration == "":
|
||||
print("Unknown device generation. Please send me details :)")
|
||||
else:
|
||||
|
|
57
edlclient/Tools/txt_to_loader.py
Executable file
57
edlclient/Tools/txt_to_loader.py
Executable file
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) B.Kerler 2019-2023 under GPLv3 license
|
||||
# If you use my code, make sure you refer to my name
|
||||
#
|
||||
# !!!!! If you use this code in commercial products, your product is automatically
|
||||
# GPLv3 and has to be open sourced under GPLv3 as well. !!!!!
|
||||
# TXT to EDL Loader (c) B.Kerler 2023
|
||||
|
||||
import os,sys
|
||||
from struct import unpack
|
||||
|
||||
def main():
|
||||
if len(sys.argv)<2:
|
||||
print("Usage: ./txt_to_loader.py [log.txt] [loader.elf]")
|
||||
sys.exit(0)
|
||||
with open(sys.argv[1],"rb") as rf:
|
||||
data=bytearray()
|
||||
for line in rf.readlines():
|
||||
if line[0]==0x20:
|
||||
tt=line.split(b" ")[:-1]
|
||||
tt=tt[1:17]
|
||||
xx=b"".join(tt)
|
||||
data.extend(bytes.fromhex(xx.decode('utf-8')))
|
||||
|
||||
outdata=bytearray()
|
||||
i=0
|
||||
seq=b"\x03\x00\x00\x00\x14\x00\x00\x00\x0D\x00\x00\x00"
|
||||
with open(sys.argv[2], "wb") as wf:
|
||||
while True:
|
||||
idx=data.find(seq)
|
||||
if idx==-1:
|
||||
if i==0:
|
||||
seq=b"\x12\x00\x00\x00\x20\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00"
|
||||
i+=1
|
||||
continue
|
||||
else:
|
||||
break
|
||||
else:
|
||||
cmd=unpack("<I", data[idx:idx+4])[0]
|
||||
if cmd==0x03:
|
||||
cmd,tlen,slen,offset,length=unpack("<IIIII",data[idx:idx+0x14])
|
||||
elif cmd==0x12:
|
||||
cmd, tlen, slen, offset, length = unpack("<IIQQQ", data[idx:idx + 0x20])
|
||||
data = data[idx + 0x20:]
|
||||
print("Offset : %08X Length: %08X" %(offset,length))
|
||||
while len(outdata)<offset+length:
|
||||
outdata.append(0xFF)
|
||||
outdata[offset:offset+length]=data[:length]
|
||||
i+=1
|
||||
data = data[length:]
|
||||
wf.write(outdata)
|
||||
|
||||
print("Done.")
|
||||
|
||||
if __name__=="__main__":
|
||||
main()
|
1
enableadb
Symbolic link
1
enableadb
Symbolic link
|
@ -0,0 +1 @@
|
|||
edlclient/Tools/enableadb
|
BIN
fastpwn
BIN
fastpwn
Binary file not shown.
BIN
fastpwn.exe
Executable file
BIN
fastpwn.exe
Executable file
Binary file not shown.
1
fhloaderparse
Symbolic link
1
fhloaderparse
Symbolic link
|
@ -0,0 +1 @@
|
|||
edlclient/Tools/fhloaderparse
|
|
@ -8,6 +8,8 @@ requires = [
|
|||
"docopt",
|
||||
"pycryptodome",
|
||||
"colorama",
|
||||
"usb"
|
||||
"Exscript",
|
||||
"requests",
|
||||
"passlib"
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
|
1
qc_diag
Symbolic link
1
qc_diag
Symbolic link
|
@ -0,0 +1 @@
|
|||
edlclient/Tools/qc_diag
|
|
@ -2,11 +2,13 @@ wheel
|
|||
pyusb>=1.1.0
|
||||
pyserial>=3.4
|
||||
docopt>=0.6.2
|
||||
pylzma>=0.5.0
|
||||
pycryptodome
|
||||
pycryptodomex
|
||||
lxml>=4.6.1
|
||||
colorama
|
||||
usb
|
||||
capstone
|
||||
keystone-engine
|
||||
|
||||
qrcode
|
||||
requests
|
||||
passlib
|
||||
Exscript
|
||||
|
|
11
setup.py
11
setup.py
|
@ -4,7 +4,7 @@ import os
|
|||
|
||||
setup(
|
||||
name='edlclient',
|
||||
version='3.60',
|
||||
version='3.62',
|
||||
packages=find_packages(),
|
||||
long_description=open("README.md").read(),
|
||||
scripts=['edl','edlclient/Tools/qc_diag.py','edlclient/Tools/sierrakeygen.py','edlclient/Tools/boottodwnload','edlclient/Tools/enableadb','edlclient/Tools/fhloaderparse','edlclient/Tools/beagle_to_loader'],
|
||||
|
@ -16,10 +16,10 @@ setup(
|
|||
},
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"License :: OSI Approved :: GPlv3 License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
license='MIT License',
|
||||
license='GPLv3 License',
|
||||
install_requires=[
|
||||
'colorama',
|
||||
'docopt',
|
||||
|
@ -29,7 +29,10 @@ setup(
|
|||
'lxml',
|
||||
'pylzma',
|
||||
'pycryptodome',
|
||||
'wheel'
|
||||
'wheel',
|
||||
'Exscript',
|
||||
'requests',
|
||||
'passlib'
|
||||
],
|
||||
author='B. Kerler',
|
||||
author_email='info@revskills.de',
|
||||
|
|
1
sierrakeygen
Symbolic link
1
sierrakeygen
Symbolic link
|
@ -0,0 +1 @@
|
|||
edlclient/Tools/sierrakeygen.py
|
|
@ -1,6 +1,6 @@
|
|||
# Challenge/Response Generator for Sierra Wireless Cards V1.2
|
||||
(c) B. Kerler 2019-2020
|
||||
MIT License
|
||||
(c) B. Kerler 2019-2023
|
||||
GPLv3 License
|
||||
|
||||
## Why
|
||||
|
||||
|
@ -20,11 +20,12 @@ MIT License
|
|||
"WP75xx", "WP85xx", "WP8548", "WP8548G", "AC340U"],
|
||||
"MDM9x30": ["EM7455", "MC7455", "EM7430", "MC7430"],
|
||||
"MDM9x30_V1": ["Netgear AC790S/AC791L"],
|
||||
"MDM9x40": ["AC815s", "AC785s","Netgear MR1100"],
|
||||
"MDM9x40": ["MR1100", "AC815s", "AC785s"],
|
||||
"MDM9x50": ["EM7565", "EM7565-9", "EM7511"],
|
||||
"MDM9x06": ["WP77xx"],
|
||||
"MDM9x07": ["SWI9X07Y", "WP76xx"]
|
||||
|
||||
"MDM9x07": ["SWI9X07Y", "WP76xx"],
|
||||
"SDX65": ["MR6400", "MR6500", "MR6110", "MR6150", "MR6450", "MR6550"]
|
||||
|
||||
## Installation
|
||||
|
||||
- Get python >=3.6 64-Bit
|
||||
|
@ -346,7 +347,7 @@ MIT License
|
|||
|
||||
## License
|
||||
|
||||
Published under MIT license
|
||||
Published under GPLv3 license
|
||||
Additional license limitations: No use in commercial products without prior permit by me.
|
||||
|
||||
Enjoy !
|
||||
|
|
Loading…
Add table
Reference in a new issue