diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
deleted file mode 100644
index e519f16..0000000
--- a/.github/workflows/android.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Android CI
-
-on:
- push:
- branches: [ "master" ]
- pull_request:
- branches: [ "master" ]
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- - name: set up JDK 11
- uses: actions/setup-java@v3
- with:
- java-version: '11'
- distribution: 'temurin'
- cache: gradle
-
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
- - name: Build with Gradle
- run: ./gradlew build
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index dbaedff..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,88 +0,0 @@
-# Built application files
-*.apk
-*.aar
-*.ap_
-*.aab
-
-# Files for the ART/Dalvik VM
-*.dex
-
-# Java class files
-*.class
-
-# Generated files
-bin/
-gen/
-out/
-# Uncomment the following line in case you need and you don't have the release build type files in your app
-# release/
-
-# Gradle files
-.gradle/
-build/
-
-# Local configuration file (sdk path, etc)
-local.properties
-
-# Proguard folder generated by Eclipse
-proguard/
-
-# Log Files
-*.log
-
-# Android Studio Navigation editor temp files
-.navigation/
-
-# Android Studio captures folder
-captures/
-
-# IntelliJ
-*.iml
-.idea/workspace.xml
-.idea/tasks.xml
-.idea/gradle.xml
-.idea/assetWizardSettings.xml
-.idea/dictionaries
-.idea/libraries
-# Android Studio 3 in .gitignore file.
-.idea/caches
-.idea/modules.xml
-# Comment next line if keeping position of elements in Navigation Editor is relevant for you
-.idea/navEditor.xml
-.idea/*
-# Keystore files
-# Uncomment the following lines if you do not want to check your keystore files in.
-#*.jks
-#*.keystore
-
-# External native build folder generated in Android Studio 2.2 and later
-.externalNativeBuild
-.cxx/
-
-# Google Services (e.g. APIs or Firebase)
-# google-services.json
-
-# Freeline
-freeline.py
-freeline/
-freeline_project_description.json
-
-# fastlane
-fastlane/report.xml
-fastlane/Preview.html
-fastlane/screenshots
-fastlane/test_output
-fastlane/readme.md
-
-# Version control
-vcs.xml
-
-# lint
-lint/intermediates/
-lint/generated/
-lint/outputs/
-lint/tmp/
-# lint/reports/
-
-# Android Profiling
-*.hprof
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index f288702..fdddb29 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,674 +1,24 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- 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.
-
-
- Copyright (C)
-
- 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 .
-
-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:
-
- Copyright (C)
- 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
-.
-
- 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
-.
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to
diff --git a/README-MOBILE.md b/README-MOBILE.md
deleted file mode 100644
index 234ef9e..0000000
--- a/README-MOBILE.md
+++ /dev/null
@@ -1,260 +0,0 @@
-**This is for Android mobile users who do not have a PC. Floating apps or similar is recommended to read this page while working at the same time**
-
-**BEST VIEWED ON MOBILE!**
-
-# Quick links
-- [Prerequisites](https://github.com/LGLTeam/Android-Mod-Menu/blob/master/README.md#prerequisites)
-- [What you need](#what-you-need)
-- [Video Tutorial](#video-tutorial)
-- [Installation](#installation)
-- [Setting up AIDE](#setting-up-aide)
-- [Files to work with and making changes](#files-to-work-with-and-making-changes)
-- [Implementing the menu to the target game](#implementing-the-menu-to-the-target-game)
-- [FAQ](#faq)
-- [Troubleshooting](#troubleshooting)
-- [Credits/Acknowledgements](#creditsacknowledgements)
-
-# What you need
-* Modded AIDE app, choose one of them you like to use. The official AIDE from Play Store will not work with this project
- * [AIDE CMODs](https://secufiles.com/nE9J/AIDE_CMODs_3.2.200108.apk)
- * [AIDE Lite Mod](https://mega.nz/file/bIpCQL6I#BzyLf1pB1Sf7EayW_PEJHl3f50qHHZDdb0BpB8FYdVo)
-* NDK support for modded AIDE
- * NDK for 32-bit/ARMv7 phones: [ndk_arm.tar.gz](https://mega.nz/folder/2c1TWIJD#UCzO7kIo1e4WpFwZHIMYVw/file/XRlRTIjJ)
- * NDK for 64-bit/ARM64 phones: [ndk_arm64.tar.gz](https://mega.nz/folder/2c1TWIJD#UCzO7kIo1e4WpFwZHIMYVw/file/7RdTzYxQ)
-* Any File Manager app you like to use but these are recommended
- * [X-plore](https://play.google.com/store/apps/details?id=com.lonelycatgames.Xplore&hl=en):
- * [MT Manager](https://bbs.binmt.cc/forum-2-1.html) [(Mirror link)](https://secufiles.com/js6i/MT2.9.2.apk) With build-in Apktool and editors to modify APK file. Note: It requires VIP to edit `AndroidManifest.xml` more than 200 lines
-* Apktool app to edit `AndroidManifest.xml` for free: [Modded APK Editor Pro app](https://mega.nz/file/zQxA0YDY#eNRgcyrHwpWh1nSTHhcc4quxzeXrXcUHlYPoRyltKEw) or [APK Repacker](https://mega.nz/file/LIom0DDL#hJyIchPDCk2n_gcDmutNsOKS86WXQN58qpEGa9JsLrU) (We use APK Editor Pro)
-* [Floating apps](https://play.google.com/store/apps/details?id=com.lwi.android.flappsfull&hl=en) (optional): You can use it to read this page and working at the same time or use a build-in feature by OEM
-
-# Video Tutorial
-Note: Videos may be quite outdated
-
-Mahmoud Gaming: https://www.youtube.com/watch?v=SMCsUy60Hs8
-
-NSRAÎNA HACKER: https://www.youtube.com/watch?v=MkkZ_loEDTU
-
-BROKE MODS OFC (Customized menu): https://www.youtube.com/watch?v=IYREVGc-quM
-
-# Installation
-
-Go to releases page https://github.com/LGLTeam/Android-Mod-Menu/releases/ and download **Source code (zip)**
-
-To download latest commit, enable desktop mode on your browser then click **Code**, and click **Download ZIP**
-
-
-
-# Setting up AIDE
-
-Now let's begin
-
-Firstly, make sure you know your phone's hardware well, and download correct NDK file coresponding to your phone's architecture. ndk_arm.tar.gz for 32-bit/ARMv7 phones, ndk_arm64.tar.gz for 64-bit/ARM64 phones. Installing incorrect version will cause problems
-
-Now install NDK support for modded AIDE. Click on 3 dots on the right-corner. Click **More... - Settings**
-
-
-
-Go to **Build & Run**, and click on **Manage native code support**.
-
-
-
-A prompt will ask to input the path of NDK file.
-
-If you use X-plore, you can show details of the file and copy file path easly.
-
-
-
-Paste it in the prompt box.
-
-
-
-Click install and wait
-
-
-
-After installiation, you can now use AIDE with NDK support
-
-# Opening project in AIDE
-
-On the main screen, it says **No open files**. We simply click on **No open files** to show file explorer. Navigate to the directory of the project and open **app** folder
-
-An option **Open Android app Project** will appear. Click on it to open
-
-
-
-Now that the file explorer will look like this, means the project has been opened
-
-
-
-Press play to compile the project whether it works or not
-
-If successful, it will ask you to install the APK. It may ask you to allow installation from unknown sources. Please allow when asked
-
-Open the app to test
-
-# Files to work with and making changes
-
-See more: https://github.com/LGLTeam/Android-Mod-Menu#files-to-work-with-and-making-changes
-
-Important for 32-bit users: Please remove arm64-v8a from application.mk
-
-# Implementing the menu to the target game
-
-### 1. Exporting to APK
-
-We need to compile the project into APK file
-
-Click on 3 dots icon on the corner. **More... - Project - Publish project**
-
-
-
-This dialog will show but why is export greyed? Because you need to create your own keystore first. Click **Create keystore**
-
-
-
-There is no need to put your organization info. Just your alias, password and name are fine. Don't forget your password!
-
-After you created your keystore, you can now export
-
-
-
-Enter your keystore password
-
-
-
-After that, it will tell you the APK has been experted
-
-
-
-### 2. Downloading standalone APK from apkcombo
-
-It is not a good idea to pull out installed APK from phone because sometimes it comes with splitted APKs, it's a dumb feature, we should use Apkcombo to download standalone APK
-
-Try to use armv7 standalone APK as possible. It support on all armv7, x86 and arm64 devices
-
-https://apkcombo.com/
-
-### 3. Know the game's main activity
-
-We are looking for main activity. X-plore app can get main activity of the app so we will use that
-
-Click **Show**, check **App manager**.
-
-
-
-Long press on an app and click **Show details**, then click **App** and expand **Activity**
-
-Here we can see the main activity. It's always on top
-
-
-
-Note it down somewhere to remember it. We will explain this later
-
-### 4. Adding dex and lib file
-
-We will use MT Manager to modify APK. Edit the files inside APK is pretty much straight forward, we do not need to decompile the whole APK to storage at all.
-
-Open the APK file. Click **View** to show its content
-
-
-
-You will now see the content structure inside the APK
-
-
-
-Do the same on compiled mod menu APK on the other pane
-
-We need to rename the dex on our mod menu APK to add dex into the game APK. We name it to classes2.dex since it contain only single dex. If the game have multiple dexes, like classes.dex, classes2.dex, classes3.dex, we would name it to classes4.dex. Mod menu dex must always be last
-
-
-
-Press and hold on our dex, and click **+ Add**. This dialog will show. Enable **Auto Sign**, leave Update mode **Replace All**
-
-
-
-Click OK, it will copy and auto sign.
-
-Copy your library file (.so file) too. Make sure to copy to the correct architecture
-armeabi-v7a is armeabi-v7a, arm64-v8a is arm64-v8a, and so on.
-
-PUTTING THE .SO file ON A WRONG ARCHITECTURE WILL RESULT IN A CRASH!
-
-
-
-### 5. Making corresponding changes and compile
-
-Ok, we go back to the main directory inside APK. You can press **..** to go back
-
-**I don't want to explain it here again, so please go to main README.md to read: https://github.com/LGLTeam/Android-Mod-Menu/blob/master/README.md#2-making-corresponding-changes-in-the-files**
-
-**Editing DEX file using MT Manager**
-
-Open `classes.dex` directly, choose **Dex Editor Plus**
-
-
-
-This dialog will show if it have multidex. **SELECT ALL** and click OK
-
-
-
-The editor opens.
-
-Make some changes. After you're done, save it
-
-
-
-Go back and **save and exit**
-
-
-
-Click OK to update the changes to the game's APK file with auto sign on
-
-
-
-Go back outside APK. You will now see a green text which tells you that you have recently modified the file
-
-
-
-**Editing XML file using APK Editor Pro**
-
-MT Manage requires an account to edit `AndroidManifest.xml` and VIP account to edit more than 200 lines. No, we don't need VIP, we will use APK Editor Pro to edit
-
-Open APK Editor Pro, click "Select an Apk file". Navigate to the location where you have stored APK, and select it to edit
-
-
-
-Open `AndroidManifest.xml`
-
-
-
-Make some changes. After you're done, save it
-
-
-
-Go back, save the APK file
-
-
-
-Wait until it finish compiling. This screen will show after it's done. You can choose to install the APK right now. You may need to uninstall original APK first
-
-
-
-It's obvious that it saved an APK to the strange location `/storage/emulated/0/ApkEditor/tmp/gen_signed.apk`, just move it somewhere if you like to.
-
-If it works, congratulations!
-
-# Troubleshooting
-
-Problem with the project like app crashes: click **More... -> Project -> Refresh Build**. This will clear the project cache and fix problems
-
-Problem with AIDE: Open System Settings -> Apps and clear data of AIDE app. This will reset everything and you need to install NDK again
-
-AIDE has a lot of compatibility issues, you need to research a lot and do some trial and errors until you fix something.
-
-# FAQ
-
-See: https://github.com/LGLTeam/Android-Mod-Menu#faq
-
-# Credits/Acknowledgements
-
-* RAUNAK MODS for help in modding games via phone, and testing the template in AIDE
\ No newline at end of file
diff --git a/README.md b/README.md
index b92a7f7..f39afa6 100644
--- a/README.md
+++ b/README.md
@@ -1,100 +1,2 @@
- This Project May Have Many Errors And Fault, Before Blaming me About errors, Try To fix As Your Need
-
- Android Mod Injector
-
-
-Android Mod Injector Is Mod Menu Injector For Rooted Device & Virtual Device. Made On Lgl Android Mod Menu 2.9. Converted By Nepmods.
-
-
-
- How It Works?
- It Have 2 CPP Library, One is Called Client and One Server. basically The server Library is Injected Inside game and All hacks Are controlled By The Client library, Client library is Connected with java, so it is easy to Control Mods.
-
-
-
- How To Use?
-
-This Project is Easy To use. but Yu need some experience with modding.
-
- Step 1: Targeting Game
-You Need To Target The Game By Entering Game's Package Name On
-FloatingModMenuServices.java
- And Find targetPackage variable. Then, Replace with Your Game Package.
-
->If You Change Lib Name in Android.ml, also Change here
-
-
-
-
- Step 2: Targeting Lib
-You need to Target A Library For Hacking Or Making Mod, You can do it on Server.cpp
-
-
-
-
-
-Adding New Feature
-YOU NEED TO ADD NEW FEATURE TO MAKE MODS.
-To do so,
-First:
- Creating New Feature
-YOU CAN ADD NEW FEATURE TO Main.cppfile.
-
-
-
-
-Creating New Request Id
-You need To Create New Feature Id for Sending / Receiving The Data using Socket.
-
For that:
-
-
-
-
-Sending Feature To Server Library
-You can Create A New Case That Matches with Feature position, You can Use
-Send(f::featureID, [bool/int])
-
-
-
-Receiving data
-
-You can Receive Sent Data In Server.cpp
-
-1. Create A New Feature Id With Same Number.
-
-2. Receive like showen
-
-```
-} else if (request.Mode == f::featureID) {
- feature2 = request.boolean;
- response.Success = true;
-
-```
-
-
-
-
- Making Mods
-You can Simply Make Mod Like LGL Android Mod Menu 2.9
-
-
-Change Log
-
-```
-*Change Log*
-1. Fixed Injection
-2. No Need To Add Libinject Manually, LibInject Will be Added Automatically
-3. Changed Root Library From Eu.Chainfire To com.topjohnwu.superuser
-4. Fixed For Magisk
-5. Fixed For Root
-6. Fixed For Virtual Androids
-7. made 2 Button To inject
-
-```
-
-Credits
-Making Project: Nepmods (https://GitHub.com/nepmods)
-*Inject Lib Framework : Chainfire/evilsocket : https://github.com/Chainfire/inject-hook-cflumen
-*Mod Template : LGLTeam : https://github.com/LGLTeam/Android-Mod-Menu
-*Socket: Kmods : https://github.com/kp7742
-*Help To Inject Fix On Root/Magisk: Mr Any Gamer
+# Android-Mod-Inject
+A Root Injector Project Based On Lgl Mod Menu 2.9
diff --git a/app/.gitignore b/app/.gitignore
deleted file mode 100644
index 796b96d..0000000
--- a/app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/app/build.gradle b/app/build.gradle
deleted file mode 100644
index ad8bcc7..0000000
--- a/app/build.gradle
+++ /dev/null
@@ -1,40 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
- compileSdkVersion 30
- defaultConfig {
- applicationId "uk.lgl"
- minSdkVersion 19
- targetSdkVersion 30
- versionCode 1
- versionName "2.9"
- ndk {
- abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86'
- }
- signingConfig signingConfigs.debug
- }
- buildTypes {
- release {
- shrinkResources false
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- debug {
- shrinkResources false
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
- externalNativeBuild {
- ndkBuild {
- path file('src/main/jni/Android.mk')
- }
- }
- ndkVersion = '22.0.7026061'
-}
-
-//dependencies must be placed below 'android' brackets to get it work on AIDE
-dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'eu.chainfire:libsuperuser:1.1.0.+'
-}
diff --git a/app/libs/classes.jar b/app/libs/classes.jar
deleted file mode 100644
index a01aa1c..0000000
Binary files a/app/libs/classes.jar and /dev/null differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
deleted file mode 100644
index 85268ad..0000000
--- a/app/proguard-rules.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
-#-dontobfuscate
--keepclassmembers class ** {
- public static void Start (***);
-}
--keep public class uk.lgl.MainActivity
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 539b8f9..0000000
--- a/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/java/uk/lgl/MainActivity.java b/app/src/main/java/uk/lgl/MainActivity.java
deleted file mode 100644
index 495a33c..0000000
--- a/app/src/main/java/uk/lgl/MainActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package uk.lgl;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.provider.Settings;
-import android.widget.Toast;
-
-import uk.lgl.modmenu.FloatingModMenuService;
-
-public class MainActivity extends Activity {
-
- //Only if you have changed MainActivity to yours and you wanna call game's activity.
- public String GameActivity = "com.unity3d.player.UnityPlayerActivity";
- public boolean hasLaunched = false;
-
- //Load lib
- static {
- // When you change the lib name, change also on Android.mk file
- // Both must have same name
- System.loadLibrary("MyLibName");
- }
-
- //To call onCreate, please refer to README.md
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- //To launch mod menu.
- Start(this);
-
- //To launch game activity
- if (!hasLaunched) {
- try {
- //Start service
- //MainActivity.this.startActivity(new Intent(MainActivity.this, Class.forName(MainActivity.this.GameActivity)));
- MainActivity.this.startActivity(new Intent(MainActivity.this, Class.forName(MainActivity.this.GameActivity)));
- hasLaunched = true;
- } catch (ClassNotFoundException e) {
- //Uncomment this if you are following METHOD 2 of CHANGING FILES
- //Toast.makeText(MainActivity.this, "Error. Game's main activity does not exist", Toast.LENGTH_LONG).show();
- e.printStackTrace();
- return;
- }
- }
- }
-
- public static void Start(final Context context) {
- //Check if overlay permission is enabled or not
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(context)) {
- Toast.makeText(context.getApplicationContext(), "Overlay permission is required in order to show mod menu. Restart the game after you allow permission", Toast.LENGTH_LONG).show();
- Toast.makeText(context.getApplicationContext(), "Overlay permission is required in order to show mod menu. Restart the game after you allow permission", Toast.LENGTH_LONG).show();
- context.startActivity(new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION",
- Uri.parse("package:" + context.getPackageName())));
- final Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- System.exit(1);
- }
- }, 5000);
- return;
- } else {
- final Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- context.startService(new Intent(context, FloatingModMenuService.class));
- }
- }, 500);
- }
- }
-}
diff --git a/app/src/main/java/uk/lgl/modmenu/FloatingModMenuService.java b/app/src/main/java/uk/lgl/modmenu/FloatingModMenuService.java
deleted file mode 100644
index 76558de..0000000
--- a/app/src/main/java/uk/lgl/modmenu/FloatingModMenuService.java
+++ /dev/null
@@ -1,1292 +0,0 @@
-//Please don't replace listeners with lambda!
-
-package uk.lgl.modmenu;
-
-import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.AlertDialog;
-import android.app.Service;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.ColorStateList;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.Typeface;
-import android.graphics.drawable.GradientDrawable;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.text.Html;
-import android.text.InputFilter;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.text.method.DigitsKeyListener;
-import android.util.Base64;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-import android.webkit.WebView;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.RelativeLayout;
-import android.widget.ScrollView;
-import android.widget.SeekBar;
-import android.widget.Spinner;
-import android.widget.Switch;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import com.topjohnwu.superuser.Shell;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.widget.RelativeLayout.ALIGN_PARENT_LEFT;
-import static android.widget.RelativeLayout.ALIGN_PARENT_RIGHT;
-import android.graphics.Canvas;
-import android.graphics.PixelFormat;
-import android.content.Context;
-import java.util.ArrayList;
-import java.io.File;
-import java.util.Iterator;
-import java.util.Locale;
-import com.topjohnwu.superuser.internal.Utils;
-
-public class FloatingModMenuService extends Service {
- //********** Here you can easly change the menu appearance **********//
-
- //***************** TARGET *********//
- String LibName = "libLibServer.so";
- String targetPackage = "fps.zombie.shooting.fun.to.dead";
-
-
- //region Variable
- public static final String TAG = "Mod_Menu"; //Tag for logcat
- int TEXT_COLOR = Color.parseColor("#82CAFD");
- int TEXT_COLOR_2 = Color.parseColor("#FFFFFF");
- int BTN_COLOR = Color.parseColor("#1C262D");
- int MENU_BG_COLOR = Color.parseColor("#EE1C2A35"); //#AARRGGBB
- int MENU_FEATURE_BG_COLOR = Color.parseColor("#DD141C22"); //#AARRGGBB
- int MENU_WIDTH = 290;
- int MENU_HEIGHT = 210;
- float MENU_CORNER = 4f;
- int ICON_SIZE = 45; //Change both width and height of image
- float ICON_ALPHA = 0.7f; //Transparent
- int ToggleON = Color.GREEN;
- int ToggleOFF = Color.RED;
- int BtnON = Color.parseColor("#1b5e20");
- int BtnOFF = Color.parseColor("#7f0000");
- int CategoryBG = Color.parseColor("#2F3D4C");
- int SeekBarColor = Color.parseColor("#80CBC4");
- int SeekBarProgressColor = Color.parseColor("#80CBC4");
- int CheckBoxColor = Color.parseColor("#80CBC4");
- int RadioColor = Color.parseColor("#FFFFFF");
- String NumberTxtColor = "#41c300";
- //********************************************************************//
- RelativeLayout mCollapsed, mRootContainer;
- LinearLayout mExpanded, patches, mSettings, mCollapse;
- LinearLayout.LayoutParams scrlLLExpanded, scrlLL;
- private WindowManager.LayoutParams espParams;
- private NepEsp overlayView;
- WindowManager mWindowManager;
- WindowManager.LayoutParams params;
- ImageView startimage;
- FrameLayout rootFrame;
- ScrollView scrollView;
-
- boolean stopChecking;
-
- //initialize methods from the native library
- native void setTitleText(TextView textView);
-
- native void setHeadingText(TextView textView);
-
- native String Icon();
-
- native String IconWebViewData();
-
- native String[] getFeatureList();
-
- native String[] settingsList();
-
- native boolean isGameLibLoaded();
-
- static native void DrawOn(NepEsp espView, Canvas canvas);
-
- native boolean IsConnected();
-
- native void Init();
-
- native void Stop();
- //endregion
-
- //When this Class is called the code in this function will be executed
- @Override
- public void onCreate() {
- super.onCreate();
- Preferences.context = this;
- this.overlayView = new NepEsp((Context) this);
- //Create the menu
- initFloating();
- DrawCanvas();
- //Create a handler for this Class
- final Handler handler = new Handler();
- handler.post(new Runnable() {
- public void run() {
-
- Thread();
- handler.postDelayed(this, 1000);
- }
- });
- }
-
- private int getLayoutType() {
- int LAYOUT_FLAG;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_TOAST;
- } else {
- LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
- }
- return LAYOUT_FLAG;
- }
- private void DrawCanvas() {
-
-
- WindowManager.LayoutParams layoutParams;
- this.espParams = layoutParams = new WindowManager.LayoutParams(
- WindowManager.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.MATCH_PARENT,
- this.getLayoutType(),
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
- WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
- PixelFormat.TRANSLUCENT);
- layoutParams.gravity = Gravity.TOP | Gravity.START;
- this.espParams.x = 0;
- this.espParams.y = 100;
- this.mWindowManager.addView((View) this.overlayView, (ViewGroup.LayoutParams) this.espParams);
- }
-
-
- //Here we write the code for our Menu
- // Reference: https://www.androidhive.info/2016/11/android-floating-widget-like-facebook-chat-head/
- private void initFloating() {
- rootFrame = new FrameLayout(this); // Global markup
- rootFrame.setOnTouchListener(onTouchListener());
- mRootContainer = new RelativeLayout(this); // Markup on which two markups of the icon and the menu itself will be placed
- mCollapsed = new RelativeLayout(this); // Markup of the icon (when the menu is minimized)
- mCollapsed.setVisibility(View.VISIBLE);
- mCollapsed.setAlpha(ICON_ALPHA);
-
- //********** The box of the mod menu **********
- mExpanded = new LinearLayout(this); // Menu markup (when the menu is expanded)
- mExpanded.setVisibility(View.GONE);
- mExpanded.setBackgroundColor(MENU_BG_COLOR);
- mExpanded.setOrientation(LinearLayout.VERTICAL);
- // mExpanded.setPadding(1, 1, 1, 1); //So borders would be visible
- mExpanded.setLayoutParams(new LinearLayout.LayoutParams(dp(MENU_WIDTH), WRAP_CONTENT));
- GradientDrawable gdMenuBody = new GradientDrawable();
- gdMenuBody.setCornerRadius(MENU_CORNER); //Set corner
- gdMenuBody.setColor(MENU_BG_COLOR); //Set background color
- gdMenuBody.setStroke(1, Color.parseColor("#32cb00")); //Set border
- //mExpanded.setBackground(gdMenuBody); //Apply GradientDrawable to it
-
- //********** The icon to open mod menu **********
- startimage = new ImageView(this);
- startimage.setLayoutParams(new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
- int applyDimension = (int) TypedValue.applyDimension(1, ICON_SIZE, getResources().getDisplayMetrics()); //Icon size
- startimage.getLayoutParams().height = applyDimension;
- startimage.getLayoutParams().width = applyDimension;
- //startimage.requestLayout();
- startimage.setScaleType(ImageView.ScaleType.FIT_XY);
- byte[] decode = Base64.decode(Icon(), 0);
- startimage.setImageBitmap(BitmapFactory.decodeByteArray(decode, 0, decode.length));
- ((ViewGroup.MarginLayoutParams) startimage.getLayoutParams()).topMargin = convertDipToPixels(10);
- //Initialize event handlers for buttons, etc.
- startimage.setOnTouchListener(onTouchListener());
- startimage.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- mCollapsed.setVisibility(View.GONE);
- mExpanded.setVisibility(View.VISIBLE);
- }
- });
-
- //********** The icon in Webview to open mod menu **********
- WebView wView = new WebView(this); //Icon size width=\"50\" height=\"50\"
- wView.setLayoutParams(new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
- int applyDimension2 = (int) TypedValue.applyDimension(1, ICON_SIZE, getResources().getDisplayMetrics()); //Icon size
- wView.getLayoutParams().height = applyDimension2;
- wView.getLayoutParams().width = applyDimension2;
- wView.loadData("" +
- "" +
- "" +
- "
" +
- "" +
- "", "text/html", "utf-8");
- wView.setBackgroundColor(0x00000000); //Transparent
- wView.setAlpha(ICON_ALPHA);
- wView.getSettings().setAppCacheEnabled(true);
- wView.setOnTouchListener(onTouchListener());
-
- //********** Settings icon **********
- TextView settings = new TextView(this); //Android 5 can't show ⚙, instead show other icon instead
- settings.setText(Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M ? "⚙" : "\uD83D\uDD27");
- settings.setTextColor(TEXT_COLOR);
- settings.setTypeface(Typeface.DEFAULT_BOLD);
- settings.setTextSize(20.0f);
- RelativeLayout.LayoutParams rlsettings = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- rlsettings.addRule(ALIGN_PARENT_RIGHT);
- settings.setLayoutParams(rlsettings);
- settings.setOnClickListener(new View.OnClickListener() {
- boolean settingsOpen;
-
- @Override
- public void onClick(View v) {
- try {
- settingsOpen = !settingsOpen;
- if (settingsOpen) {
- scrollView.removeView(patches);
- scrollView.addView(mSettings);
- scrollView.scrollTo(0, 0);
- } else {
- scrollView.removeView(mSettings);
- scrollView.addView(patches);
- }
- } catch (IllegalStateException e) {
- }
- }
- });
-
- //********** Settings **********
- mSettings = new LinearLayout(this);
- mSettings.setOrientation(LinearLayout.VERTICAL);
- featureList(settingsList(), mSettings);
-
- //********** Title text **********
- RelativeLayout titleText = new RelativeLayout(this);
- titleText.setPadding(10, 5, 10, 5);
- titleText.setVerticalGravity(16);
-
- TextView title = new TextView(this);
- title.setTextColor(TEXT_COLOR);
- title.setTextSize(18.0f);
- title.setGravity(Gravity.CENTER);
- RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- rl.addRule(RelativeLayout.CENTER_HORIZONTAL);
- title.setLayoutParams(rl);
- setTitleText(title);
-
- //********** Heading text **********
- TextView heading = new TextView(this);
- //heading.setText(Html.fromHtml(Heading()));
- heading.setEllipsize(TextUtils.TruncateAt.MARQUEE);
- heading.setMarqueeRepeatLimit(-1);
- heading.setSingleLine(true);
- heading.setSelected(true);
- heading.setTextColor(TEXT_COLOR);
- heading.setTextSize(10.0f);
- heading.setGravity(Gravity.CENTER);
- heading.setPadding(0, 0, 0, 5);
- setHeadingText(heading);
-
- //********** Mod menu feature list **********
- scrollView = new ScrollView(this);
- //Auto size. To set size manually, change the width and height example 500, 500
- scrlLL = new LinearLayout.LayoutParams(MATCH_PARENT, dp(MENU_HEIGHT));
- scrlLLExpanded = new LinearLayout.LayoutParams(mExpanded.getLayoutParams());
- scrlLLExpanded.weight = 1.0f;
- scrollView.setLayoutParams(Preferences.isExpanded ? scrlLLExpanded : scrlLL);
- scrollView.setBackgroundColor(MENU_FEATURE_BG_COLOR);
- patches = new LinearLayout(this);
- patches.setOrientation(LinearLayout.VERTICAL);
-
- //********** RelativeLayout for buttons **********
- RelativeLayout relativeLayout = new RelativeLayout(this);
- relativeLayout.setPadding(10, 3, 10, 3);
- relativeLayout.setVerticalGravity(Gravity.CENTER);
-
- //********** Hide/Kill button **********
- RelativeLayout.LayoutParams lParamsHideBtn = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- lParamsHideBtn.addRule(ALIGN_PARENT_LEFT);
-
- Button hideBtn = new Button(this);
- hideBtn.setLayoutParams(lParamsHideBtn);
- hideBtn.setBackgroundColor(Color.TRANSPARENT);
- hideBtn.setText("HIDE/KILL (Hold)");
- hideBtn.setTextColor(TEXT_COLOR);
- hideBtn.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- mCollapsed.setVisibility(View.VISIBLE);
- mCollapsed.setAlpha(0);
- mExpanded.setVisibility(View.GONE);
- Toast.makeText(view.getContext(), "Icon hidden. Remember the hidden icon position", Toast.LENGTH_LONG).show();
- }
- });
- hideBtn.setOnLongClickListener(new View.OnLongClickListener() {
- public boolean onLongClick(View view) {
- Toast.makeText(view.getContext(), "Menu service killed", Toast.LENGTH_LONG).show();
- FloatingModMenuService.this.stopSelf();
- return false;
- }
- });
-
- //********** Close button **********
- RelativeLayout.LayoutParams lParamsCloseBtn = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- lParamsCloseBtn.addRule(ALIGN_PARENT_RIGHT);
-
- Button closeBtn = new Button(this);
- closeBtn.setLayoutParams(lParamsCloseBtn);
- closeBtn.setBackgroundColor(Color.TRANSPARENT);
- closeBtn.setText("MINIMIZE");
- closeBtn.setTextColor(TEXT_COLOR);
- closeBtn.setOnClickListener(new View.OnClickListener() {
- public void onClick(View view) {
- mCollapsed.setVisibility(View.VISIBLE);
- mCollapsed.setAlpha(ICON_ALPHA);
- mExpanded.setVisibility(View.GONE);
- }
- });
-
- //********** Params **********
- //Variable to check later if the phone supports Draw over other apps permission
- int iparams = Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ? 2038 : 2002;
- params = new WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, iparams, 8, -3);
- params.gravity = 51;
- params.x = 0;
- params.y = 100;
-
- //********** Adding view components **********
- rootFrame.addView(mRootContainer);
- mRootContainer.addView(mCollapsed);
- mRootContainer.addView(mExpanded);
- if (IconWebViewData() != null) {
- mCollapsed.addView(wView);
- } else {
- mCollapsed.addView(startimage);
- }
- titleText.addView(title);
- titleText.addView(settings);
- mExpanded.addView(titleText);
- mExpanded.addView(heading);
- scrollView.addView(patches);
- mExpanded.addView(scrollView);
- relativeLayout.addView(hideBtn);
- relativeLayout.addView(closeBtn);
- mExpanded.addView(relativeLayout);
- mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
- mWindowManager.addView(rootFrame, params);
-
- final Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- boolean viewLoaded = false;
-
- @Override
- public void run() {
- //If the save preferences is enabled, it will check if game lib is loaded before starting menu
- //Comment the if-else code out except startService if you want to run the app and test preferences
- if (Preferences.loadPref && !isGameLibLoaded() && !stopChecking) {
- if (!viewLoaded) {
- patches.addView(Category("Save preferences was been enabled. Waiting for game lib to be loaded...\n\nForce load menu may not apply mods instantly. You would need to reactivate them again"));
- patches.addView(Button(-100, "Force load menu"));
- viewLoaded = true;
- }
- handler.postDelayed(this, 600);
- } else {
- patches.removeAllViews();
- InjectBtn(patches);
- // featureList(getFeatureList(), patches);
- }
- }
- }, 500);
- }
-
- private View.OnTouchListener onTouchListener() {
- return new View.OnTouchListener() {
- final View collapsedView = mCollapsed;
- final View expandedView = mExpanded;
- private float initialTouchX, initialTouchY;
- private int initialX, initialY;
-
- public boolean onTouch(View view, MotionEvent motionEvent) {
- switch (motionEvent.getAction()) {
- case MotionEvent.ACTION_DOWN:
- initialX = params.x;
- initialY = params.y;
- initialTouchX = motionEvent.getRawX();
- initialTouchY = motionEvent.getRawY();
- return true;
- case MotionEvent.ACTION_UP:
- int rawX = (int) (motionEvent.getRawX() - initialTouchX);
- int rawY = (int) (motionEvent.getRawY() - initialTouchY);
- mExpanded.setAlpha(1f);
- mCollapsed.setAlpha(1f);
- //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
- //So that is click event.
- if (rawX < 10 && rawY < 10 && isViewCollapsed()) {
- //When user clicks on the image view of the collapsed layout,
- //visibility of the collapsed layout will be changed to "View.GONE"
- //and expanded view will become visible.
- try {
- collapsedView.setVisibility(View.GONE);
- expandedView.setVisibility(View.VISIBLE);
- } catch (NullPointerException e) {
-
- }
- }
- return true;
- case MotionEvent.ACTION_MOVE:
- mExpanded.setAlpha(0.5f);
- mCollapsed.setAlpha(0.5f);
- //Calculate the X and Y coordinates of the view.
- params.x = initialX + ((int) (motionEvent.getRawX() - initialTouchX));
- params.y = initialY + ((int) (motionEvent.getRawY() - initialTouchY));
- //Update the layout with new X & Y coordinate
- mWindowManager.updateViewLayout(rootFrame, params);
- return true;
- default:
- return false;
- }
- }
- };
- }
-
- private void featureList(String[] listFT, LinearLayout linearLayout) {
- //Currently looks messy right now. Let me know if you have improvements
- linearLayout.removeAllViews();
- int featNum, subFeat = 0;
- LinearLayout llBak = linearLayout;
-
- for (int i = 0; i < listFT.length; i++) {
- boolean switchedOn = false;
- //Log.i("featureList", listFT[i]);
- String feature = listFT[i];
- if (feature.contains("True_")) {
- switchedOn = true;
- feature = feature.replaceFirst("True_", "");
- }
-
- linearLayout = llBak;
- if (feature.contains("CollapseAdd_")) {
- //if (collapse != null)
- linearLayout = mCollapse;
- feature = feature.replaceFirst("CollapseAdd_", "");
- }
- String[] str = feature.split("_");
-
- //Assign feature number
- if (TextUtils.isDigitsOnly(str[0]) || str[0].matches("-[0-9]*")) {
- featNum = Integer.parseInt(str[0]);
- feature = feature.replaceFirst(str[0] + "_", "");
- subFeat++;
- } else {
- //Subtract feature number. We don't want to count ButtonLink, Category, RichTextView and RichWebView
- featNum = i - subFeat;
- }
- String[] strSplit = feature.split("_");
- switch (strSplit[0]) {
- case "Toggle":
- linearLayout.addView(Switch(featNum, strSplit[1], switchedOn));
- break;
- case "SeekBar":
- linearLayout.addView(SeekBar(featNum, strSplit[1], Integer.parseInt(strSplit[2]), Integer.parseInt(strSplit[3])));
- break;
- case "Button":
- linearLayout.addView(Button(featNum, strSplit[1]));
- break;
- case "ButtonOnOff":
- linearLayout.addView(ButtonOnOff(featNum, strSplit[1], switchedOn));
- break;
- case "Spinner":
- linearLayout.addView(RichTextView(strSplit[1]));
- linearLayout.addView(Spinner(featNum, strSplit[1], strSplit[2]));
- break;
- case "InputText":
- linearLayout.addView(TextField(featNum, strSplit[1], false, 0));
- break;
- case "InputValue":
- if (strSplit.length == 3)
- linearLayout.addView(TextField(featNum, strSplit[2], true, Integer.parseInt(strSplit[1])));
- if (strSplit.length == 2)
- linearLayout.addView(TextField(featNum, strSplit[1], true, 0));
- break;
- case "CheckBox":
- linearLayout.addView(CheckBox(featNum, strSplit[1], switchedOn));
- break;
- case "RadioButton":
- linearLayout.addView(RadioButton(featNum, strSplit[1], strSplit[2]));
- break;
- case "Collapse":
- Collapse(linearLayout, strSplit[1]);
- subFeat++;
- break;
- case "ButtonLink":
- subFeat++;
- linearLayout.addView(ButtonLink(strSplit[1], strSplit[2]));
- break;
- case "Category":
- subFeat++;
- linearLayout.addView(Category(strSplit[1]));
- break;
- case "RichTextView":
- subFeat++;
- linearLayout.addView(RichTextView(strSplit[1]));
- break;
- case "RichWebView":
- subFeat++;
- linearLayout.addView(RichWebView(strSplit[1]));
- break;
- }
- }
- }
-
- private View Switch(final int featNum, final String featName, boolean swiOn) {
- final Switch switchR = new Switch(this);
- ColorStateList buttonStates = new ColorStateList(
- new int[][]{
- new int[]{-android.R.attr.state_enabled},
- new int[]{android.R.attr.state_checked},
- new int[]{}
- },
- new int[]{
- Color.BLUE,
- ToggleON, // ON
- ToggleOFF // OFF
- }
- );
- //Set colors of the switch. Comment out if you don't like it
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- switchR.getThumbDrawable().setTintList(buttonStates);
- switchR.getTrackDrawable().setTintList(buttonStates);
- }
- switchR.setText(featName);
- switchR.setTextColor(TEXT_COLOR_2);
- switchR.setPadding(10, 5, 0, 5);
- switchR.setChecked(Preferences.loadPrefBool(featName, featNum, swiOn));
- switchR.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- public void onCheckedChanged(CompoundButton compoundButton, boolean bool) {
- Preferences.changeFeatureBool(featName, featNum, bool);
- switch (featNum) {
- case -1: //Save perferences
- Preferences.with(switchR.getContext()).writeBoolean(-1, bool);
- if (bool == false)
- Preferences.with(switchR.getContext()).clear(); //Clear perferences if switched off
- break;
- case -3:
- Preferences.isExpanded = bool;
- scrollView.setLayoutParams(bool ? scrlLLExpanded : scrlLL);
- break;
- }
- }
- });
- return switchR;
- }
-
- private View SeekBar(final int featNum, final String featName, final int min, int max) {
- int loadedProg = Preferences.loadPrefInt(featName, featNum);
- LinearLayout linearLayout = new LinearLayout(this);
- linearLayout.setPadding(10, 5, 0, 5);
- linearLayout.setOrientation(LinearLayout.VERTICAL);
- linearLayout.setGravity(Gravity.CENTER);
-
- final TextView textView = new TextView(this);
- textView.setText(Html.fromHtml(featName + ": " + ((loadedProg == 0) ? min : loadedProg)));
- textView.setTextColor(TEXT_COLOR_2);
-
- SeekBar seekBar = new SeekBar(this);
- seekBar.setPadding(25, 10, 35, 10);
- seekBar.setMax(max);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
- seekBar.setMin(min); //setMin for Oreo and above
- seekBar.setProgress((loadedProg == 0) ? min : loadedProg);
- seekBar.getThumb().setColorFilter(SeekBarColor, PorterDuff.Mode.SRC_ATOP);
- seekBar.getProgressDrawable().setColorFilter(SeekBarProgressColor, PorterDuff.Mode.SRC_ATOP);
- seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
-
- public void onStopTrackingTouch(SeekBar seekBar) {
- }
-
- public void onProgressChanged(SeekBar seekBar, int i, boolean z) {
- //if progress is greater than minimum, don't go below. Else, set progress
- seekBar.setProgress(i < min ? min : i);
- Preferences.changeFeatureInt(featName, featNum, i < min ? min : i);
- textView.setText(Html.fromHtml(featName + ": " + (i < min ? min : i)));
- }
- });
- linearLayout.addView(textView);
- linearLayout.addView(seekBar);
-
- return linearLayout;
- }
-
- private View Button(final int featNum, final String featName) {
- final Button button = new Button(this);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- layoutParams.setMargins(7, 5, 7, 5);
- button.setLayoutParams(layoutParams);
- button.setTextColor(TEXT_COLOR_2);
- button.setAllCaps(false); //Disable caps to support html
- button.setText(Html.fromHtml(featName));
- button.setBackgroundColor(BTN_COLOR);
- button.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- switch (featNum) {
- case -4:
- Logcat.Save(getApplicationContext());
- break;
- case -5:
- Logcat.Clear(getApplicationContext());
- break;
- case -6:
- scrollView.removeView(mSettings);
- scrollView.addView(patches);
- break;
- case -100:
- stopChecking = true;
- break;
- }
- Preferences.changeFeatureInt(featName, featNum, 0);
- }
- });
-
- return button;
- }
-
- private View ButtonLink(final String featName, final String url) {
- final Button button = new Button(this);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- layoutParams.setMargins(7, 5, 7, 5);
- button.setLayoutParams(layoutParams);
- button.setAllCaps(false); //Disable caps to support html
- button.setTextColor(TEXT_COLOR_2);
- button.setText(Html.fromHtml(featName));
- button.setBackgroundColor(BTN_COLOR);
- button.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setData(Uri.parse(url));
- startActivity(intent);
- }
- });
- return button;
- }
-
- private View ButtonOnOff(final int featNum, String featName, boolean switchedOn) {
- final Button button = new Button(this);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- layoutParams.setMargins(7, 5, 7, 5);
- button.setLayoutParams(layoutParams);
- button.setTextColor(TEXT_COLOR_2);
- button.setAllCaps(false); //Disable caps to support html
-
- final String finalfeatName = featName.replace("OnOff_", "");
- boolean isOn = Preferences.loadPrefBool(featName, featNum, switchedOn);
- if (isOn) {
- button.setText(Html.fromHtml(finalfeatName + ": ON"));
- button.setBackgroundColor(BtnON);
- isOn = false;
- } else {
- button.setText(Html.fromHtml(finalfeatName + ": OFF"));
- button.setBackgroundColor(BtnOFF);
- isOn = true;
- }
- final boolean finalIsOn = isOn;
- button.setOnClickListener(new View.OnClickListener() {
- boolean isOn = finalIsOn;
-
- public void onClick(View v) {
- Preferences.changeFeatureBool(finalfeatName, featNum, isOn);
- //Log.d(TAG, finalfeatName + " " + featNum + " " + isActive2);
- if (isOn) {
- button.setText(Html.fromHtml(finalfeatName + ": ON"));
- button.setBackgroundColor(BtnON);
- isOn = false;
- } else {
- button.setText(Html.fromHtml(finalfeatName + ": OFF"));
- button.setBackgroundColor(BtnOFF);
- isOn = true;
- }
- }
- });
- return button;
- }
-
- private View Spinner(final int featNum, final String featName, final String list) {
- Log.d(TAG, "spinner " + featNum + " " + featName + " " + list);
- final List lists = new LinkedList<>(Arrays.asList(list.split(",")));
-
- // Create another LinearLayout as a workaround to use it as a background
- // to keep the down arrow symbol. No arrow symbol if setBackgroundColor set
- LinearLayout linearLayout2 = new LinearLayout(this);
- LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
- layoutParams2.setMargins(7, 2, 7, 5);
- linearLayout2.setOrientation(LinearLayout.VERTICAL);
- linearLayout2.setBackgroundColor(BTN_COLOR);
- linearLayout2.setLayoutParams(layoutParams2);
-
- final Spinner spinner = new Spinner(this, Spinner.MODE_DROPDOWN);
- spinner.setLayoutParams(layoutParams2);
- spinner.getBackground().setColorFilter(1, PorterDuff.Mode.SRC_ATOP); //trick to show white down arrow color
- //Creating the ArrayAdapter instance having the list
- ArrayAdapter aa = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, lists);
- aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- //Setting the ArrayAdapter data on the Spinner'
- spinner.setAdapter(aa);
- spinner.setSelection(Preferences.loadPrefInt(featName, featNum));
- spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parentView, View selectedItemView, int position, long id) {
- Preferences.changeFeatureInt(spinner.getSelectedItem().toString(), featNum, position);
- ((TextView) parentView.getChildAt(0)).setTextColor(TEXT_COLOR_2);
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- }
- });
- linearLayout2.addView(spinner);
- return linearLayout2;
- }
-
- private View TextField(final int featNum, final String featName, final boolean numOnly, final int maxValue) {
- final EditTextString edittextstring = new EditTextString();
- final EditTextNum edittextnum = new EditTextNum();
- LinearLayout linearLayout = new LinearLayout(this);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- layoutParams.setMargins(7, 5, 7, 5);
-
- final Button button = new Button(this);
- if (numOnly) {
- int num = Preferences.loadPrefInt(featName, featNum);
- edittextnum.setNum((num == 0) ? 1 : num);
- button.setText(Html.fromHtml(featName + ": " + ((num == 0) ? 1 : num) + ""));
- } else {
- String string = Preferences.loadPrefString(featName, featNum);
- edittextstring.setString((string == "") ? "" : string);
- button.setText(Html.fromHtml(featName + ": " + string + ""));
- }
- button.setAllCaps(false);
- button.setLayoutParams(layoutParams);
- button.setBackgroundColor(BTN_COLOR);
- button.setTextColor(TEXT_COLOR_2);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- final AlertDialog alert = new AlertDialog.Builder(getApplicationContext(), 2).create();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- Objects.requireNonNull(alert.getWindow()).setType(Build.VERSION.SDK_INT >= 26 ? 2038 : 2002);
- }
- alert.setOnCancelListener(new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- InputMethodManager imm = (InputMethodManager) getSystemService(getApplicationContext().INPUT_METHOD_SERVICE);
- imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
- }
- });
-
- //LinearLayout
- LinearLayout linearLayout1 = new LinearLayout(getApplicationContext());
- linearLayout1.setPadding(5, 5, 5, 5);
- linearLayout1.setOrientation(LinearLayout.VERTICAL);
- linearLayout1.setBackgroundColor(MENU_FEATURE_BG_COLOR);
-
- //TextView
- final TextView TextViewNote = new TextView(getApplicationContext());
- TextViewNote.setText("Tap OK to apply changes. Tap outside to cancel");
- if (maxValue != 0)
- TextViewNote.setText("Tap OK to apply changes. Tap outside to cancel\nMax value: " + maxValue);
- TextViewNote.setTextColor(TEXT_COLOR_2);
-
- //Edit text
- final EditText edittext = new EditText(getApplicationContext());
- edittext.setMaxLines(1);
- edittext.setWidth(convertDipToPixels(300));
- edittext.setTextColor(TEXT_COLOR_2);
- if (numOnly) {
- edittext.setInputType(InputType.TYPE_CLASS_NUMBER);
- edittext.setKeyListener(DigitsKeyListener.getInstance("0123456789-"));
- InputFilter[] FilterArray = new InputFilter[1];
- FilterArray[0] = new InputFilter.LengthFilter(10);
- edittext.setFilters(FilterArray);
- } else {
- edittext.setText(edittextstring.getString());
- }
- edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- InputMethodManager imm = (InputMethodManager) getSystemService(getApplicationContext().INPUT_METHOD_SERVICE);
- if (hasFocus) {
- imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
- } else {
- imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
- }
- }
- });
- edittext.requestFocus();
-
- //Button
- Button btndialog = new Button(getApplicationContext());
- btndialog.setBackgroundColor(BTN_COLOR);
- btndialog.setTextColor(TEXT_COLOR_2);
- btndialog.setText("OK");
- btndialog.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (numOnly) {
- int num;
- try {
- num = Integer.parseInt(TextUtils.isEmpty(edittext.getText().toString()) ? "0" : edittext.getText().toString());
- if (maxValue != 0 && num >= maxValue)
- num = maxValue;
- } catch (NumberFormatException ex) {
- num = 2147483640;
- }
- edittextnum.setNum(num);
- button.setText(Html.fromHtml(featName + ": " + num + ""));
- alert.dismiss();
- Preferences.changeFeatureInt(featName, featNum, num);
- } else {
- String str = edittext.getText().toString();
- edittextstring.setString(edittext.getText().toString());
- button.setText(Html.fromHtml(featName + ": " + str + ""));
- alert.dismiss();
- Preferences.changeFeatureString(featName, featNum, str);
- }
- edittext.setFocusable(false);
- }
- });
-
- linearLayout1.addView(TextViewNote);
- linearLayout1.addView(edittext);
- linearLayout1.addView(btndialog);
- alert.setView(linearLayout1);
- alert.show();
- }
- });
-
- linearLayout.addView(button);
- return linearLayout;
- }
-
- private View CheckBox(final int featNum, final String featName, boolean switchedOn) {
- final CheckBox checkBox = new CheckBox(this);
- checkBox.setText(featName);
- checkBox.setTextColor(TEXT_COLOR_2);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- checkBox.setButtonTintList(ColorStateList.valueOf(CheckBoxColor));
- checkBox.setChecked(Preferences.loadPrefBool(featName, featNum, switchedOn));
- checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (checkBox.isChecked()) {
- Preferences.changeFeatureBool(featName, featNum, isChecked);
- } else {
- Preferences.changeFeatureBool(featName, featNum, isChecked);
- }
- }
- });
- return checkBox;
- }
-
- private View RadioButton(final int featNum, String featName, final String list) {
- //Credit: LoraZalora
- final List lists = new LinkedList<>(Arrays.asList(list.split(",")));
-
- final TextView textView = new TextView(this);
- textView.setText(featName + ":");
- textView.setTextColor(TEXT_COLOR_2);
-
- final RadioGroup radioGroup = new RadioGroup(this);
- radioGroup.setPadding(10, 5, 10, 5);
- radioGroup.setOrientation(LinearLayout.VERTICAL);
- radioGroup.addView(textView);
-
- for (int i = 0; i < lists.size(); i++) {
- final RadioButton Radioo = new RadioButton(this);
- final String finalfeatName = featName, radioName = lists.get(i);
- View.OnClickListener first_radio_listener = new View.OnClickListener() {
- public void onClick(View v) {
- textView.setText(Html.fromHtml(finalfeatName + ": " + radioName));
- Preferences.changeFeatureInt(finalfeatName, featNum, radioGroup.indexOfChild(Radioo));
- }
- };
- System.out.println(lists.get(i));
- Radioo.setText(lists.get(i));
- Radioo.setTextColor(Color.LTGRAY);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- Radioo.setButtonTintList(ColorStateList.valueOf(RadioColor));
- Radioo.setOnClickListener(first_radio_listener);
- radioGroup.addView(Radioo);
- }
-
- int index = Preferences.loadPrefInt(featName, featNum);
- if (index > 0) { //Preventing it to get an index less than 1. below 1 = null = crash
- textView.setText(Html.fromHtml(featName + ": " + lists.get(index - 1)));
- ((RadioButton) radioGroup.getChildAt(index)).setChecked(true);
- }
-
- return radioGroup;
- }
-
- private void Collapse(LinearLayout linLayout, final String text) {
- LinearLayout.LayoutParams layoutParamsLL = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- layoutParamsLL.setMargins(0, 5, 0, 0);
-
- LinearLayout collapse = new LinearLayout(this);
- collapse.setLayoutParams(layoutParamsLL);
- collapse.setVerticalGravity(16);
- collapse.setOrientation(LinearLayout.VERTICAL);
-
- final LinearLayout collapseSub = new LinearLayout(this);
- collapseSub.setVerticalGravity(16);
- collapseSub.setPadding(0, 5, 0, 5);
- collapseSub.setOrientation(LinearLayout.VERTICAL);
- collapseSub.setBackgroundColor(Color.parseColor("#222D38"));
- collapseSub.setVisibility(View.GONE);
- mCollapse = collapseSub;
-
- final TextView textView = new TextView(this);
- textView.setBackgroundColor(CategoryBG);
- textView.setText("▽ " + text + " ▽");
- textView.setGravity(Gravity.CENTER);
- textView.setTextColor(TEXT_COLOR_2);
- textView.setTypeface(null, Typeface.BOLD);
- textView.setPadding(0, 20, 0, 20);
- textView.setOnClickListener(new View.OnClickListener() {
- boolean isChecked;
-
- @Override
- public void onClick(View v) {
-
- boolean z = !this.isChecked;
- this.isChecked = z;
- if (z) {
- collapseSub.setVisibility(View.VISIBLE);
- textView.setText("△ " + text + " △");
- return;
- }
- collapseSub.setVisibility(View.GONE);
- textView.setText("▽ " + text + " ▽");
- }
- });
- collapse.addView(textView);
- collapse.addView(collapseSub);
- linLayout.addView(collapse);
- }
-
- private View Category(String text) {
- TextView textView = new TextView(this);
- textView.setBackgroundColor(CategoryBG);
- textView.setText(Html.fromHtml(text));
- textView.setGravity(Gravity.CENTER);
- textView.setTextColor(TEXT_COLOR_2);
- textView.setTypeface(null, Typeface.BOLD);
- textView.setPadding(0, 5, 0, 5);
- return textView;
- }
-
- private View RichTextView(String text) {
- TextView textView = new TextView(this);
- textView.setText(Html.fromHtml(text));
- textView.setTextColor(TEXT_COLOR_2);
- textView.setPadding(10, 5, 10, 5);
- return textView;
- }
-
- private View RichWebView(String text) {
- WebView wView = new WebView(this);
- wView.loadData(text, "text/html", "utf-8");
- wView.setBackgroundColor(0x00000000); //Transparent
- wView.setPadding(0, 5, 0, 5);
- wView.getSettings().setAppCacheEnabled(false);
- return wView;
- }
- private void InjectBtn(LinearLayout l) {
- l.removeAllViews();
- TextView textView = new TextView(this);
- textView.setBackgroundColor(Color.parseColor("#00000000"));
- textView.setText("First, Try to inject with Root Method, It will work On Virtual Also. \n If Virtual Crashes Try Virtual Method");
- textView.setGravity(Gravity.CENTER_HORIZONTAL);
- textView.setTextSize(14.0f);
- textView.setTextColor(Color.YELLOW);
- textView.setTypeface(null, Typeface.BOLD);
- textView.setPadding(10, 5, 0, 5);
-
-
- final Button button = new Button(this);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- layoutParams.setMargins(7, 5, 7, 5);
- button.setLayoutParams(layoutParams);
- button.setTextColor(TEXT_COLOR_2);
- button.setAllCaps(false); //Disable caps to support html
- button.setText(Html.fromHtml("Inject On Virtual [Vmos ++]"));
- button.setBackgroundColor(BTN_COLOR);
-
- final Button button2 = new Button(this);
-
- button2.setLayoutParams(layoutParams);
- button2.setTextColor(TEXT_COLOR_2);
- button2.setAllCaps(false); //Disable caps to support html
- button2.setText(Html.fromHtml("Inject On Root [Magisk ++]"));
- button2.setBackgroundColor(BTN_COLOR);
-
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (InjectVirtual(LibName)) {
- if (IsConnected()){
- featureList(getFeatureList(), patches);
-
- Toast.makeText(FloatingModMenuService.this, "Injection Success!", Toast.LENGTH_LONG).show();
- button.setVisibility(View.GONE);
-
- } else {
-
- // button.setVisibility(View.GONE);
-
- String[] NotInjected = {"Category_Not Injected"};
- featureList(NotInjected, patches);
- Toast.makeText(FloatingModMenuService.this, "Injection Failed!", Toast.LENGTH_LONG).show();
-
- }
- } else {
- button.setEnabled(true);
- }
- }
- });
- button2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (InjectRoot(LibName)) {
- if (IsConnected()){
- featureList(getFeatureList(), patches);
-
- Toast.makeText(FloatingModMenuService.this, "Injection Success!", Toast.LENGTH_LONG).show();
- button.setVisibility(View.GONE);
-
- } else {
-
- //button.setVisibility(View.GONE);
-
- String[] NotInjected = {"Category_Not Injected"};
- featureList(NotInjected, patches);
- Toast.makeText(FloatingModMenuService.this, "Injection Failed!", Toast.LENGTH_LONG).show();
-
- }
- } else {
- button.setEnabled(true);
- }
- }
- });
-
-
-
- l.addView(textView);
- l.addView(button);
- l.addView(button2);
-
- }
-
- public static int getProcessID(String pkg) {
-
- int pid = -1;
- if (Shell.rootAccess()) {
- String cmd = "for p in /proc/[0-9]*; do [[ $(<$p/cmdline) = " + pkg + " ]] && echo ${p##*/}; done";
- List outs = new ArrayList<>();
- Shell.su(cmd).to(outs).exec();
- if (outs.size() > 0) {
- pid = Integer.parseInt(outs.get(0));
- }
- } else {
- Shell.Result out = Shell.sh("/system/bin/ps -A | grep \"" + pkg + "\"").exec();
- List output = out.getOut();
- if (output.isEmpty() || output.get(0).contains("bad pid")) {
- out = Shell.sh("/system/bin/ps | grep \"" + pkg + "\"").exec();
- output = out.getOut();
- if (!output.isEmpty() && !output.get(0).contains("bad pid")) {
- for (int i = 0; i < output.size(); i++) {
- String[] results = output.get(i).trim().replaceAll("( )+", ",").replaceAll("(\n)+", ",").split(",");
- if (results[8].equals(pkg)) {
- pid = Integer.parseInt(results[1]);
- }
- }
- }
- } else {
- for (int i = 0; i < output.size(); i++) {
- String[] results = output.get(i).trim().replaceAll("( )+", ",").replaceAll("(\n)+", ",").split(",");
- for (int j = 0; j < results.length; j++) {
- if (results[j].equals(pkg)) {
- pid = Integer.parseInt(results[j - 7]);
- }
- }
- }
- }
- }
- return pid;
- }
-
- private boolean InjectRoot(String Lib) {
- try {
- String target = targetPackage;
- String injector = this.getApplicationInfo().nativeLibraryDir + File.separator + "libGlobalInject.so";
- String payload_source = this.getApplicationInfo().nativeLibraryDir + File.separator + Lib;
- String payload_dest = "/data/local/tmp/"+Lib;
- String context = "u:object_r:system_lib_file:s0";
- List STDOUT = new ArrayList<>();
- Shell.su("ls -lZ /system/lib/libandroid_runtime.so").to(STDOUT).exec();
- for (String line : STDOUT) {
- if (line.contains(" u:object_r:") && line.contains(":s0 ")) {
- context = line.substring(line.indexOf("u:object_r:"));
- context = context.substring(0, context.indexOf(' '));
- }
- }
- Shell.su("cp " + payload_source + " " + payload_dest).exec();
- Shell.su("chmod 777 " + payload_dest).exec();
- Shell.su("chcon " + context + " " + payload_dest).exec();
- while (getProcessID(target) <= 0) {}
- Thread.sleep(1000);
- int pid = getProcessID(target);
- String command = String.format(Locale.ENGLISH,"%s %d %s", injector, pid, payload_dest);
- Shell.su(command).exec();
- Init();
- return true;
- } catch (Exception e) {
- e.printStackTrace();
-
- return false;
- }
- }
- private boolean InjectVirtual(String Lib) {
- try {
- String target = targetPackage;
- String injector = this.getApplicationInfo().nativeLibraryDir + File.separator + "libVirtualInject.so";
- String payload_source = this.getApplicationInfo().nativeLibraryDir + File.separator + Lib;
- String payload_dest = "/data/local/tmp/"+Lib;
- String context = "u:object_r:system_lib_file:s0";
- List STDOUT = new ArrayList<>();
- Shell.su("ls -lZ /system/lib/libandroid_runtime.so").to(STDOUT).exec();
- for (String line : STDOUT) {
- if (line.contains(" u:object_r:") && line.contains(":s0 ")) {
- context = line.substring(line.indexOf("u:object_r:"));
- context = context.substring(0, context.indexOf(' '));
- }
- }
- Shell.su("cp " + payload_source + " " + payload_dest).exec();
- Shell.su("chmod 777 " + payload_dest).exec();
- Shell.su("chcon " + context + " " + payload_dest).exec();
- while (getProcessID(target) <= 0) {}
- Thread.sleep(1000);
- int pid = getProcessID(target);
- String command = String.format(Locale.ENGLISH,"%s %d %s", injector, pid, payload_dest);
- Shell.su(command).exec();
- Init();
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
-
- }
- //Override our Start Command so the Service doesnt try to recreate itself when the App is closed
- public int onStartCommand(Intent intent, int i, int i2) {
- return Service.START_NOT_STICKY;
- }
-
- private boolean isViewCollapsed() {
- return rootFrame == null || mCollapsed.getVisibility() == View.VISIBLE;
- }
-
- //For our image a little converter
- private int convertDipToPixels(int i) {
- return (int) ((((float) i) * getResources().getDisplayMetrics().density) + 0.5f);
- }
-
- private int dp(int i) {
- return (int) TypedValue.applyDimension(1, (float) i, getResources().getDisplayMetrics());
- }
-
- //Check if we are still in the game. If now our menu and menu button will dissapear
- private boolean isNotInGame() {
- RunningAppProcessInfo runningAppProcessInfo = new RunningAppProcessInfo();
- ActivityManager.getMyMemoryState(runningAppProcessInfo);
- return runningAppProcessInfo.importance != 100;
- }
-
- //Destroy our View
- public void onDestroy() {
- super.onDestroy();
- if (rootFrame != null) {
- mWindowManager.removeView(rootFrame);
- }
- }
-
- //Same as above so it wont crash in the background and therefore use alot of Battery life
- public void onTaskRemoved(Intent intent) {
- super.onTaskRemoved(intent);
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- stopSelf();
- }
-
- private void Thread() {
- if (rootFrame == null) {
- return;
- }
- }
-
- private class EditTextString {
- private String text;
-
- public void setString(String s) {
- text = s;
- }
-
- public String getString() {
- return text;
- }
- }
-
- private class EditTextNum {
- private int val;
-
- public void setNum(int i) {
- val = i;
- }
-
- public int getNum() {
- return val;
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/app/src/main/java/uk/lgl/modmenu/Logcat.java b/app/src/main/java/uk/lgl/modmenu/Logcat.java
deleted file mode 100644
index 43f1b4a..0000000
--- a/app/src/main/java/uk/lgl/modmenu/Logcat.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package uk.lgl.modmenu;
-
-import android.content.Context;
-import android.os.Build;
-import android.util.Log;
-import android.widget.Toast;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-public class Logcat {
- public static void Clear(Context context) {
- try {
- Runtime.getRuntime().exec("logcat -c");
- Toast.makeText(context, "Logcat cleared", Toast.LENGTH_LONG).show();
- } catch (IOException e) {
- Toast.makeText(context, "There was an error saving logcat to file", Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- }
-
- public static void Save(Context context) {
- File path = null;
- try {
- Process process = Runtime.getRuntime().exec("logcat -d");
- BufferedReader bufferedReader = new BufferedReader(
- new InputStreamReader(process.getInputStream()));
-
- StringBuilder log = new StringBuilder();
- String line = "";
- while ((line = bufferedReader.readLine()) != null) {
- log.append(line + "\n");
- }
- long unixTime = System.currentTimeMillis() / 1000L;
- if (Build.VERSION.SDK_INT >= 30) { //Android R. AIDE didn't support Build.VERSION_CODES.R
- path = new File("/storage/emulated/0/Documents/");
- } else {
- path = new File(context.getExternalFilesDir(null) + "/Mod Menu");
- }
-
- File folder = new File(String.valueOf(path));
- folder.mkdirs();
-
- File file = new File(path + "/Mod menu log - " + context.getPackageName() + ".txt");
- file.createNewFile();
-
- try {
- //BufferedWriter for performance, true to set append to file flag
- BufferedWriter buf = new BufferedWriter(new FileWriter(file));
- buf.append(log.toString());
- buf.newLine();
- buf.close();
- Toast.makeText(context, "Logcat saved successfully to: " + file.toString(), Toast.LENGTH_LONG).show();
- Toast.makeText(context, "Logcat saved successfully to: " + file.toString(), Toast.LENGTH_LONG).show();
- } catch (IOException e) {
- Toast.makeText(context, "There was an error saving logcat to file: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- } catch (IOException e) {
- Toast.makeText(context, "There was an error saving logcat to file: " + Log.getStackTraceString(e), Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- }
-}
diff --git a/app/src/main/java/uk/lgl/modmenu/NepCaller.java b/app/src/main/java/uk/lgl/modmenu/NepCaller.java
deleted file mode 100644
index 43a4af2..0000000
--- a/app/src/main/java/uk/lgl/modmenu/NepCaller.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package uk.lgl.modmenu;
-
-
-import android.app.Application;
-import eu.chainfire.libsuperuser.Shell;
-import java.io.IOException;
-
-public class NepCaller extends Application {
-
- @Override
- public void onCreate() {
- super.onCreate();
- try {
- Runtime.getRuntime().exec("su");
- Shell.SU.run("setenforce 0");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/app/src/main/java/uk/lgl/modmenu/NepEsp.java b/app/src/main/java/uk/lgl/modmenu/NepEsp.java
deleted file mode 100644
index 2a33a3d..0000000
--- a/app/src/main/java/uk/lgl/modmenu/NepEsp.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package uk.lgl.modmenu;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
-import android.graphics.Paint.Style;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.os.Process;
-import android.util.Log;
-import android.view.View;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-import uk.lgl.modmenu.FloatingModMenuService;
-
-public class NepEsp extends View implements Runnable {
- Paint mStrokePaint;
- Paint mFilledPaint;
- Paint mTextPaint;
- Thread mThread;
- int FPS = 60;
- long sleepTime;
- Date time;
- SimpleDateFormat formatter;
-
-
- public NepEsp(Context context) {
- super(context, null, 0);
- InitializePaints();
- setFocusableInTouchMode(false);
- setBackgroundColor(Color.TRANSPARENT);
- time = new Date();
- formatter = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
- sleepTime = 1000 / FPS;
- mThread = new Thread(this);
- mThread.start();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (canvas != null && getVisibility() == VISIBLE) {
- ClearCanvas(canvas);
- time.setTime(System.currentTimeMillis());
- FloatingModMenuService.DrawOn(this, canvas);
- }
- }
-
- @Override
- public void run() {
- android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
- while (mThread.isAlive() && !mThread.isInterrupted()) {
- try {
- long t1 = System.currentTimeMillis();
- postInvalidate();
- long td = System.currentTimeMillis() - t1;
- Thread.sleep(Math.max(Math.min(0, sleepTime - td), sleepTime));
- } catch (InterruptedException it) {
- Log.e("OverlayThread", it.getMessage());
- }
- }
- }
-
- public void InitializePaints() {
- mStrokePaint = new Paint();
- mStrokePaint.setStyle(Paint.Style.STROKE);
- mStrokePaint.setAntiAlias(true);
- mStrokePaint.setColor(Color.rgb(0, 0, 0));
-
- mFilledPaint = new Paint();
- mFilledPaint.setStyle(Paint.Style.FILL);
- mFilledPaint.setAntiAlias(true);
- mFilledPaint.setColor(Color.rgb(0, 0, 0));
-
- mTextPaint = new Paint();
- mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mTextPaint.setAntiAlias(true);
- mTextPaint.setColor(Color.rgb(0, 0, 0));
- mTextPaint.setTextAlign(Paint.Align.CENTER);
- mTextPaint.setStrokeWidth(1.1f);
- }
-
- public void ClearCanvas(Canvas cvs) {
- cvs.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
- }
-
- public void DrawLine(Canvas cvs, int a, int r, int g, int b, float lineWidth, float fromX, float fromY, float toX, float toY) {
- mStrokePaint.setColor(Color.rgb(r, g, b));
- mStrokePaint.setAlpha(a);
- mStrokePaint.setStrokeWidth(lineWidth);
- cvs.drawLine(fromX, fromY, toX, toY, mStrokePaint);
- }
-
- public void DrawText(Canvas cvs, int a, int r, int g, int b, String txt, float posX, float posY, float size) {
- mTextPaint.setColor(Color.rgb(r, g, b));
- mTextPaint.setAlpha(a);
-
- if (getRight() > 1920 || getBottom() > 1920)
- mTextPaint.setTextSize(4 + size);
- else if (getRight() == 1920 || getBottom() == 1920)
- mTextPaint.setTextSize(2 + size);
- else
- mTextPaint.setTextSize(size);
- cvs.drawText(txt, posX, posY, mTextPaint);
- }
-
- public void DrawCircle(Canvas cvs, int a, int r, int g, int b, float stroke, float posX, float posY, float radius) {
- mStrokePaint.setColor(Color.rgb(r, g, b));
- mStrokePaint.setAlpha(a);
- mStrokePaint.setStrokeWidth(stroke);
- cvs.drawCircle(posX, posY, radius, mStrokePaint);
- }
-
- public void DrawFilledCircle(Canvas cvs, int a, int r, int g, int b, float posX, float posY, float radius) {
- mFilledPaint.setColor(Color.rgb(r, g, b));
- mFilledPaint.setAlpha(a);
- cvs.drawCircle(posX, posY, radius, mFilledPaint);
- }
-
- public void DrawRect(Canvas cvs, int a, int r, int g, int b, int stroke, float x, float y, float width, float height) {
- mStrokePaint.setStrokeWidth(stroke);
- mStrokePaint.setColor(Color.rgb(r, g, b));
- mStrokePaint.setAlpha(a);
- cvs.drawRect(x, y, x + width, y + height, mStrokePaint);
- }
-
- public void DrawFilledRect(Canvas cvs, int a, int r, int g, int b, float x, float y, float width, float height) {
- mFilledPaint.setColor(Color.rgb(r, g, b));
- mFilledPaint.setAlpha(a);
- cvs.drawRect(x, y, x + width, y + height, mFilledPaint);
- }
- }
diff --git a/app/src/main/java/uk/lgl/modmenu/NepRoot.java b/app/src/main/java/uk/lgl/modmenu/NepRoot.java
deleted file mode 100644
index 89f2327..0000000
--- a/app/src/main/java/uk/lgl/modmenu/NepRoot.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package uk.lgl.modmenu;
-
-import android.app.Dialog;
-import android.content.Intent;
-import android.graphics.drawable.ColorDrawable;
-import android.os.AsyncTask;
-import android.widget.ProgressBar;
-import android.widget.Toast;
-import eu.chainfire.libsuperuser.Shell;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import android.app.AlertDialog;
-import android.app.Activity;
-import uk.lgl.MainActivity;
-
-public class NepRoot extends Activity {
-
- public static native int Init();
-
- private MainActivity thiz;
-
- public NepRoot(MainActivity thiz) {
- this.thiz = thiz;
- }
-
- public void showNoRootMessage() {
- (new AlertDialog.Builder(thiz))
- .setMessage("Could not acquire root")
- .setNegativeButton(android.R.string.ok, null)
- .show();
- }
-
- public int Game(String pkg) {
- try {
- ArrayList arrayList = new ArrayList();
- Shell.PoolWrapper poolWrapper = Shell.Pool.SU;
- poolWrapper.run("(toolbox ps; toolbox ps -A; toybox ps; toybox ps -A) | grep \" " + pkg + "$\"", arrayList, null, false);
- Iterator iterator = arrayList.iterator();
- while (iterator.hasNext()) {
- String Trim = ((String) iterator.next()).trim();
- while (Trim.contains(" ")) {
- Trim = Trim.replace(" ", " ");
- }
- String[] Split = Trim.split(" ");
- if (Split.length >= 2) {
- return Integer.parseInt(Split[1]);
- }
- }
- return -1;
- } catch (Shell.ShellDiedException e) {
- e.printStackTrace();
- return -1;
- }
- }
-}
diff --git a/app/src/main/java/uk/lgl/modmenu/Preferences.java b/app/src/main/java/uk/lgl/modmenu/Preferences.java
deleted file mode 100644
index 1aebc26..0000000
--- a/app/src/main/java/uk/lgl/modmenu/Preferences.java
+++ /dev/null
@@ -1,488 +0,0 @@
-package uk.lgl.modmenu;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.os.Build;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import static android.preference.PreferenceManager.getDefaultSharedPreferences;
-
-public class Preferences {
- private static SharedPreferences sharedPreferences;
- private static Preferences prefsInstance;
- public static Context context;
- public static boolean loadPref, isExpanded;
-
- private static final String LENGTH = "_length";
- private static final String DEFAULT_STRING_VALUE = "";
- private static final int DEFAULT_INT_VALUE = 0; //-1
- private static final double DEFAULT_DOUBLE_VALUE = 0d; //-1d
- private static final float DEFAULT_FLOAT_VALUE = 0f; //-1f
- private static final long DEFAULT_LONG_VALUE = 0L; //-1L
- private static final boolean DEFAULT_BOOLEAN_VALUE = false;
-
- public static native void Changes(Context con, int fNum, String fName, int i, boolean bool, String str);
-
- public static void changeFeatureInt(String featureName, int featureNum, int value) {
- Preferences.with(context).writeInt(featureNum, value);
- Changes(context, featureNum, featureName, value, false, null);
- }
-
- public static void changeFeatureString(String featureName, int featureNum, String str) {
- Preferences.with(context).writeString(featureNum, str);
- Changes(context, featureNum, featureName, 0, false, str);
- }
-
- public static void changeFeatureBool(String featureName, int featureNum, boolean bool) {
- Preferences.with(context).writeBoolean(featureNum, bool);
- Changes(context, featureNum, featureName, 0, bool, null);
- }
-
- public static int loadPrefInt(String featureName, int featureNum) {
- if (loadPref) {
- int i = Preferences.with(context).readInt(featureNum);
- Changes(context, featureNum, featureName, i, false, null);
- return i;
- }
- return 0;
- }
-
- public static boolean loadPrefBool(String featureName, int featureNum, boolean bDef) {
- boolean bool = Preferences.with(context).readBoolean(featureNum, bDef);
- if (featureNum == -1) {
- loadPref = bool;
- }
- if (featureNum == -3) {
- isExpanded = bool;
- }
- if (loadPref || featureNum < 0) {
- bDef = bool;
- }
-
- Changes(context, featureNum, featureName, 0, bDef, null);
- return bDef;
- }
-
- public static String loadPrefString(String featureName, int featureNum) {
- if (loadPref || featureNum <= 0) {
- String str = Preferences.with(context).readString(featureNum);
- Changes(context, featureNum, featureName, 0, false, str);
- return str;
- }
- return "";
- }
-
- private Preferences(Context context) {
- sharedPreferences = context.getApplicationContext().getSharedPreferences(
- context.getPackageName() + "_preferences",
- Context.MODE_PRIVATE
- );
- }
-
- private Preferences(Context context, String preferencesName) {
- sharedPreferences = context.getApplicationContext().getSharedPreferences(
- preferencesName,
- Context.MODE_PRIVATE
- );
- }
-
- /**
- * @param context
- * @return Returns a 'Preferences' instance
- */
- public static Preferences with(Context context) {
- if (prefsInstance == null) {
- prefsInstance = new Preferences(context);
- }
- return prefsInstance;
- }
-
- /**
- * @param context
- * @param forceInstantiation
- * @return Returns a 'Preferences' instance
- */
- public static Preferences with(Context context, boolean forceInstantiation) {
- if (forceInstantiation) {
- prefsInstance = new Preferences(context);
- }
- return prefsInstance;
- }
-
- /**
- * @param context
- * @param preferencesName
- * @return Returns a 'Preferences' instance
- */
- public static Preferences with(Context context, String preferencesName) {
- if (prefsInstance == null) {
- prefsInstance = new Preferences(context, preferencesName);
- }
- return prefsInstance;
- }
-
- /**
- * @param context
- * @param preferencesName
- * @param forceInstantiation
- * @return Returns a 'Preferences' instance
- */
- public static Preferences with(Context context, String preferencesName,
- boolean forceInstantiation) {
- if (forceInstantiation) {
- prefsInstance = new Preferences(context, preferencesName);
- }
- return prefsInstance;
- }
-
- // String related methods
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public String readString(String what) {
- return sharedPreferences.getString(what, DEFAULT_STRING_VALUE);
- }
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public String readString(int what) {
- try {
- return sharedPreferences.getString(String.valueOf(what), DEFAULT_STRING_VALUE);
- } catch (java.lang.ClassCastException ex) {
- return "";
- }
- }
-
- /**
- * @param what
- * @param defaultString
- * @return Returns the stored value of 'what'
- */
- public String readString(String what, String defaultString) {
- return sharedPreferences.getString(what, defaultString);
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeString(String where, String what) {
- sharedPreferences.edit().putString(where, what).apply();
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeString(int where, String what) {
- sharedPreferences.edit().putString(String.valueOf(where), what).apply();
- }
-
- // int related methods
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public int readInt(String what) {
- return sharedPreferences.getInt(what, DEFAULT_INT_VALUE);
- }
-
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public int readInt(int what) {
- try {
- return sharedPreferences.getInt(String.valueOf(what), DEFAULT_INT_VALUE);
- } catch (java.lang.ClassCastException ex) {
- return 0;
- }
- }
-
- /**
- * @param what
- * @param defaultInt
- * @return Returns the stored value of 'what'
- */
- public int readInt(String what, int defaultInt) {
- return sharedPreferences.getInt(what, defaultInt);
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeInt(String where, int what) {
- sharedPreferences.edit().putInt(where, what).apply();
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeInt(int where, int what) {
- sharedPreferences.edit().putInt(String.valueOf(where), what).apply();
- }
-
- // double related methods
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public double readDouble(String what) {
- if (!contains(what))
- return DEFAULT_DOUBLE_VALUE;
- return Double.longBitsToDouble(readLong(what));
- }
-
- /**
- * @param what
- * @param defaultDouble
- * @return Returns the stored value of 'what'
- */
- public double readDouble(String what, double defaultDouble) {
- if (!contains(what))
- return defaultDouble;
- return Double.longBitsToDouble(readLong(what));
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeDouble(String where, double what) {
- writeLong(where, Double.doubleToRawLongBits(what));
- }
-
- // float related methods
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public float readFloat(String what) {
- return sharedPreferences.getFloat(what, DEFAULT_FLOAT_VALUE);
- }
-
- /**
- * @param what
- * @param defaultFloat
- * @return Returns the stored value of 'what'
- */
- public float readFloat(String what, float defaultFloat) {
- return sharedPreferences.getFloat(what, defaultFloat);
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeFloat(String where, float what) {
- sharedPreferences.edit().putFloat(where, what).apply();
- }
-
- // long related methods
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public long readLong(String what) {
- return sharedPreferences.getLong(what, DEFAULT_LONG_VALUE);
- }
-
- /**
- * @param what
- * @param defaultLong
- * @return Returns the stored value of 'what'
- */
- public long readLong(String what, long defaultLong) {
- return sharedPreferences.getLong(what, defaultLong);
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeLong(String where, long what) {
- sharedPreferences.edit().putLong(where, what).apply();
- }
-
- // boolean related methods
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public boolean readBoolean(String what) {
- return sharedPreferences.getBoolean(what, DEFAULT_BOOLEAN_VALUE);
- }
-
- /**
- * @param what
- * @return Returns the stored value of 'what'
- */
- public boolean readBoolean(int what) {
- return sharedPreferences.getBoolean(String.valueOf(what), DEFAULT_BOOLEAN_VALUE);
- }
-
- /**
- * @param what
- * @param defaultBoolean
- * @return Returns the stored value of 'what'
- */
- public boolean readBoolean(String what, boolean defaultBoolean) {
- /*if (defaultBoolean == true && !sharedPreferences.contains(what))
- writeBoolean(what, true);*/
- return sharedPreferences.getBoolean(what, defaultBoolean);
- }
-
- /**
- * @param what
- * @param defaultBoolean
- * @return Returns the stored value of 'what'
- */
- public boolean readBoolean(int what, boolean defaultBoolean) {
- /*if (defaultBoolean == true && !sharedPreferences.contains(String.valueOf(what)))
- writeBoolean(what, true);*/
- try {
- return sharedPreferences.getBoolean(String.valueOf(what), defaultBoolean);
- } catch (java.lang.ClassCastException ex) {
- return defaultBoolean;
- }
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeBoolean(String where, boolean what) {
- sharedPreferences.edit().putBoolean(where, what).apply();
- }
-
- /**
- * @param where
- * @param what
- */
- public void writeBoolean(int where, boolean what) {
- sharedPreferences.edit().putBoolean(String.valueOf(where), what).apply();
- }
-
- // String set methods
-
- /**
- * @param key
- * @param value
- */
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void putStringSet(final String key, final Set value) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- sharedPreferences.edit().putStringSet(key, value).apply();
- } else {
- // Workaround for pre-HC's lack of StringSets
- putOrderedStringSet(key, value);
- }
- }
-
- /**
- * @param key
- * @param value
- */
- public void putOrderedStringSet(String key, Set value) {
- int stringSetLength = 0;
- if (sharedPreferences.contains(key + LENGTH)) {
- // First read what the value was
- stringSetLength = readInt(key + LENGTH);
- }
- writeInt(key + LENGTH, value.size());
- int i = 0;
- for (String aValue : value) {
- writeString(key + "[" + i + "]", aValue);
- i++;
- }
- for (; i < stringSetLength; i++) {
- // Remove any remaining values
- remove(key + "[" + i + "]");
- }
- }
-
- /**
- * @param key
- * @param defValue
- * @return Returns the String Set with HoneyComb compatibility
- */
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public Set getStringSet(final String key, final Set defValue) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- return sharedPreferences.getStringSet(key, defValue);
- } else {
- // Workaround for pre-HC's missing getStringSet
- return getOrderedStringSet(key, defValue);
- }
- }
-
- /**
- * @param key
- * @param defValue
- * @return Returns the ordered String Set
- */
- public Set getOrderedStringSet(String key, final Set defValue) {
- if (contains(key + LENGTH)) {
- LinkedHashSet set = new LinkedHashSet<>();
- int stringSetLength = readInt(key + LENGTH);
- if (stringSetLength >= 0) {
- for (int i = 0; i < stringSetLength; i++) {
- set.add(readString(key + "[" + i + "]"));
- }
- }
- return set;
- }
- return defValue;
- }
-
- // end related methods
-
- /**
- * @param key
- */
- public void remove(final String key) {
- if (contains(key + LENGTH)) {
- // Workaround for pre-HC's lack of StringSets
- int stringSetLength = readInt(key + LENGTH);
- if (stringSetLength >= 0) {
- sharedPreferences.edit().remove(key + LENGTH).apply();
- for (int i = 0; i < stringSetLength; i++) {
- sharedPreferences.edit().remove(key + "[" + i + "]").apply();
- }
- }
- }
- sharedPreferences.edit().remove(key).apply();
- }
-
- /**
- * @param key
- * @return Returns if that key exists
- */
- public boolean contains(final String key) {
- return sharedPreferences.contains(key);
- }
-
- /**
- * Clear all the preferences
- */
- public void clear() {
- sharedPreferences.edit().clear().apply();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/jni/And64InlineHook/And64InlineHook.cpp b/app/src/main/jni/And64InlineHook/And64InlineHook.cpp
deleted file mode 100644
index 72702dd..0000000
--- a/app/src/main/jni/And64InlineHook/And64InlineHook.cpp
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * @date : 2018/04/18
- * @author : Rprop (r_prop@outlook.com)
- * https://github.com/Rprop/And64InlineHook
- */
-/*
- MIT License
-
- Copyright (c) 2018 Rprop (r_prop@outlook.com)
-
- 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:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- 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.
- */
-#define __STDC_FORMAT_MACROS
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#if defined(__aarch64__)
-
-#include "And64InlineHook.hpp"
-
-#define A64_MAX_INSTRUCTIONS 5
-#define A64_MAX_REFERENCES (A64_MAX_INSTRUCTIONS * 2)
-#define A64_NOP 0xd503201fu
-#define A64_JNIEXPORT __attribute__((visibility("hidden")))
-#define A64_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "A64_HOOK", __VA_ARGS__))
-#ifndef NDEBUG
-# define A64_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "A64_HOOK", __VA_ARGS__))
-#else
-# define A64_LOGI(...) ((void)0)
-#endif // NDEBUG
-typedef uint32_t *__restrict *__restrict instruction;
-typedef struct {
- struct fix_info {
- uint32_t *bp;
- uint32_t ls; // left-shift counts
- uint32_t ad; // & operand
- };
- struct insns_info {
- union {
- uint64_t insu;
- int64_t ins;
- void *insp;
- };
- fix_info fmap[A64_MAX_REFERENCES];
- };
- int64_t basep;
- int64_t endp;
- insns_info dat[A64_MAX_INSTRUCTIONS];
-
-public:
- inline bool is_in_fixing_range(const int64_t absolute_addr) {
- return absolute_addr >= this->basep && absolute_addr < this->endp;
- }
-
- inline intptr_t get_ref_ins_index(const int64_t absolute_addr) {
- return static_cast((absolute_addr - this->basep) / sizeof(uint32_t));
- }
-
- inline intptr_t get_and_set_current_index(uint32_t *__restrict inp, uint32_t *__restrict outp) {
- intptr_t current_idx = this->get_ref_ins_index(reinterpret_cast(inp));
- this->dat[current_idx].insp = outp;
- return current_idx;
- }
-
- inline void reset_current_ins(const intptr_t idx, uint32_t *__restrict outp) {
- this->dat[idx].insp = outp;
- }
-
- void
- insert_fix_map(const intptr_t idx, uint32_t *bp, uint32_t ls = 0u, uint32_t ad = 0xffffffffu) {
- for (auto &f : this->dat[idx].fmap) {
- if (f.bp == NULL) {
- f.bp = bp;
- f.ls = ls;
- f.ad = ad;
- return;
- } //if
- }
- // What? GGing..
- }
-
- void process_fix_map(const intptr_t idx) {
- for (auto &f : this->dat[idx].fmap) {
- if (f.bp == NULL) break;
- *(f.bp) = *(f.bp) |
- (((int32_t(this->dat[idx].ins - reinterpret_cast(f.bp)) >> 2)
- << f.ls) & f.ad);
- f.bp = NULL;
- }
- }
-} context;
-
-//-------------------------------------------------------------------------
-
-static bool __fix_branch_imm(instruction inpp, instruction outpp, context *ctxp) {
- static constexpr uint32_t mbits = 6u;
- static constexpr uint32_t mask = 0xfc000000u; // 0b11111100000000000000000000000000
- static constexpr uint32_t rmask = 0x03ffffffu; // 0b00000011111111111111111111111111
- static constexpr uint32_t op_b = 0x14000000u; // "b" ADDR_PCREL26
- static constexpr uint32_t op_bl = 0x94000000u; // "bl" ADDR_PCREL26
-
- const uint32_t ins = *(*inpp);
- const uint32_t opc = ins & mask;
- switch (opc) {
- case op_b:
- case op_bl: {
- intptr_t current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
- int64_t absolute_addr = reinterpret_cast(*inpp) +
- (static_cast(ins << mbits)
- >> (mbits - 2u)); // sign-extended
- int64_t new_pc_offset =
- static_cast(absolute_addr - reinterpret_cast(*outpp))
- >> 2; // shifted
- bool special_fix_type = ctxp->is_in_fixing_range(absolute_addr);
- // whether the branch should be converted to absolute jump
- if (!special_fix_type && llabs(new_pc_offset) >= (rmask >> 1)) {
- bool b_aligned = (reinterpret_cast(*outpp + 2) & 7u) == 0u;
- if (opc == op_b) {
- if (b_aligned != true) {
- (*outpp)[0] = A64_NOP;
- ctxp->reset_current_ins(current_idx, ++(*outpp));
- } //if
- (*outpp)[0] = 0x58000051u; // LDR X17, #0x8
- (*outpp)[1] = 0xd61f0220u; // BR X17
- memcpy(*outpp + 2, &absolute_addr, sizeof(absolute_addr));
- *outpp += 4;
- } else {
- if (b_aligned == true) {
- (*outpp)[0] = A64_NOP;
- ctxp->reset_current_ins(current_idx, ++(*outpp));
- } //if
- (*outpp)[0] = 0x58000071u; // LDR X17, #12
- (*outpp)[1] = 0x1000009eu; // ADR X30, #16
- (*outpp)[2] = 0xd61f0220u; // BR X17
- memcpy(*outpp + 3, &absolute_addr, sizeof(absolute_addr));
- *outpp += 5;
- } //if
- } else {
- if (special_fix_type) {
- intptr_t ref_idx = ctxp->get_ref_ins_index(absolute_addr);
- if (ref_idx <= current_idx) {
- new_pc_offset = static_cast(ctxp->dat[ref_idx].ins -
- reinterpret_cast(*outpp))
- >> 2;
- } else {
- ctxp->insert_fix_map(ref_idx, *outpp, 0u, rmask);
- new_pc_offset = 0;
- } //if
- } //if
-
- (*outpp)[0] = opc | (new_pc_offset & ~mask);
- ++(*outpp);
- } //if
-
- ++(*inpp);
- return ctxp->process_fix_map(current_idx), true;
- }
- }
- return false;
-}
-
-//-------------------------------------------------------------------------
-
-static bool __fix_cond_comp_test_branch(instruction inpp, instruction outpp, context *ctxp) {
- static constexpr uint32_t lsb = 5u;
- static constexpr uint32_t lmask01 = 0xff00001fu; // 0b11111111000000000000000000011111
- static constexpr uint32_t mask0 = 0xff000010u; // 0b11111111000000000000000000010000
- static constexpr uint32_t op_bc = 0x54000000u; // "b.c" ADDR_PCREL19
- static constexpr uint32_t mask1 = 0x7f000000u; // 0b01111111000000000000000000000000
- static constexpr uint32_t op_cbz = 0x34000000u; // "cbz" Rt, ADDR_PCREL19
- static constexpr uint32_t op_cbnz = 0x35000000u; // "cbnz" Rt, ADDR_PCREL19
- static constexpr uint32_t lmask2 = 0xfff8001fu; // 0b11111111111110000000000000011111
- static constexpr uint32_t mask2 = 0x7f000000u; // 0b01111111000000000000000000000000
- static constexpr uint32_t op_tbz = 0x36000000u; // 0b00110110000000000000000000000000 "tbz" Rt, BIT_NUM, ADDR_PCREL14
- static constexpr uint32_t op_tbnz = 0x37000000u; // 0b00110111000000000000000000000000 "tbnz" Rt, BIT_NUM, ADDR_PCREL14
-
- const uint32_t ins = *(*inpp);
- uint32_t lmask = lmask01;
- if ((ins & mask0) != op_bc) {
- uint32_t opc = ins & mask1;
- if (opc != op_cbz && opc != op_cbnz) {
- opc = ins & mask2;
- if (opc != op_tbz && opc != op_tbnz) {
- return false;
- } //if
- lmask = lmask2;
- } //if
- } //if
-
- intptr_t current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
- int64_t absolute_addr = reinterpret_cast(*inpp) + ((ins & ~lmask) >> (lsb - 2u));
- int64_t new_pc_offset =
- static_cast(absolute_addr - reinterpret_cast(*outpp)) >> 2; // shifted
- bool special_fix_type = ctxp->is_in_fixing_range(absolute_addr);
- if (!special_fix_type && llabs(new_pc_offset) >= (~lmask >> (lsb + 1))) {
- if ((reinterpret_cast(*outpp + 4) & 7u) != 0u) {
- (*outpp)[0] = A64_NOP;
- ctxp->reset_current_ins(current_idx, ++(*outpp));
- } //if
- (*outpp)[0] = (((8u >> 2u) << lsb) & ~lmask) | (ins & lmask); // B.C #0x8
- (*outpp)[1] = 0x14000005u; // B #0x14
- (*outpp)[2] = 0x58000051u; // LDR X17, #0x8
- (*outpp)[3] = 0xd61f0220u; // BR X17
- memcpy(*outpp + 4, &absolute_addr, sizeof(absolute_addr));
- *outpp += 6;
- } else {
- if (special_fix_type) {
- intptr_t ref_idx = ctxp->get_ref_ins_index(absolute_addr);
- if (ref_idx <= current_idx) {
- new_pc_offset = static_cast(ctxp->dat[ref_idx].ins -
- reinterpret_cast(*outpp)) >> 2;
- } else {
- ctxp->insert_fix_map(ref_idx, *outpp, lsb, ~lmask);
- new_pc_offset = 0;
- } //if
- } //if
-
- (*outpp)[0] = (static_cast(new_pc_offset << lsb) & ~lmask) | (ins & lmask);
- ++(*outpp);
- } //if
-
- ++(*inpp);
- return ctxp->process_fix_map(current_idx), true;
-}
-
-//-------------------------------------------------------------------------
-
-static bool __fix_loadlit(instruction inpp, instruction outpp, context *ctxp) {
- const uint32_t ins = *(*inpp);
-
- // memory prefetch("prfm"), just skip it
- // http://infocenter.arm.com/help/topic/com.arm.doc.100069_0608_00_en/pge1427897420050.html
- if ((ins & 0xff000000u) == 0xd8000000u) {
- ctxp->process_fix_map(ctxp->get_and_set_current_index(*inpp, *outpp));
- ++(*inpp);
- return true;
- } //if
-
- static constexpr uint32_t msb = 8u;
- static constexpr uint32_t lsb = 5u;
- static constexpr uint32_t mask_30 = 0x40000000u; // 0b01000000000000000000000000000000
- static constexpr uint32_t mask_31 = 0x80000000u; // 0b10000000000000000000000000000000
- static constexpr uint32_t lmask = 0xff00001fu; // 0b11111111000000000000000000011111
- static constexpr uint32_t mask_ldr = 0xbf000000u; // 0b10111111000000000000000000000000
- static constexpr uint32_t op_ldr = 0x18000000u; // 0b00011000000000000000000000000000 "LDR Wt/Xt, label" | ADDR_PCREL19
- static constexpr uint32_t mask_ldrv = 0x3f000000u; // 0b00111111000000000000000000000000
- static constexpr uint32_t op_ldrv = 0x1c000000u; // 0b00011100000000000000000000000000 "LDR St/Dt/Qt, label" | ADDR_PCREL19
- static constexpr uint32_t mask_ldrsw = 0xff000000u; // 0b11111111000000000000000000000000
- static constexpr uint32_t op_ldrsw = 0x98000000u; // "LDRSW Xt, label" | ADDR_PCREL19 | load register signed word
- // LDR S0, #0 | 0b00011100000000000000000000000000 | 32-bit
- // LDR D0, #0 | 0b01011100000000000000000000000000 | 64-bit
- // LDR Q0, #0 | 0b10011100000000000000000000000000 | 128-bit
- // INVALID | 0b11011100000000000000000000000000 | may be 256-bit
-
- uint32_t mask = mask_ldr;
- uintptr_t faligned = (ins & mask_30) ? 7u : 3u;
- if ((ins & mask_ldr) != op_ldr) {
- mask = mask_ldrv;
- if (faligned != 7u)
- faligned = (ins & mask_31) ? 15u : 3u;
- if ((ins & mask_ldrv) != op_ldrv) {
- if ((ins & mask_ldrsw) != op_ldrsw) {
- return false;
- } //if
- mask = mask_ldrsw;
- faligned = 7u;
- } //if
- } //if
-
- intptr_t current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
- int64_t absolute_addr = reinterpret_cast(*inpp) +
- ((static_cast(ins << msb) >> (msb + lsb - 2u)) & ~3u);
- int64_t new_pc_offset =
- static_cast(absolute_addr - reinterpret_cast(*outpp)) >> 2; // shifted
- bool special_fix_type = ctxp->is_in_fixing_range(absolute_addr);
- // special_fix_type may encounter issue when there are mixed data and code
- if (special_fix_type || (llabs(new_pc_offset) + (faligned + 1u - 4u) / 4u) >=
- (~lmask >> (lsb + 1))) { // inaccurate, but it works
- while ((reinterpret_cast(*outpp + 2) & faligned) != 0u) {
- *(*outpp)++ = A64_NOP;
- }
- ctxp->reset_current_ins(current_idx, *outpp);
-
- // Note that if memory at absolute_addr is writeable (non-const), we will fail to fetch it.
- // And what's worse, we may unexpectedly overwrite something if special_fix_type is true...
- uint32_t ns = static_cast((faligned + 1) / sizeof(uint32_t));
- (*outpp)[0] = (((8u >> 2u) << lsb) & ~mask) | (ins & lmask); // LDR #0x8
- (*outpp)[1] = 0x14000001u + ns; // B #0xc
- memcpy(*outpp + 2, reinterpret_cast(absolute_addr), faligned + 1);
- *outpp += 2 + ns;
- } else {
- faligned >>= 2; // new_pc_offset is shifted and 4-byte aligned
- while ((new_pc_offset & faligned) != 0) {
- *(*outpp)++ = A64_NOP;
- new_pc_offset =
- static_cast(absolute_addr - reinterpret_cast(*outpp)) >> 2;
- }
- ctxp->reset_current_ins(current_idx, *outpp);
-
- (*outpp)[0] = (static_cast(new_pc_offset << lsb) & ~mask) | (ins & lmask);
- ++(*outpp);
- } //if
-
- ++(*inpp);
- return ctxp->process_fix_map(current_idx), true;
-}
-
-//-------------------------------------------------------------------------
-
-static bool __fix_pcreladdr(instruction inpp, instruction outpp, context *ctxp) {
- // Load a PC-relative address into a register
- // http://infocenter.arm.com/help/topic/com.arm.doc.100069_0608_00_en/pge1427897645644.html
- static constexpr uint32_t msb = 8u;
- static constexpr uint32_t lsb = 5u;
- static constexpr uint32_t mask = 0x9f000000u; // 0b10011111000000000000000000000000
- static constexpr uint32_t rmask = 0x0000001fu; // 0b00000000000000000000000000011111
- static constexpr uint32_t lmask = 0xff00001fu; // 0b11111111000000000000000000011111
- static constexpr uint32_t fmask = 0x00ffffffu; // 0b00000000111111111111111111111111
- static constexpr uint32_t max_val = 0x001fffffu; // 0b00000000000111111111111111111111
- static constexpr uint32_t op_adr = 0x10000000u; // "adr" Rd, ADDR_PCREL21
- static constexpr uint32_t op_adrp = 0x90000000u; // "adrp" Rd, ADDR_ADRP
-
- const uint32_t ins = *(*inpp);
- intptr_t current_idx;
- switch (ins & mask) {
- case op_adr: {
- current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
- int64_t lsb_bytes = static_cast(ins << 1u) >> 30u;
- int64_t absolute_addr = reinterpret_cast(*inpp) +
- (((static_cast(ins << msb) >> (msb + lsb - 2u)) &
- ~3u) | lsb_bytes);
- int64_t new_pc_offset = static_cast(absolute_addr -
- reinterpret_cast(*outpp));
- bool special_fix_type = ctxp->is_in_fixing_range(absolute_addr);
- if (!special_fix_type && llabs(new_pc_offset) >= (max_val >> 1)) {
- if ((reinterpret_cast(*outpp + 2) & 7u) != 0u) {
- (*outpp)[0] = A64_NOP;
- ctxp->reset_current_ins(current_idx, ++(*outpp));
- } //if
-
- (*outpp)[0] =
- 0x58000000u | (((8u >> 2u) << lsb) & ~mask) | (ins & rmask); // LDR #0x8
- (*outpp)[1] = 0x14000003u; // B #0xc
- memcpy(*outpp + 2, &absolute_addr, sizeof(absolute_addr));
- *outpp += 4;
- } else {
- if (special_fix_type) {
- intptr_t ref_idx = ctxp->get_ref_ins_index(absolute_addr & ~3ull);
- if (ref_idx <= current_idx) {
- new_pc_offset = static_cast(ctxp->dat[ref_idx].ins -
- reinterpret_cast(*outpp));
- } else {
- ctxp->insert_fix_map(ref_idx, *outpp, lsb, fmask);
- new_pc_offset = 0;
- } //if
- } //if
-
- // the lsb_bytes will never be changed, so we can use lmask to keep it
- (*outpp)[0] = (static_cast(new_pc_offset << (lsb - 2u)) & fmask) |
- (ins & lmask);
- ++(*outpp);
- } //if
- }
- break;
- case op_adrp: {
- current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
- int32_t lsb_bytes = static_cast(ins << 1u) >> 30u;
- int64_t absolute_addr = (reinterpret_cast(*inpp) & ~0xfffll) +
- ((((static_cast(ins << msb) >> (msb + lsb - 2u)) &
- ~3u) | lsb_bytes) << 12);
- A64_LOGI("ins = 0x%.8X, pc = %p, abs_addr = %p",
- ins, *inpp, reinterpret_cast(absolute_addr));
- if (ctxp->is_in_fixing_range(absolute_addr)) {
- intptr_t ref_idx = ctxp->get_ref_ins_index(absolute_addr/* & ~3ull*/);
- if (ref_idx > current_idx) {
- // the bottom 12 bits of absolute_addr are masked out,
- // so ref_idx must be less than or equal to current_idx!
- A64_LOGE("ref_idx must be less than or equal to current_idx!");
- } //if
-
- // *absolute_addr may be changed due to relocation fixing
- A64_LOGI("What is the correct way to fix this?");
- *(*outpp)++ = ins; // 0x90000000u;
- } else {
- if ((reinterpret_cast(*outpp + 2) & 7u) != 0u) {
- (*outpp)[0] = A64_NOP;
- ctxp->reset_current_ins(current_idx, ++(*outpp));
- } //if
-
- (*outpp)[0] =
- 0x58000000u | (((8u >> 2u) << lsb) & ~mask) | (ins & rmask); // LDR #0x8
- (*outpp)[1] = 0x14000003u; // B #0xc
- memcpy(*outpp + 2, &absolute_addr, sizeof(absolute_addr)); // potential overflow?
- *outpp += 4;
- } //if
- }
- break;
- default:
- return false;
- }
-
- ctxp->process_fix_map(current_idx);
- ++(*inpp);
- return true;
-}
-
-//-------------------------------------------------------------------------
-#define __flush_cache(c, n) __builtin___clear_cache(reinterpret_cast(c), reinterpret_cast(c) + n)
-
-static void __fix_instructions(uint32_t *__restrict inp, int32_t count, uint32_t *__restrict outp) {
- context ctx;
- ctx.basep = reinterpret_cast(inp);
- ctx.endp = reinterpret_cast(inp + count);
- memset(ctx.dat, 0, sizeof(ctx.dat));
- static_assert(sizeof(ctx.dat) / sizeof(ctx.dat[0]) == A64_MAX_INSTRUCTIONS,
- "please use A64_MAX_INSTRUCTIONS!");
-#ifndef NDEBUG
- if (count > A64_MAX_INSTRUCTIONS) {
- A64_LOGE("too many fixing instructions!");
- } //if
-#endif // NDEBUG
-
- uint32_t *const outp_base = outp;
-
- while (--count >= 0) {
- if (__fix_branch_imm(&inp, &outp, &ctx)) continue;
- if (__fix_cond_comp_test_branch(&inp, &outp, &ctx)) continue;
- if (__fix_loadlit(&inp, &outp, &ctx)) continue;
- if (__fix_pcreladdr(&inp, &outp, &ctx)) continue;
-
- // without PC-relative offset
- ctx.process_fix_map(ctx.get_and_set_current_index(inp, outp));
- *(outp++) = *(inp++);
- }
-
- static constexpr uint_fast64_t mask = 0x03ffffffu; // 0b00000011111111111111111111111111
- auto callback = reinterpret_cast(inp);
- auto pc_offset = static_cast(callback - reinterpret_cast(outp)) >> 2;
- if (llabs(pc_offset) >= (mask >> 1)) {
- if ((reinterpret_cast(outp + 2) & 7u) != 0u) {
- outp[0] = A64_NOP;
- ++outp;
- } //if
- outp[0] = 0x58000051u; // LDR X17, #0x8
- outp[1] = 0xd61f0220u; // BR X17
- *reinterpret_cast(outp + 2) = callback;
- outp += 4;
- } else {
- outp[0] = 0x14000000u | (pc_offset & mask); // "B" ADDR_PCREL26
- ++outp;
- } //if
-
- const uintptr_t total = (outp - outp_base) * sizeof(uint32_t);
- __flush_cache(outp_base, total); // necessary
-}
-
-//-------------------------------------------------------------------------
-
-extern "C" {
-#define __attribute __attribute__
-#define aligned(x) __aligned__(x)
-#define __intval(p) reinterpret_cast(p)
-#define __uintval(p) reinterpret_cast(p)
-#define __ptr(p) reinterpret_cast(p)
-#define __page_size 4096
-#define __page_align(n) __align_up(static_cast(n), __page_size)
-#define __ptr_align(x) __ptr(__align_down(reinterpret_cast(x), __page_size))
-#define __align_up(x, n) (((x) + ((n) - 1)) & ~((n) - 1))
-#define __align_down(x, n) ((x) & -(n))
-#define __countof(x) static_cast(sizeof(x) / sizeof((x)[0])) // must be signed
-#define __atomic_increase(p) __sync_add_and_fetch(p, 1)
-#define __sync_cmpswap(p, v, n) __sync_bool_compare_and_swap(p, v, n)
-#define __predict_true(exp) __builtin_expect((exp) != 0, 1)
-#define __make_rwx(p, n) ::mprotect(__ptr_align(p), \
- __page_align(__uintval(p) + n) != __page_align(__uintval(p)) ? __page_align(n) + __page_size : __page_align(n), \
- PROT_READ | PROT_WRITE | PROT_EXEC)
-
-//-------------------------------------------------------------------------
-
-static __attribute((aligned(__page_size))) uint32_t __insns_pool[A64_MAX_BACKUPS][
- A64_MAX_INSTRUCTIONS * 10];
-
-//-------------------------------------------------------------------------
-
-class A64HookInit {
-public:
- A64HookInit() {
- __make_rwx(__insns_pool, sizeof(__insns_pool));
- A64_LOGI("insns pool initialized.");
- }
-};
-static A64HookInit __init;
-
-//-------------------------------------------------------------------------
-
-static uint32_t *FastAllocateTrampoline() {
- static_assert((A64_MAX_INSTRUCTIONS * 10 * sizeof(uint32_t)) % 8 == 0, "8-byte align");
- static volatile int32_t __index = -1;
-
- int32_t i = __atomic_increase(&__index);
- if (__predict_true(i >= 0 && i < __countof(__insns_pool))) {
- return __insns_pool[i];
- } //if
-
- A64_LOGE("failed to allocate trampoline!");
- return NULL;
-}
-
-//-------------------------------------------------------------------------
-
-A64_JNIEXPORT void *A64HookFunctionV(void *const symbol, void *const replace,
- void *const rwx, const uintptr_t rwx_size) {
- static constexpr uint_fast64_t mask = 0x03ffffffu; // 0b00000011111111111111111111111111
-
- uint32_t *trampoline = static_cast(rwx), *original = static_cast(symbol);
-
- static_assert(A64_MAX_INSTRUCTIONS >= 5, "please fix A64_MAX_INSTRUCTIONS!");
- auto pc_offset = static_cast(__intval(replace) - __intval(symbol)) >> 2;
- if (llabs(pc_offset) >= (mask >> 1)) {
- int32_t count = (reinterpret_cast(original + 2) & 7u) != 0u ? 5 : 4;
- if (trampoline) {
- if (rwx_size < count * 10u) {
- A64_LOGI("rwx size is too small to hold %u bytes backup instructions!",
- count * 10u);
- return NULL;
- } //if
- __fix_instructions(original, count, trampoline);
- } //if
-
- if (__make_rwx(original, 5 * sizeof(uint32_t)) == 0) {
- if (count == 5) {
- original[0] = A64_NOP;
- ++original;
- } //if
- original[0] = 0x58000051u; // LDR X17, #0x8
- original[1] = 0xd61f0220u; // BR X17
- *reinterpret_cast(original + 2) = __intval(replace);
- __flush_cache(symbol, 5 * sizeof(uint32_t));
-
- A64_LOGI("inline hook %p->%p successfully! %zu bytes overwritten",
- symbol, replace, 5 * sizeof(uint32_t));
- } else {
- A64_LOGE("mprotect failed with errno = %d, p = %p, size = %zu",
- errno, original, 5 * sizeof(uint32_t));
- trampoline = NULL;
- } //if
- } else {
- if (trampoline) {
- if (rwx_size < 1u * 10u) {
- A64_LOGI("rwx size is too small to hold %u bytes backup instructions!", 1u * 10u);
- return NULL;
- } //if
- __fix_instructions(original, 1, trampoline);
- } //if
-
- if (__make_rwx(original, 1 * sizeof(uint32_t)) == 0) {
- __sync_cmpswap(original, *original,
- 0x14000000u | (pc_offset & mask)); // "B" ADDR_PCREL26
- __flush_cache(symbol, 1 * sizeof(uint32_t));
-
- A64_LOGI("inline hook %p->%p successfully! %zu bytes overwritten",
- symbol, replace, 1 * sizeof(uint32_t));
- } else {
- A64_LOGE("mprotect failed with errno = %d, p = %p, size = %zu",
- errno, original, 1 * sizeof(uint32_t));
- trampoline = NULL;
- } //if
- } //if
-
- return trampoline;
-}
-
-//-------------------------------------------------------------------------
-
-A64_JNIEXPORT void A64HookFunction(void *const symbol, void *const replace, void **result) {
- void *trampoline = NULL;
- if (result != NULL) {
- trampoline = FastAllocateTrampoline();
- *result = trampoline;
- if (trampoline == NULL) return;
- } //if
-
- //fix Android 10 .text segment is read-only by default
- __make_rwx(symbol, 5 * sizeof(size_t));
-
- trampoline = A64HookFunctionV(symbol, replace, trampoline, A64_MAX_INSTRUCTIONS * 10u);
- if (trampoline == NULL && result != NULL) {
- *result = NULL;
- } //if
-}
-}
-
-#endif // defined(__aarch64__)
\ No newline at end of file
diff --git a/app/src/main/jni/And64InlineHook/And64InlineHook.hpp b/app/src/main/jni/And64InlineHook/And64InlineHook.hpp
deleted file mode 100644
index d274848..0000000
--- a/app/src/main/jni/And64InlineHook/And64InlineHook.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * @date : 2018/04/18
- * @author : Rprop (r_prop@outlook.com)
- * https://github.com/Rprop/And64InlineHook
- */
-/*
- MIT License
-
- Copyright (c) 2018 Rprop (r_prop@outlook.com)
-
- 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:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- 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.
- */
-#pragma once
-#define A64_MAX_BACKUPS 256
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void A64HookFunction(void *const symbol, void *const replace, void **result);
-void *A64HookFunctionV(void *const symbol, void *const replace, void *const rwx, const uintptr_t rwx_size);
-
-#ifdef __cplusplus
-}
-#endif
\ No newline at end of file
diff --git a/app/src/main/jni/And64InlineHook/LICENSE b/app/src/main/jni/And64InlineHook/LICENSE
deleted file mode 100644
index 75a6020..0000000
--- a/app/src/main/jni/And64InlineHook/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 RLib
-
-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:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-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.
diff --git a/app/src/main/jni/And64InlineHook/README.md b/app/src/main/jni/And64InlineHook/README.md
deleted file mode 100644
index 44f651d..0000000
--- a/app/src/main/jni/And64InlineHook/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# And64InlineHook
-Lightweight ARMv8-A(ARM64, AArch64, Little-Endian) Inline Hook Library for Android C/C++
-
-# References
-[Arm Compiler armasm User Guide](http://infocenter.arm.com/help/topic/com.arm.doc.100069_0610_00_en/pge1427898258836.html)
-[Procedure Call Standard for the Arm® 64-bit Architecture (AArch64)](https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst)
-
diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk
deleted file mode 100644
index 22c9cd2..0000000
--- a/app/src/main/jni/Android.mk
+++ /dev/null
@@ -1,71 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-MAIN_LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := GlobalInject
-LOCAL_SRC_FILES := RootLib/libGlobalInject.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := VirtualInject
-LOCAL_SRC_FILES := RootLib/libVirtualInject.so
-include $(PREBUILT_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := MyLibName
-# Code optimization
-# -std=c++17 is required to support AIDE app with NDK
-LOCAL_CFLAGS := -Wno-error=format-security -fvisibility=hidden -ffunction-sections -fdata-sections -w
-LOCAL_CFLAGS += -fno-rtti -fno-exceptions -fpermissive
-LOCAL_CPPFLAGS := -Wno-error=format-security -fvisibility=hidden -ffunction-sections -fdata-sections -w -Werror -s -std=c++17
-LOCAL_CPPFLAGS += -Wno-error=c++11-narrowing -fms-extensions -fno-rtti -fno-exceptions -fpermissive
-LOCAL_LDFLAGS += -Wl,--gc-sections,--strip-all, -llog
-LOCAL_ARM_MODE := arm
-
-LOCAL_C_INCLUDES += $(MAIN_LOCAL_PATH)
-
-# Here you add the cpp file
-LOCAL_SRC_FILES := Main.cpp \
- SOCKET/client.cpp \
-
-LOCAL_LDLIBS := -llog -landroid -lGLESv2
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-# Here is the name of your lib.
-# When you change the lib name, change also on System.loadLibrary("") under OnCreate method on StaticActivity.java
-# Both must have same name
-LOCAL_MODULE := LibServer
-
-LOCAL_CFLAGS := -Wno-error=format-security -fvisibility=hidden -ffunction-sections -fdata-sections -w
-LOCAL_CFLAGS += -fno-rtti -fno-exceptions -fpermissive
-LOCAL_CPPFLAGS := -Wno-error=format-security -fvisibility=hidden -ffunction-sections -fdata-sections -w -Werror -s -std=c++17
-LOCAL_CPPFLAGS += -Wno-error=c++11-narrowing -fms-extensions -fno-rtti -fno-exceptions -fpermissive
-LOCAL_LDFLAGS += -Wl,--gc-sections,--strip-all, -llog
-LOCAL_ARM_MODE := arm
-
-LOCAL_C_INCLUDES += $(MAIN_LOCAL_PATH)
-
-# Here you add the cpp file
-LOCAL_SRC_FILES := Server.cpp \
- Substrate/hde64.c \
- Substrate/SubstrateDebug.cpp \
- Substrate/SubstrateHook.cpp \
- Substrate/SubstratePosixMemory.cpp \
- Substrate/SymbolFinder.cpp \
- KittyMemory/KittyMemory.cpp \
- KittyMemory/MemoryPatch.cpp \
- KittyMemory/MemoryBackup.cpp \
- KittyMemory/KittyUtils.cpp \
- And64InlineHook/And64InlineHook.cpp \
- SOCKET/server.cpp \
-
-LOCAL_LDLIBS := -llog -landroid -lGLESv2
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-
-
-
diff --git a/app/src/main/jni/Application.mk b/app/src/main/jni/Application.mk
deleted file mode 100644
index 571a371..0000000
--- a/app/src/main/jni/Application.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-# To AIDE Users: If you are using 32-bit/ARMv7 phone, please remove arm64-v8a
-APP_ABI := armeabi-v7a
-# APP_PLATFORM := android-18 #APP_PLATFORM does not need to be set. It will automatically defaulting
-APP_STL := c++_static
-APP_OPTIM := release
-APP_THIN_ARCHIVE := true
-APP_PIE := true
diff --git a/app/src/main/jni/Canvas/Bools.h b/app/src/main/jni/Canvas/Bools.h
deleted file mode 100644
index 4a6ca59..0000000
--- a/app/src/main/jni/Canvas/Bools.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef BOOLS_H
-#define BOOLS_H
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-bool isESP = false;
-
-bool isPlayerLine2 = false;
-
-bool isPlayerName = false;
-
-bool isPlayerDist = false;
-
-bool isPlayerHealth = false;
-
-bool isTeamMateShow = false;
-
-bool isPlayerBox = false;
-
-bool isPlayerLine = false;
-
-bool isPlayer360 = false;
-
-bool isPlayerDistance = false;
-
-bool isCrosshair = false;
-
-bool isDrawCircle = false;
-
-bool isPlayerCount = false;
-
-Color LineColorBranco = Color::White();
-
-Color LineColorPreto = Color::Black();
-
-Color CrossColor = Color::White();
-
-Color CircleColor = Color::White();
-
-int LineColor = 0;
-
-float CrossSize = 42;
-
-float playerTextSize = 12;
-
-float CircleSize = 22;
-
-float Linesize = 1;
-
-#endif
diff --git a/app/src/main/jni/Canvas/ESP.h b/app/src/main/jni/Canvas/ESP.h
deleted file mode 100644
index 51f25f8..0000000
--- a/app/src/main/jni/Canvas/ESP.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef ESP_H
-#define ESP_H
-
-#include
-#include "StructsCommon.h"
-
-class ESP {
-private:
- JNIEnv *_env;
- jobject _cvsView;
- jobject _cvs;
-
-public:
- ESP() {
- _env = nullptr;
- _cvsView = nullptr;
- _cvs = nullptr;
- }
-
- ESP(JNIEnv *env, jobject cvsView, jobject cvs) {
- this->_env = env;
- this->_cvsView = cvsView;
- this->_cvs = cvs;
- }
-
- bool isValid() const {
- return (_env != nullptr && _cvsView != nullptr && _cvs != nullptr);
- }
-
- int getWidth() const {
- if (isValid()) {
- jclass canvas = _env->GetObjectClass(_cvs);
- jmethodID width = _env->GetMethodID(canvas, "getWidth", "()I");
- return _env->CallIntMethod(_cvs, width);
- }
- return 0;
- }
-
- int getHeight() const {
- if (isValid()) {
- jclass canvas = _env->GetObjectClass(_cvs);
- jmethodID width = _env->GetMethodID(canvas, "getHeight", "()I");
- return _env->CallIntMethod(_cvs, width);
- }
- return 0;
- }
-
- void DrawLine(Color color, float thickness, Vector2 start, Vector2 end) {
- if (isValid()) {
- jclass canvasView = _env->GetObjectClass(_cvsView);
- jmethodID drawline = _env->GetMethodID(canvasView, "DrawLine",
- "(Landroid/graphics/Canvas;IIIIFFFFF)V");
- _env->CallVoidMethod(_cvsView, drawline, _cvs, (int) color.a, (int) color.r,
- (int) color.g, (int) color.b,
- thickness,
- start.X, start.Y, end.X, end.Y);
- }
- }
-
- void DrawText(Color color, const char *txt, Vector2 pos, float size) {
- if (isValid()) {
- jclass canvasView = _env->GetObjectClass(_cvsView);
- jmethodID drawtext = _env->GetMethodID(canvasView, "DrawText",
- "(Landroid/graphics/Canvas;IIIILjava/lang/String;FFF)V");
- _env->CallVoidMethod(_cvsView, drawtext, _cvs, (int) color.a, (int) color.r,
- (int) color.g, (int) color.b,
- _env->NewStringUTF(txt), pos.X, pos.Y, size);
- }
- }
-
- void DrawFilledCircle(Color color, Vector2 pos, float radius) {
- if (isValid()) {
- jclass canvasView = _env->GetObjectClass(_cvsView);
- jmethodID drawfilledcircle = _env->GetMethodID(canvasView, "DrawFilledCircle",
- "(Landroid/graphics/Canvas;IIIIFFF)V");
- _env->CallVoidMethod(_cvsView, drawfilledcircle, _cvs, (int) color.a, (int) color.r,
- (int) color.g, (int) color.b, pos.X, pos.Y, radius);
- }
- }
-
- void DrawBox(Color color, float stroke, Rect rect) {
- Vector2 v1 = Vector2(rect.x, rect.y);
- Vector2 v2 = Vector2(rect.x + rect.width, rect.y);
- Vector2 v3 = Vector2(rect.x + rect.width, rect.y + rect.height);
- Vector2 v4 = Vector2(rect.x, rect.y + rect.height);
-
- DrawLine(color, stroke, v1, v2);
- DrawLine(color, stroke, v2, v3);
- DrawLine(color, stroke, v3, v4);
- DrawLine(color, stroke, v4, v1);
- }
-
- void DrawHorizontalHealthBar(Vector2 screenPos, float width, float maxHealth, float currentHealth) {
- screenPos -= Vector2(0.0f, 8.0f);
- DrawBox(Color(0, 0, 0, 255), 3, Rect(screenPos.X, screenPos.Y, width + 2, 5.0f));
- screenPos += Vector2(1.0f, 1.0f);
- Color clr = Color(0, 255, 0, 255);
- float hpWidth = (currentHealth * width) / maxHealth;
- if (currentHealth <= (maxHealth * 0.6)) {
- clr = Color(255, 255, 0, 255);
- }
- if (currentHealth < (maxHealth * 0.3)) {
- clr = Color(255, 0, 0, 255);
- }
- DrawBox(clr, 3, Rect(screenPos.X, screenPos.Y, hpWidth, 3.0f));
- }
-
- void DrawCrosshair(Color clr, Vector2 center, float size = 20) {
- float x = center.X - (size / 2.0f);
- float y = center.Y - (size / 2.0f);
- DrawLine(clr, 3, Vector2(x, center.Y), Vector2(x + size, center.Y));
- DrawLine(clr, 3, Vector2(center.X, y), Vector2(center.X, y + size));
- }
-};
-
-#endif
diff --git a/app/src/main/jni/Canvas/Log.h b/app/src/main/jni/Canvas/Log.h
deleted file mode 100644
index 40fe0c4..0000000
--- a/app/src/main/jni/Canvas/Log.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef LOGGER_H
-#define LOGGER_H
-
-#include
-
-//Log
-#define TAG "KMODs"
-#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__))
-#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__))
-#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__))
-#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__))
-
-#endif //LOGGER_H
diff --git a/app/src/main/jni/Canvas/StructsCommon.h b/app/src/main/jni/Canvas/StructsCommon.h
deleted file mode 100644
index eb2c2b9..0000000
--- a/app/src/main/jni/Canvas/StructsCommon.h
+++ /dev/null
@@ -1,276 +0,0 @@
-#ifndef STRUCTSCOMM_H
-#define STRUCTSCOMM_H
-#pragma once
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-using namespace std;
-
-#define maxplayerCount 54
-#define maxvehicleCount 54
-#define maxitemsCount 200
-
-class Color {
-public:
- float r;
- float g;
- float b;
- float a;
-
- Color() {
- this->r = 0;
- this->g = 0;
- this->b = 0;
- this->a = 0;
- }
-
- Color(float r, float g, float b, float a) {
- this->r = r;
- this->g = g;
- this->b = b;
- this->a = a;
- }
-
- Color(float r, float g, float b) {
- this->r = r;
- this->g = g;
- this->b = b;
- this->a = 255;
- }
-
- static Color Black(){
- return Color(0, 0, 0);
- }
-
- static Color White(){
- return Color(255, 255, 255);
- }
-
- static Color Green(){
- return Color(0, 255, 0);
- }
-
- static Color Blue(){
- return Color(0, 0, 255);
- }
-
- static Color Cyan(){
- return Color(0, 255, 255);
- }
-
- static Color DarkGolden(){
- return Color(218,165,32);
- }
-
- static Color Indigo(){
- return Color(75,0,130);
- }
-
- static Color Purple(){
- return Color(128,0,128);
- }
-
- static Color Pink() {
- return Color(255,192,203);
- }
-
- static Color Red() {
- return Color(255, 0, 0);
- }
-
- static Color Yellow() {
- return Color(255, 255, 0);
- }
-
- static Color Magenta() {
- return Color(255, 0, 255);
- }
-};
-
-class Rect {
-public:
- float x;
- float y;
- float width;
- float height;
-
- Rect() {
- this->x = 0;
- this->y = 0;
- this->width = 0;
- this->height = 0;
- }
-
- Rect(float x, float y, float width, float height) {
- this->x = x;
- this->y = y;
- this->width = width;
- this->height = height;
- }
-
- bool operator==(const Rect &src) const {
- return (src.x == this->x && src.y == this->y && src.height == this->height &&
- src.width == this->width);
- }
-
- bool operator!=(const Rect &src) const {
- return (src.x != this->x && src.y != this->y && src.height != this->height &&
- src.width != this->width);
- }
-};
-
-struct FMatrix {
- float M[4][4];
-};
-
-struct Quat {
- float X;
- float Y;
- float Z;
- float W;
-};
-
-struct FTransform {
- Quat Rotation;
- Vector3 Translation;
- Vector3 Scale3D;
-};
-
-Vector3 MarixToVector(FMatrix matrix) {
- return Vector3(matrix.M[3][0], matrix.M[3][1], matrix.M[3][2]);
-}
-
-FMatrix MatrixMulti(FMatrix m1, FMatrix m2) {
- FMatrix matrix = FMatrix();
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- for (int k = 0; k < 4; k++) {
- matrix.M[i][j] += m1.M[i][k] * m2.M[k][j];
- }
- }
- }
- return matrix;
-}
-
-FMatrix TransformToMatrix(FTransform transform) {
- FMatrix matrix;
-
- matrix.M[3][0] = transform.Translation.X;
- matrix.M[3][1] = transform.Translation.Y;
- matrix.M[3][2] = transform.Translation.Z;
-
- float x2 = transform.Rotation.X + transform.Rotation.X;
- float y2 = transform.Rotation.Y + transform.Rotation.Y;
- float z2 = transform.Rotation.Z + transform.Rotation.Z;
-
- float xx2 = transform.Rotation.X * x2;
- float yy2 = transform.Rotation.Y * y2;
- float zz2 = transform.Rotation.Z * z2;
-
- matrix.M[0][0] = (1.0f - (yy2 + zz2)) * transform.Scale3D.X;
- matrix.M[1][1] = (1.0f - (xx2 + zz2)) * transform.Scale3D.Y;
- matrix.M[2][2] = (1.0f - (xx2 + yy2)) * transform.Scale3D.Z;
-
- float yz2 = transform.Rotation.Y * z2;
- float wx2 = transform.Rotation.W * x2;
- matrix.M[2][1] = (yz2 - wx2) * transform.Scale3D.Z;
- matrix.M[1][2] = (yz2 + wx2) * transform.Scale3D.Y;
-
- float xy2 = transform.Rotation.X * y2;
- float wz2 = transform.Rotation.W * z2;
- matrix.M[1][0] = (xy2 - wz2) * transform.Scale3D.Y;
- matrix.M[0][1] = (xy2 + wz2) * transform.Scale3D.X;
-
- float xz2 = transform.Rotation.X * z2;
- float wy2 = transform.Rotation.W * y2;
- matrix.M[2][0] = (xz2 + wy2) * transform.Scale3D.Z;
- matrix.M[0][2] = (xz2 - wy2) * transform.Scale3D.X;
-
- matrix.M[0][3] = 0;
- matrix.M[1][3] = 0;
- matrix.M[2][3] = 0;
- matrix.M[3][3] = 1;
-
- return matrix;
-}
-
-struct FRotator {
- float Pitch;
- float Yaw;
- float Roll;
-};
-
-FMatrix RotatorToMatrix(FRotator rotation) {
- float radPitch = rotation.Pitch * ((float)M_PI / 180.0f);
- float radYaw = rotation.Yaw * ((float)M_PI / 180.0f);
- float radRoll = rotation.Roll * ((float)M_PI / 180.0f);
-
- float SP = sinf(radPitch);
- float CP = cosf(radPitch);
- float SY = sinf(radYaw);
- float CY = cosf(radYaw);
- float SR = sinf(radRoll);
- float CR = cosf(radRoll);
-
- FMatrix matrix;
-
- matrix.M[0][0] = (CP * CY);
- matrix.M[0][1] = (CP * SY);
- matrix.M[0][2] = (SP);
- matrix.M[0][3] = 0;
-
- matrix.M[1][0] = (SR * SP * CY - CR * SY);
- matrix.M[1][1] = (SR * SP * SY + CR * CY);
- matrix.M[1][2] = (-SR * CP);
- matrix.M[1][3] = 0;
-
- matrix.M[2][0] = (-(CR * SP * CY + SR * SY));
- matrix.M[2][1] = (CY * SR - CR * SP * SY);
- matrix.M[2][2] = (CR * CP);
- matrix.M[2][3] = 0;
-
- matrix.M[3][0] = 0;
- matrix.M[3][1] = 0;
- matrix.M[3][2] = 0;
- matrix.M[3][3] = 1;
-
- return matrix;
-}
-
-struct MinimalViewInfo {
- Vector3 Location;
- FRotator Rotation;
- float FOV;
-};
-
-Vector2 WorldToScreen(Vector3 worldLocation, MinimalViewInfo camViewInfo, int width, int height) {
- FMatrix tempMatrix = RotatorToMatrix(camViewInfo.Rotation);
-
- Vector3 vAxisX(tempMatrix.M[0][0], tempMatrix.M[0][1], tempMatrix.M[0][2]);
- Vector3 vAxisY(tempMatrix.M[1][0], tempMatrix.M[1][1], tempMatrix.M[1][2]);
- Vector3 vAxisZ(tempMatrix.M[2][0], tempMatrix.M[2][1], tempMatrix.M[2][2]);
-
- Vector3 vDelta = worldLocation - camViewInfo.Location;
-
- Vector3 vTransformed(Vector3::Dot(vDelta, vAxisY), Vector3::Dot(vDelta, vAxisZ), Vector3::Dot(vDelta, vAxisX));
-
- if (vTransformed.Z < 1.0f) {
- vTransformed.Z = 1.0f;
- }
-
- float fov = camViewInfo.FOV;
- float screenCenterX = (width / 2.0f);
- float screenCenterY = (height / 2.0f);
-
- return Vector2(
- (screenCenterX + vTransformed.X * (screenCenterX / tanf(fov * ((float)M_PI / 360.0f))) / vTransformed.Z),
- (screenCenterY - vTransformed.Y * (screenCenterX / tanf(fov * ((float)M_PI / 360.0f))) / vTransformed.Z)
- );
-}
-
-#endif
diff --git a/app/src/main/jni/Includes/Logger.h b/app/src/main/jni/Includes/Logger.h
deleted file mode 100644
index 72021bf..0000000
--- a/app/src/main/jni/Includes/Logger.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef DAWN_LOGGER_H
-#define DAWN_LOGGER_H
-
-#include
-
-enum daLogType {
- daDEBUG = 3,
- daERROR = 6,
- daINFO = 4,
- daWARN = 5
-};
-
-//Change this to another Log Tag if ya want. IN the batch script I provide you change the log tag then too
-#define TAG OBFUSCATE("Mod_Menu")
-
-#define LOGD(...) ((void)__android_log_print(daDEBUG, TAG, __VA_ARGS__))
-#define LOGE(...) ((void)__android_log_print(daERROR, TAG, __VA_ARGS__))
-#define LOGI(...) ((void)__android_log_print(daINFO, TAG, __VA_ARGS__))
-#define LOGW(...) ((void)__android_log_print(daWARN, TAG, __VA_ARGS__))
-
-#endif //DAWN_LOGGER_H
\ No newline at end of file
diff --git a/app/src/main/jni/Includes/Macros.h b/app/src/main/jni/Includes/Macros.h
deleted file mode 100644
index 852a0f0..0000000
--- a/app/src/main/jni/Includes/Macros.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef ANDROID_MOD_MENU_MACROS_H
-#define ANDROID_MOD_MENU_MACROS_H
-
-// thanks to shmoo and joeyjurjens for the usefull stuff under this comment.
-
-#if defined(__aarch64__) //Compile for arm64 lib only
-#include
-
-#define HOOK(offset, ptr, orig) A64HookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)
-#define HOOK_LIB(lib, offset, ptr, orig) A64HookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)
-
-#define HOOK_NO_ORIG(offset, ptr) A64HookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)
-#define HOOK_LIB_NO_ORIG(lib, offset, ptr) A64HookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)
-
-#define HOOKSYM(sym, ptr, org) A64HookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)
-#define HOOKSYM_LIB(lib, sym, ptr, org) A64HookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)
-
-#define HOOKSYM_NO_ORIG(sym, ptr) A64HookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL)
-#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) A64HookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL)
-
-#else //Compile for armv7 lib only. Do not worry about greyed out highlighting code, it still works
-
-#include
-#include
-
-#define HOOK(offset, ptr, orig) MSHookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)
-#define HOOK_LIB(lib, offset, ptr, orig) MSHookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, (void **)&orig)
-
-#define HOOK_NO_ORIG(offset, ptr) MSHookFunction((void *)getAbsoluteAddress(targetLibName, string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)
-#define HOOK_LIB_NO_ORIG(lib, offset, ptr) MSHookFunction((void *)getAbsoluteAddress(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset))), (void *)ptr, NULL)
-
-#define HOOKSYM(sym, ptr, org) MSHookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)
-#define HOOKSYM_LIB(lib, sym, ptr, org) MSHookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, (void **)&org)
-
-#define HOOKSYM_NO_ORIG(sym, ptr) MSHookFunction(dlsym(dlopen(targetLibName, 4), OBFUSCATE(sym)), (void *)ptr, NULL)
-#define HOOKSYM_LIB_NO_ORIG(lib, sym, ptr) MSHookFunction(dlsym(dlopen(OBFUSCATE(lib), 4), OBFUSCATE(sym)), (void *)ptr, NULL)
-
-#endif
-
-// Obfuscate offset
-#define OBFUSCATEOFFSET(str) string2Offset(OBFUSCATE(str)) // Encrypt offset
-
-// Patching a offset without switch.
-void patchOffset(const char *fileName, uint64_t offset, std::string hexBytes) {
- MemoryPatch patch = MemoryPatch::createWithHex(fileName, offset, hexBytes);
- if(!patch.isValid()){
- LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex you entered."), offset);
- return;
- }
- if(!patch.Modify()) {
- LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset);
- return;
- }
-}
-
-void patchOffset(uint64_t offset, std::string hexBytes) {
- MemoryPatch patch = MemoryPatch::createWithHex(targetLibName, offset, hexBytes);
- if(!patch.isValid()){
- LOGE(OBFUSCATE("Failing offset: 0x%llu, please re-check the hex you entered."), offset);
- return;
- }
- if(!patch.Modify()) {
- LOGE(OBFUSCATE("Something went wrong while patching this offset: 0x%llu"), offset);
- return;
- }
-}
-
-#define PATCHOFFSET(offset, hex) patchOffset(string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex))
-#define PATCHOFFSET_LIB(lib, offset, hex) patchOffset(OBFUSCATE(lib), string2Offset(OBFUSCATE(offset)), OBFUSCATE(hex))
-
-#endif //ANDROID_MOD_MENU_MACROS_H
diff --git a/app/src/main/jni/Includes/Utils.h b/app/src/main/jni/Includes/Utils.h
deleted file mode 100644
index 968c594..0000000
--- a/app/src/main/jni/Includes/Utils.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#ifndef UTILS
-#define UTILS
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "Logger.h"
-#include "Unity/unity.h"
-#include "Canvas/ESP.h"
-#include "Canvas/Bools.h"
-#include "Canvas/StructsCommon.h"
-
-typedef unsigned long DWORD;
-static uintptr_t libBase;
-
-bool isGameLibLoaded = false;
-
-DWORD findLibrary(const char *library) {
- char filename[0xFF] = {0},
- buffer[1024] = {0};
- FILE *fp = NULL;
- DWORD address = 0;
-
- sprintf(filename, OBFUSCATE("/proc/self/maps"));
-
- fp = fopen(filename, OBFUSCATE("rt"));
- if (fp == NULL) {
- perror(OBFUSCATE("fopen"));
- goto done;
- }
-
- while (fgets(buffer, sizeof(buffer), fp)) {
- if (strstr(buffer, library)) {
- address = (DWORD) strtoul(buffer, NULL, 16);
- goto done;
- }
- }
-
- done:
-
- if (fp) {
- fclose(fp);
- }
-
- return address;
-}
-
-DWORD getAbsoluteAddress(const char *libraryName, DWORD relativeAddr) {
- libBase = findLibrary(libraryName);
- if (libBase == 0)
- return 0;
- return (reinterpret_cast(libBase + relativeAddr));
-}
-
-extern "C" {
-JNIEXPORT jboolean JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_isGameLibLoaded(JNIEnv *env, jobject thiz) {
- return isGameLibLoaded;
-}
-}
-
-bool isLibraryLoaded(const char *libraryName) {
- //isGameLibLoaded = true;
- char line[512] = {0};
- FILE *fp = fopen(OBFUSCATE("/proc/self/maps"), OBFUSCATE("rt"));
- if (fp != NULL) {
- while (fgets(line, sizeof(line), fp)) {
- std::string a = line;
- if (strstr(line, libraryName)) {
- isGameLibLoaded = true;
- return true;
- }
- }
- fclose(fp);
- }
- return false;
-}
-
-//Credit: Octowolve
-void MakeToast(JNIEnv *env, jobject thiz, const char *text, int length) {
- //Add our toast in here so it wont be easy to change by simply editing the smali and cant
- //be cut out because this method is needed to start the hack (Octowolve is smart)
- jstring jstr = env->NewStringUTF(text); //Edit this text to your desired toast message!
- jclass toast = env->FindClass(OBFUSCATE("android/widget/Toast"));
- jmethodID methodMakeText =
- env->GetStaticMethodID(
- toast,
- OBFUSCATE("makeText"),
- OBFUSCATE(
- "(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;"));
- if (methodMakeText == NULL) {
- LOGE(OBFUSCATE("toast.makeText not Found"));
- return;
- }
- //The last int is the length on how long the toast should be displayed
- //0 = Short, 1 = Long
- jobject toastobj = env->CallStaticObjectMethod(toast, methodMakeText,
- thiz, jstr, length);
-
- jmethodID methodShow = env->GetMethodID(toast, OBFUSCATE("show"), OBFUSCATE("()V"));
- if (methodShow == NULL) {
- LOGE(OBFUSCATE("toast.show not Found"));
- return;
- }
- env->CallVoidMethod(toastobj, methodShow);
-}
-
-uintptr_t string2Offset(const char *c) {
- int base = 16;
- // See if this function catches all possibilities.
- // If it doesn't, the function would have to be amended
- // whenever you add a combination of architecture and
- // compiler that is not yet addressed.
- static_assert(sizeof(uintptr_t) == sizeof(unsigned long)
- || sizeof(uintptr_t) == sizeof(unsigned long long),
- "Please add string to handle conversion for this architecture.");
-
- // Now choose the correct function ...
- if (sizeof(uintptr_t) == sizeof(unsigned long)) {
- return strtoul(c, nullptr, base);
- }
-
- // All other options exhausted, sizeof(uintptr_t) == sizeof(unsigned long long))
- return strtoull(c, nullptr, base);
-}
-
-namespace Toast {
- inline const int LENGTH_LONG = 1;
- inline const int LENGTH_SHORT = 0;
-}
-
-#endif
diff --git a/app/src/main/jni/Includes/obfuscate.h b/app/src/main/jni/Includes/obfuscate.h
deleted file mode 100644
index cec60ae..0000000
--- a/app/src/main/jni/Includes/obfuscate.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* --------------------------------- ABOUT -------------------------------------
-Original Author: Adam Yaxley
-Website: https://github.com/adamyaxley
-License: See end of file
-Obfuscate
-Guaranteed compile-time string literal obfuscation library for C++14
-Usage:
-Pass string literals into the AY_OBFUSCATE macro to obfuscate them at compile
-time. AY_OBFUSCATE returns a reference to an ay::obfuscated_data object with the
-following traits:
- - Guaranteed obfuscation of string
- The passed string is encrypted with a simple XOR cipher at compile-time to
- prevent it being viewable in the binary image
- - Global lifetime
- The actual instantiation of the ay::obfuscated_data takes place inside a
- lambda as a function level static
- - Implicitly convertable to a char*
- This means that you can pass it directly into functions that would normally
- take a char* or a const char*
-Example:
-const char* obfuscated_string = AY_OBFUSCATE("Hello World");
-std::cout << obfuscated_string << std::endl;
------------------------------------------------------------------------------ */
-#include
-#include
-
-#ifndef AY_OBFUSCATE_DEFAULT_KEY
-// The default 64 bit key to obfuscate strings with.
-// This can be user specified by defining AY_OBFUSCATE_DEFAULT_KEY before
-// including obfuscate.h
-#define AY_OBFUSCATE_DEFAULT_KEY ay::generate_key(__LINE__)
-#endif
-
-namespace ay
-{
- using size_type = unsigned long long;
- using key_type = unsigned long long;
-
- // Generate a psuedo-random key that spans all 8 bytes
- constexpr key_type generate_key(key_type seed)
- {
- // Use the MurmurHash3 64-bit finalizer to hash our seed
- key_type key = seed;
- key ^= (key >> 33);
- key *= 0xff51afd7ed558ccd;
- key ^= (key >> 33);
- key *= 0xc4ceb9fe1a85ec53;
- key ^= (key >> 33);
-
- // Make sure that a bit in each byte is set
- key |= 0x0101010101010101ull;
-
- return key;
- }
-
- // Obfuscates or deobfuscates data with key
- constexpr void cipher(char* data, size_type size, key_type key)
- {
- // Obfuscate with a simple XOR cipher based on key
- for (size_type i = 0; i < size; i++)
- {
- data[i] ^= char(key >> ((i % 8) * 8));
- }
- }
-
- // Obfuscates a string at compile time
- template
- class obfuscator
- {
- public:
- // Obfuscates the string 'data' on construction
- constexpr obfuscator(const char* data)
- {
- // Copy data
- for (size_type i = 0; i < N; i++)
- {
- m_data[i] = data[i];
- }
-
- // On construction each of the characters in the string is
- // obfuscated with an XOR cipher based on key
- cipher(m_data, N, KEY);
- }
-
- constexpr const char* data() const
- {
- return &m_data[0];
- }
-
- constexpr size_type size() const
- {
- return N;
- }
-
- constexpr key_type key() const
- {
- return KEY;
- }
-
- private:
-
- char m_data[N]{};
- };
-
- // Handles decryption and re-encryption of an encrypted string at runtime
- template
- class obfuscated_data
- {
- public:
- obfuscated_data(const obfuscator& obfuscator)
- {
- // Copy obfuscated data
- for (size_type i = 0; i < N; i++)
- {
- m_data[i] = obfuscator.data()[i];
- }
- }
-
- ~obfuscated_data()
- {
- // Zero m_data to remove it from memory
- for (size_type i = 0; i < N; i++)
- {
- m_data[i] = 0;
- }
- }
-
- // Returns a pointer to the plain text string, decrypting it if
- // necessary
- operator char*()
- {
- decrypt();
- return m_data;
- }
-
- operator std::string()
- {
- decrypt();
- return m_data;
- }
-
- // Manually decrypt the string
- void decrypt()
- {
- if (m_encrypted)
- {
- cipher(m_data, N, KEY);
- m_encrypted = false;
- }
- }
-
- // Manually re-encrypt the string
- void encrypt()
- {
- if (!m_encrypted)
- {
- cipher(m_data, N, KEY);
- m_encrypted = true;
- }
- }
-
- // Returns true if this string is currently encrypted, false otherwise.
- bool is_encrypted() const
- {
- return m_encrypted;
- }
-
- private:
-
- // Local storage for the string. Call is_encrypted() to check whether or
- // not the string is currently obfuscated.
- char m_data[N];
-
- // Whether data is currently encrypted
- bool m_encrypted{ true };
- };
-
- // This function exists purely to extract the number of elements 'N' in the
- // array 'data'
- template
- constexpr auto make_obfuscator(const char(&data)[N])
- {
- return obfuscator(data);
- }
-}
-
-// Obfuscates the string 'data' at compile-time and returns a reference to a
-// ay::obfuscated_data object with global lifetime that has functions for
-// decrypting the string and is also implicitly convertable to a char*
-#define OBFUSCATE(data) OBFUSCATE_KEY(data, AY_OBFUSCATE_DEFAULT_KEY)
-
-// Obfuscates the string 'data' with 'key' at compile-time and returns a
-// reference to a ay::obfuscated_data object with global lifetime that has
-// functions for decrypting the string and is also implicitly convertable to a
-// char*
-#define OBFUSCATE_KEY(data, key) \
- []() -> ay::obfuscated_data& { \
- static_assert(sizeof(decltype(key)) == sizeof(ay::key_type), "key must be a 64 bit unsigned integer"); \
- static_assert((key) >= (1ull << 56), "key must span all 8 bytes"); \
- constexpr auto n = sizeof(data)/sizeof(data[0]); \
- constexpr auto obfuscator = ay::make_obfuscator(data); \
- static auto obfuscated_data = ay::obfuscated_data(obfuscator); \
- return obfuscated_data; \
- }()
-
-/* -------------------------------- LICENSE ------------------------------------
-Public Domain (http://www.unlicense.org)
-This is free and unencumbered software released into the public domain.
-Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
-software, either in source code form or as a compiled binary, for any purpose,
-commercial or non-commercial, and by any means.
-In jurisdictions that recognize copyright laws, the author or authors of this
-software dedicate any and all copyright interest in the software to the public
-domain. We make this dedication for the benefit of the public at large and to
-the detriment of our heirs and successors. We intend this dedication to be an
-overt act of relinquishment in perpetuity of all present and future rights to
-this software under copyright law.
-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 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.
------------------------------------------------------------------------------ */
\ No newline at end of file
diff --git a/app/src/main/jni/KittyMemory/KittyMemory.cpp b/app/src/main/jni/KittyMemory/KittyMemory.cpp
deleted file mode 100644
index 7beb667..0000000
--- a/app/src/main/jni/KittyMemory/KittyMemory.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// KittyMemory.cpp
-//
-// Created by MJ (Ruit) on 1/1/19.
-//
-
-#include
-#include "KittyMemory.h"
-
-using KittyMemory::Memory_Status;
-using KittyMemory::ProcMap;
-
-
-struct mapsCache {
- std::string identifier;
- ProcMap map;
-};
-
-static std::vector __mapsCache;
-static ProcMap findMapInCache(std::string id){
- ProcMap ret;
- for(int i = 0; i < __mapsCache.size(); i++){
- if(__mapsCache[i].identifier.compare(id) == 0){
- ret = __mapsCache[i].map;
- break;
- }
- }
- return ret;
-}
-
-
-bool KittyMemory::ProtectAddr(void *addr, size_t length, int protection) {
- uintptr_t pageStart = _PAGE_START_OF_(addr);
- uintptr_t pageLen = _PAGE_LEN_OF_(addr, length);
- return (
- mprotect(reinterpret_cast(pageStart), pageLen, protection) != -1
- );
-}
-
-
-Memory_Status KittyMemory::memWrite(void *addr, const void *buffer, size_t len) {
- if (addr == NULL)
- return INV_ADDR;
-
- if (buffer == NULL)
- return INV_BUF;
-
- if (len < 1 || len > INT_MAX)
- return INV_LEN;
-
- if (!ProtectAddr(addr, len, _PROT_RWX_))
- return INV_PROT;
-
- if (memcpy(addr, buffer, len) != NULL && ProtectAddr(addr, len, _PROT_RX_))
- return SUCCESS;
-
- return FAILED;
-}
-
-
-Memory_Status KittyMemory::memRead(void *buffer, const void *addr, size_t len) {
- if (addr == NULL)
- return INV_ADDR;
-
- if (buffer == NULL)
- return INV_BUF;
-
- if (len < 1 || len > INT_MAX)
- return INV_LEN;
-
- if (memcpy(buffer, addr, len) != NULL)
- return SUCCESS;
-
- return FAILED;
-}
-
-
-std::string KittyMemory::read2HexStr(const void *addr, size_t len) {
- char temp[len];
- memset(temp, 0, len);
-
- const size_t bufferLen = len * 2 + 1;
- char buffer[bufferLen];
- memset(buffer, 0, bufferLen);
-
- std::string ret;
-
- if (memRead(temp, addr, len) != SUCCESS)
- return ret;
-
- for (int i = 0; i < len; i++) {
- sprintf(&buffer[i * 2], "%02X", (unsigned char) temp[i]);
- }
-
- ret += buffer;
- return ret;
-}
-
-ProcMap KittyMemory::getLibraryMap(const char *libraryName) {
- ProcMap retMap;
- char line[512] = {0};
-
- FILE *fp = fopen(OBFUSCATE("/proc/self/maps"), OBFUSCATE("rt"));
- if (fp != NULL) {
- while (fgets(line, sizeof(line), fp)) {
- if (strstr(line, libraryName)) {
- char tmpPerms[5] = {0}, tmpDev[12] = {0}, tmpPathname[444] = {0};
- // parse a line in maps file
- // (format) startAddress-endAddress perms offset dev inode pathname
- sscanf(line, "%llx-%llx %s %ld %s %d %s",
- (long long unsigned *) &retMap.startAddr,
- (long long unsigned *) &retMap.endAddr,
- tmpPerms, &retMap.offset, tmpDev, &retMap.inode, tmpPathname);
-
- retMap.length = (uintptr_t) retMap.endAddr - (uintptr_t) retMap.startAddr;
- retMap.perms = tmpPerms;
- retMap.dev = tmpDev;
- retMap.pathname = tmpPathname;
-
- break;
- }
- }
- fclose(fp);
- }
- return retMap;
-}
-
-uintptr_t KittyMemory::getAbsoluteAddress(const char *libraryName, uintptr_t relativeAddr, bool useCache) {
- ProcMap libMap;
-
- if(useCache){
- libMap = findMapInCache(libraryName);
- if(libMap.isValid())
- return (reinterpret_cast(libMap.startAddr) + relativeAddr);
- }
-
- libMap = getLibraryMap(libraryName);
- if (!libMap.isValid())
- return 0;
-
- if(useCache){
- mapsCache cachedMap;
- cachedMap.identifier = libraryName;
- cachedMap.map = libMap;
- __mapsCache.push_back(cachedMap);
- }
-
- return (reinterpret_cast(libMap.startAddr) + relativeAddr);
-}
diff --git a/app/src/main/jni/KittyMemory/KittyMemory.h b/app/src/main/jni/KittyMemory/KittyMemory.h
deleted file mode 100644
index 21f0160..0000000
--- a/app/src/main/jni/KittyMemory/KittyMemory.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// KittyMemory.hpp
-//
-// Created by MJ (Ruit) on 1/1/19.
-//
-
-#pragma once
-
-#include
-#include
-#include
-#include
-#include
-
-
-#define _SYS_PAGE_SIZE_ (sysconf(_SC_PAGE_SIZE))
-
-#define _PAGE_START_OF_(x) ((uintptr_t)x & ~(uintptr_t)(_SYS_PAGE_SIZE_ - 1))
-#define _PAGE_END_OF_(x, len) (_PAGE_START_OF_((uintptr_t)x + len - 1))
-#define _PAGE_LEN_OF_(x, len) (_PAGE_END_OF_(x, len) - _PAGE_START_OF_(x) + _SYS_PAGE_SIZE_)
-#define _PAGE_OFFSET_OF_(x) ((uintptr_t)x - _PAGE_START_OF_(x))
-
-#define _PROT_RWX_ (PROT_READ | PROT_WRITE | PROT_EXEC)
-#define _PROT_RX_ (PROT_READ | PROT_EXEC)
-
-
-#define EMPTY_VEC_OFFSET std::vector()
-
-namespace KittyMemory {
-
- typedef enum {
- FAILED = 0,
- SUCCESS = 1,
- INV_ADDR = 2,
- INV_LEN = 3,
- INV_BUF = 4,
- INV_PROT = 5
- } Memory_Status;
-
-
- struct ProcMap {
- void *startAddr;
- void *endAddr;
- size_t length;
- std::string perms;
- long offset;
- std::string dev;
- int inode;
- std::string pathname;
-
- bool isValid() { return (startAddr != NULL && endAddr != NULL && !pathname.empty()); }
- };
-
- /*
- * Changes protection of an address with given length
- */
- bool ProtectAddr(void *addr, size_t length, int protection);
-
- /*
- * Writes buffer content to an address
- */
- Memory_Status memWrite(void *addr, const void *buffer, size_t len);
-
- /*
- * Reads an address content into a buffer
- */
- Memory_Status memRead(void *buffer, const void *addr, size_t len);
-
- /*
- * Reads an address content and returns hex string
- */
- std::string read2HexStr(const void *addr, size_t len);
-
-
- /*
- * Wrapper to dereference & get value of a multi level pointer
- * Make sure to use the correct data type!
- */
- template
- Type readMultiPtr(void *ptr, std::vector offsets) {
- Type defaultVal = {};
- if (ptr == NULL)
- return defaultVal;
-
- uintptr_t finalPtr = reinterpret_cast(ptr);
- int offsetsSize = offsets.size();
- if (offsetsSize > 0) {
- for (int i = 0; finalPtr != 0 && i < offsetsSize; i++) {
- if (i == (offsetsSize - 1))
- return *reinterpret_cast(finalPtr + offsets[i]);
-
- finalPtr = *reinterpret_cast(finalPtr + offsets[i]);
- }
- }
-
- if (finalPtr == 0)
- return defaultVal;
-
- return *reinterpret_cast(finalPtr);
- }
-
-
- /*
- * Wrapper to dereference & set value of a multi level pointer
- * Make sure to use the correct data type!, const objects won't work
- */
- template
- bool writeMultiPtr(void *ptr, std::vector offsets, Type val) {
- if (ptr == NULL)
- return false;
-
- uintptr_t finalPtr = reinterpret_cast(ptr);
- int offsetsSize = offsets.size();
- if (offsetsSize > 0) {
- for (int i = 0; finalPtr != 0 && i < offsetsSize; i++) {
- if (i == (offsetsSize - 1)) {
- *reinterpret_cast(finalPtr + offsets[i]) = val;
- return true;
- }
-
- finalPtr = *reinterpret_cast(finalPtr + offsets[i]);
- }
- }
-
- if (finalPtr == 0)
- return false;
-
- *reinterpret_cast(finalPtr) = val;
- return true;
- }
-
- /*
- * Wrapper to dereference & get value of a pointer
- * Make sure to use the correct data type!
- */
- template
- Type readPtr(void *ptr) {
- Type defaultVal = {};
- if (ptr == NULL)
- return defaultVal;
-
- return *reinterpret_cast(ptr);
- }
-
- /*
- * Wrapper to dereference & set value of a pointer
- * Make sure to use the correct data type!, const objects won't work
- */
- template
- bool writePtr(void *ptr, Type val) {
- if (ptr == NULL)
- return false;
-
- *reinterpret_cast(ptr) = val;
- return true;
- }
-
- /*
- * Gets info of a mapped library in self process
- */
- ProcMap getLibraryMap(const char *libraryName);
-
- /*
- * Expects a relative address in a library
- * Returns final absolute address
- */
- uintptr_t
- getAbsoluteAddress(const char *libraryName, uintptr_t relativeAddr, bool useCache = false);
-};
diff --git a/app/src/main/jni/KittyMemory/KittyUtils.cpp b/app/src/main/jni/KittyMemory/KittyUtils.cpp
deleted file mode 100644
index b459287..0000000
--- a/app/src/main/jni/KittyMemory/KittyUtils.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "KittyUtils.h"
-
-static void xtrim(std::string &hex){
- if(hex.compare(0, 2, "0x") == 0){
- hex.erase(0, 2);
- }
-
- // https://www.techiedelight.com/remove-whitespaces-string-cpp/
- hex.erase(std::remove_if(hex.begin(), hex.end(), [](char c){
- return (c == ' ' || c == '\n' || c == '\r' ||
- c == '\t' || c == '\v' || c == '\f');
- }),
- hex.end());
-}
-
-
-bool KittyUtils::validateHexString(std::string &xstr){
- if(xstr.length() < 2) return false;
- xtrim(xstr); // first remove spaces
- if(xstr.length() % 2 != 0) return false;
- for(size_t i = 0; i < xstr.length(); i++){
- if(!std::isxdigit((unsigned char)xstr[i])){
- return false;
- }
- }
- return true;
-}
-
-
-// https://tweex.net/post/c-anything-tofrom-a-hex-string/
-#include
-#include
-
-
-// ------------------------------------------------------------------
-/*!
- Convert a block of data to a hex string
-*/
-void KittyUtils::toHex(
- void *const data, //!< Data to convert
- const size_t dataLength, //!< Length of the data to convert
- std::string &dest //!< Destination string
- )
-{
- unsigned char *byteData = reinterpret_cast(data);
- std::stringstream hexStringStream;
-
- hexStringStream << std::hex << std::setfill('0');
- for(size_t index = 0; index < dataLength; ++index)
- hexStringStream << std::setw(2) << static_cast(byteData[index]);
- dest = hexStringStream.str();
-}
-
-
-// ------------------------------------------------------------------
-/*!
- Convert a hex string to a block of data
-*/
-void KittyUtils::fromHex(
- const std::string &in, //!< Input hex string
- void *const data //!< Data store
- )
-{
- size_t length = in.length();
- unsigned char *byteData = reinterpret_cast(data);
-
- std::stringstream hexStringStream; hexStringStream >> std::hex;
- for(size_t strIndex = 0, dataIndex = 0; strIndex < length; ++dataIndex)
- {
- // Read out and convert the string two characters at a time
- const char tmpStr[3] = { in[strIndex++], in[strIndex++], 0 };
-
- // Reset and fill the string stream
- hexStringStream.clear();
- hexStringStream.str(tmpStr);
-
- // Do the conversion
- int tmpValue = 0;
- hexStringStream >> tmpValue;
- byteData[dataIndex] = static_cast(tmpValue);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/jni/KittyMemory/KittyUtils.h b/app/src/main/jni/KittyMemory/KittyUtils.h
deleted file mode 100644
index ffd81c6..0000000
--- a/app/src/main/jni/KittyMemory/KittyUtils.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include
-#include
-
-namespace KittyUtils {
-
- bool validateHexString(std::string &xstr);
- void toHex(void *const data, const size_t dataLength, std::string &dest);
- void fromHex(const std::string &in, void *const data);
-
-}
\ No newline at end of file
diff --git a/app/src/main/jni/KittyMemory/MemoryBackup.cpp b/app/src/main/jni/KittyMemory/MemoryBackup.cpp
deleted file mode 100644
index acf7a82..0000000
--- a/app/src/main/jni/KittyMemory/MemoryBackup.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// MemoryBackup.cpp
-//
-// Created by MJ (Ruit) on 4/19/20.
-//
-
-#include
-#include "MemoryBackup.h"
-
-
-MemoryBackup::MemoryBackup() {
- _address = 0;
- _size = 0;
- _orig_code.clear();
-}
-
-MemoryBackup::MemoryBackup(const char *libraryName, uintptr_t address, size_t backup_size, bool useMapCache) {
- MemoryBackup();
-
- if (libraryName == NULL || address == 0 || backup_size < 1)
- return;
-
- _address = KittyMemory::getAbsoluteAddress(libraryName, address, useMapCache);
- if(_address == 0) return;
-
- _size = backup_size;
-
- _orig_code.resize(backup_size);
-
- // backup current content
- KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), backup_size);
-}
-
-
-MemoryBackup::MemoryBackup(uintptr_t absolute_address, size_t backup_size) {
- MemoryBackup();
-
- if (absolute_address == 0 || backup_size < 1)
- return;
-
- _address = absolute_address;
-
- _size = backup_size;
-
- _orig_code.resize(backup_size);
-
- // backup current content
- KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), backup_size);
-}
-
- MemoryBackup::~MemoryBackup() {
- // clean up
- _orig_code.clear();
- }
-
-
- bool MemoryBackup::isValid() const {
- return (_address != 0 && _size > 0
- && _orig_code.size() == _size);
- }
-
- size_t MemoryBackup::get_BackupSize() const{
- return _size;
- }
-
- uintptr_t MemoryBackup::get_TargetAddress() const{
- return _address;
- }
-
- bool MemoryBackup::Restore() {
- if (!isValid()) return false;
- return KittyMemory::memWrite(reinterpret_cast(_address), &_orig_code[0], _size) == Memory_Status::SUCCESS;
- }
-
- std::string MemoryBackup::get_CurrBytes() {
- if (!isValid())
- _hexString = std::string(OBFUSCATE("0xInvalid"));
- else
- _hexString = KittyMemory::read2HexStr(reinterpret_cast(_address), _size);
-
- return _hexString;
- }
diff --git a/app/src/main/jni/KittyMemory/MemoryBackup.h b/app/src/main/jni/KittyMemory/MemoryBackup.h
deleted file mode 100644
index fde1ea4..0000000
--- a/app/src/main/jni/KittyMemory/MemoryBackup.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// MemoryBackup.h
-//
-// Created by MJ (Ruit) on 4/19/20.
-//
-
-#pragma once
-
-#include
-
-#include "KittyMemory.h"
-using KittyMemory::Memory_Status;
-using KittyMemory::ProcMap;
-
-
-class MemoryBackup {
-private:
- uintptr_t _address;
- size_t _size;
-
- std::vector _orig_code;
-
- std::string _hexString;
-
-public:
- MemoryBackup();
-
- /*
- * expects library name and relative address
- */
- MemoryBackup(const char *libraryName, uintptr_t address, size_t backup_size, bool useMapCache=true);
-
- /*
- * expects absolute address
- */
- MemoryBackup(uintptr_t absolute_address, size_t backup_size);
-
-
- ~MemoryBackup();
-
-
- /*
- * Validate patch
- */
- bool isValid() const;
-
-
- size_t get_BackupSize() const;
-
- /*
- * Returns pointer to the target address
- */
- uintptr_t get_TargetAddress() const;
-
-
- /*
- * Restores backup code
- */
- bool Restore();
-
-
- /*
- * Returns current target address bytes as hex string
- */
- std::string get_CurrBytes();
-};
diff --git a/app/src/main/jni/KittyMemory/MemoryPatch.cpp b/app/src/main/jni/KittyMemory/MemoryPatch.cpp
deleted file mode 100644
index 74b6874..0000000
--- a/app/src/main/jni/KittyMemory/MemoryPatch.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-//
-// MemoryPatch.cpp
-//
-// Created by MJ (Ruit) on 1/1/19.
-//
-
-#include
-#include "MemoryPatch.h"
-#include "Includes/Logger.h"
-
-MemoryPatch::MemoryPatch() {
- _address = 0;
- _size = 0;
- _orig_code.clear();
- _patch_code.clear();
-}
-
-MemoryPatch::MemoryPatch(const char *libraryName, uintptr_t address,
- const void *patch_code, size_t patch_size, bool useMapCache) {
- MemoryPatch();
-
- if (libraryName == NULL || address == 0 || patch_code == NULL || patch_size < 1)
- return;
-
- _address = KittyMemory::getAbsoluteAddress(libraryName, address, useMapCache);
- if (_address == 0) return;
-
- _size = patch_size;
-
- _orig_code.resize(patch_size);
- _patch_code.resize(patch_size);
-
- // initialize patch & backup current content
- KittyMemory::memRead(&_patch_code[0], patch_code, patch_size);
- KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), patch_size);
-}
-
-MemoryPatch::MemoryPatch(uintptr_t absolute_address,
- const void *patch_code, size_t patch_size) {
- MemoryPatch();
-
- if (absolute_address == 0 || patch_code == NULL || patch_size < 1)
- return;
-
- _address = absolute_address;
- _size = patch_size;
-
- _orig_code.resize(patch_size);
- _patch_code.resize(patch_size);
-
- // initialize patch & backup current content
- KittyMemory::memRead(&_patch_code[0], patch_code, patch_size);
- KittyMemory::memRead(&_orig_code[0], reinterpret_cast(_address), patch_size);
-}
-
-MemoryPatch::~MemoryPatch() {
- // clean up
- _orig_code.clear();
- _patch_code.clear();
-}
-
-MemoryPatch MemoryPatch::createWithHex(const char *libraryName, uintptr_t address,
- std::string hex, bool useMapCache) {
- MemoryPatch patch;
-
- if (libraryName == NULL || address == 0 || !KittyUtils::validateHexString(hex))
- return patch;
-
- patch._address = KittyMemory::getAbsoluteAddress(libraryName, address, useMapCache);
- if (patch._address == 0) return patch;
-
- patch._size = hex.length() / 2;
-
- patch._orig_code.resize(patch._size);
- patch._patch_code.resize(patch._size);
-
- // initialize patch
- KittyUtils::fromHex(hex, &patch._patch_code[0]);
-
- // backup current content
- KittyMemory::memRead(&patch._orig_code[0], reinterpret_cast(patch._address),
- patch._size);
- return patch;
-}
-
-MemoryPatch MemoryPatch::createWithHex(uintptr_t absolute_address, std::string hex) {
- MemoryPatch patch;
-
- if (absolute_address == 0 || !KittyUtils::validateHexString(hex))
- return patch;
-
- patch._address = absolute_address;
- patch._size = hex.length() / 2;
-
- patch._orig_code.resize(patch._size);
- patch._patch_code.resize(patch._size);
-
- // initialize patch
- KittyUtils::fromHex(hex, &patch._patch_code[0]);
-
- // backup current content
- KittyMemory::memRead(&patch._orig_code[0], reinterpret_cast(patch._address),
- patch._size);
- return patch;
-}
-
-bool MemoryPatch::isValid() const {
- return (_address != 0 && _size > 0
- && _orig_code.size() == _size && _patch_code.size() == _size);
-}
-
-size_t MemoryPatch::get_PatchSize() const {
- return _size;
-}
-
-uintptr_t MemoryPatch::get_TargetAddress() const {
- return _address;
-}
-
-bool MemoryPatch::Restore() {
- if (!isValid()) return false;
- //LOGI("Restore %i", isLeeched);
- return KittyMemory::memWrite(reinterpret_cast(_address), &_orig_code[0], _size) ==
- Memory_Status::SUCCESS;
-}
-
-bool MemoryPatch::Modify() {
- if (!isValid()) return false;
- //LOGI("Modify");
- return (KittyMemory::memWrite(reinterpret_cast(_address), &_patch_code[0], _size) ==
- Memory_Status::SUCCESS);
-}
-
-std::string MemoryPatch::get_CurrBytes() {
- if (!isValid())
- _hexString = std::string(OBFUSCATE("0xInvalid"));
- else
- _hexString = KittyMemory::read2HexStr(reinterpret_cast(_address), _size);
-
- return _hexString;
-}
diff --git a/app/src/main/jni/KittyMemory/MemoryPatch.h b/app/src/main/jni/KittyMemory/MemoryPatch.h
deleted file mode 100644
index f63d91c..0000000
--- a/app/src/main/jni/KittyMemory/MemoryPatch.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// MemoryPatch.h
-//
-// Created by MJ (Ruit) on 1/1/19.
-//
-
-#pragma once
-
-#include
-#include "KittyUtils.h"
-#include "KittyMemory.h"
-using KittyMemory::Memory_Status;
-using KittyMemory::ProcMap;
-
-class MemoryPatch {
-private:
- uintptr_t _address;
- size_t _size;
-
- std::vector _orig_code;
- std::vector _patch_code;
-
- std::string _hexString;
-
-public:
- MemoryPatch();
-
- /*
- * expects library name and relative address
- */
- MemoryPatch(const char *libraryName, uintptr_t address,
- const void *patch_code, size_t patch_size, bool useMapCache=true);
-
-
- /*
- * expects absolute address
- */
- MemoryPatch(uintptr_t absolute_address,
- const void *patch_code, size_t patch_size);
-
-
- ~MemoryPatch();
-
- /*
- * compatible hex format (0xffff & ffff & ff ff)
- */
- static MemoryPatch createWithHex(const char *libraryName, uintptr_t address, std::string hex, bool useMapCache=true);
- static MemoryPatch createWithHex(uintptr_t absolute_address, std::string hex);
-
- /*
- * Validate patch
- */
- bool isValid() const;
-
-
- size_t get_PatchSize() const;
-
- /*
- * Returns pointer to the target address
- */
- uintptr_t get_TargetAddress() const;
-
-
- /*
- * Restores patch to original value
- */
- bool Restore();
-
-
- /*
- * Applies patch modifications to target address
- */
- bool Modify();
-
-
- /*
- * Returns current patch target address bytes as hex string
- */
- std::string get_CurrBytes();
-};
diff --git a/app/src/main/jni/Main.cpp b/app/src/main/jni/Main.cpp
deleted file mode 100644
index 774b643..0000000
--- a/app/src/main/jni/Main.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "Includes/Logger.h"
-#include "Includes/obfuscate.h"
-#include "Includes/Utils.h"
-#include "Menu.h"
-#include
-#include
-ESP espOverlay;
-
-bool feature1, feature2, featureHookToggle, Health;
-int sliderValue = 1, level = 0;
-
-enum f {
- f1 = 4,
- f2 = 5,
- f3 = 6,
- f4 = 7,
- f5 = 8,
- f6 = 9,
- f7 = 10,
- f8 = 11,
- f9 = 12,
- f10 = 13,
-};
-
-
-//JNI calls
-extern "C" {
-
- // Do not change or translate the first text unless you know what you are doing
- // Assigning feature numbers is optional. Without it, it will automatically count for you, starting from 0
- // Assigned feature numbers can be like any numbers 1,3,200,10... instead in order 0,1,2,3,4,5...
- // ButtonLink, Category, RichTextView and RichWebView is not counted. They can't have feature number assigned
- // Toggle, ButtonOnOff and Checkbox can be switched on by default, if you add True_. Example: CheckBox_True_The Check Box
- // To learn HTML, go to this page: https://www.w3schools.com/
-
- JNIEXPORT jobjectArray
- JNICALL
- Java_uk_lgl_modmenu_FloatingModMenuService_getFeatureList(JNIEnv *env, jobject context) {
- jobjectArray ret;
-
- //Toasts added here so it's harder to remove it
- MakeToast(env, context, OBFUSCATE("Modded by LGL"), Toast::LENGTH_LONG);
-
- const char *features[] = {
- OBFUSCATE("Category_The Category"),
- //Not counted
- OBFUSCATE("Toggle_The toggle"),
- OBFUSCATE(
- "100_Toggle_True_The toggle 2"),
- //This one have feature number assigned, and switched on by default
- OBFUSCATE("110_Toggle_The toggle 3"),
- //This one too
- OBFUSCATE("SeekBar_The slider_1_100"),
- OBFUSCATE("SeekBar_Kittymemory slider example_1_5"),
- OBFUSCATE("Spinner_The spinner_Items 1,Items 2,Items 3"),
- OBFUSCATE("Button_The button"),
- OBFUSCATE("ButtonLink_The button with link_https://www.youtube.com/"),
- //Not counted
- OBFUSCATE("ButtonOnOff_The On/Off button"),
- OBFUSCATE("CheckBox_The Check Box"),
- OBFUSCATE("InputValue_Input number"),
- OBFUSCATE("InputValue_1000_Input number 2"),
- //Max value
- OBFUSCATE("InputText_Input text"),
- OBFUSCATE("RadioButton_Radio buttons_OFF,Mod 1,Mod 2,Mod 3"),
-
- //Create new collapse
- OBFUSCATE("Collapse_Collapse 1"),
- OBFUSCATE("CollapseAdd_Toggle_The toggle"),
- OBFUSCATE("CollapseAdd_Toggle_The toggle"),
- OBFUSCATE("123_CollapseAdd_Toggle_The toggle"),
- OBFUSCATE("CollapseAdd_Button_The button"),
-
- //Create new collapse again
- OBFUSCATE("Collapse_Collapse 2"),
- OBFUSCATE("CollapseAdd_SeekBar_The slider_1_100"),
- OBFUSCATE("CollapseAdd_InputValue_Input number"),
-
- OBFUSCATE("RichTextView_This is text view, not fully HTML."
- "Bold italic underline"
- "
New line Support colors"
- "
bigger Text"),
- OBFUSCATE("RichWebView_"
- "This is WebView, with REAL HTML support!"
- "Support CSS
"
- ""
- "")
- };
-
- //Now you dont have to manually update the number everytime;
- int Total_Feature = (sizeof features / sizeof features[0]);
- ret = (jobjectArray)
- env->NewObjectArray(Total_Feature, env->FindClass(OBFUSCATE("java/lang/String")),
- env->NewStringUTF(""));
-
- for (int i = 0; i < Total_Feature; i++)
- env->SetObjectArrayElement(ret, i, env->NewStringUTF(features[i]));
-
- pthread_t ptid;
- pthread_create(&ptid, NULL, antiLeech, NULL);
-
- return (ret);
- }
-
- JNIEXPORT void JNICALL
- Java_uk_lgl_modmenu_Preferences_Changes(JNIEnv *env, jclass clazz, jobject obj,
- jint featNum, jstring featName, jint value,
- jboolean boolean, jstring str) {
-
- LOGD(OBFUSCATE("Feature name: %d - %s | Value: = %d | Bool: = %d | Text: = %s"), featNum,
- env->GetStringUTFChars(featName, 0), value,
- boolean, str != NULL ? env->GetStringUTFChars(str, 0): "");
-
- //BE CAREFUL NOT TO ACCIDENTLY REMOVE break;
-
- switch (featNum) {
- case 0:
- feature2 = boolean;
- Send(f::f1, feature2);
-
- break;
- case 100:
- break;
- case 110:
- break;
- case 1:
- if (value >= 1) {
- sliderValue = value;
- }
- Send(f::f2, sliderValue);
- break;
- case 2:
- Send(f::f3, value);
- case 3:
- Send(f::f4, value);
- case 4:
- Send(f::f5, value);
- // MakeToast(env, obj, OBFUSCATE("Button pressed"), Toast::LENGTH_SHORT);
- break;
- case 5:
- break;
- case 6:
- featureHookToggle = boolean;
- Send(f::f6, featureHookToggle);
- break;
- case 7:
- level = value;
- Send(f::f7, value);
- break;
- case 8:
- //MakeToast(env, obj, TextInput, Toast::LENGTH_SHORT);
- break;
- case 9:
- break;
- }
- }
-}
-void DrawESP(ESP esp, int screenWidth, int screenHeight) {
- float mScale = (float) screenHeight / (float) 1080;
- esp.DrawText(Color::Yellow(), "Nepmods V1.90", Vector2(screenWidth / 2, screenHeight/1.2), 17);
-}
-
-
-extern "C"
-JNIEXPORT void JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_DrawOn(JNIEnv *env, jclass type, jobject espView, jobject canvas) {
- espOverlay = ESP(env, espView, canvas);
- if (espOverlay.isValid()) {
- DrawESP(espOverlay, espOverlay.getWidth(), espOverlay.getHeight());
- }
-}
-
-extern "C" {
- JNIEXPORT jboolean JNICALL
- Java_uk_lgl_modmenu_FloatingModMenuService_IsConnected(JNIEnv *env, jobject thiz) {
- return client.connected;
- }
-}
-
-
-extern "C"
-JNIEXPORT void JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_Init(JNIEnv *env, jobject thiz) {
- startClient();
-}
-
-extern "C"
-JNIEXPORT void JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_Stop(JNIEnv *env, jobject type) {
- stopClient();
-}
diff --git a/app/src/main/jni/Menu.h b/app/src/main/jni/Menu.h
deleted file mode 100644
index 132113b..0000000
--- a/app/src/main/jni/Menu.h
+++ /dev/null
@@ -1,106 +0,0 @@
-bool titleValid, headingValid, iconValid, settingsValid, isLeeched;
-
-void *antiLeech(void *) {
- sleep(20);
-
- if (!titleValid || !headingValid || !iconValid || !settingsValid) {
- int *p = 0;
- *p = 0;
- }
- return NULL;
-}
-
-void setText(JNIEnv *env, jobject obj, const char* text){
- //https://stackoverflow.com/a/33627640/3763113
- //A little JNI calls here. You really really need a great knowledge if you want to play with JNI stuff
- //Html.fromHtml("");
- jclass html = (*env).FindClass(OBFUSCATE("android/text/Html"));
- jmethodID fromHtml = (*env).GetStaticMethodID(html, OBFUSCATE("fromHtml"), OBFUSCATE("(Ljava/lang/String;)Landroid/text/Spanned;"));
-
- //setText("");
- jclass textView = (*env).FindClass(OBFUSCATE("android/widget/TextView"));
- jmethodID setText = (*env).GetMethodID(textView, OBFUSCATE("setText"), OBFUSCATE("(Ljava/lang/CharSequence;)V"));
-
- //Java string
- jstring jstr = (*env).NewStringUTF(text);
- (*env).CallVoidMethod(obj, setText, (*env).CallStaticObjectMethod(html, fromHtml, jstr));
-}
-
-extern "C" {
-JNIEXPORT void JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_setTitleText(JNIEnv *env, jobject thiz, jobject obj) {
- setText(env, obj, OBFUSCATE("Modded by (yourname)"));
-
- titleValid = true;
-}
-
-JNIEXPORT void JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_setHeadingText(JNIEnv *env, jobject thiz, jobject obj) {
- setText(env, obj, OBFUSCATE("
"
- ""));
-
- headingValid = true;
-}
-
-JNIEXPORT jstring JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_Icon(JNIEnv *env, jobject thiz) {
- iconValid = true;
-
- //Use https://www.base64encode.org/ to encode your image to base64
- return env->NewStringUTF(
- OBFUSCATE("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"));
-}
-
-JNIEXPORT jstring JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_IconWebViewData(JNIEnv *env, jobject thiz) {
- iconValid = true;
- //WebView support GIF animation. Upload your image or GIF on imgur.com or other sites
-
- // From internet (Requires android.permission.INTERNET)
- // return env->NewStringUTF(OBFUSCATE("https://i.imgur.com/SujJ85j.gif"));
-
- // Base64 html:
- // return env->NewStringUTF("data:image/png;base64, ");
-
- // To disable it, return NULL. It will use normal image above:
- // return NULL
-
- //return env->NewStringUTF(OBFUSCATE_KEY("https://i.imgur.com/SujJ85j.gif", 'u'));
- return NULL;
-}
-
-JNIEXPORT jobjectArray JNICALL
-Java_uk_lgl_modmenu_FloatingModMenuService_settingsList(JNIEnv *env, jobject activityObject) {
- jobjectArray ret;
-
- const char *features[] = {
- OBFUSCATE("Category_Settings"),
- OBFUSCATE("-1_Toggle_Save feature preferences"), //-1 is checked on Preferences.java
- OBFUSCATE("-3_Toggle_Auto size vertically"),
- OBFUSCATE("Category_Logcat"),
- OBFUSCATE("RichTextView_Save logcat if a bug occured and sent it to the modder. Clear logcat and reproduce bug again if the log file is too large"),
- OBFUSCATE("RichTextView_Saving logcat does not need file permission. Logcat location:"
- "
Android 11: /storage/emulated/0/Documents/"
- "
Android 10 and below: /storage/emulated/0/Android/data/(package name)/files/Mod Menu"),
- OBFUSCATE("-4_Button_Save logcat to file"),
- OBFUSCATE("-5_Button_Clear logcat"),
- OBFUSCATE("Category_Menu"),
- OBFUSCATE("-6_Button_Close settings"),
- };
-
- int Total_Feature = (sizeof features /
- sizeof features[0]); //Now you dont have to manually update the number everytime;
- ret = (jobjectArray)
- env->NewObjectArray(Total_Feature, env->FindClass(OBFUSCATE("java/lang/String")),
- env->NewStringUTF(""));
- int i;
- for (i = 0; i < Total_Feature; i++)
- env->SetObjectArrayElement(ret, i, env->NewStringUTF(features[i]));
-
- settingsValid = true;
-
- return (ret);
-}
-}
diff --git a/app/src/main/jni/RootLib/libGlobalInject.so b/app/src/main/jni/RootLib/libGlobalInject.so
deleted file mode 100644
index a26a58e..0000000
Binary files a/app/src/main/jni/RootLib/libGlobalInject.so and /dev/null differ
diff --git a/app/src/main/jni/RootLib/libVirtualInject.so b/app/src/main/jni/RootLib/libVirtualInject.so
deleted file mode 100644
index 1120322..0000000
Binary files a/app/src/main/jni/RootLib/libVirtualInject.so and /dev/null differ
diff --git a/app/src/main/jni/SOCKET/IncludeClient.h b/app/src/main/jni/SOCKET/IncludeClient.h
deleted file mode 100644
index a5d8cfb..0000000
--- a/app/src/main/jni/SOCKET/IncludeClient.h
+++ /dev/null
@@ -1,146 +0,0 @@
-SocketClient client;
-void startDaemon();
-int startClient();
-bool isConnected();
-void stopClient();
-bool initServer();
-bool stopServer();
-
-enum Mode {
- InitMode = 1,
- HackMode = 2,
- StopMode = 3,
- EspMode = 99,
-};
-
-struct Request {
- int Mode;
- bool isOn;
- int Value;
- int screenWidth;
- int screenHeight;
-};
-
-
-
-
-#define maxplayerCount 54
-
-struct PlayerData {
- char PlayerName[64];
- float Health;
- float Distance2;
- bool get_IsDieing;
- bool isBot;
- Vector3 CloseEnemyHeadLocation;
- Vector3 HeadLocation;
- Vector3 ToeLocation;
- Vector2 RShoulder;
- Vector3 LShoulder;
- Vector3 Toe;
- Vector3 Hip;
- Vector3 Head;
- int x;
- int y;
- int z;
- int id;
- int h;
- char debug[60];
-};
-
-struct Response {
- bool Success;
- int PlayerCount;
- PlayerData Players[maxplayerCount];
-};
-
-
-
-
-int startClient(){
- client = SocketClient();
- if(!client.Create()){ return -1; }
- if(!client.Connect()){ return -1; }
- if(!initServer()){ return -1; }
- return 0;
-}
-
-bool isConnected(){
- return client.connected;
-
-}
-
-void stopClient() {
- if(client.created && isConnected()){
- stopServer();
- client.Close();
- }
-}
-
-bool initServer() {
- Request request{Mode::InitMode, true, 0};
- int code = client.sendX((void*) &request, sizeof(request));
- if(code > 0) {
- Response response{};
- size_t length = client.receive((void*) &response);
- if(length > 0) {
- return response.Success;
- }
- }
- return false;
-}
-
-bool stopServer() {
- Request request{Mode::StopMode};
- int code = client.sendX((void*) &request, sizeof(request));
- if(code > 0) {
- Response response{};
- size_t length = client.receive((void*) &response);
- if(length > 0) {
- return response.Success;
- }
- }
- return false;
-}
-
-void Send(int32_t number, bool ftr) {
- Request request{number, ftr};
- int code = client.sendX((void*) &request, sizeof(request));
- if (code > 0) {
- Response response{};
- size_t length = client.receive((void*) &response);
- if (length > 0) {
- ;
- }
- }
-}
-void Send(int32_t number, int Value) {
- Request request{number, true, Value};
- int code = client.sendX((void*) &request, sizeof(request));
- if (code > 0) {
- Response response{};
- size_t length = client.receive((void*) &response);
- if (length > 0) {
- ;
- }
- }
-}
-Response getData(int screenWidth, int screenHeight){
- Request request{Mode::EspMode, screenWidth, screenHeight};
- int code = client.sendX((void*) &request, sizeof(request));
- if(code > 0){
- Response response{};
- size_t length = client.receive((void*) &response);
- if(length > 0){
- return response;
- }
- }
- Response response{false, 0};
- return response;
-}
-bool isValidPlayer(PlayerData data) {
- return (data.HeadLocation != Vector3::Zero());
-}
-bool isValidCloseEnemy(PlayerData data) {
- return (data.CloseEnemyHeadLocation != Vector3::Zero());
-}
diff --git a/app/src/main/jni/SOCKET/Includes.h b/app/src/main/jni/SOCKET/Includes.h
deleted file mode 100644
index f2f7581..0000000
--- a/app/src/main/jni/SOCKET/Includes.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include