├── .gitignore
├── LICENSE
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
├── resources
└── java
│ └── com
│ └── hack
│ └── opensdk
│ └── CmdConstants.java
└── src
└── main
├── AndroidManifest.xml
├── AndroidManifest_assist.xml
├── assets
├── com.waxmoon.ma.gp.apk
└── moon.jar
├── java
└── com
│ └── hack
│ ├── Features.java
│ ├── Slog.java
│ ├── agent
│ ├── AppAgentFileProvider.java
│ ├── BaseAgentFileProvider.java
│ ├── HackAppActivity.java
│ ├── HackAppProvider.java
│ ├── HackFileProvider.java
│ ├── HackJobService.java
│ ├── HackNotificationService.java
│ ├── HackReceiver.java
│ └── ProviderBase.java
│ ├── assist
│ ├── AssistActivity.java
│ └── AssistProvider.java
│ ├── opensdk
│ ├── Cmd.java
│ ├── HackApi.java
│ ├── HackApplication.java
│ ├── HackRuntime.java
│ └── IPackageObserver.java
│ ├── server
│ └── core
│ │ ├── ForgroundService.java
│ │ ├── HackServerProvider.java
│ │ ├── TransactCallback.java
│ │ ├── TransactProvider.java
│ │ ├── TransactRegistry.java
│ │ └── transact
│ │ ├── OuterActivityMonitor.java
│ │ ├── ProcessBindCallback.java
│ │ └── TransactActivityLifecycle.java
│ └── utils
│ ├── FileLock.java
│ ├── FileUtils.java
│ ├── IntentUtils.java
│ ├── ProcessUtils.java
│ ├── RefUtils.java
│ ├── Singleton.java
│ └── ThreadUtils.java
├── jniLibs
├── arm64-v8a
│ ├── libl.so
│ └── libpl.so
└── armeabi-v7a
│ ├── libl.so
│ └── libpl.so
└── res
├── layout
├── hk_notification_wp.xml
└── hk_notification_wp_simple.xml
├── values-zh-rCN
└── strings.xml
└── values
├── dimens.xml
├── strings.xml
└── themes.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .externalNativeBuild
2 | import-summary.txt
3 |
4 | *.class
5 | *.dex
6 | .sync/
7 |
8 | *.iws
9 | *.ipr
10 | *.iml
11 | target/
12 | .idea/
13 | .gradle/
14 | .disk/
15 | release/
16 | build/
17 | spoon/
18 |
19 | #mac temp file
20 | .idea/
21 | __MACOSX
22 | .DS_Store
23 | ._.DS_Store
24 |
25 | #for eclipse
26 | .settings/
27 | local.properties
28 | *gen/
29 | *.classpath
30 | */bin/
31 | .project
32 |
33 | #temp file
34 | *.bak
35 |
36 | *.pmd
37 | sh.exe.stackdump
38 |
39 | .vs/
40 | .vscode/
41 |
42 | *.log
43 | *.ctxt
44 | .mtj.tmp/
45 |
46 | hs_err_pid*
47 |
48 | *.war
49 | *.nar
50 | *.ear
51 | *.zip
52 | *.tar.gz
53 | *.rar
54 | *.cxx
55 | *.cfg
56 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 |
5 | android {
6 | compileSdk rootProject.ext.compileSdkVersion
7 |
8 | defaultConfig {
9 | minSdk rootProject.ext.minSdkVersion
10 | targetSdk rootProject.ext.targetSdkVersion
11 | versionCode rootProject.ext.versionCode
12 | versionName rootProject.ext.versionName
13 |
14 | consumerProguardFiles "consumer-rules.pro"
15 | buildConfigField "boolean", "localTest", "${rootProject.ext.localTest}"
16 | buildConfigField "boolean", "isMasterPkg", "${rootProject.ext.isMasterPkg}"
17 |
18 | buildConfigField "String", "ENGINE_JAR_NAME", "\"${rootProject.ext.hackJarName}\""
19 | buildConfigField "String", "ASSIST_PACKAGE", "\"$rootProject.ext.assistPkg\""
20 | buildConfigField "String", "MASTER_PACKAGE", "\"$rootProject.ext.masterPkg\""
21 |
22 | if (!rootProject.ext.isMasterPkg) {
23 | manifestPlaceholders = [masterPkg: "${rootProject.ext.masterPkg}"]
24 | }
25 | }
26 |
27 | sourceSets {
28 | main {
29 | java.srcDirs = ['src', "${projectDir}/build/src/main/java"]
30 |
31 | if (rootProject.ext.isMasterPkg) {
32 | manifest.srcFile 'src/main/AndroidManifest.xml'
33 | } else {
34 | manifest.srcFile 'src/main/AndroidManifest_assist.xml'
35 | }
36 | }
37 | }
38 |
39 | buildTypes {
40 | release {
41 | minifyEnabled false
42 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
43 | }
44 | }
45 |
46 | compileOptions {
47 | sourceCompatibility rootProject.ext.javaVersion
48 | targetCompatibility rootProject.ext.javaVersion
49 | }
50 |
51 | afterEvaluate {
52 | task generateConstantJavaFile(type: Exec) {
53 | File source = new File("${projectDir}/resources/java/com/hack/opensdk/CmdConstants.java")
54 | File destDir = new File("${projectDir}/build/src/main/java/com/hack/opensdk")
55 | destDir.mkdirs()
56 | copy {
57 | from source
58 | into destDir
59 | }
60 | }
61 |
62 | generateConstantJavaFile
63 | }
64 | lintOptions {
65 | checkReleaseBuilds true
66 | quiet true
67 | abortOnError false
68 | ignoreWarnings true
69 | textOutput "stdout"
70 | textReport false
71 | disable "UnusedResources", 'RestrictedApi'
72 | disable 'TypographyFractions', 'TypographyQuotes'
73 | enable 'RtlHardcoded', 'RtlCompat', 'RtlEnabled'
74 | check 'NewApi', 'InlinedApi'
75 | }
76 | }
77 |
78 | tasks.withType(Javadoc) {
79 | options.addStringOption('Xdoclint:none', '-quiet')
80 | options.addStringOption('encoding', 'UTF-8')
81 | options.addStringOption('charSet', 'UTF-8')
82 | options.encoding = "UTF-8"
83 | }
--------------------------------------------------------------------------------
/consumer-rules.pro:
--------------------------------------------------------------------------------
1 | -keepclassmembers class ** implements com.hack.opensdk.IPackageObserver$Install {
2 | public void onPackageInstalled(...);
3 | }
4 |
5 | -keepclassmembers class ** implements com.hack.opensdk.IPackageObserver$Delete {
6 | public void onPackageDeleted(...);
7 | }
--------------------------------------------------------------------------------
/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/resources/java/com/hack/opensdk/CmdConstants.java:
--------------------------------------------------------------------------------
1 | package com.hack.opensdk;
2 |
3 | /**
4 | * 基于安全考虑,将来CMD每一个版本都不能相同。
5 | * 所以将此java文件放在工程根目录的src/main下面,方便后续自动生成
6 | */
7 | public class CmdConstants {
8 |
9 | public static int MODE_INSTALL_ALONE = 0x01 << 0;
10 | public static int MODE_FORCE_INSTALL = 0x01 << 1;
11 |
12 | public static final int CMD_APPLICATION_ATTACHBASE = 1;
13 | public static final int CMD_APPLICATION_ONCREATE = 2;
14 |
15 | public static final int CMD_INSTALL_PACKAGE = 10;
16 | public static final int CMD_UNINSTALL_PACKAGE = 11;
17 | public static final int CMD_UPDATA_PACKAGE = 12;
18 | public static final int CMD_REMOVE_PKG_DATA = 13;
19 | public static final int CMD_DELETE_PKG_CACHE = 14;
20 | public static final int CMD_KILL_PACKAGE = 15;
21 | public static final int CMD_PACKAGE_MAYBE_VISIBLE = 16;
22 |
23 | public static final int CMD_GET_PACKAGE_INFO = 20;
24 | public static final int CMD_RESOLVE_INTENT = 21;
25 | public static final int CMD_QUERY_ACTIVITIES = 22;
26 | public static final int CMD_GET_ACTIVITY_INFO = 23;
27 | public static final int CMD_GET_INSTALLED_PKGS = 24;
28 | public static final int CMD_GET_PKG_SETTINGS = 25;
29 | public static final int CMD_GET_LAUNCHER_INTENT = 26;
30 | public static final int CMD_GET_UNAVAILABLE_PKGS = 27;
31 |
32 | public static final int CMD_START_PACKAGE = 30;
33 | public static final int CMD_START_ACTIVITY = 31;
34 | public static final int CMD_QUICK_START_ACTIVITY = 32;
35 |
36 | public static final int CMD_REGISTER_UNINSTALL_OBSERVER = 40;
37 | public static final int CMD_UNREGISTER_UNINSTALL_OBSERVER = 41;
38 | public static final int CMD_REGISTER_INSTALL_OBSERVER = 42;
39 | public static final int CMD_UNREGISTER_INSTALL_OBSERVER = 43;
40 |
41 | public static final int CMD_AGENT_JOB_SERVICE_BIND = 90;
42 | public static final int CMD_AGENT_JOB_SERVICE_UNBIND = 91;
43 |
44 | public static final int CMD_AGENT_PROVIDER_CALL = 100;
45 |
46 | public static final int CMD_AGENT_INTENT_SENDER = 120;
47 |
48 | public static final int CMD_CORE_PROVIDER_CREATE = 150;
49 | public static final int CMD_CORE_PROVIDER_CALL = 151;
50 |
51 | public static final int CMD_GET_ALL_USERID = 160;
52 | public static final int CMD_PKG_ALL_USERID = 161;
53 |
54 | public static final int CMD_GET_ATTRIBUTION_PARCEL = 200;
55 | public static final int CMD_BINDER_CALLING_UID = 201;
56 |
57 | public static final int CMD_ASSIST_PROVIDER_CALL = 210;
58 |
59 | public static final int CMD_ASSIST_ACTIVITY_CALL = 220;
60 | public static final int CMD_ASSIST_ACTIVITY_CALL2 = 221;
61 |
62 | public static final int CMD_FILE_PROVIDER_MAKE_URI = 240;
63 |
64 | public static final int CMD_GET_RUNTIME_PROPERTIES = 300;
65 |
66 | public static final int CMD_REGISTER_APPLICATION_CALLBACK = 400;
67 |
68 | // CMD_GET_PKG_SETTINGS Bundle key
69 | public static final String PKG_SET_REQUEST_ASSISTANT = "request_assistant";
70 | public static final String PKG_SUPPORTED_ABIS = "supported_abis";
71 | public static final String PKG_INSTALLED_MODE = "installed_mode";
72 |
73 | /**************BEGIN TransactProvider*******************/
74 | public static final String TRANSACT_PROVIDER_AUTHORITY = "com.hack.server.core.TransactProvider";
75 | public static final String TRANSACT_PROVIDER_METHOD = "transact";
76 | public static final String TRANSACT_KEY_CMD = "transact_cmd";
77 |
78 | public static final String TRANSACT_KEY_PKG = "pkg";
79 | public static final String TRANSACT_KEY_SHELL_PKG = "shell_pkg";
80 | public static final String TRANSACT_KEY_PROCESS = "agent_process";
81 | public static final String TRANSACT_KEY_SPACE = "space";
82 | public static final String TRANSACT_KEY_INTENT = "intent";
83 | public static final String TRANSACT_KEY_FROM_TOKEN = "from_token";
84 |
85 | public static final String TRANSACT_KEY_RESULT = "ret";
86 | public static final String TRANSACT_KEY_OUT_INTENT = "outIntent";
87 |
88 | public static final String TRANSACT_KEY_AUTHORITY = "authority";
89 |
90 | public static final int TRANSACT_CMD_PROCESS_BINDED = 1;
91 | public static final int TRANSACT_CMD_OUTER_INTENT = 2;
92 | public static final int TRANSACT_CMD_ACQUIRE_PROVIDER = 3;
93 | /**************END TransactProvider*******************/
94 |
95 | /**************BEGIN RUNTIME_PROPERTIES*******************/
96 | public static final String RUNTIME_HACK_CLASSLOADER = "hack.runtime.classloader";
97 | public static final String RUNTIME_PROPERTIES = "hack.runtime.properties";
98 | public static final String RUNTIME_PROPERTIES_SPACE = "space";
99 | public static final String RUNTIME_PROPERTIES_PKG = "pkg";
100 | public static final String RUNTIME_PROPERTIES_PROCESS = "process";
101 | public static final String RUNTIME_PROPERTIES_APPID = "appId";
102 | /**************BEGIN RUNTIME_PROPERTIES*******************/
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/assets/com.waxmoon.ma.gp.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WaxMoon/opensdk/eaab1645e57c0be6d3c1b0f5bf586984f4de141f/src/main/assets/com.waxmoon.ma.gp.apk
--------------------------------------------------------------------------------
/src/main/assets/moon.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WaxMoon/opensdk/eaab1645e57c0be6d3c1b0f5bf586984f4de141f/src/main/assets/moon.jar
--------------------------------------------------------------------------------
/src/main/java/com/hack/Features.java:
--------------------------------------------------------------------------------
1 | package com.hack;
2 |
3 | public class Features {
4 |
5 | public static final boolean DEBUG = false;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/Slog.java:
--------------------------------------------------------------------------------
1 | package com.hack;
2 |
3 | import android.util.Log;
4 |
5 | public class Slog {
6 | public static void print(String tag, String format) {
7 | Log.d(tag, format);
8 | }
9 |
10 | public static void d(String tag, String format) {
11 | Log.d(tag, format);
12 | }
13 |
14 | public static void v(String tag, String format) {
15 | Log.v(tag, format);
16 | }
17 |
18 | public static void e(String tag, String format) {
19 | Log.e(tag, format);
20 | }
21 |
22 | public static void w(String tag, String format) {
23 | Log.w(tag, format);
24 | }
25 |
26 | public static void i(String tag, String format) {
27 | Log.i(tag, format);
28 | }
29 |
30 | public static void e(String tag, String msg, Object... format) {
31 | Log.e(tag, String.format(msg, format));
32 | }
33 |
34 | public static void w(String tag, String msg, Object... format) {
35 | Log.w(tag, String.format(msg, format));
36 | }
37 |
38 | public static void i(String tag, String msg, Object... format) {
39 | Log.i(tag, String.format(msg, format));
40 | }
41 |
42 | public static void d(String tag, String msg, Object... format) {
43 | Log.d(tag, String.format(msg, format));
44 | }
45 |
46 | public static void v(String tag, String msg, Object... format) {
47 | Log.v(tag, String.format(msg, format));
48 | }
49 |
50 | public static boolean iSloggable(String tag, int verbose) {
51 | if (Features.DEBUG) {
52 | return true;
53 | }
54 | return false;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/AppAgentFileProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | public class AppAgentFileProvider extends BaseAgentFileProvider {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/BaseAgentFileProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import static com.hack.opensdk.CmdConstants.CMD_FILE_PROVIDER_MAKE_URI;
4 |
5 | import android.content.ContentProvider;
6 | import android.content.ContentProviderClient;
7 | import android.content.ContentProviderOperation;
8 | import android.content.ContentProviderResult;
9 | import android.content.ContentResolver;
10 | import android.content.ContentValues;
11 | import android.content.Context;
12 | import android.content.OperationApplicationException;
13 | import android.content.res.AssetFileDescriptor;
14 | import android.database.Cursor;
15 | import android.net.Uri;
16 | import android.os.Bundle;
17 | import android.os.CancellationSignal;
18 | import android.os.ParcelFileDescriptor;
19 | import android.os.RemoteException;
20 | import android.util.Log;
21 |
22 | import com.hack.opensdk.Cmd;
23 |
24 | import java.io.FileNotFoundException;
25 | import java.util.ArrayList;
26 | import java.util.Arrays;
27 |
28 | public class BaseAgentFileProvider extends ContentProvider {
29 | private static final String TAG ="proxies." + BaseAgentFileProvider.class.getSimpleName();
30 |
31 | @Override
32 | public boolean onCreate() {
33 | return false;
34 | }
35 |
36 | public static ContentProviderClient getClient(Context context, Uri uri) {
37 | ContentResolver resolver = context.getContentResolver();
38 | return resolver.acquireContentProviderClient(uri.getAuthority());
39 | }
40 |
41 | @Override
42 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
43 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
44 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
45 | if (client != null) {
46 | try {
47 | return client.query(proxyOrTarget, projection, selection, selectionArgs, sortOrder);
48 | } catch (RemoteException e) {
49 | e.printStackTrace();
50 | }
51 | }
52 | return null;
53 | }
54 |
55 | @Override
56 | public String getType(Uri uri) {
57 | Log.e(TAG, "getType: "+uri );
58 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
59 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
60 | if (client != null) {
61 | try {
62 | return client.getType(proxyOrTarget);
63 | } catch (RemoteException e) {
64 | e.printStackTrace();
65 | }
66 | }
67 | return null;
68 | }
69 |
70 | @Override
71 | public Uri insert(Uri uri, ContentValues values) {
72 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
73 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
74 | if (client != null) {
75 | try {
76 | return client.insert(proxyOrTarget, values);
77 | } catch (RemoteException e) {
78 | e.printStackTrace();
79 | }
80 | }
81 | return null;
82 | }
83 |
84 | @Override
85 | public int delete(Uri uri, String selection, String[] selectionArgs) {
86 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
87 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
88 | if (client != null) {
89 | try {
90 | return client.delete(proxyOrTarget, selection, selectionArgs);
91 | } catch (RemoteException e) {
92 | e.printStackTrace();
93 | }
94 | }
95 | return 0;
96 | }
97 |
98 | @Override
99 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
100 | Log.e(TAG, "update: "+uri );
101 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
102 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
103 | if (client != null) {
104 | try {
105 | return client.update(proxyOrTarget, values, selection, selectionArgs);
106 | } catch (RemoteException e) {
107 | e.printStackTrace();
108 | }
109 | }
110 | return 0;
111 | }
112 |
113 | @Override
114 | public int bulkInsert(Uri uri, ContentValues[] values) {
115 | Log.e(TAG, "bulkInsert: "+uri );
116 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
117 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
118 | if (client != null) {
119 | try {
120 | return client.bulkInsert(proxyOrTarget, values);
121 | } catch (RemoteException e) {
122 | e.printStackTrace();
123 | }
124 | }
125 | return 0;
126 | }
127 |
128 | @Override
129 | public AssetFileDescriptor openAssetFile(Uri uri, String str)
130 | throws FileNotFoundException {
131 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
132 | Log.e(TAG, "openAssetFile " + uri + ", str " + str + "->" + proxyOrTarget);
133 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
134 | Log.e(TAG, "openAssetFile: client result "+client );
135 | if (client != null) {
136 | try {
137 | AssetFileDescriptor descriptor = client.openAssetFile(proxyOrTarget, str);
138 | Log.e(TAG, "openAssetFile result " + uri + ", str " + str + "->" + descriptor);
139 | return descriptor;
140 | } catch (RemoteException e) {
141 | e.printStackTrace();
142 | Log.e(TAG, "openAssetFile result "+uri ,e);
143 | throw new FileNotFoundException(uri.toString());
144 |
145 |
146 | }
147 | }
148 | return super.openAssetFile(uri, str);
149 | }
150 |
151 | @Override
152 | public AssetFileDescriptor openAssetFile(Uri uri, String str, CancellationSignal cancellationSignal)
153 | throws FileNotFoundException {
154 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
155 | Log.e(TAG, "openAssetFile 2" + uri + ", str " + str + ", cancellationSignal " + cancellationSignal + "->" + proxyOrTarget);
156 |
157 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
158 | if (client != null) {
159 | try {
160 | AssetFileDescriptor descriptor = client.openAssetFile(proxyOrTarget, str, cancellationSignal);
161 | Log.e(TAG, "openAssetFile 2 result " + proxyOrTarget + ", str " + str + "->" + client.getLocalContentProvider());
162 | return descriptor;
163 | } catch (RemoteException e) {
164 | e.printStackTrace();
165 | }
166 | }
167 | return super.openAssetFile(uri, str, cancellationSignal);
168 | }
169 |
170 | @Override
171 | public ParcelFileDescriptor openFile(Uri uri, String str)
172 | throws FileNotFoundException {
173 | Log.e(TAG, "openFile: "+uri );
174 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
175 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
176 | if (client != null) {
177 | try {
178 | return client.openFile(proxyOrTarget, str);
179 | } catch (RemoteException e) {
180 | e.printStackTrace();
181 | }
182 | }
183 | return super.openFile(uri, str);
184 | }
185 |
186 | @Override
187 | public ParcelFileDescriptor openFile(Uri uri, String str, CancellationSignal cancellationSignal)
188 | throws FileNotFoundException {
189 | Log.e(TAG, "openFile: "+uri );
190 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
191 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
192 | if (client != null) {
193 | try {
194 | return client.openFile(proxyOrTarget, str, cancellationSignal);
195 | } catch (RemoteException e) {
196 | e.printStackTrace();
197 | }
198 | }
199 | return super.openFile(uri, str, cancellationSignal);
200 | }
201 |
202 | @Override
203 | public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
204 | throws FileNotFoundException {
205 | Log.e(TAG, "openTypedAssetFile: "+uri );
206 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
207 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
208 | if (client != null) {
209 | try {
210 | return client.openTypedAssetFileDescriptor(proxyOrTarget, mimeTypeFilter, opts);
211 | } catch (RemoteException e) {
212 | e.printStackTrace();
213 | }
214 | }
215 | return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
216 | }
217 |
218 | @Override
219 | public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts,
220 | CancellationSignal cancellationSignal)
221 | throws FileNotFoundException {
222 | Log.e(TAG, "openTypedAssetFile: "+uri );
223 | Uri proxyOrTarget = (Uri) Cmd.INSTANCE().exec(CMD_FILE_PROVIDER_MAKE_URI, uri);
224 | ContentProviderClient client = getClient(getContext(), proxyOrTarget);
225 | if (client != null) {
226 | try {
227 | return client.openTypedAssetFile(proxyOrTarget, mimeTypeFilter, opts, cancellationSignal);
228 | } catch (RemoteException e) {
229 | e.printStackTrace();
230 | }
231 | }
232 | return super.openTypedAssetFile(uri, mimeTypeFilter, opts, cancellationSignal);
233 | }
234 |
235 | @Override
236 | public ContentProviderResult[] applyBatch(ArrayList operations)
237 | throws OperationApplicationException {
238 | Log.e(TAG, "applyBatch: " );
239 | if (operations != null) {
240 | Log.d(TAG, "applyBatch operations " + Arrays.toString(operations.toArray()));
241 | }
242 | return super.applyBatch(operations);
243 | }
244 | }
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/HackAppActivity.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import android.app.Activity;
4 |
5 | public class HackAppActivity extends Activity {
6 | //portrait normal
7 | public static class P extends HackAppActivity {
8 | }
9 |
10 | //portrait Translucent
11 | public static class PT extends HackAppActivity {
12 | }
13 |
14 | //landscape normal
15 | public static class L extends HackAppActivity {
16 | }
17 |
18 | //landscape Translucent
19 | public static class LT extends HackAppActivity {
20 | }
21 |
22 | //behind normal
23 | public static class B extends HackAppActivity {
24 | }
25 |
26 | //behind Translucent
27 | public static class BT extends HackAppActivity {
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/HackAppProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import static com.hack.opensdk.CmdConstants.CMD_AGENT_PROVIDER_CALL;
4 |
5 | public class HackAppProvider extends ProviderBase {
6 | @Override
7 | public int getProviderCallType() {
8 | return CMD_AGENT_PROVIDER_CALL;
9 | }
10 |
11 | public static class P0 extends HackAppProvider {
12 | }
13 |
14 | public static class P1 extends HackAppProvider {
15 | }
16 |
17 | public static class P2 extends HackAppProvider {
18 | }
19 |
20 | public static class P3 extends HackAppProvider {
21 | }
22 |
23 | public static class P4 extends HackAppProvider {
24 | }
25 |
26 | public static class P5 extends HackAppProvider {
27 | }
28 |
29 | public static class P6 extends HackAppProvider {
30 | }
31 |
32 | public static class P7 extends HackAppProvider {
33 | }
34 |
35 | public static class P8 extends HackAppProvider {
36 | }
37 |
38 | public static class P9 extends HackAppProvider {
39 | }
40 |
41 | public static class P10 extends HackAppProvider {
42 | }
43 |
44 | public static class P11 extends HackAppProvider {
45 | }
46 |
47 | public static class P12 extends HackAppProvider {
48 | }
49 |
50 | public static class P13 extends HackAppProvider {
51 | }
52 |
53 | public static class P14 extends HackAppProvider {
54 | }
55 |
56 | public static class P15 extends HackAppProvider {
57 | }
58 |
59 | public static class P16 extends HackAppProvider {
60 | }
61 |
62 | public static class P17 extends HackAppProvider {
63 | }
64 |
65 | public static class P18 extends HackAppProvider {
66 | }
67 |
68 | public static class P19 extends HackAppProvider {
69 | }
70 |
71 | public static class P20 extends HackAppProvider {
72 | }
73 |
74 | public static class P21 extends HackAppProvider {
75 | }
76 |
77 | public static class P22 extends HackAppProvider {
78 | }
79 |
80 | public static class P23 extends HackAppProvider {
81 | }
82 |
83 | public static class P24 extends HackAppProvider {
84 | }
85 |
86 | public static class P25 extends HackAppProvider {
87 | }
88 |
89 | public static class P26 extends HackAppProvider {
90 | }
91 |
92 | public static class P27 extends HackAppProvider {
93 | }
94 |
95 | public static class P28 extends HackAppProvider {
96 | }
97 |
98 | public static class P29 extends HackAppProvider {
99 | }
100 |
101 | public static class P30 extends HackAppProvider {
102 | }
103 |
104 | public static class P31 extends HackAppProvider {
105 | }
106 |
107 | public static class P32 extends HackAppProvider {
108 | }
109 |
110 | public static class P33 extends HackAppProvider {
111 | }
112 |
113 | public static class P34 extends HackAppProvider {
114 | }
115 |
116 | public static class P35 extends HackAppProvider {
117 | }
118 |
119 | public static class P36 extends HackAppProvider {
120 | }
121 |
122 | public static class P37 extends HackAppProvider {
123 | }
124 |
125 | public static class P38 extends HackAppProvider {
126 | }
127 |
128 | public static class P39 extends HackAppProvider {
129 | }
130 |
131 | public static class P40 extends HackAppProvider {
132 | }
133 |
134 | public static class P41 extends HackAppProvider {
135 | }
136 |
137 | public static class P42 extends HackAppProvider {
138 | }
139 |
140 | public static class P43 extends HackAppProvider {
141 | }
142 |
143 | public static class P44 extends HackAppProvider {
144 | }
145 |
146 | public static class P45 extends HackAppProvider {
147 | }
148 |
149 | public static class P46 extends HackAppProvider {
150 | }
151 |
152 | public static class P47 extends HackAppProvider {
153 | }
154 |
155 | public static class P48 extends HackAppProvider {
156 | }
157 |
158 | public static class P49 extends HackAppProvider {
159 | }
160 |
161 | public static class P50 extends HackAppProvider {
162 | }
163 |
164 | public static class P51 extends HackAppProvider {
165 | }
166 |
167 | public static class P52 extends HackAppProvider {
168 | }
169 |
170 | public static class P53 extends HackAppProvider {
171 | }
172 |
173 | public static class P54 extends HackAppProvider {
174 | }
175 |
176 | public static class P55 extends HackAppProvider {
177 | }
178 |
179 | public static class P56 extends HackAppProvider {
180 | }
181 |
182 | public static class P57 extends HackAppProvider {
183 | }
184 |
185 | public static class P58 extends HackAppProvider {
186 | }
187 |
188 | public static class P59 extends HackAppProvider {
189 | }
190 |
191 | public static class P60 extends HackAppProvider {
192 | }
193 |
194 | public static class P61 extends HackAppProvider {
195 | }
196 |
197 | public static class P62 extends HackAppProvider {
198 | }
199 |
200 | public static class P63 extends HackAppProvider {
201 | }
202 |
203 | public static class P64 extends HackAppProvider {
204 | }
205 |
206 | public static class P65 extends HackAppProvider {
207 | }
208 |
209 | public static class P66 extends HackAppProvider {
210 | }
211 |
212 | public static class P67 extends HackAppProvider {
213 | }
214 |
215 | public static class P68 extends HackAppProvider {
216 | }
217 |
218 | public static class P69 extends HackAppProvider {
219 | }
220 |
221 | public static class P70 extends HackAppProvider {
222 | }
223 |
224 | public static class P71 extends HackAppProvider {
225 | }
226 |
227 | public static class P72 extends HackAppProvider {
228 | }
229 |
230 | public static class P73 extends HackAppProvider {
231 | }
232 |
233 | public static class P74 extends HackAppProvider {
234 | }
235 |
236 | public static class P75 extends HackAppProvider {
237 | }
238 |
239 | public static class P76 extends HackAppProvider {
240 | }
241 |
242 | public static class P77 extends HackAppProvider {
243 | }
244 |
245 | public static class P78 extends HackAppProvider {
246 | }
247 |
248 | public static class P79 extends HackAppProvider {
249 | }
250 |
251 | public static class P80 extends HackAppProvider {
252 | }
253 |
254 | public static class P81 extends HackAppProvider {
255 | }
256 |
257 | public static class P82 extends HackAppProvider {
258 | }
259 |
260 | public static class P83 extends HackAppProvider {
261 | }
262 |
263 | public static class P84 extends HackAppProvider {
264 | }
265 |
266 | public static class P85 extends HackAppProvider {
267 | }
268 |
269 | public static class P86 extends HackAppProvider {
270 | }
271 |
272 | public static class P87 extends HackAppProvider {
273 | }
274 |
275 | public static class P88 extends HackAppProvider {
276 | }
277 |
278 | public static class P89 extends HackAppProvider {
279 | }
280 |
281 | public static class P90 extends HackAppProvider {
282 | }
283 |
284 | public static class P91 extends HackAppProvider {
285 | }
286 |
287 | public static class P92 extends HackAppProvider {
288 | }
289 |
290 | public static class P93 extends HackAppProvider {
291 | }
292 |
293 | public static class P94 extends HackAppProvider {
294 | }
295 |
296 | public static class P95 extends HackAppProvider {
297 | }
298 |
299 | public static class P96 extends HackAppProvider {
300 | }
301 |
302 | public static class P97 extends HackAppProvider {
303 | }
304 |
305 | public static class P98 extends HackAppProvider {
306 | }
307 |
308 | public static class P99 extends HackAppProvider {
309 | }
310 |
311 | public static class P100 extends HackAppProvider {
312 | }
313 |
314 | public static class P101 extends HackAppProvider {
315 | }
316 |
317 | public static class P102 extends HackAppProvider {
318 | }
319 |
320 | public static class P103 extends HackAppProvider {
321 | }
322 |
323 | public static class P104 extends HackAppProvider {
324 | }
325 |
326 | public static class P105 extends HackAppProvider {
327 | }
328 |
329 | public static class P106 extends HackAppProvider {
330 | }
331 |
332 | public static class P107 extends HackAppProvider {
333 | }
334 |
335 | public static class P108 extends HackAppProvider {
336 | }
337 |
338 | public static class P109 extends HackAppProvider {
339 | }
340 |
341 | public static class P110 extends HackAppProvider {
342 | }
343 |
344 | public static class P111 extends HackAppProvider {
345 | }
346 |
347 | public static class P112 extends HackAppProvider {
348 | }
349 |
350 | public static class P113 extends HackAppProvider {
351 | }
352 |
353 | public static class P114 extends HackAppProvider {
354 | }
355 |
356 | public static class P115 extends HackAppProvider {
357 | }
358 |
359 | public static class P116 extends HackAppProvider {
360 | }
361 |
362 | public static class P117 extends HackAppProvider {
363 | }
364 |
365 | public static class P118 extends HackAppProvider {
366 | }
367 |
368 | public static class P119 extends HackAppProvider {
369 | }
370 |
371 | public static class P120 extends HackAppProvider {
372 | }
373 |
374 | public static class P121 extends HackAppProvider {
375 | }
376 |
377 | public static class P122 extends HackAppProvider {
378 | }
379 |
380 | public static class P123 extends HackAppProvider {
381 | }
382 |
383 | public static class P124 extends HackAppProvider {
384 | }
385 |
386 | public static class P125 extends HackAppProvider {
387 | }
388 |
389 | public static class P126 extends HackAppProvider {
390 | }
391 |
392 | public static class P127 extends HackAppProvider {
393 | }
394 |
395 | public static class P128 extends HackAppProvider {
396 | }
397 |
398 | public static class P129 extends HackAppProvider {
399 | }
400 |
401 | public static class P130 extends HackAppProvider {
402 | }
403 |
404 | public static class P131 extends HackAppProvider {
405 | }
406 |
407 | public static class P132 extends HackAppProvider {
408 | }
409 |
410 | public static class P133 extends HackAppProvider {
411 | }
412 |
413 | public static class P134 extends HackAppProvider {
414 | }
415 |
416 | public static class P135 extends HackAppProvider {
417 | }
418 |
419 | public static class P136 extends HackAppProvider {
420 | }
421 |
422 | public static class P137 extends HackAppProvider {
423 | }
424 |
425 | public static class P138 extends HackAppProvider {
426 | }
427 |
428 | public static class P139 extends HackAppProvider {
429 | }
430 |
431 | public static class P140 extends HackAppProvider {
432 | }
433 |
434 | public static class P141 extends HackAppProvider {
435 | }
436 |
437 | public static class P142 extends HackAppProvider {
438 | }
439 |
440 | public static class P143 extends HackAppProvider {
441 | }
442 |
443 | public static class P144 extends HackAppProvider {
444 | }
445 |
446 | public static class P145 extends HackAppProvider {
447 | }
448 |
449 | public static class P146 extends HackAppProvider {
450 | }
451 |
452 | public static class P147 extends HackAppProvider {
453 | }
454 |
455 | public static class P148 extends HackAppProvider {
456 | }
457 |
458 | public static class P149 extends HackAppProvider {
459 | }
460 | }
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/HackFileProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | public class HackFileProvider extends BaseAgentFileProvider {
4 | @Override
5 | public boolean onCreate() {
6 | return super.onCreate();
7 | }
8 | }
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/HackJobService.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import static com.hack.opensdk.CmdConstants.CMD_AGENT_JOB_SERVICE_BIND;
4 | import static com.hack.opensdk.CmdConstants.CMD_AGENT_JOB_SERVICE_UNBIND;
5 |
6 | import android.app.Service;
7 | import android.content.Intent;
8 | import android.os.IBinder;
9 |
10 | import com.hack.opensdk.Cmd;
11 |
12 | public class HackJobService extends Service {
13 | private static final String TAG = "HackJobService";
14 |
15 | @Override
16 | public IBinder onBind(Intent intent) {
17 | return (IBinder) Cmd.INSTANCE().exec(CMD_AGENT_JOB_SERVICE_BIND, intent);
18 | }
19 |
20 | @Override
21 | public boolean onUnbind(Intent intent) {
22 | return (boolean) Cmd.INSTANCE().exec(CMD_AGENT_JOB_SERVICE_UNBIND, intent);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/HackNotificationService.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import android.app.NotificationChannel;
4 | import android.app.NotificationChannelGroup;
5 | import android.content.Intent;
6 | import android.os.IBinder;
7 | import android.os.UserHandle;
8 | import android.service.notification.NotificationListenerService;
9 | import android.service.notification.StatusBarNotification;
10 |
11 | import com.hack.Features;
12 | import com.hack.Slog;
13 |
14 | public class HackNotificationService extends NotificationListenerService {
15 | private static final boolean DEBUG = false || Features.DEBUG;
16 | private static final String TAG = HackNotificationService.class.getSimpleName();
17 |
18 | public HackNotificationService() {
19 | super();
20 | if (DEBUG) {
21 | Slog.d(TAG, "Constructor in");
22 | new Exception().printStackTrace();
23 | }
24 | }
25 |
26 | @Override
27 | public void onNotificationPosted(StatusBarNotification sbn) {
28 | super.onNotificationPosted(sbn);
29 | if (DEBUG) {
30 | Slog.d(TAG, "onNotificationPosted in1");
31 | }
32 | }
33 |
34 | @Override
35 | public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
36 | super.onNotificationPosted(sbn, rankingMap);
37 | if (DEBUG) {
38 | Slog.d(TAG, "onNotificationPosted in2");
39 | }
40 | }
41 |
42 | @Override
43 | public void onNotificationRemoved(StatusBarNotification sbn) {
44 | super.onNotificationRemoved(sbn);
45 | if (DEBUG) {
46 | Slog.d(TAG, "onNotificationRemoved in1");
47 | }
48 | }
49 |
50 | @Override
51 | public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
52 | super.onNotificationRemoved(sbn, rankingMap);
53 | if (DEBUG) {
54 | Slog.d(TAG, "onNotificationRemoved in2");
55 | }
56 | }
57 |
58 | @Override
59 | public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, int reason) {
60 | super.onNotificationRemoved(sbn, rankingMap, reason);
61 | if (DEBUG) {
62 | Slog.d(TAG, "onNotificationRemoved in3");
63 | }
64 | }
65 |
66 | @Override
67 | public void onListenerConnected() {
68 | super.onListenerConnected();
69 | if (DEBUG) {
70 | Slog.d(TAG, "onListenerConnected in");
71 | }
72 | }
73 |
74 | @Override
75 | public void onListenerDisconnected() {
76 | super.onListenerDisconnected();
77 | if (DEBUG) {
78 | Slog.d(TAG, "onListenerDisconnected in");
79 | }
80 | }
81 |
82 | @Override
83 | public void onNotificationRankingUpdate(RankingMap rankingMap) {
84 | super.onNotificationRankingUpdate(rankingMap);
85 | if (DEBUG) {
86 | Slog.d(TAG, "onNotificationRankingUpdate in");
87 | }
88 | }
89 |
90 | @Override
91 | public void onListenerHintsChanged(int hints) {
92 | super.onListenerHintsChanged(hints);
93 | if (DEBUG) {
94 | Slog.d(TAG, "onListenerHintsChanged in");
95 | }
96 | }
97 |
98 | @Override
99 | public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) {
100 | super.onSilentStatusBarIconsVisibilityChanged(hideSilentStatusIcons);
101 | if (DEBUG) {
102 | Slog.d(TAG, "onSilentStatusBarIconsVisibilityChanged in");
103 | }
104 | }
105 |
106 | @Override
107 | public void onNotificationChannelModified(String pkg, UserHandle user, NotificationChannel channel, int modificationType) {
108 | super.onNotificationChannelModified(pkg, user, channel, modificationType);
109 | if (DEBUG) {
110 | Slog.d(TAG, "onNotificationChannelModified in");
111 | }
112 | }
113 |
114 | @Override
115 | public void onNotificationChannelGroupModified(String pkg, UserHandle user, NotificationChannelGroup group, int modificationType) {
116 | super.onNotificationChannelGroupModified(pkg, user, group, modificationType);
117 | if (DEBUG) {
118 | Slog.d(TAG, "onNotificationChannelGroupModified in");
119 | }
120 | }
121 |
122 | @Override
123 | public void onInterruptionFilterChanged(int interruptionFilter) {
124 | super.onInterruptionFilterChanged(interruptionFilter);
125 | if (DEBUG) {
126 | Slog.d(TAG, "onInterruptionFilterChanged in");
127 | }
128 | }
129 |
130 | @Override
131 | public StatusBarNotification[] getActiveNotifications() {
132 | if (DEBUG) {
133 | Slog.d(TAG, "getActiveNotifications in1");
134 | }
135 | return super.getActiveNotifications();
136 | }
137 |
138 | @Override
139 | public StatusBarNotification[] getActiveNotifications(String[] keys) {
140 | if (DEBUG) {
141 | Slog.d(TAG, "getActiveNotifications in2");
142 | }
143 | return super.getActiveNotifications(keys);
144 | }
145 |
146 | @Override
147 | public RankingMap getCurrentRanking() {
148 | if (DEBUG) {
149 | Slog.d(TAG, "getCurrentRanking in");
150 | }
151 | return super.getCurrentRanking();
152 | }
153 |
154 | @Override
155 | public IBinder onBind(Intent intent) {
156 | if (DEBUG) {
157 | Slog.d(TAG, "onBind in " + intent);
158 | }
159 | return super.onBind(intent);
160 | }
161 |
162 | @Override
163 | public void onDestroy() {
164 | super.onDestroy();
165 | if (DEBUG) {
166 | Slog.d(TAG, "onDestroy in ");
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/HackReceiver.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import static com.hack.opensdk.CmdConstants.CMD_AGENT_INTENT_SENDER;
4 |
5 | import android.content.BroadcastReceiver;
6 | import android.content.Context;
7 | import android.content.Intent;
8 |
9 | import com.hack.opensdk.Cmd;
10 |
11 | public class HackReceiver extends BroadcastReceiver {
12 |
13 | private static final String TAG = HackReceiver.class.getSimpleName();
14 |
15 | @Override
16 | public void onReceive(Context context, Intent intent) {
17 | Cmd.INSTANCE().exec(CMD_AGENT_INTENT_SENDER, context, intent);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/agent/ProviderBase.java:
--------------------------------------------------------------------------------
1 | package com.hack.agent;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.content.pm.ProviderInfo;
6 | import android.os.Bundle;
7 |
8 | import com.hack.Features;
9 | import com.hack.opensdk.Cmd;
10 | import com.hack.opensdk.HackRuntime;
11 | import com.hack.server.core.transact.TransactActivityLifecycle;
12 |
13 | public abstract class ProviderBase extends AppAgentFileProvider {
14 | private static final boolean DEBUG = Features.DEBUG;
15 | private static final String TAG = ProviderBase.class.getSimpleName();
16 |
17 | @Override
18 | public void attachInfo(Context context, ProviderInfo info) {
19 | Application application = (Application) context.getApplicationContext();
20 | application.registerActivityLifecycleCallbacks(TransactActivityLifecycle.INSTANCE);
21 | HackRuntime.attachProviderInfo(info);
22 | super.attachInfo(context, info);
23 | }
24 |
25 | @Override
26 | public boolean onCreate() {
27 | return true;
28 | }
29 |
30 | @Override
31 | public Bundle call(String method, String arg, Bundle extras) {
32 | return (Bundle) Cmd.INSTANCE().exec(getProviderCallType(), method, arg, extras);
33 | }
34 |
35 | public abstract int getProviderCallType();
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/assist/AssistActivity.java:
--------------------------------------------------------------------------------
1 | package com.hack.assist;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 |
7 | import com.hack.Features;
8 | import com.hack.opensdk.Cmd;
9 | import com.hack.opensdk.CmdConstants;
10 |
11 | public class AssistActivity extends Activity {
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | if (Features.DEBUG) {
15 | Log.d("TRAMP", " " + this.getLocalClassName() + " onCreate");
16 | }
17 | super.onCreate(savedInstanceState);
18 | Cmd.INSTANCE().exec(CmdConstants.CMD_ASSIST_ACTIVITY_CALL, this);
19 | }
20 |
21 | public static class BaseActivity extends Activity {
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | if (Features.DEBUG) {
26 | Log.d("TRAMP", " " + this.getLocalClassName() + " onCreate");
27 | }
28 | super.onCreate(savedInstanceState);
29 | Cmd.INSTANCE().exec(CmdConstants.CMD_ASSIST_ACTIVITY_CALL2, this);
30 | }
31 | }
32 |
33 | public static class P0 extends BaseActivity {
34 | }
35 |
36 | public static class P1 extends BaseActivity {
37 | }
38 |
39 | public static class P2 extends BaseActivity {
40 | }
41 |
42 | public static class P3 extends BaseActivity {
43 | }
44 |
45 | public static class P4 extends BaseActivity {
46 | }
47 |
48 | public static class P5 extends BaseActivity {
49 | }
50 |
51 | public static class P6 extends BaseActivity {
52 | }
53 |
54 | public static class P7 extends BaseActivity {
55 | }
56 |
57 | public static class P8 extends BaseActivity {
58 | }
59 |
60 | public static class P9 extends BaseActivity {
61 | }
62 |
63 | public static class P10 extends BaseActivity {
64 | }
65 |
66 | public static class P11 extends BaseActivity {
67 | }
68 |
69 | public static class P12 extends BaseActivity {
70 | }
71 |
72 | public static class P13 extends BaseActivity {
73 | }
74 |
75 | public static class P14 extends BaseActivity {
76 | }
77 |
78 | public static class P15 extends BaseActivity {
79 | }
80 |
81 | public static class P16 extends BaseActivity {
82 | }
83 |
84 | public static class P17 extends BaseActivity {
85 | }
86 |
87 | public static class P18 extends BaseActivity {
88 | }
89 |
90 | public static class P19 extends BaseActivity {
91 | }
92 |
93 | public static class P20 extends BaseActivity {
94 | }
95 |
96 | public static class P21 extends BaseActivity {
97 | }
98 |
99 | public static class P22 extends BaseActivity {
100 | }
101 |
102 | public static class P23 extends BaseActivity {
103 | }
104 |
105 | public static class P24 extends BaseActivity {
106 | }
107 |
108 | public static class P25 extends BaseActivity {
109 | }
110 |
111 | public static class P26 extends BaseActivity {
112 | }
113 |
114 | public static class P27 extends BaseActivity {
115 | }
116 |
117 | public static class P28 extends BaseActivity {
118 | }
119 |
120 | public static class P29 extends BaseActivity {
121 | }
122 |
123 | public static class P30 extends BaseActivity {
124 | }
125 |
126 | public static class P31 extends BaseActivity {
127 | }
128 |
129 | public static class P32 extends BaseActivity {
130 | }
131 |
132 | public static class P33 extends BaseActivity {
133 | }
134 |
135 | public static class P34 extends BaseActivity {
136 | }
137 |
138 | public static class P35 extends BaseActivity {
139 | }
140 |
141 | public static class P36 extends BaseActivity {
142 | }
143 |
144 | public static class P37 extends BaseActivity {
145 | }
146 |
147 | public static class P38 extends BaseActivity {
148 | }
149 |
150 | public static class P39 extends BaseActivity {
151 | }
152 |
153 | public static class P40 extends BaseActivity {
154 | }
155 |
156 | public static class P41 extends BaseActivity {
157 | }
158 |
159 | public static class P42 extends BaseActivity {
160 | }
161 |
162 | public static class P43 extends BaseActivity {
163 | }
164 |
165 | public static class P44 extends BaseActivity {
166 | }
167 |
168 | public static class P45 extends BaseActivity {
169 | }
170 |
171 | public static class P46 extends BaseActivity {
172 | }
173 |
174 | public static class P47 extends BaseActivity {
175 | }
176 |
177 | public static class P48 extends BaseActivity {
178 | }
179 |
180 | public static class P49 extends BaseActivity {
181 | }
182 |
183 | public static class P50 extends BaseActivity {
184 | }
185 |
186 | public static class P51 extends BaseActivity {
187 | }
188 |
189 | public static class P52 extends BaseActivity {
190 | }
191 |
192 | public static class P53 extends BaseActivity {
193 | }
194 |
195 | public static class P54 extends BaseActivity {
196 | }
197 |
198 | public static class P55 extends BaseActivity {
199 | }
200 |
201 | public static class P56 extends BaseActivity {
202 | }
203 |
204 | public static class P57 extends BaseActivity {
205 | }
206 |
207 | public static class P58 extends BaseActivity {
208 | }
209 |
210 | public static class P59 extends BaseActivity {
211 | }
212 |
213 | public static class P60 extends BaseActivity {
214 | }
215 |
216 | public static class P61 extends BaseActivity {
217 | }
218 |
219 | public static class P62 extends BaseActivity {
220 | }
221 |
222 | public static class P63 extends BaseActivity {
223 | }
224 |
225 | public static class P64 extends BaseActivity {
226 | }
227 |
228 | public static class P65 extends BaseActivity {
229 | }
230 |
231 | public static class P66 extends BaseActivity {
232 | }
233 |
234 | public static class P67 extends BaseActivity {
235 | }
236 |
237 | public static class P68 extends BaseActivity {
238 | }
239 |
240 | public static class P69 extends BaseActivity {
241 | }
242 |
243 | public static class P70 extends BaseActivity {
244 | }
245 |
246 | public static class P71 extends BaseActivity {
247 | }
248 |
249 | public static class P72 extends BaseActivity {
250 | }
251 |
252 | public static class P73 extends BaseActivity {
253 | }
254 |
255 | public static class P74 extends BaseActivity {
256 | }
257 |
258 | public static class P75 extends BaseActivity {
259 | }
260 |
261 | public static class P76 extends BaseActivity {
262 | }
263 |
264 | public static class P77 extends BaseActivity {
265 | }
266 |
267 | public static class P78 extends BaseActivity {
268 | }
269 |
270 | public static class P79 extends BaseActivity {
271 | }
272 |
273 | public static class P80 extends BaseActivity {
274 | }
275 |
276 | public static class P81 extends BaseActivity {
277 | }
278 |
279 | public static class P82 extends BaseActivity {
280 | }
281 |
282 | public static class P83 extends BaseActivity {
283 | }
284 |
285 | public static class P84 extends BaseActivity {
286 | }
287 |
288 | public static class P85 extends BaseActivity {
289 | }
290 |
291 | public static class P86 extends BaseActivity {
292 | }
293 |
294 | public static class P87 extends BaseActivity {
295 | }
296 |
297 | public static class P88 extends BaseActivity {
298 | }
299 |
300 | public static class P89 extends BaseActivity {
301 | }
302 |
303 | public static class P90 extends BaseActivity {
304 | }
305 |
306 | public static class P91 extends BaseActivity {
307 | }
308 |
309 | public static class P92 extends BaseActivity {
310 | }
311 |
312 | public static class P93 extends BaseActivity {
313 | }
314 |
315 | public static class P94 extends BaseActivity {
316 | }
317 |
318 | public static class P95 extends BaseActivity {
319 | }
320 |
321 | public static class P96 extends BaseActivity {
322 | }
323 |
324 | public static class P97 extends BaseActivity {
325 | }
326 |
327 | public static class P98 extends BaseActivity {
328 | }
329 |
330 | public static class P99 extends BaseActivity {
331 | }
332 |
333 | public static class P100 extends BaseActivity {
334 | }
335 |
336 | public static class P101 extends BaseActivity {
337 | }
338 |
339 | public static class P102 extends BaseActivity {
340 | }
341 |
342 | public static class P103 extends BaseActivity {
343 | }
344 |
345 | public static class P104 extends BaseActivity {
346 | }
347 |
348 | public static class P105 extends BaseActivity {
349 | }
350 |
351 | public static class P106 extends BaseActivity {
352 | }
353 |
354 | public static class P107 extends BaseActivity {
355 | }
356 |
357 | public static class P108 extends BaseActivity {
358 | }
359 |
360 | public static class P109 extends BaseActivity {
361 | }
362 |
363 | public static class P110 extends BaseActivity {
364 | }
365 |
366 | public static class P111 extends BaseActivity {
367 | }
368 |
369 | public static class P112 extends BaseActivity {
370 | }
371 |
372 | public static class P113 extends BaseActivity {
373 | }
374 |
375 | public static class P114 extends BaseActivity {
376 | }
377 |
378 | public static class P115 extends BaseActivity {
379 | }
380 |
381 | public static class P116 extends BaseActivity {
382 | }
383 |
384 | public static class P117 extends BaseActivity {
385 | }
386 |
387 | public static class P118 extends BaseActivity {
388 | }
389 |
390 | public static class P119 extends BaseActivity {
391 | }
392 |
393 | public static class P120 extends BaseActivity {
394 | }
395 |
396 | public static class P121 extends BaseActivity {
397 | }
398 |
399 | public static class P122 extends BaseActivity {
400 | }
401 |
402 | public static class P123 extends BaseActivity {
403 | }
404 |
405 | public static class P124 extends BaseActivity {
406 | }
407 |
408 | public static class P125 extends BaseActivity {
409 | }
410 |
411 | public static class P126 extends BaseActivity {
412 | }
413 |
414 | public static class P127 extends BaseActivity {
415 | }
416 |
417 | public static class P128 extends BaseActivity {
418 | }
419 |
420 | public static class P129 extends BaseActivity {
421 | }
422 |
423 | public static class P130 extends BaseActivity {
424 | }
425 |
426 | public static class P131 extends BaseActivity {
427 | }
428 |
429 | public static class P132 extends BaseActivity {
430 | }
431 |
432 | public static class P133 extends BaseActivity {
433 | }
434 |
435 | public static class P134 extends BaseActivity {
436 | }
437 |
438 | public static class P135 extends BaseActivity {
439 | }
440 |
441 | public static class P136 extends BaseActivity {
442 | }
443 |
444 | public static class P137 extends BaseActivity {
445 | }
446 |
447 | public static class P138 extends BaseActivity {
448 | }
449 |
450 | public static class P139 extends BaseActivity {
451 | }
452 |
453 | public static class P140 extends BaseActivity {
454 | }
455 |
456 | public static class P141 extends BaseActivity {
457 | }
458 |
459 | public static class P142 extends BaseActivity {
460 | }
461 |
462 | public static class P143 extends BaseActivity {
463 | }
464 |
465 | public static class P144 extends BaseActivity {
466 | }
467 |
468 | public static class P145 extends BaseActivity {
469 | }
470 |
471 | public static class P146 extends BaseActivity {
472 | }
473 |
474 | public static class P147 extends BaseActivity {
475 | }
476 |
477 | public static class P148 extends BaseActivity {
478 | }
479 |
480 | public static class P149 extends BaseActivity {
481 | }
482 |
483 | }
484 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/assist/AssistProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.assist;
2 |
3 | import com.hack.agent.ProviderBase;
4 | import com.hack.opensdk.CmdConstants;
5 |
6 | public class AssistProvider extends ProviderBase {
7 |
8 | @Override
9 | public int getProviderCallType() {
10 | return CmdConstants.CMD_ASSIST_PROVIDER_CALL;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/opensdk/Cmd.java:
--------------------------------------------------------------------------------
1 | package com.hack.opensdk;
2 |
3 | import com.hack.Features;
4 | import com.hack.Slog;
5 | import com.hack.utils.RefUtils;
6 | import com.hack.utils.Singleton;
7 |
8 | import java.util.Arrays;
9 |
10 | public class Cmd {
11 | private static final String TAG = Cmd.class.getSimpleName();
12 | private static final boolean DEBUG = Features.DEBUG;
13 |
14 | private static final String ENGINE_CMD_CLASS = "com.core.Cmd";
15 |
16 | private RefUtils.MethodRef mEngineExecMethod;
17 |
18 | public static Cmd INSTANCE() {
19 | return singleton.get();
20 | }
21 |
22 | private static Singleton singleton = new Singleton() {
23 | @Override
24 | protected Cmd create() {
25 | return new Cmd();
26 | }
27 | };
28 |
29 | private Cmd() {
30 | Class engineCmdClass = null;
31 | try {
32 | engineCmdClass = Class.forName(ENGINE_CMD_CLASS);
33 | } catch (ClassNotFoundException ignore) {
34 | }
35 |
36 | if (engineCmdClass == null) {
37 | try {
38 | engineCmdClass = HackRuntime.getHackClassLoader().loadClass(ENGINE_CMD_CLASS);
39 | } catch (ClassNotFoundException e) {
40 | e.printStackTrace();
41 | }
42 | }
43 |
44 | mEngineExecMethod = new RefUtils.MethodRef(
45 | engineCmdClass,
46 | true, "exec",
47 | new Class[]{int.class, Object[].class});
48 | }
49 |
50 | public Object exec(int cmd, Object... args) {
51 | if (DEBUG) Slog.d(TAG, "begin exec %d %s", cmd, Arrays.toString(args));
52 | Object ret = mEngineExecMethod.invoke(null, cmd, args);
53 | if (DEBUG) Slog.d(TAG, "end exec %d %s", cmd, ret);
54 | return ret;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/opensdk/HackApi.java:
--------------------------------------------------------------------------------
1 | package com.hack.opensdk;
2 |
3 | import android.app.Application;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.ActivityInfo;
8 | import android.content.pm.PackageInfo;
9 | import android.content.pm.ResolveInfo;
10 | import android.os.Build;
11 | import android.os.Bundle;
12 | import android.util.Log;
13 |
14 | import com.hack.Slog;
15 | import com.hack.server.core.TransactCallback;
16 | import com.hack.server.core.TransactRegistry;
17 |
18 | import java.lang.reflect.InvocationHandler;
19 | import java.lang.reflect.Method;
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | public class HackApi {
24 | private static final String TAG = HackApi.class.getSimpleName();
25 | private static final TransactRegistry sTransactRegistry = new TransactRegistry();
26 |
27 | public static void attachBaseContext(Application app, Context base) {
28 | Cmd.INSTANCE().exec(CmdConstants.CMD_APPLICATION_ATTACHBASE, app, base);
29 | }
30 |
31 | public static void onCreate() {
32 | Cmd.INSTANCE().exec(CmdConstants.CMD_APPLICATION_ONCREATE);
33 | }
34 |
35 | public static Bundle getPackageSetting(String pkg, int userId, int flags) {
36 | return (Bundle) Cmd.INSTANCE().exec(CmdConstants.CMD_GET_PKG_SETTINGS, pkg, userId, flags);
37 | }
38 |
39 | /**
40 | * install the app that is installed on the system.
41 | * @param packageName the packageName of this app.
42 | * @param userId
43 | * @param forceInstall
44 | * @return public static final int INSTALL_SUCCEEDED = 1;
45 | */
46 | public static int installPackageFromHost(String packageName, int userId, boolean forceInstall) {
47 | return (int) Cmd.INSTANCE().exec(
48 | CmdConstants.CMD_INSTALL_PACKAGE,
49 | userId, packageName,
50 | forceInstall ? CmdConstants.MODE_FORCE_INSTALL : 0
51 | );
52 | }
53 |
54 | /**
55 | * install the apk/apks that is not installed on the system.
56 | * @param apkPathOrDir if this app is a full apk file, apkPathOrDir should pass an absolute path,
57 | * such as /sdcard/com.xx.yy/com.xx.yy.apk;
58 | *
59 | * if this app is split apk files, apkPathOrDir should pass the directory
60 | * containing all the apk files for this app, such as /sdcard/com.xx.yy/,
61 | * and this directory can't contain apk files that do not belong to the current app.
62 | *
63 | * @param userId
64 | * @param forceInstall
65 | * @return public static final int INSTALL_SUCCEEDED = 1;
66 | */
67 | public static int installApkFiles(String apkPathOrDir, int userId, boolean forceInstall) {
68 | int flags = CmdConstants.MODE_INSTALL_ALONE;
69 | if (forceInstall) {
70 | flags |= CmdConstants.MODE_FORCE_INSTALL;
71 | }
72 | return (int) Cmd.INSTANCE().exec(
73 | CmdConstants.CMD_INSTALL_PACKAGE, userId, apkPathOrDir, flags
74 | );
75 | }
76 |
77 | /**
78 | * @param packageName
79 | * @param userId
80 | * @return public static final int DELETE_SUCCEEDED = 1;
81 | */
82 | public static int uninstallPackage(String packageName, int userId) {
83 | return (int) Cmd.INSTANCE().exec(
84 | CmdConstants.CMD_UNINSTALL_PACKAGE,
85 | userId,
86 | packageName,
87 | 0
88 | );
89 | }
90 |
91 | /**
92 | * @param packageName
93 | * @param userId
94 | * @return public static final int DELETE_SUCCEEDED = 1;
95 | */
96 | public static int deletePackageData(String packageName, int userId) {
97 | return (int) Cmd.INSTANCE().exec(
98 | CmdConstants.CMD_REMOVE_PKG_DATA,
99 | userId,
100 | packageName,
101 | 0
102 | );
103 | }
104 |
105 | /**
106 | * @param packageName
107 | * @param userId
108 | * @return public static final int DELETE_SUCCEEDED = 1;
109 | */
110 | public static int deletePackageCache(String packageName, int userId) {
111 | return (int) Cmd.INSTANCE().exec(
112 | CmdConstants.CMD_DELETE_PKG_CACHE,
113 | userId,
114 | packageName,
115 | 0
116 | );
117 | }
118 |
119 | public static PackageInfo getPackageInfo(String packageName, int userId, int flags) {
120 | return (PackageInfo) Cmd.INSTANCE().exec(
121 | CmdConstants.CMD_GET_PACKAGE_INFO,
122 | userId,
123 | packageName,
124 | flags
125 | );
126 | }
127 |
128 | public static ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) {
129 | return (ResolveInfo) Cmd.INSTANCE().exec(
130 | CmdConstants.CMD_RESOLVE_INTENT,
131 | intent,
132 | resolvedType,
133 | flags,
134 | userId
135 | );
136 | }
137 |
138 | public static List queryIntentActivities(Intent intent, String resolvedType, int flags, int userId) {
139 | return (List) Cmd.INSTANCE().exec(
140 | CmdConstants.CMD_QUERY_ACTIVITIES,
141 | intent,
142 | resolvedType,
143 | flags,
144 | userId
145 | );
146 | }
147 |
148 | public static ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
149 | return (ActivityInfo) Cmd.INSTANCE().exec(
150 | CmdConstants.CMD_GET_ACTIVITY_INFO,
151 | component,
152 | flags,
153 | userId
154 | );
155 | }
156 |
157 | public static List getInstalledPackages(int flags, int userId) {
158 | return (List) Cmd.INSTANCE().exec(
159 | CmdConstants.CMD_GET_INSTALLED_PKGS,
160 | flags,
161 | userId
162 | );
163 | }
164 |
165 |
166 | public static Map> getUnavailablePackages(int flags) {
167 | return (Map>) Cmd.INSTANCE().exec(
168 | CmdConstants.CMD_GET_UNAVAILABLE_PKGS,
169 | flags, 0);
170 | }
171 |
172 | public static void registerTransactCallback(int cmd, TransactCallback callback) {
173 | sTransactRegistry.registerTransactCallback(cmd, callback);
174 | }
175 |
176 | public static void unregisterTransactCallback(int cmd) {
177 | sTransactRegistry.unregisterTransactCallback(cmd);
178 | }
179 |
180 | /**
181 | *
182 | * @param packageName
183 | * @param userId
184 | * @return
185 | */
186 | @Deprecated
187 | public static boolean startPackage(String packageName, int userId) {
188 | return (boolean) Cmd.INSTANCE().exec(
189 | CmdConstants.CMD_START_PACKAGE,
190 | packageName,
191 | userId,
192 | 0
193 | );
194 | }
195 |
196 | /**
197 | * START_SUCCESS = 0;
198 | * START_RETURN_INTENT_TO_CALLER = 1
199 | * START_TASK_TO_FRONT = 2
200 | * START_DELIVERED_TO_TOP = 3
201 | * others...
202 | *
203 | * @param intent
204 | * @param userId
205 | * @return
206 | */
207 | public static int startActivity(Intent intent, int userId) {
208 | return (int) Cmd.INSTANCE().exec(
209 | CmdConstants.CMD_START_ACTIVITY,
210 | intent,
211 | null,
212 | userId
213 | );
214 | }
215 |
216 | public static void killApplication(int userId, String pkg, String reason/*NonNull*/) {
217 | Cmd.INSTANCE().exec(CmdConstants.CMD_KILL_PACKAGE, userId, pkg, reason);
218 | }
219 |
220 | public static boolean hasAnyRunningActivity(int userId, String pkg) {
221 | return (boolean) Cmd.INSTANCE().exec(CmdConstants.CMD_PACKAGE_MAYBE_VISIBLE, userId, pkg);
222 | }
223 |
224 | /**
225 | * @param callback callback必须要含有onPackageDeleted函数,hack engine会通过反射调用
226 | * public void onPackageDeleted(String packageName, int returnCode, String msg, int userId);
227 | * @return 返回值建议保存,unregisterDeleteObserver的参数需要使用该返回值
228 | */
229 | public static Object registerDeleteObserver(Object callback) {
230 | return (int) Cmd.INSTANCE().exec(
231 | CmdConstants.CMD_REGISTER_UNINSTALL_OBSERVER,
232 | callback
233 | );
234 | }
235 |
236 | public static void unregisterDeleteObserver(Object observer) {
237 | Cmd.INSTANCE().exec(
238 | CmdConstants.CMD_UNREGISTER_UNINSTALL_OBSERVER,
239 | observer
240 | );
241 | }
242 |
243 | /**
244 | * @param callback callback必须要含有onPackageInstalled函数, hack engine会通过反射调用
245 | * public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras, int userId)
246 | * @return 返回值建议保存, unregisterInstallObserver的参数需要使用该返回值
247 | */
248 | public static Object registerInstallObserver(Object callback) {
249 | return (int) Cmd.INSTANCE().exec(
250 | CmdConstants.CMD_REGISTER_INSTALL_OBSERVER,
251 | callback
252 | );
253 | }
254 |
255 | public static void unregisterInstallObserver(Object observer) {
256 | Cmd.INSTANCE().exec(
257 | CmdConstants.CMD_UNREGISTER_INSTALL_OBSERVER,
258 | observer
259 | );
260 | }
261 |
262 | public static int[] getAvailableUserSpace() {
263 | return (int[]) Cmd.INSTANCE().exec(
264 | CmdConstants.CMD_GET_ALL_USERID
265 | );
266 | }
267 |
268 | public static int[] getInstallUsersForPackage(String packageName) {
269 | return (int[]) Cmd.INSTANCE().exec(CmdConstants.CMD_PKG_ALL_USERID, packageName);
270 | }
271 |
272 | public static int getAvailableUser(String packageName) {
273 | int userId = 0;
274 | long time = System.currentTimeMillis();
275 | int[] users = getInstallUsersForPackage(packageName);
276 | if (users != null) {
277 | for (int i = 0; i < Integer.MAX_VALUE; i++) {
278 | boolean found = false;
279 | for (int user : users) {
280 | if (user == i) {
281 | found = true;
282 | break;
283 | }
284 | }
285 | if (!found) {
286 | userId = i;
287 | break;
288 | }
289 | }
290 | }
291 | Slog.v(TAG, "getUsers consume: " + (System.currentTimeMillis() - time) / 1000);
292 | return userId;
293 | }
294 |
295 | public static TransactRegistry getTransactRegistry() {
296 | return sTransactRegistry;
297 | }
298 |
299 |
300 | public static Intent getLaunchIntentForPackage(String packageName, int uerId) {
301 | // First see if the package has an INFO activity; the existence of
302 | // such an activity is implied to be the desired front-door for the
303 | // overall package (such as if it has multiple launcher entries).
304 | Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
305 | intentToResolve.addCategory(Intent.CATEGORY_INFO);
306 | intentToResolve.setPackage(packageName);
307 | List ris = queryIntentActivities(intentToResolve, null, 0, uerId);
308 |
309 | // Otherwise, try to find a main launcher activity.
310 | if (ris == null || ris.size() <= 0) {
311 | // reuse the intent instance
312 | intentToResolve.removeCategory(Intent.CATEGORY_INFO);
313 | intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
314 | intentToResolve.setPackage(packageName);
315 | ris = queryIntentActivities(intentToResolve, null, 0, uerId);
316 | }
317 | if (ris == null || ris.size() <= 0) {
318 | return null;
319 | }
320 | Intent intent = new Intent(intentToResolve);
321 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
322 | intent.setClassName(ris.get(0).activityInfo.packageName, ris.get(0).activityInfo.name);
323 | return intent;
324 | }
325 |
326 | public static Map getRuntimeProperties() {
327 | Map map = (Map) Cmd.INSTANCE().exec(CmdConstants.CMD_GET_RUNTIME_PROPERTIES);
328 | return map;
329 | }
330 |
331 | public static T getRuntimeProperty(String key, T defaultValue) {
332 | try {
333 | Object o = getRuntimeProperties().get(key);
334 | if (o == null) {
335 | return defaultValue;
336 | }
337 | return (T) o;
338 | } catch (Throwable e) {
339 | return defaultValue;
340 | }
341 | }
342 |
343 | public static void registerApplicationCallback(ApplicationCallback callback){
344 | Cmd.INSTANCE().exec(CmdConstants.CMD_REGISTER_APPLICATION_CALLBACK, new InvocationHandler() {
345 | @Override
346 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
347 | int cmd = (int) args[0];
348 | switch (cmd) {
349 | case 0: {
350 | callback.onInitAppContext(args[1], (Context) args[2]);
351 | break;
352 | }
353 | case 1: {
354 | callback.onAttachBaseContext((Application) args[1]);
355 | break;
356 | }
357 | case 2: {
358 | callback.onInstallProviders((Application) args[1]);
359 | break;
360 | }
361 | case 3: {
362 | callback.onCreate((Application) args[1]);
363 | break;
364 | }
365 |
366 | }
367 | return null;
368 | }
369 | });
370 | }
371 |
372 | public interface ApplicationCallback {
373 |
374 | void onInitAppContext(Object loadedApk, Context appContext);
375 |
376 | void onAttachBaseContext(Application app);
377 |
378 | void onInstallProviders(Application app);
379 |
380 | void onCreate(Application app);
381 |
382 | }
383 | }
384 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/opensdk/HackApplication.java:
--------------------------------------------------------------------------------
1 | package com.hack.opensdk;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.content.pm.PackageManager;
6 | import android.os.Process;
7 | import android.text.TextUtils;
8 | import android.util.Log;
9 |
10 | import com.hack.Features;
11 |
12 | public class HackApplication extends Application {
13 |
14 | private static final boolean DEBUG = Features.DEBUG;
15 | private static final String TAG = HackApplication.class.getSimpleName();
16 |
17 | @Override
18 | protected void attachBaseContext(Context base) {
19 | super.attachBaseContext(base);
20 | if (DEBUG) Log.d(TAG, "attachBaseContext start");
21 | Context engineContext = base;
22 | if (TextUtils.equals(base.getPackageName(), BuildConfig.MASTER_PACKAGE)) {
23 | engineContext.getSharedPreferences("hack", Context.MODE_PRIVATE).edit().putString("sp.assist.pkg", BuildConfig.ASSIST_PACKAGE).commit();
24 | } else {
25 | try {
26 | if (engineContext.getPackageManager().getPackageInfo(BuildConfig.MASTER_PACKAGE, 0).applicationInfo.uid == Process.myUid()) {
27 | engineContext = base.createPackageContext(BuildConfig.MASTER_PACKAGE, 0);
28 | }
29 | } catch (PackageManager.NameNotFoundException e) {
30 | e.printStackTrace();
31 | Log.e(TAG, "master package not install ");
32 | }
33 | }
34 | HackRuntime.install(engineContext, "version", true);
35 | Cmd.INSTANCE().exec(CmdConstants.CMD_APPLICATION_ATTACHBASE, this, base);
36 | if (DEBUG) Log.d(TAG, "attachBaseContext end");
37 | }
38 |
39 | @Override
40 | public void onCreate() {
41 | super.onCreate();
42 | if (DEBUG) Log.d(TAG, "onCreate start");
43 | Cmd.INSTANCE().exec(CmdConstants.CMD_APPLICATION_ONCREATE);
44 | if (DEBUG) Log.d(TAG, "onCreate end");
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/opensdk/HackRuntime.java:
--------------------------------------------------------------------------------
1 | package com.hack.opensdk;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ProviderInfo;
5 | import android.os.Build;
6 | import android.os.Process;
7 | import android.text.TextUtils;
8 |
9 | import com.hack.Slog;
10 | import com.hack.utils.FileUtils;
11 | import com.hack.utils.ProcessUtils;
12 |
13 | import org.json.JSONException;
14 | import org.json.JSONObject;
15 |
16 | import java.io.File;
17 | import java.util.ArrayList;
18 |
19 | import dalvik.system.DexClassLoader;
20 |
21 | public class HackRuntime {
22 | private static final String ENGINE_JAR_DIR = ".plugin";
23 | private static final String ENGINE_JAR_NAME = BuildConfig.ENGINE_JAR_NAME;
24 | private static ProviderInfo providerInfo;
25 | private static DexClassLoader hackClassLoader;
26 |
27 | public static void attachProviderInfo(ProviderInfo info) {
28 | HackRuntime.providerInfo = info;
29 | }
30 |
31 | public static boolean isHackProcess() {
32 | return HackRuntime.providerInfo != null;
33 | }
34 |
35 | public static ProviderInfo getHackProvider() {
36 | return providerInfo;
37 | }
38 |
39 | public static void install(Context app, String name, boolean check) {
40 | if (hackClassLoader != null) {
41 | return;
42 | }
43 | File root = new File(app.getFilesDir(), ENGINE_JAR_DIR);
44 | File config = new File(root, name + ".json");
45 | JSONObject object = readJson(config);
46 | File workspace = null;
47 | String workPath = object.optString("current");
48 | if (!TextUtils.isEmpty(workPath)) {
49 | workspace = new File(workPath);
50 | }
51 | if (check || TextUtils.isEmpty(workPath)) {
52 | if (!check) {
53 | Slog.e(HackRuntime.class.getName(), "engine load fail");
54 | }
55 | long time = object.optLong("time");
56 | long installTime = new File(app.getPackageCodePath()).lastModified();
57 | if (time != installTime) {
58 | if (workspace == null) {
59 | workspace = new File(root, name + "-1");
60 | } else {
61 | if (workPath.endsWith("-1")) {
62 | workspace = new File(root, name + "-2");
63 | } else {
64 | workspace = new File(root, name + "-1");
65 | }
66 | FileUtils.deleteQuietly(new File(workPath));
67 | }
68 | File sdk = new File(workspace, "base.apk");
69 | try {
70 | FileUtils.extractAsset(app, ENGINE_JAR_NAME, sdk);
71 | FileUtils.extractFile(sdk, "lib/", workspace);
72 | object.putOpt("current", workspace.getPath());
73 | object.putOpt("time", installTime);
74 | FileUtils.writeString(config, object.toString());
75 | } catch (Throwable e) {
76 | throw new RuntimeException(e);
77 | }
78 | }
79 | }
80 | loadEngine(workspace);
81 | }
82 |
83 | private static JSONObject readJson(File file) {
84 | String config = FileUtils.readString(file);
85 | if (config != null) {
86 | try {
87 | return new JSONObject(config);
88 | } catch (JSONException e) {
89 | return new JSONObject();
90 | }
91 | }
92 | return new JSONObject();
93 | }
94 |
95 |
96 | private static void loadEngine(File root) {
97 | File sdk = new File(root, "base.apk");
98 | File engineLibDir = new File(root, "lib");
99 | ArrayList libDirs = new ArrayList<>();
100 | if (ProcessUtils.is64Bit()) {
101 | for (String abi : Build.SUPPORTED_64_BIT_ABIS) {
102 | File libDir = new File(engineLibDir, abi);
103 | if (libDir.exists()) libDirs.add(libDir.getAbsolutePath());
104 | }
105 | } else {
106 | for (String abi : Build.SUPPORTED_32_BIT_ABIS) {
107 | File libDir = new File(engineLibDir, abi);
108 | if (libDir.exists()) libDirs.add(libDir.getAbsolutePath());
109 | }
110 | }
111 |
112 | StringBuilder builder = new StringBuilder();
113 |
114 | int size = libDirs.size();
115 | for (int i = 0; i < size; i++) {
116 | builder.append(libDirs.get(i));
117 | if (i != (size - 1)) {
118 | builder.append(File.pathSeparator);
119 | }
120 | }
121 |
122 | String libSearchDir = builder.toString();
123 |
124 |
125 | hackClassLoader = new DexClassLoader(sdk.getPath(), sdk.getParent(), libSearchDir, Context.class.getClassLoader());
126 | }
127 |
128 | public static DexClassLoader getHackClassLoader() {
129 | return hackClassLoader;
130 | }
131 |
132 | public static void setHackClassLoader(DexClassLoader classLoader) {
133 | hackClassLoader = classLoader;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/opensdk/IPackageObserver.java:
--------------------------------------------------------------------------------
1 | package com.hack.opensdk;
2 |
3 | import android.os.Bundle;
4 |
5 | public class IPackageObserver {
6 | public interface Install {
7 | //can't proguard! must keep
8 | void onPackageInstalled(String basePackageName, int returnCode,
9 | String msg, Bundle extras, int userId);
10 | }
11 |
12 | public interface Delete {
13 | //can't proguard! must keep
14 | void onPackageDeleted(String packageName, int returnCode, String msg, int userId);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/ForgroundService.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.app.PendingIntent;
7 | import android.app.Service;
8 | import android.content.Context;
9 | import android.content.Intent;
10 | import android.os.Build;
11 | import android.os.IBinder;
12 | import com.hack.opensdk.R;
13 |
14 | public class ForgroundService extends Service {
15 |
16 | private static final String FORGROUND_CHANNEL_ID = "hack_forground_id";
17 | private static final String FORGROUND_CHANNEL_NAME = "hack_forground_channel";
18 | private static final int FORGROUND_NOTIFICATION_ID = 1000000;
19 |
20 | @Override
21 | public void onCreate() {
22 | super.onCreate();
23 | startForgroundNotification(getApplicationContext());
24 | }
25 |
26 | @Override
27 | public IBinder onBind(Intent intent) {
28 | return null;
29 | }
30 |
31 | private void startForgroundNotification(Context context) {
32 | //1.create channel if needed
33 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
34 | final NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
35 | final NotificationChannel forgroundChannel = new NotificationChannel(FORGROUND_CHANNEL_ID,
36 | FORGROUND_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
37 | notificationManager.createNotificationChannel(forgroundChannel);
38 | }
39 |
40 | //2.create notification
41 | final Notification notification;
42 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
43 | notification = new Notification();
44 | } else {
45 |
46 | Intent notificationIntent = new Intent();
47 | notificationIntent.setPackage(getPackageName());
48 | notificationIntent.setAction(Intent.ACTION_MAIN);
49 | notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
50 | PendingIntent pendingIntent = PendingIntent.getActivity(
51 | this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
52 |
53 | String name = String.valueOf(getApplicationInfo().loadLabel(getPackageManager()));
54 | notification = new Notification.Builder(this, FORGROUND_CHANNEL_ID)
55 | .setContentTitle(getString(R.string.notification_running_title, name))
56 | .setContentText(getString(R.string.notification_running_warn, name))
57 | .setContentIntent(pendingIntent)
58 | .setAutoCancel(false)
59 | .build();
60 | }
61 |
62 | try {
63 | //3.start
64 | startForeground(FORGROUND_NOTIFICATION_ID, notification);
65 | } catch (Exception e) {
66 | e.printStackTrace();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/HackServerProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core;
2 |
3 | import android.content.ContentValues;
4 | import android.content.Intent;
5 | import android.database.Cursor;
6 | import android.net.Uri;
7 |
8 | import com.hack.Features;
9 | import com.hack.agent.ProviderBase;
10 | import com.hack.opensdk.Cmd;
11 | import com.hack.opensdk.CmdConstants;
12 | import com.hack.utils.ThreadUtils;
13 |
14 | public class HackServerProvider extends ProviderBase {
15 | private static final boolean DEBUG = Features.DEBUG;
16 | private static final String TAG = HackServerProvider.class.getSimpleName();
17 |
18 | @Override
19 | public int delete(Uri uri, String selection, String[] selectionArgs) {
20 | return 0;
21 | }
22 |
23 | @Override
24 | public String getType(Uri uri) {
25 | return null;
26 | }
27 |
28 | @Override
29 | public Uri insert(Uri uri, ContentValues values) {
30 | return null;
31 | }
32 |
33 | @Override
34 | public boolean onCreate() {
35 | ThreadUtils.postOnBackgroundThread(()->{
36 | getContext().startService(new Intent(getContext(), ForgroundService.class));
37 | });
38 | return (boolean) Cmd.INSTANCE().exec(CmdConstants.CMD_CORE_PROVIDER_CREATE, getContext());
39 | }
40 |
41 | @Override
42 | public Cursor query(Uri uri, String[] projection, String selection,
43 | String[] selectionArgs, String sortOrder) {
44 | return null;
45 | }
46 |
47 | @Override
48 | public int update(Uri uri, ContentValues values, String selection,
49 | String[] selectionArgs) {
50 | return 0;
51 | }
52 |
53 | @Override
54 | public int getProviderCallType() {
55 | return CmdConstants.CMD_CORE_PROVIDER_CALL;
56 | }
57 | }
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/TransactCallback.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 |
6 | public interface TransactCallback {
7 | Bundle transact(Context context,int cmd, Bundle extras);
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/TransactProvider.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core;
2 |
3 | import static com.hack.opensdk.CmdConstants.TRANSACT_CMD_ACQUIRE_PROVIDER;
4 | import static com.hack.opensdk.CmdConstants.TRANSACT_CMD_OUTER_INTENT;
5 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_AUTHORITY;
6 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_CMD;
7 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_INTENT;
8 | import static com.hack.opensdk.CmdConstants.TRANSACT_PROVIDER_METHOD;
9 |
10 | import android.content.ContentProvider;
11 | import android.content.ContentValues;
12 | import android.content.Intent;
13 | import android.database.Cursor;
14 | import android.net.Uri;
15 | import android.os.Bundle;
16 | import android.text.TextUtils;
17 |
18 | import com.hack.Features;
19 | import com.hack.Slog;
20 | import com.hack.opensdk.HackApi;
21 | import com.hack.utils.IntentUtils;
22 |
23 | public class TransactProvider extends ContentProvider {
24 | private static final String TAG = TransactProvider.class.getSimpleName();
25 |
26 | @Override
27 | public boolean onCreate() {
28 | return false;
29 | }
30 |
31 | @Override
32 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
33 | return null;
34 | }
35 |
36 | @Override
37 | public String getType(Uri uri) {
38 | return null;
39 | }
40 |
41 | @Override
42 | public Uri insert(Uri uri, ContentValues values) {
43 | return null;
44 | }
45 |
46 | @Override
47 | public int delete(Uri uri, String selection, String[] selectionArgs) {
48 | return 0;
49 | }
50 |
51 | @Override
52 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
53 | return 0;
54 | }
55 |
56 | @Override
57 | public Bundle call(String method, String arg, Bundle extras) {
58 | if (Features.DEBUG) {
59 | if (extras != null) {
60 | extras.size();
61 | }
62 | Slog.d(TAG, "m:" + method + " arg:" + arg + " extras:" + extras);
63 | }
64 | if (TextUtils.equals(method, TRANSACT_PROVIDER_METHOD)) {
65 | extras.setClassLoader(TransactProvider.class.getClassLoader());
66 | int cmd = extras.getInt(TRANSACT_KEY_CMD);
67 |
68 | if (cmd == TRANSACT_CMD_ACQUIRE_PROVIDER) {
69 | Uri uri = extras.getParcelable(TRANSACT_KEY_AUTHORITY);
70 | getContext().getContentResolver().acquireUnstableContentProviderClient(uri);
71 | return null;
72 | } else if (Features.DEBUG && cmd == TRANSACT_CMD_OUTER_INTENT) {
73 | Slog.d(TAG, "---->" + IntentUtils.toShortString((Intent) extras.getParcelable(TRANSACT_KEY_INTENT)));
74 | }
75 | return HackApi.getTransactRegistry().transact(getContext(), cmd, extras);
76 | }
77 | return null;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/TransactRegistry.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.util.SparseArray;
6 |
7 | public class TransactRegistry implements TransactCallback {
8 | private final SparseArray transactCallbacks = new SparseArray<>();
9 |
10 | public TransactRegistry() {
11 | }
12 |
13 | public final void registerTransactCallback(int cmd, TransactCallback callback) {
14 | synchronized (transactCallbacks) {
15 | transactCallbacks.put(cmd, callback);
16 | }
17 | }
18 |
19 | public final void unregisterTransactCallback(int cmd) {
20 | synchronized (transactCallbacks) {
21 | transactCallbacks.remove(cmd);
22 | }
23 |
24 | }
25 |
26 | @Override
27 | public Bundle transact(Context context, int cmd, Bundle extra) {
28 | TransactCallback callback;
29 | synchronized (transactCallbacks) {
30 | callback = transactCallbacks.get(cmd);
31 | }
32 | if (callback != null) {
33 | return callback.transact(context, cmd, extra);
34 | }
35 | return null;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/transact/OuterActivityMonitor.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core.transact;
2 |
3 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_FROM_TOKEN;
4 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_INTENT;
5 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_PKG;
6 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_RESULT;
7 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_SHELL_PKG;
8 |
9 | import android.content.Context;
10 | import android.content.Intent;
11 | import android.os.Bundle;
12 | import android.os.IBinder;
13 | import android.util.Log;
14 |
15 | import com.hack.server.core.TransactCallback;
16 | import com.hack.utils.IntentUtils;
17 | import com.hack.utils.ThreadUtils;
18 |
19 | public class OuterActivityMonitor implements TransactCallback {
20 | @Override
21 | public Bundle transact(Context context, int cmd, Bundle extras) {
22 | String callerPkg = extras.getString(TRANSACT_KEY_PKG);
23 | String callerShell = extras.getString(TRANSACT_KEY_SHELL_PKG);
24 | Intent intent = extras.getParcelable(TRANSACT_KEY_INTENT);
25 | IBinder callerActivityToken = extras.getBinder(TRANSACT_KEY_FROM_TOKEN);
26 |
27 | Log.d("TransactProvider", String.format("target intent not found! " +
28 | "[caller: %s-%s] [fromToken: %s] [intent: %s]",
29 | callerPkg, callerShell, callerActivityToken, intent));
30 |
31 |
32 | Integer ret = startActivity(context, intent);
33 | if (ret != null) {
34 | Bundle bundle = new Bundle();
35 | bundle.putInt(TRANSACT_KEY_RESULT, ret);
36 | return bundle;
37 | }
38 | return null;
39 | }
40 |
41 | public Integer startActivity(Context context, Intent intent) {
42 | if (IntentUtils.isSysLauncherHome(intent)) {
43 | ThreadUtils.postOnMainThread(() -> {
44 | //当前进程可能不在前台,startActivity可能失败,应该使用callerShell包去启动目标activity
45 | //所以辅包也需要注册TransactProvider
46 | context.startActivity(intent);
47 | });
48 | return 0;
49 | }
50 | return null;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/transact/ProcessBindCallback.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core.transact;
2 |
3 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_PKG;
4 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_PROCESS;
5 | import static com.hack.opensdk.CmdConstants.TRANSACT_KEY_SPACE;
6 |
7 | import android.content.Context;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 |
11 | import com.hack.opensdk.CmdConstants;
12 | import com.hack.server.core.TransactCallback;
13 |
14 | public class ProcessBindCallback implements TransactCallback {
15 | @Override
16 | public final Bundle transact(Context context, int cmd, Bundle extras) {
17 | if (cmd != CmdConstants.TRANSACT_CMD_PROCESS_BINDED) {
18 | return null;
19 | }
20 | int space = extras.getInt(TRANSACT_KEY_SPACE);
21 | String pkg = extras.getString(TRANSACT_KEY_PKG);
22 | String process = extras.getString(TRANSACT_KEY_PROCESS);
23 | onBindProcess(process, pkg, space);
24 | return null;
25 | }
26 |
27 | /**
28 | * @param process
29 | * @param pkg
30 | * @param space
31 | */
32 | protected void onBindProcess(String process, String pkg, int space) {
33 | Log.d("TransactProvider", String.format("agent process bind complete! " + "[space: %d] [pkg: %s] [process: %s]", space, pkg, process));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/server/core/transact/TransactActivityLifecycle.java:
--------------------------------------------------------------------------------
1 | package com.hack.server.core.transact;
2 |
3 | import android.app.Activity;
4 | import android.app.ActivityManager;
5 | import android.app.Application;
6 | import android.content.ComponentName;
7 | import android.content.pm.ActivityInfo;
8 | import android.content.pm.PackageManager;
9 | import android.graphics.Bitmap;
10 | import android.graphics.Canvas;
11 | import android.graphics.PixelFormat;
12 | import android.graphics.drawable.BitmapDrawable;
13 | import android.graphics.drawable.Drawable;
14 | import android.os.Bundle;
15 | import android.util.Log;
16 |
17 | import com.hack.Features;
18 | import com.hack.opensdk.CmdConstants;
19 | import com.hack.opensdk.HackApi;
20 |
21 | public class TransactActivityLifecycle implements Application.ActivityLifecycleCallbacks {
22 | private static final String TAG = TransactActivityLifecycle.class.getSimpleName();
23 | public static final TransactActivityLifecycle INSTANCE = new TransactActivityLifecycle();
24 |
25 | @Override
26 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
27 | if (Features.DEBUG) {
28 | Log.e(TAG, "onActivityCreated: " + activity.getLocalClassName());
29 | }
30 | if (activity.isTaskRoot()) {
31 | fixTaskDescription(activity);
32 | }
33 |
34 | }
35 |
36 | private boolean fixTaskDescription(Activity activity) {
37 | int space = HackApi.getRuntimeProperty(CmdConstants.RUNTIME_PROPERTIES_SPACE, 0);
38 | ActivityInfo info = HackApi.getActivityInfo(new ComponentName(activity.getPackageName(), activity.getClass().getName()), 0, space);
39 | if (info == null) {
40 | Log.e(TAG, "fixTaskDescription: fail");
41 | return false;
42 | }
43 | PackageManager pm = activity.getPackageManager();
44 | Drawable data = info.loadIcon(pm);
45 | String label = String.valueOf(info.loadLabel(pm));
46 | if (space != 0) {
47 | label += "(" + (space + 1) + ")";
48 | }
49 | Bitmap icon;
50 | if (data instanceof BitmapDrawable) {
51 | icon = ((BitmapDrawable) data).getBitmap();
52 | } else {
53 | icon = Bitmap.createBitmap(data.getIntrinsicWidth(), data.getIntrinsicHeight(), data.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
54 | Canvas canvas = new Canvas(icon);
55 | data.setBounds(0, 0, data.getIntrinsicWidth(), data.getIntrinsicHeight());
56 | data.draw(canvas);
57 | }
58 | activity.setTaskDescription(new ActivityManager.TaskDescription(label, icon));
59 | return true;
60 | }
61 |
62 |
63 | @Override
64 | public void onActivityStarted(Activity activity) {
65 |
66 | }
67 |
68 | @Override
69 | public void onActivityResumed(Activity activity) {
70 |
71 | }
72 |
73 | @Override
74 | public void onActivityPaused(Activity activity) {
75 |
76 | }
77 |
78 | @Override
79 | public void onActivityStopped(Activity activity) {
80 |
81 | }
82 |
83 | @Override
84 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
85 |
86 | }
87 |
88 | @Override
89 | public void onActivityDestroyed(Activity activity) {
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/FileLock.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.RandomAccessFile;
6 | import java.nio.channels.FileChannel;
7 | import java.util.Map;
8 | import java.util.concurrent.ConcurrentHashMap;
9 |
10 | public class FileLock {
11 | private static FileLock singleton;
12 | private Map mRefCountMap = new ConcurrentHashMap();
13 |
14 | public static FileLock getInstance() {
15 | if (singleton == null) {
16 | singleton = new FileLock();
17 | }
18 | return singleton;
19 | }
20 |
21 | private int RefCntInc(String filePath, java.nio.channels.FileLock fileLock, RandomAccessFile randomAccessFile,
22 | FileChannel fileChannel) {
23 | int refCount;
24 | if (this.mRefCountMap.containsKey(filePath)) {
25 | FileLockCount fileLockCount = this.mRefCountMap.get(filePath);
26 | int i = fileLockCount.mRefCount;
27 | fileLockCount.mRefCount = i + 1;
28 | refCount = i;
29 | } else {
30 | refCount = 1;
31 | this.mRefCountMap.put(filePath, new FileLockCount(fileLock, refCount, randomAccessFile, fileChannel));
32 |
33 | }
34 | return refCount;
35 | }
36 |
37 | private int RefCntDec(String filePath) {
38 | int refCount = 0;
39 | if (this.mRefCountMap.containsKey(filePath)) {
40 | FileLockCount fileLockCount = this.mRefCountMap.get(filePath);
41 | int i = fileLockCount.mRefCount - 1;
42 | fileLockCount.mRefCount = i;
43 | refCount = i;
44 | if (refCount <= 0) {
45 | this.mRefCountMap.remove(filePath);
46 | }
47 | }
48 | return refCount;
49 | }
50 |
51 | public boolean LockExclusive(File targetFile) {
52 |
53 | if (targetFile == null) {
54 | return false;
55 | }
56 | try {
57 | File lockFile = new File(targetFile.getParentFile().getAbsolutePath().concat("/lock"));
58 | if (!lockFile.exists()) {
59 | lockFile.createNewFile();
60 | }
61 | RandomAccessFile randomAccessFile = new RandomAccessFile(lockFile.getAbsolutePath(), "rw");
62 | FileChannel channel = randomAccessFile.getChannel();
63 | java.nio.channels.FileLock lock = channel.lock();
64 | if (!lock.isValid()) {
65 | return false;
66 | }
67 | RefCntInc(lockFile.getAbsolutePath(), lock, randomAccessFile, channel);
68 | return true;
69 | } catch (Exception e) {
70 | return false;
71 | }
72 | }
73 |
74 | /**
75 | * unlock odex file
76 | **/
77 | public void unLock(File targetFile) {
78 |
79 | File lockFile = new File(targetFile.getParentFile().getAbsolutePath().concat("/lock"));
80 | if (!lockFile.exists()) {
81 | return;
82 | }
83 | if (this.mRefCountMap.containsKey(lockFile.getAbsolutePath())) {
84 | FileLockCount fileLockCount = this.mRefCountMap.get(lockFile.getAbsolutePath());
85 | if (fileLockCount != null) {
86 | java.nio.channels.FileLock fileLock = fileLockCount.mFileLock;
87 | RandomAccessFile randomAccessFile = fileLockCount.fOs;
88 | FileChannel fileChannel = fileLockCount.fChannel;
89 | try {
90 | if (RefCntDec(lockFile.getAbsolutePath()) <= 0) {
91 | if (fileLock != null && fileLock.isValid()) {
92 | fileLock.release();
93 | }
94 | if (randomAccessFile != null) {
95 | randomAccessFile.close();
96 | }
97 | if (fileChannel != null) {
98 | fileChannel.close();
99 | }
100 | }
101 | } catch (IOException e) {
102 | e.printStackTrace();
103 | }
104 | }
105 | }
106 | }
107 |
108 | private class FileLockCount {
109 | FileChannel fChannel;
110 | RandomAccessFile fOs;
111 | java.nio.channels.FileLock mFileLock;
112 | int mRefCount;
113 |
114 | FileLockCount(java.nio.channels.FileLock fileLock, int mRefCount, RandomAccessFile fOs,
115 | FileChannel fChannel) {
116 | this.mFileLock = fileLock;
117 | this.mRefCount = mRefCount;
118 | this.fOs = fOs;
119 | this.fChannel = fChannel;
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | import android.content.Context;
4 |
5 | import com.hack.Features;
6 | import com.hack.Slog;
7 |
8 | import java.io.BufferedInputStream;
9 | import java.io.BufferedOutputStream;
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.Closeable;
12 | import java.io.File;
13 | import java.io.FileInputStream;
14 | import java.io.FileOutputStream;
15 | import java.io.IOException;
16 | import java.io.InputStream;
17 | import java.io.OutputStream;
18 | import java.nio.charset.Charset;
19 | import java.nio.charset.StandardCharsets;
20 | import java.util.Enumeration;
21 | import java.util.zip.ZipEntry;
22 | import java.util.zip.ZipFile;
23 |
24 | public class FileUtils {
25 | private static final boolean DEBUG = Features.DEBUG;
26 | private static final int FILE_BYTE_BUFFER = 4096;
27 | private static final String TAG = FileUtils.class.getSimpleName();
28 |
29 | public static int copy(InputStream in, OutputStream out) throws IOException {
30 | int total = 0;
31 | byte[] buffer = new byte[FILE_BYTE_BUFFER];
32 | int c;
33 | while ((c = in.read(buffer)) != -1) {
34 | total += c;
35 | out.write(buffer, 0, c);
36 | }
37 | return total;
38 | }
39 |
40 | public static int copyAndClose(InputStream in, OutputStream out) throws IOException {
41 | try {
42 | int total = 0;
43 | byte[] buffer = new byte[FILE_BYTE_BUFFER];
44 | int c;
45 | while ((c = in.read(buffer)) != -1) {
46 | total += c;
47 | out.write(buffer, 0, c);
48 | }
49 | return total;
50 | } finally {
51 | closeQuietly(in);
52 | closeQuietly(out);
53 | }
54 |
55 | }
56 |
57 | public static void closeQuietly(Closeable closeable) {
58 | if (closeable != null) {
59 | try {
60 | closeable.close();
61 | } catch (IOException e) {
62 | //ignore
63 | }
64 | }
65 | }
66 |
67 | public static void extractAsset(Context context, String name, File target) throws IOException {
68 | target.getParentFile().mkdirs();
69 | copyAndClose(context.getAssets().open(name), new FileOutputStream(target));
70 | }
71 |
72 | public static void extractFile(File file, String dir, File output) throws IOException {
73 | ZipFile zipFile = null;
74 | try {
75 | zipFile = new ZipFile(file);
76 | Enumeration extends ZipEntry> entries = zipFile.entries();
77 | String DIR = output.getCanonicalPath();
78 | while (entries.hasMoreElements()) {
79 | ZipEntry entry = entries.nextElement();
80 | if (entry.getName().startsWith(dir)) {
81 | if (entry.isDirectory()) {
82 | continue;
83 | }
84 | File target = new File(output, entry.getName());
85 | String canonicalPath = target.getCanonicalPath();
86 | if (!canonicalPath.startsWith(DIR)) {
87 | throw new IOException("security path " + entry.getName());
88 | }
89 | target.getParentFile().mkdirs();
90 | copyAndClose(zipFile.getInputStream(entry), new FileOutputStream(target));
91 | }
92 | }
93 | } finally {
94 | if (zipFile != null) {
95 | try {
96 | zipFile.close();
97 | } catch (IOException e) {
98 | e.printStackTrace();
99 | }
100 |
101 | }
102 | }
103 | }
104 |
105 |
106 | public static boolean deleteQuietly(File scratch) {
107 | try {
108 | if (!scratch.isFile()) {
109 | File[] files = scratch.listFiles();
110 | if (files != null) {
111 | for (File file : files) {
112 | deleteQuietly(file);
113 | }
114 | }
115 | }
116 | return scratch.delete();
117 | } catch (Exception e) {
118 |
119 | }
120 | return false;
121 |
122 | }
123 |
124 | public static String readString(File file) {
125 | return readString(file, StandardCharsets.UTF_8);
126 | }
127 |
128 | public static String readString(File file, Charset charset) {
129 | try {
130 | FileInputStream inputStream = new FileInputStream(file);
131 | String result = readString(inputStream, charset);
132 | inputStream.close();
133 | return result;
134 | } catch (IOException e) {
135 | e.printStackTrace();
136 | }
137 | return null;
138 | }
139 |
140 | public static String readString(InputStream inputStream, Charset charset) {
141 | ByteArrayOutputStream os = new ByteArrayOutputStream();
142 | try {
143 | FileUtils.copy(inputStream, os);
144 | if (charset != null) {
145 | return new String(os.toByteArray(), charset);
146 | }
147 | return os.toString();
148 | } catch (Throwable e) {
149 | //ignore
150 | }
151 | return null;
152 |
153 | }
154 |
155 | public static void writeString(File file, String json) throws IOException {
156 | FileOutputStream outputStream = null;
157 | try {
158 | file.getParentFile().mkdirs();
159 | outputStream = new FileOutputStream(file);
160 | outputStream.write(json.getBytes());
161 | } finally {
162 | closeQuietly(outputStream);
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/IntentUtils.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.BaseBundle;
7 | import android.os.Bundle;
8 | import android.text.TextUtils;
9 | import android.util.ArrayMap;
10 |
11 | import java.util.Map;
12 | import java.util.Set;
13 |
14 | public class IntentUtils {
15 |
16 | public static String getPackage(Intent intent) {
17 | if (intent == null) {
18 | return null;
19 | }
20 | ComponentName cnn = intent.getComponent();
21 | if (cnn != null) {
22 | return cnn.getPackageName();
23 | }
24 | return intent.getPackage();
25 | }
26 |
27 | public static boolean isSysLauncherHome(Intent intent) {
28 | if (intent == null) {
29 | return false;
30 | }
31 |
32 | return intent.getAction() != null && TextUtils.equals(intent.getAction(), Intent.ACTION_MAIN)
33 | && intent.hasCategory(Intent.CATEGORY_HOME);
34 | }
35 |
36 | public static String toShortString(Intent intent) {
37 | if (intent != null) {
38 | StringBuilder builder = new StringBuilder();
39 | if (intent.getExtras() != null) {
40 | builder.append(toShortString(intent.getExtras()));
41 | }
42 | return builder.toString();
43 | }
44 | return null;
45 | }
46 |
47 | public static String toShortString(Bundle bundle) {
48 | if (bundle != null) {
49 | bundle.setClassLoader(IntentUtils.class.getClassLoader());
50 | bundle.containsKey("test");//force unparcel
51 | if (bundle != null && bundle instanceof BaseBundle) {
52 | RefUtils.FieldRef> filed_mMap =
53 | new RefUtils.FieldRef(BaseBundle.class, false, "mMap");
54 | ArrayMap mMap = filed_mMap.get(bundle);
55 | if (mMap != null) {
56 | StringBuilder builder = new StringBuilder("{<- ");
57 | Set> entrySet = mMap.entrySet();
58 | for (Map.Entry entry : entrySet) {
59 | builder.append("[" + entry.getKey());
60 | builder.append(":");
61 | Object value = entry.getValue();
62 | if (value instanceof Bundle) {
63 | builder.append(toShortString((Bundle)value));
64 | } else if (value instanceof Intent) {
65 | builder.append(toShortString((Intent)value));
66 | } else {
67 | builder.append(value);
68 | }
69 | builder.append("]");
70 | }
71 | builder.append(" ->}");
72 | return builder.toString();
73 | }
74 | }
75 | }
76 | return null;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/ProcessUtils.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | import static com.hack.Features.DEBUG;
4 |
5 | import android.app.ActivityManager;
6 | import android.content.Context;
7 | import android.os.Build;
8 | import android.os.Process;
9 | import android.text.TextUtils;
10 | import java.io.BufferedReader;
11 | import java.io.FileInputStream;
12 | import java.io.InputStreamReader;
13 |
14 | public class ProcessUtils {
15 | private static boolean sbInit;
16 | private static boolean sIs64bit;
17 | private static String sCurProcessName;
18 | private static ProcessType sProcessType = ProcessType.TYPE_UNKNOWN;
19 | public enum ProcessType {
20 | TYPE_UNKNOWN,
21 | TYPE_CLIENT,
22 | TYPE_APP,
23 | TYPE_ASSIST,
24 | TYPE_SERVICE
25 | }
26 |
27 | public static ProcessType tryGetProcessType(Context context) {
28 | if (sProcessType == ProcessType.TYPE_UNKNOWN) {
29 | final String hostPkg = context.getPackageName();
30 | String processName = ProcessUtils.getCurProcessName(context);
31 | if (TextUtils.equals(processName, hostPkg)
32 | || TextUtils.equals(processName, hostPkg + ":client")) {
33 | sProcessType = ProcessType.TYPE_CLIENT;
34 | } else if (TextUtils.equals(processName, hostPkg + ":core")) {
35 | sProcessType = ProcessType.TYPE_SERVICE;
36 | } else if (TextUtils.equals(processName, hostPkg + ":assist")) {
37 | sProcessType = ProcessType.TYPE_ASSIST;
38 | } else {
39 | sProcessType = ProcessType.TYPE_APP;
40 | }
41 | }
42 |
43 | return sProcessType;
44 | }
45 |
46 | public static boolean isService() {
47 | return sProcessType == ProcessType.TYPE_SERVICE;
48 | }
49 |
50 | public static boolean isClient() {
51 | return sProcessType == ProcessType.TYPE_CLIENT;
52 | }
53 |
54 | public static boolean isAssist() {
55 | return sProcessType == ProcessType.TYPE_ASSIST;
56 | }
57 |
58 | public static boolean isApp() {
59 | return sProcessType == ProcessType.TYPE_APP;
60 | }
61 |
62 | public static String getCurProcessName(Context context) {
63 | String procName = sCurProcessName;
64 | if (!TextUtils.isEmpty(procName)) {
65 | return procName;
66 | }
67 | try {
68 | int pid = Process.myPid();
69 | ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
70 | for (ActivityManager.RunningAppProcessInfo info : mActivityManager.getRunningAppProcesses()) {
71 | if (info.pid == pid) {
72 | sCurProcessName = info.processName;
73 | return sCurProcessName;
74 | }
75 | }
76 | } catch (Exception e) {
77 | if (DEBUG) e.printStackTrace();
78 | }
79 | sCurProcessName = getProcessNameFromProc(-1);
80 | return sCurProcessName;
81 | }
82 |
83 | public static String getProcessNameFromProc(int pid) {
84 | BufferedReader cmdlineReader = null;
85 | if (pid == -1) {
86 | pid = Process.myPid();
87 | }
88 | try {
89 | cmdlineReader = new BufferedReader(new InputStreamReader(
90 | new FileInputStream(
91 | "/proc/" + pid + "/cmdline"),
92 | "iso-8859-1"));
93 | int c;
94 | StringBuilder processName = new StringBuilder();
95 | while ((c = cmdlineReader.read()) > 0) {
96 | processName.append((char) c);
97 | }
98 | return processName.toString();
99 | } catch (Throwable e) {
100 | // ignore
101 | } finally {
102 | if (cmdlineReader != null) {
103 | try {
104 | cmdlineReader.close();
105 | } catch (Exception e) {
106 | // ignore
107 | }
108 | }
109 | }
110 | return null;
111 | }
112 |
113 | public static boolean is64Bit() {
114 | if (sbInit) {
115 | return sIs64bit;
116 | }
117 |
118 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
119 | sIs64bit = false;
120 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
121 | sIs64bit = Process.is64Bit();
122 | } else {
123 | final String VMRuntime_className = "dalvik.system.VMRuntime";
124 | RefUtils.MethodRef method_getRuntime = new RefUtils.MethodRef(
125 | VMRuntime_className, true, "getRuntime", new Class[0]);
126 | RefUtils.MethodRef method_is64Bit = new RefUtils.MethodRef(
127 | VMRuntime_className, false, "is64Bit", new Class[0]);
128 |
129 | Object invokeResult = method_is64Bit.invoke(method_getRuntime.invoke(null));
130 | if (invokeResult != null) {
131 | sIs64bit = (Boolean) invokeResult;
132 | }
133 | }
134 | sbInit = true;
135 | return sIs64bit;
136 | }
137 |
138 | public static String typeToString(ProcessType type) {
139 | switch (type) {
140 | case TYPE_APP:
141 | return type + "#" + "TYPE_APP";
142 | case TYPE_CLIENT:
143 | return type + "#" + "TYPE_CLIENT";
144 | case TYPE_SERVICE:
145 | return type + "#" + "TYPE_SERVICE";
146 | case TYPE_ASSIST:
147 | return type + "#" + "TYPE_ASSIST";
148 | default:
149 | return null;
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/RefUtils.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | import java.lang.reflect.Field;
4 | import java.lang.reflect.Method;
5 |
6 | public class RefUtils {
7 | public static Field getField(Class refClass, boolean isStatic, String filedName) {
8 | if (refClass == null || filedName == null) {
9 | return null;
10 | }
11 | try {
12 | return refClass.getDeclaredField(filedName);
13 | } catch (NoSuchFieldException e) {
14 |
15 | }
16 | return null;
17 | }
18 |
19 | public static Method getMethod(Class refClass, boolean isStatic, String funcName, Class[] paramTypes) {
20 | if (refClass == null || funcName == null) {
21 | return null;
22 | }
23 | try {
24 | return refClass.getDeclaredMethod(funcName, paramTypes);
25 | } catch (NoSuchMethodException e) {
26 |
27 | }
28 | return null;
29 | }
30 |
31 | public static class FieldRef {
32 | boolean mIsStatic;
33 | Field mField;
34 | public FieldRef(Class refClass, boolean isStatic, String name) {
35 | mIsStatic = isStatic;
36 | mField = getField(refClass, isStatic, name);
37 | if (mField != null) {
38 | mField.setAccessible(true);
39 | }
40 | }
41 | public FieldRef(String className, boolean isStatic, String name) {
42 | try {
43 | Class targetClass = Class.forName(className);
44 | mField = getField(targetClass, isStatic, name);
45 | } catch (ClassNotFoundException e) {
46 | }
47 | mIsStatic = isStatic;
48 | if (mField != null) {
49 | mField.setAccessible(true);
50 | }
51 | }
52 |
53 | public boolean isValid() {
54 | return mField != null;
55 | }
56 |
57 | public T get(Object instance) {
58 | try {
59 | return (T) mField.get(instance);
60 | } catch (Exception e) {
61 |
62 | }
63 | return null;
64 | }
65 | public void set(Object instance, T value) {
66 | try {
67 | mField.set(instance, value);
68 | } catch (Exception e) {
69 |
70 | }
71 | }
72 | }
73 |
74 | public static class MethodRef {
75 | Method mMethod;
76 | public MethodRef(String className, boolean isStatic, String funcName, Class[] paramsTypes) {
77 | try {
78 | Class targetClass = Class.forName(className);
79 | mMethod = getMethod(targetClass, isStatic, funcName, paramsTypes);
80 | } catch (Exception e) {
81 | }
82 | if (mMethod != null) {
83 | mMethod.setAccessible(true);
84 | }
85 | }
86 | public MethodRef(Class refClass, boolean isStatic, String funcName, Class[] paramsTypes) {
87 | mMethod = getMethod(refClass, isStatic, funcName, paramsTypes);
88 | if (mMethod != null) {
89 | mMethod.setAccessible(true);
90 | }
91 | }
92 |
93 | public boolean isValid() {
94 | return mMethod != null;
95 | }
96 |
97 | public T invoke(Object instance, Object...args) {
98 | try {
99 | return (T) mMethod.invoke(instance, args);
100 | } catch (Exception e) {
101 | }
102 | return null;
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/Singleton.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | /*
4 | * Copyright (C) 2010 The Android Open Source Project
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | /**
20 | * Singleton helper class for lazily initialization.
21 | *
22 | * Modeled after frameworks/base/include/utils/Singleton.h
23 | *
24 | * @hide
25 | */
26 | public abstract class Singleton {
27 | public Singleton() {
28 | }
29 |
30 | private T mInstance;
31 |
32 | protected abstract T create();
33 |
34 | public final T get() {
35 | synchronized (this) {
36 | if (mInstance == null) {
37 | mInstance = create();
38 | }
39 | return mInstance;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/com/hack/utils/ThreadUtils.java:
--------------------------------------------------------------------------------
1 | package com.hack.utils;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import java.util.concurrent.Callable;
7 | import java.util.concurrent.ExecutorService;
8 | import java.util.concurrent.Future;
9 | import java.util.concurrent.LinkedBlockingQueue;
10 | import java.util.concurrent.ThreadPoolExecutor;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | public class ThreadUtils {
14 | private static Thread sMainThread;
15 | private static Handler sMainThreadHandler;
16 | private static volatile ThreadPoolExecutor sThreadExecutor;
17 |
18 | public static final int ASYNC_MAX_THREAD = 4;
19 |
20 | static {
21 | sMainThread = Looper.getMainLooper().getThread();
22 | sMainThreadHandler = new Handler(Looper.getMainLooper());
23 | }
24 |
25 | /**
26 | * Returns true if the current thread is the UI thread.
27 | */
28 | public static boolean isMainThread() {
29 | return Thread.currentThread() == sMainThread;
30 | }
31 |
32 | /**
33 | * Returns a shared UI thread handler.
34 | */
35 | public static Handler getUiThreadHandler() {
36 | return sMainThreadHandler;
37 | }
38 |
39 | /**
40 | * Checks that the current thread is the UI thread. Otherwise throws an exception.
41 | */
42 | public static void ensureMainThread() {
43 | if (!isMainThread()) {
44 | throw new RuntimeException("Must be called on the UI thread");
45 | }
46 | }
47 |
48 | /**
49 | * Posts runnable in background using shared background thread pool.
50 | *
51 | * @Return A future of the task that can be monitored for updates or cancelled.
52 | */
53 | public static Future postOnBackgroundThread(Runnable runnable) {
54 | return getThreadExecutor().submit(runnable);
55 | }
56 |
57 | /**
58 | * Posts callable in background using shared background thread pool.
59 | *
60 | * @Return A future of the task that can be monitored for updates or cancelled.
61 | */
62 | public static Future postOnBackgroundThread(Callable callable) {
63 | return getThreadExecutor().submit(callable);
64 | }
65 |
66 | /**
67 | * Posts the runnable on the main thread.
68 | */
69 | public static void postOnMainThread(Runnable runnable) {
70 | getUiThreadHandler().post(runnable);
71 | }
72 |
73 | private static ExecutorService getThreadExecutor() {
74 | if (sThreadExecutor == null) {
75 | synchronized (ThreadUtils.class) {
76 | if (sThreadExecutor == null) {
77 | int coreNum = Runtime.getRuntime().availableProcessors();
78 | if (coreNum > ASYNC_MAX_THREAD) coreNum = ASYNC_MAX_THREAD;
79 |
80 | sThreadExecutor = new ThreadPoolExecutor(coreNum, coreNum,
81 | 5L, TimeUnit.SECONDS,
82 | new LinkedBlockingQueue());
83 | sThreadExecutor.allowCoreThreadTimeOut(true);
84 | }
85 | }
86 | }
87 | return sThreadExecutor;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/jniLibs/arm64-v8a/libl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WaxMoon/opensdk/eaab1645e57c0be6d3c1b0f5bf586984f4de141f/src/main/jniLibs/arm64-v8a/libl.so
--------------------------------------------------------------------------------
/src/main/jniLibs/arm64-v8a/libpl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WaxMoon/opensdk/eaab1645e57c0be6d3c1b0f5bf586984f4de141f/src/main/jniLibs/arm64-v8a/libpl.so
--------------------------------------------------------------------------------
/src/main/jniLibs/armeabi-v7a/libl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WaxMoon/opensdk/eaab1645e57c0be6d3c1b0f5bf586984f4de141f/src/main/jniLibs/armeabi-v7a/libl.so
--------------------------------------------------------------------------------
/src/main/jniLibs/armeabi-v7a/libpl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WaxMoon/opensdk/eaab1645e57c0be6d3c1b0f5bf586984f4de141f/src/main/jniLibs/armeabi-v7a/libpl.so
--------------------------------------------------------------------------------
/src/main/res/layout/hk_notification_wp.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
15 |
16 |
23 |
27 |
31 |
35 |
39 |
40 |
41 |
49 |
53 |
57 |
61 |
65 |
66 |
67 |
75 |
79 |
83 |
87 |
91 |
92 |
93 |
101 |
105 |
109 |
113 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/main/res/layout/hk_notification_wp_simple.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | %1$s正在运行
3 | 确保%1$s能够收到消息
4 |
--------------------------------------------------------------------------------
/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 256dp
3 | 128dp
4 | 64dp
5 | 4dp
6 | -1dp
7 | 8dp
8 |
9 |
--------------------------------------------------------------------------------
/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | :core
3 | :assist
4 |
5 | %1$s is running
6 | Ensure %1$s can receive msg
7 |
--------------------------------------------------------------------------------
/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------