├── .gitignore
├── LICENSE
├── README.md
├── ext_docs
├── 安全sdk-so6.3.80_保护.pdf
└── 安全sdk-so6.4.36_保护.pdf
├── libsg6.4.176
├── call_rc4.c
├── createGlobalBoolean_Integer_String.c
├── create_vdata.c
├── decrypto.c
├── extends_vdata.c
├── libsgmainso-6.4.176.txt
├── make_data.c
└── vdata.h
└── libsg6.4.36
├── breaklist.idc
├── doCommandNative.c
├── jni_load.c
├── libsgmainso-6.4.36分析
├── patches.py
├── put_unconditional_branch.py
├── put_unconditional_branch1.py
├── sub_14FEE.c
├── sub_1511C.c
├── sub_2A01E.c
├── sub_2AC24.c
├── sub_2B4BE.c
├── sub_2D1DA.c
├── sub_301DE.c
├── sub_3026A.c
├── sub_305BE.c
├── sub_30D60.c
├── sub_32C46.c
├── sub_32F44.c
├── sub_72080.c
├── sub_73668.c
├── sub_73e56.c
├── sub_77dbc.c
├── sub_7AFB6.c
├── sub_7B606.c
├── sub_7B86C.c
├── sub_7B93A.c
├── sub_7C10C.c
├── sub_9970.c
├── sub_9D82.c
├── sub_9a14.c
├── sub_9f1c.c
├── sub_E890.c
└── sub_b7f6.c
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Object files
5 | *.o
6 | *.ko
7 | *.obj
8 | *.elf
9 |
10 | # Linker output
11 | *.ilk
12 | *.map
13 | *.exp
14 |
15 | # Precompiled Headers
16 | *.gch
17 | *.pch
18 |
19 | # Libraries
20 | *.lib
21 | *.a
22 | *.la
23 | *.lo
24 |
25 | # Shared objects (inc. Windows DLLs)
26 | *.dll
27 | *.so
28 | *.so.*
29 | *.dylib
30 |
31 | # Executables
32 | *.exe
33 | *.out
34 | *.app
35 | *.i*86
36 | *.x86_64
37 | *.hex
38 |
39 | # Debug files
40 | *.dSYM/
41 | *.su
42 | *.idb
43 | *.pdb
44 |
45 | # Kernel Module Compile Results
46 | *.mod*
47 | *.cmd
48 | .tmp_versions/
49 | modules.order
50 | Module.symvers
51 | Mkfile.old
52 | dkms.conf
53 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 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 General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # crack_libsgmain
2 | Reverse libsgmain
3 |
4 |
5 | 逆向libsgmain.so,它类似一个安全sdk,谁都可以集成, 我自己也可以集成, 所以测试其安全强度,对其进行逆向分析
6 |
7 | 不侵权吧, 如果涉及侵权请及时告知,我会马上删掉项目。
8 |
9 |
10 | 首先它没你想的那么简单, 那逆向时间完全随我心情; 我想起来就搞搞,想不搞了就放几天;
11 |
12 | 我会尽量多想一些办法去尝试逆向。
13 |
14 | 后续想起来什么在补充吧。
15 |
16 | 各版本目錄:
17 |
18 |
19 | libsgmain6.4.176
20 |
21 | libsgmain6.3.80
22 |
23 | libsgmain6.4.36
24 |
25 | ;ext_docs为早期的一些文档,可能存在错误或者过时,随便看看吧,还有很多文档
26 |
27 | 但不便公开!
28 |
29 | 難度 : 6.3.80 > 6.4.36 > 6.4.176
30 |
31 |
32 | 本人聲明:
33 | 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ext_docs/安全sdk-so6.3.80_保护.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ylcangel/crack_libsgmain/763eafaeb233a7224d9111540b97b635ed168cc9/ext_docs/安全sdk-so6.3.80_保护.pdf
--------------------------------------------------------------------------------
/ext_docs/安全sdk-so6.4.36_保护.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ylcangel/crack_libsgmain/763eafaeb233a7224d9111540b97b635ed168cc9/ext_docs/安全sdk-so6.4.36_保护.pdf
--------------------------------------------------------------------------------
/libsg6.4.176/call_rc4.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | vdata* call_rc4(vdata *key, vdata *cryptedata)
14 | {
15 | int key_len; // r0@3
16 | vdata* decrypted_data; // r4@4
17 | char swapkey[264]; // [sp+0h] [bp-120h]@9
18 |
19 | if ( !key )
20 | goto exit1;
21 | if ( !key->data )
22 | goto exit1;
23 | key_len = key->data_len;
24 | if ( !key_len )
25 | goto exit1;
26 | decrypted_data = 0;
27 | if ( !cryptedata || key_len < 16 )
28 | goto exit;
29 | if ( !cryptedata->data || !cryptedata->data_len || (key->data_len = 16, (decrypted_data = create_vdata(cryptedata->data_len)) == 0) )
30 | {
31 | goto exit;
32 | }
33 | memset(swapkey, 0, 264); // 实际只用256,算法里面是swapkey+8开始的
34 | init_rc4key(swapkey, key->data, key->data_len);
35 | rc4_(swapkey, cryptedata->data_len, cryptedata->data, decrypted_data->data);
36 | if ( decrypted_data->data )
37 | decrypted_data->data_len = cryptedata->data_len;
38 |
39 | exit1:
40 | decrypted_data = 0;
41 | exit:
42 | return decrypted_data;
43 | }
--------------------------------------------------------------------------------
/libsg6.4.176/createGlobalBoolean_Integer_String.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int createGlobalBoolean_Integer_String(_JavaVM *a1)
14 | { // 对应源码
15 | _JNIEnv *env; // r0@1
16 | _JNIEnv *envf; // r4@1
17 | int v3; // r0@1
18 | int v4; // r0@1
19 | int v5; // r0@1
20 | int result; // r0@1
21 |
22 | javavm = (int)a1;
23 | env = (_JNIEnv *)getEnv(0);
24 | envf = env;
25 | v3 = ((int (*)(void))env->functions->FindClass)();
26 | global_jbooleanobj = ((int (__fastcall *)(_JNIEnv *, int))envf->functions->NewGlobalRef)(envf, v3);
27 | v4 = ((int (__fastcall *)(_JNIEnv *, const char *))envf->functions->FindClass)(envf, "java/lang/Integer");
28 | global_jintegerobj = ((int (__fastcall *)(_JNIEnv *, int))envf->functions->NewGlobalRef)(envf, v4);
29 | v5 = ((int (__fastcall *)(_JNIEnv *, const char *))envf->functions->FindClass)(envf, "java/lang/String");
30 | result = ((int (__fastcall *)(_DWORD, _DWORD))envf->functions->NewGlobalRef)(envf, v5);
31 | global_jstringobj = result;
32 | return result;
33 | }
34 |
--------------------------------------------------------------------------------
/libsg6.4.176/create_vdata.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | struct data {
14 | char* d; // 可变长数据
15 | };
16 |
17 | struct vdata{
18 | struct data* data;
19 | int data_len; // 前一次记录的内存大小
20 | int data_mlen; // 占总内存大小
21 | void* f1;
22 | void* f2;
23 | void* f3;
24 | void* f4;
25 | void* f5;
26 | void* f6;
27 | void* f7;
28 | void* f8;
29 | void* f9;
30 | void* f10; // f10 f11 = long long ,低四字节存放sub_B3BB1512,高四字节存放sub_B3BB1528
31 | void* f11;
32 | };
33 |
34 |
35 | struct vdata* create_vdata(int datalen) {
36 |
37 | if (data_len < 1) {
38 | return NULL;
39 | }
40 |
41 | struct vdata* vdata = malloc(56);
42 | if (vdata) {
43 | memset(vdata->data_len, 0, 52) // (char*) vdata + 4
44 | vdata->data = 0;
45 | vdata->data_mlen = datalen;
46 |
47 | struct vdata* data = malloc(datalen);
48 | if(data) {
49 | memset(data, 0, datalen);
50 | vdata->data_len = 0;
51 | vdata->data = data;
52 | vdata->f1 = make_data;
53 | vdata->f3 = extend_vdata;
54 | vdata->f4 = sub_B3BB13F4;
55 | vdata->f5 = sub_B3BB1412;
56 | vdata->f6 = sub_B3BB144A;
57 | vdata->f7 = sub_B3BB1468;
58 | vdata->f2 = sub_B3BB14D2;
59 | vdata->f8 = sub_B3BB14AC;
60 | vdata->f9 = sub_B3BB1500;
61 | vdata->f10 = sub_B3BB1512;
62 | vdata->f11 = sub_B3BB1528;
63 | }
64 | free(vdata);
65 | vdata = NULL;
66 | }
67 | return vdata;
68 | }
69 |
--------------------------------------------------------------------------------
/libsg6.4.176/decrypto.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 | struct dcryptdata {
13 | void* v;
14 | int caseno;
15 | void* v1;
16 | void* decryptdata_;
17 | struct vdata* key;
18 | struct vdata* cryptedata;
19 | }
20 |
21 | decryptdata_ 取值 820000 880000 890000
22 |
23 | int decrypto(struct dcryptdata* decryptdata_, int* a2) {
24 | // 传递两个参数 一个代表待解密结构体,一个代表返回码
25 | // 应该是解密算法
26 | // 内置n种解密算法
27 | // 如rc4
28 | // 解压缩等
29 | // 传递两个参数
30 | // 应该是解密算法
31 | // 内置n种解密算法
32 | // 如rc4
33 | // 解压缩等
34 | int caseno; // r1@3
35 | int result; // r0@4
36 |
37 | *a2 = 820000;
38 | if ( !decryptdata_ || !decryptdata_->cryptedata || (caseno = decryptdata_->caseno, (unsigned int)v5 > 0x1B) )
39 | {
40 | result = 0;
41 | *a2 = 890000;
42 | return result;
43 | }
44 | v3 = 880000;
45 | result = 0;
46 | switch ( caseno )
47 | {
48 | case 0x10u:
49 | case 0x11u:
50 | case 0x12u:
51 | result = ((int (__fastcall *)(void *))call_aes)(decryptdata_->v);
52 | break;
53 | case 3u:
54 | result = ((int (__fastcall *)(struct vdata *, struct vdata *))call_rc4)(decryptdata_->key, decryptdata_->cryptedata);
55 | break;
56 | case 0x14u:
57 | result = ((int (__fastcall *)(void *, struct vdata *))call_uncompress)(decryptdata_->v, decryptdata_->cryptedata);
58 | break;
59 | case 0x15u:
60 | result = ((int (__fastcall *)(void *, struct vdata *, _DWORD *))call_base64)(decryptdata_->v, decryptdata_->cryptedata, 820000);
61 | break;
62 | case 0x16u:
63 | result = ((int (__fastcall *)(struct vdata *))call_md5)(decryptdata_->cryptedata);
64 | break;
65 | case 0x17u:
66 | result = ((int (__fastcall *)(struct vdata *, struct vdata *))call_hmac_sha1)(decryptdata_->key, decryptdata_->cryptedata);
67 | break;
68 | case 0x18u:
69 | result = ((int (__fastcall *)(struct vdata *))call_sha1)(decryptdata_->cryptedata);
70 | break;
71 | case 0x19u:
72 | result = ((int (__fastcall *)(struct vdata *))call_sha256)(decryptdata_->cryptedata);
73 | break;
74 | case 0x1Au:
75 | result = (int)call_sgcustom((int)decryptdata_->v, (int)decryptdata_->v1, (int)decryptdata_->cryptedata, v4);
76 | break;
77 | default:
78 | result = 0;
79 | *a2 = 880000;
80 | return result;
81 | }
82 |
83 | if ( result ) {
84 | result = 0;
85 | *a2 = 0;
86 | return result;
87 | }
88 |
89 | return 0;
90 | }
--------------------------------------------------------------------------------
/libsg6.4.176/extends_vdata.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | // 主要完成扩展vdata
14 | // @old_vdata 待扩展vdata结构
15 | // @extend_len 扩展长度
16 | int extend_vdata(vdata *old_vdata, int extend_len) {
17 | int newlen; // r1@3
18 | struct data *newdata; // r0@3
19 | int oldlen; // r6@4
20 | int result; // r0@4
21 |
22 | if ( old_vdata ) {
23 | if ( old_vdata->data ) {
24 | extendlen = extend_len + 100; // 扩展长度加100
25 | newlen = old_vdata->data_mlen + extendlen;
26 | newdata = relloc(old_vdata->data, newlen);
27 | if ( newdata ) {
28 | oldlen = old_vdata->data_mlen;
29 | old_vdata->data = (struct data *) newdata;
30 | memset(newdata + oldlen, 0, extendlen);
31 | old_vdata->data_mlen = extendlen + oldlen;
32 | return 0;
33 | }
34 | } else {
35 | if ( relen <= 100 )
36 | relen = 100;
37 | newdata = (struct data *) malloc(relen);
38 | if ( newdata ) {
39 | memset(newdata, 0, relen);
40 | old_vdata->data = newdata;
41 | old_vdata->data_len = 0;
42 | old_vdata->data_mlen = relen;
43 | return 0;
44 | }
45 | old_vdata->data = 0;
46 | }
47 | }
48 | return -1;
49 | }
--------------------------------------------------------------------------------
/libsg6.4.176/libsgmainso-6.4.176.txt:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | libsgmainso-6.4.176分析:
14 |
15 | libsgmain.so是一个apk,其中com.alibaba.wireless.security.mainplugin.SecurityGuardMainPlugin
16 | 类中加载真正的libsgmainso-6.4.176.so
17 |
18 |
19 | # libsgmain.so 被做了处理, section表失效
20 | 1、尝试修复,通过dynamic段信息进行section节修复,我修复了一个版本,不过有两三个节存在问题,特别是data,不过ida能加载。
21 | 2、可以通过010 editor把section 节个数设为0,这样ida可以通过段加载。
22 | 修复后可以静态先看看,我们可以发现此版本较libsgmainso-6.3.80版本变化挺大,libsgmainso-6.3.80版本里面的大量的跳转逻辑
23 | 不见了,可能是性能考虑吧, 觉得之前的版本比较恶心。
24 |
25 |
26 | # 有几种比较好的办法尝试逆向
27 | 1、尝试手动加载so,先逆向跑跑看
28 | 2、找一个集成该sdk的app,进行调试,注意最好这个app本身没什么防护,否则你要花特别多的时间在对抗app上。
29 | 3、同2,可以通过frida hook art::JNI::RegisterNatives(_JNIEnv *, _jclass *, JNINativeMethod const*, int) 把注册的
30 | doCommandNative对应的地址打印出来,然后通过加载地址和base计算得到文件偏移,静态看一看;libsgmainso-6.3.80版本
31 | 对应文件偏移的指令没法看,应该做了处理。
32 |
33 | # 加载段地址, 后面可能对不上,忘记这是第几次调试拷贝下来的了
34 | libsgmainso_6.4.176.so B3B25000 B3BD5000 R . X D . byte 00 public CODE 32 00 00
35 | libsgmainso_6.4.176.so B3BD5000 B3BD8000 R . . . . byte 00 public CONST 32 00 00
36 | libsgmainso_6.4.176.so B3BD8000 B3BF3000 R W . . . byte 00 public DATA 32 00 00
37 |
38 | # 分析:
39 | # init_array 没有逻辑
40 | 我手机linker调用init_array 导出函数 __dl__ZN6soinfo9CallArrayEPKcPPFvvEjb B6F97AC8
41 | 但该so没有init_array为空
42 |
43 |
44 | # call jni_onload
45 | ## 首先初始化了 三个全局jobject (Boolean, Integer, String)
46 |
47 | 首先肯定用了llvm混淆指令平坦化
48 |
49 | sub_8D194被我改名为createGlobalBoolean_Integer_String
50 | 详细见createGlobalBoolean_Integer_String.c
51 | r0 = javavm
52 | r1 = [stack]:BEBED5E8 DCD 0
53 | r2 = 0x10004
54 | r3 = art::CheckJII::GetEnv(_JavaVM *, void **, int)
55 | 调用GetEnv获取env
56 | static jint GetEnv(JavaVM* vm, void** env, jint version) {
57 | ScopedCheck sc(vm, true, __FUNCTION__);
58 | sc.Check(true, "vpI", vm);
59 | return CHECK_JNI_EXIT("I", BaseVm(vm)->GetEnv(vm, env, version));
60 | }
61 |
62 | 调用FindClass(env, "java/lang/Boolean")
63 | 调用NewGlobalRef(env, BooleanObj)并保存它
64 | 调用FindClass(env, "java/lang/Integer")
65 | 调用NewGlobalRef(env, Integer)并保存它
66 | 调用FindClass(env, "java/lang/String")
67 | 调用NewGlobalRef(env, String)并保存它
68 |
69 | # 拉了一块,后面在补
70 | libart.so:B4DD560E BLX R7 ; // 对应文件偏移1e660e
71 | //TODO 落下一点东西,操作一个栈变量,没细看
72 |
73 | [stack]:BEC335E0 DCD 0xA3FADAB9
74 | [stack]:BEC335E4 DCD 0x53
75 | [stack]:BEC335E8 DCD 0x22
76 | [stack]:BEC335EC DCD 0x9FEE1FCD
77 | [stack]:BEC335F0 DCD 1
78 | [stack]:BEC335F4 DCD 0xB4F7D200
79 | [stack]:BEC335F8 DCD 0xA3FD44EF
80 | [stack]:BEC335FC DCD 0xE8
81 | [stack]:BEC33600 DCD 0xD3
82 | [stack]:BEC33604 DCD 0x43
83 | [stack]:BEC33608 DCD 0xB4F53DC0
84 | [stack]:BEC3360C DCD 0
85 | [stack]:BEC33610 DCD 0xBEC33650
86 | [stack]:BEC33614 DCD 0xA3F373A7
87 | [stack]:BEC33618 DCD 0
88 | [stack]:BEC3361C DCD 0
89 | [stack]:BEC33620 DCD 0
90 | [stack]:BEC33624 DCD 0x9D
91 | [stack]:BEC33628 DCD 0x16
92 | [stack]:BEC3362C DCD 0x9FEE1FCD
93 | [stack]:BEC33630 DCD 0xB4F07800
94 | [stack]:BEC33634 DCD 0xB4F07800
95 | [stack]:BEC33638 DCD 0xBEC33870
96 | [stack]:BEC3363C DCD 0xBEC33860
97 | [stack]:BEC33640 DCD 0xB4EFCA64
98 | [stack]:BEC33644 DCD 0x43
99 | [stack]:BEC33648 DCD 0xB4EFDAE0
100 | [stack]:BEC3364C DCD 0
101 | [stack]:BEC33650 DCD 0xBEC336A0
102 | [stack]:BEC33654 DCD 0xB126976F
103 | [stack]:BEC33658 DCD 0xAFE00284
104 | [stack]:BEC3365C DCD 0xA3F372E9
105 | [stack]:BEC33660 DCD 0x27
106 | [stack]:BEC33664 DCD 0xB126A711
107 | [stack]:BEC33668 DCB 0xD3 ;
108 | [stack]:BEC33669 DCB 0xA6 ;
109 | [stack]:BEC3366A DCB 0x26 ; &
110 | [stack]:BEC3366B DCB 0xB1 ;
111 |
112 | libsgmainso_6.4.176.so:A3FAD9C4 BLX R2 = FindClass
113 | com/taobao/wireless/security/adapter/common/HttpUtil
114 | 调用art::CheckJNI::NewGlobalRef(_JNIEnv *, _jobject *)创建HttpUtil的NewGlobalRef
115 | 后续逻辑就没了,因为vm中没有该class
116 | 解密出字符串"sendSyncHttpGetRequestBridge"
117 | 調用env->getStaticMethodID
118 | 解密出數據"sendSyncHttpPostRequestBridge"
119 | 在解密出"downloadFileBridge"
120 |
121 |
122 | # 进入解密
123 | .text:000849B6 BL sub_8586C ; r0 = 0x84ab8
124 | .text:000849B6 ; r1 = 见下面,好像这个函数没有参数
125 | .text:000849B6 ; r2 = 0x35
126 | .text:000849B6 ; r3 = 0x53
127 |
128 |
129 | libsgmainso_6.4.176.so:B3BB15D0 (我给重命名为create_vdata(int len))
130 | .text:000858BE BL sub_8C5D0 ; r0 = 0x11
131 | .text:000858BE ; r1
132 | .text:000858BE ; r2 = 0x858b9
133 | .text:000858BE ; r3 = 0x5a
134 |
135 | debug014:ACC1CFC8 DCB 0 ; mallocA
136 | ma = malloc(0x38); // 56个字节大小的内存
137 | memset((char*) (ma + 4), 0, 0x34);
138 | debug120:A40082F8 DCB 0x6C ; l ; mallocb
139 | mb = malloc(0x11); // 传入大小
140 | memset(mb, 0, 0x11);
141 | ma = 0xA40082F8 = mb;
142 | ma + 0x4 = 0;
143 | ma + 0x8 = 0x11; // 即mb大小
144 | ma + 0xc = 0x8c34d; (一个函数起始地址)
145 | ma + 0x10 = 0x8c4d2;(一个函数起始地址)
146 | ma + 0x14 = 0x8c392;(一个函数起始地址)
147 | ma + 0x18 = 0x8c3f4;(一个函数起始地址)
148 | ma + 0x1c = 0x8c412(一个函数起始地址)
149 | ma + 0x20 = 0x8c44a
150 | ma + 0x24 = 0x8c468
151 | ma + 0x28 = 0x8c4ac
152 | ma + 0x2c = 0x8c500
153 | ma + 0x30 = 0x8c512
154 | ma + 0x34 = 0x8c528
155 | 对应结构体如下:
156 | struct data {
157 | char* d;
158 | };
159 |
160 | struct vdata{
161 | struct data* data;
162 | int data_len;
163 | int data_mlen; // = len + 1
164 | void* f1;
165 | void* f2;
166 | void* f3;
167 | void* f4;
168 | void* f5;
169 | void* f6;
170 | void* f7;
171 | void* f8;
172 | void* f9;
173 | void* f10;
174 | void* f11;
175 | };
176 |
177 | 跳转到跳转到0x858c2处继续执行
178 | ///////////////////////////////////////////////////////////////////////////////////////
179 | 后继续执行libsgmainso_6.4.176.so:B3BB15D0 create_vdata(我给重命名为create_vdata,见逆向代码create_vdata)
180 | debug024:AD3A1858 DCB 0 ; mmaloca
181 | mma
182 | debug024:AD3A1970 DCB 0 ; mmallocb
183 | mmb
184 | ////////////////////////////////////////////////////////////////////////////////////////
185 | libsgmainso_6.4.176.so:B3BAA91C BLX R3
186 | r0 = ma = debug014:ACC1CFC8 DCD 0xA40082F8 ; mallocA
187 | r1 = libsgmainso_6.4.176.so:B3BAAA48 aDcoLckHM3cQ DCB "DcO/lcK+h?m3c*q@",0
188 | r2 = 0x10
189 | blx rx = libsgmainso_6.4.176.so:B3BB134C sub_B3BB134C 被我重命名为 make_data
190 | 详细见make_data.c
191 | 第一次执行
192 | va = ma + 4 = 0;
193 | vb = ma + 8 = 0x11
194 | memcpy(mb, r1, 0x10); mb = "DcO/lcK+h?m3c*q@" // 分析是rc4的初始key
195 | ma + 4 = 0x10
196 |
197 | 对应调试内存
198 | debug014:ACC1CFC8 DCD 0xA40082F8 ; mallocA
199 | debug014:ACC1CFCC DCD 0x10
200 | debug014:ACC1CFD0 DCD 0x11
201 | debug014:ACC1CFD4 DCD 0xB3BB134D
202 | debug014:ACC1CFD8 DCD 0xB3BB14D3
203 | debug014:ACC1CFDC DCD 0xB3BB1393
204 | debug014:ACC1CFE0 DCD 0xB3BB13F5
205 | debug014:ACC1CFE4 DCD 0xB3BB1413
206 | debug014:ACC1CFE8 DCD 0xB3BB144B
207 | debug014:ACC1CFEC DCD 0xB3BB1469
208 | debug014:ACC1CFF0 DCD 0xB3BB14AD
209 | debug014:ACC1CFF4 DCD 0xB3BB1501
210 | debug014:ACC1CFF8 DCD 0xB3BB1513
211 | debug014:ACC1CFFC DCD 0xB3BB1529
212 | //////////////////////////////////////////////////////////////////////////////////////
213 | libsgmainso_6.4.176.so:B3BAA968 MOV R4, R1走到这里对应文件0x85968
214 | 对栈[stack]:BEC335A8 DCD memset,长度232个字节,memset(BEC335A8, 0x35, 0xe8)
215 | 对栈[stack]:BEC335A8 DCD memset,长度21个字节,memset(BEC335A8, 0, 0x15)
216 |
217 | 继续执行libsgmainso_6.4.176.so:B3BAA98A BLX R3,实际是跳转到make_data
218 | r0 = mma = debug024:AD3A1858 DCB 0x70 ; mmaloca
219 | ===========================================================================
220 | .text:00084AB9 DCD 0x3D21A7F9
221 | .text:00084ABD DCD 0x77FE3E8C
222 | .text:00084AC1 DCD 0x2ADB4018
223 | .text:00084AC5 DCD 0xF9C54AAD
224 | .text:00084AC9 DCD 0x547556A1
225 | .text:00084ACD DCD 0xA6C7BE23
226 | .text:00084AD1 DCD 0x8EEC357A
227 | .text:00084AD5 DCD 0x117405B2
228 | .text:00084AD9 DCD 0x6E7F5893
229 | .text:00084ADD DCD 0x9D4FE33A
230 | .text:00084AE1 DCD 0x6B7E0354
231 | .text:00084AE5 DCD 0xE35B1BFA
232 | .text:00084AE9 DCD 0xF902C1F8
233 | ==========================================================================
234 | r1 = libsgmainso_6.4.176.so:B3BA9AB9 loc_B3BA9AB8 ,对应文件偏移0x84AB9
235 | r2 = 0x34,52个字节
236 |
237 | va = ma + 4 = 0;
238 | vb = ma + 8 = 0x35
239 | memcpy(mb, r1, 0x10); mmb = B3BA9AB9
240 | ma + 4 = 0x34
241 |
242 | 对应测试内存
243 | debug024:AD3A1858 DCD 0xAD3A1970 ; mmaloca
244 | debug024:AD3A185C DCD 0x34
245 | debug024:AD3A1860 DCD 0x35
246 | debug024:AD3A1864 DCD 0xB3BB134D
247 | debug024:AD3A1868 DCD 0xB3BB14D3
248 | debug024:AD3A186C DCD 0xB3BB1393
249 | debug024:AD3A1870 DCD 0xB3BB13F5
250 | debug024:AD3A1874 DCD 0xB3BB1413
251 | debug024:AD3A1878 DCD 0xB3BB144B
252 | debug024:AD3A187C DCD 0xB3BB1469
253 | debug024:AD3A1880 DCD 0xB3BB14AD
254 | debug024:AD3A1884 DCD 0xB3BB1501
255 | debug024:AD3A1888 DCD 0xB3BB1513
256 | debug024:AD3A188C DCD 0xB3BB1529
257 |
258 | 继续进入.text:00074FEC sub_74FEC
259 | libsgmainso_6.4.176.so:B3BAA9A4 BL sub_B3B99FEC, 被我重命名为decrypto
260 | 详细见decrypto.c
261 | 传递两个参数(一个代表待解密结构体,一个代表返回码),应该是解密算法,内置n种解密算法如rc4、解压缩等
262 | r0 = BEC33560
263 | r1 = BEC3357C
264 |
265 | 先进入case 3:
266 | 被我重命名为call_rc4,详细见逆向的代码;
267 | 里面实际上就是调用了rc4算法解密,上面的mma数据(mma未被解密,而是重新拷贝一个结构体用于解密)
268 | r0 = ma = ACC1CFC8, r1 = mma = AD3A1858
269 |
270 | 首先创建vdatac拷贝mma数据内容
271 | debug120:A41BB158 DCB 0x20 ; vdatac
272 | debug120:A41BB120 DCB 0 ; decryptedata
273 | [stack]:BEC333F8 DCB 0 ; swapkey
274 | char buf[264];
275 | memset(buf, 0, 264); // 实际只用256,算法里面是buf+8开始的
276 | init_rc4key(swapkey, vdata->data, vata->data_len);
277 | rc4_(swapkey, cryptedata->data_len, cryptedata->data, decrypted_data->data);
278 | 解密后字符串
279 | com/taobao/wireless/security/adapter/umid/UmidAdapter
280 |
281 | 继续执行到
282 | libsgmainso_6.4.176.so:A40AA9D0 BX R10 = A40AA9E9
283 | 执行memcpy把解密字符串拷贝到栈上
284 | libsgmainso_6.4.176.so:A40AA9FC LDR R0, [SP,#8]
285 | libsgmainso_6.4.176.so:A40AA9FE BLX memcpy
286 | [stack]:BEC335A8 DCB 0
287 |
288 | 执行free把之前解密的数据释放掉
289 | libsgmainso_6.4.176.so:A40AAA06 BL free__
290 | 继续free掉之前的vdata结构体
291 |
292 | com/taobao/wireless/security/adapter/umid/UmidAdapter这个类也没有,又遇到上面提到的问题
293 | 調用env->findclass找到UmidAdapterClass,調用env->NewGlobalRef UmidAdapterRef
294 | 調用env->DeleteLocalRef, 刪除UmidAdapterClass,wtf?
295 | BL goto_decrypt_entry(, , 16)
296 | 解密出"umidInitAdapter"
297 | 調用env->getStaticMethodID(UmidAdapterRef, "umidInitAdapter")
298 | 繼續解密出"com/taobao/wireless/security/adapter/JNICLibrary"
299 |
--------------------------------------------------------------------------------
/libsg6.4.176/make_data.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | vdata* make_data(vdata *old_vdata, char* databuf, int new_len)
14 | { // 创建数据
15 | // vdata结构相当于一个数据容器
16 | // 完成向容器中添加数据
17 |
18 | // 第一次执行示例
19 | // va = ma + 4 = 0;
20 | // vb = ma->data_mlen = 0x11
21 | // memcpy(r1, mb, 0x10); 第一次mb = "DcO/lcK+h?m3c*q@"
22 | // ma->data_len = data_mlen -1;
23 |
24 | if ( old_vdata && databuf && new_len >= 1 ) {
25 | old_data_len = old_vdata->data_len;
26 |
27 | if ( (int)(old_data_len + new_len) >= old_vdata->data_mlen ) {
28 |
29 | old_vdata = (vdata *)extend_vdata(old_vdata, new_len);
30 | if ( (int)old_vdata < 0 )
31 | return old_vdata;
32 | }
33 |
34 | memcpy((char *)old_vdata->data + old_data_len, databuf, new_len);
35 | old_vdata->data_len = (int)(old_vdata->data_len + new_len);
36 | }
37 | return old_vdata;
38 | }
--------------------------------------------------------------------------------
/libsg6.4.176/vdata.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | struct data {
14 | char* d;
15 | };
16 |
17 | struct vdata_64176 { // 對應版本6.4.176
18 | struct data* data;
19 | int data_len;
20 | int data_mlen; // = len + 1
21 | void* f1;
22 | void* f2;
23 | void* f3;
24 | void* f4;
25 | void* f5;
26 | void* f6;
27 | void* f7;
28 | void* f8;
29 | void* f9;
30 | void* f10;
31 | void* f11;
32 | };
33 |
34 | struct vdata_6436_nest {
35 | void* nf1;
36 | void* nf2;
37 | void* nf3;
38 | };
39 |
40 | struct vdata_6436 { // 對應版本6.4.36
41 | struct data* data;
42 | int data_len;
43 | int data_mlen; // = len + 1
44 | void* f1;
45 | void* f2;
46 | void* f3;
47 | void* f4;
48 | void* f5;
49 | void* f6;
50 | void* f7;
51 | void* f8;
52 | struct vdata_6436_nest* nest;
53 | };
54 |
55 | struct dcryptdata {
56 | void* v;
57 | int caseno;
58 | void* v1;
59 | void* decryptdata_;
60 | struct vdata* key;
61 | struct vdata* cryptedata;
62 | };
63 |
64 | struct vdata32_nest {
65 | void* nf1;
66 | void* nf2;
67 | void* nf3;
68 | void* nf4;
69 | };
70 |
71 | struct vdata32 {
72 | struct data* data128;
73 | int data_count;
74 | int chunk_size;
75 | void* f1; // goto_make_vdata32;
76 | struct vdata32_nest* nest;
77 | };
78 |
79 | struct global_command_entry { // 記錄著生成和執行command的核心方法
80 | void* goto_make_command_entry; // 對應sub_9B3C
81 | void* goto_do_command1; // // 對應sub_9d82; command_native_inner
82 | void* goto_do_command2; // 對應sub_9e7e; 和sub_9d82差不多
83 | };
84 |
85 | struct command_nest {
86 | void* nf1;
87 | void* nf2;
88 | int len;
89 | };
90 |
91 | struct command_vdata {
92 | struct data** datalist; // 第一層$8bitstruct
93 | int data_count;
94 | int data_size;
95 | void* f1;
96 | void* f2; // make_vdata
97 | void* f3;
98 | struct command_nest* nest;
99 | };
100 |
101 | struct $8bitstruct { // 第一層結構
102 | int command_arg1; // command arg1
103 | struct command_vdata* vdata; // 指向第二層
104 | };
105 |
106 | struct $24bitstruct { // 第二層結構
107 | int command_arg1; // command arg1
108 | int command_arg2; // command arg2
109 | long time;
110 | int c; // (time >> 31)
111 | struct command_vdata* vdata; // 指向第三層
112 | int d; // 未知
113 | };
114 |
115 | struct $16bitstruct { // 第三層結構
116 | int command_arg1; // command arg1
117 | int command_arg2; // command arg2
118 | int command_arg3; // command arg3
119 | int xoraddr;
120 | };
121 |
122 | struct command_arg {
123 | int arg1;
124 | int arg2;
125 | int arg3;
126 | _JNIEnv* env;
127 | void* args;
128 | };
129 |
130 | struct vstring {
131 | int len;
132 | char* str;
133 | };
134 |
--------------------------------------------------------------------------------
/libsg6.4.36/breaklist.idc:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | static main(void)
14 | { // 所有JNI_OnLoad 函數,以及我認爲重要的函數斷點
15 | auto bpt;
16 |
17 | auto libsgmain_base = 0;
18 | auto base = GetFirstModule();
19 | auto name = GetModuleName(base);
20 | auto size = GetModuleSize(base);
21 |
22 | while(1) {
23 | base = GetNextModule(base);
24 | name = GetModuleName(base);
25 | size = GetModuleSize(base);
26 | if (strstr (name, "libsgmainso-6.4.36.so") != -1) {
27 | libsgmain_base = base;
28 | Message("libsgmain_base = %x\n", libsgmain_base);
29 | break;
30 | }
31 | }
32 |
33 | bpt = Breakpoint();
34 | bpt.set_abs_bpt(libsgmain_base + 0x7B86C); // create_command_vdata
35 | Breakpoints.Add(bpt);
36 | Message("call create_command_vdata %x\n", (libsgmain_base + 0x7B86C));
37 |
38 | bpt = Breakpoint();
39 | bpt.set_abs_bpt(libsgmain_base + 0x73ed8); // goto_dcrypto
40 | Breakpoints.Add(bpt);
41 | Message("call goto_dcrypto %x\n", (libsgmain_base + 0x73ed8));
42 |
43 | bpt = Breakpoint();
44 | bpt.set_abs_bpt(libsgmain_base + 0x73eec); // memcpy
45 | Breakpoints.Add(bpt);
46 | Message("call memcpy %x\n", (libsgmain_base + 0x73eec));
47 |
48 | bpt = Breakpoint();
49 | bpt.set_abs_bpt(libsgmain_base + 0x9a14); // build_command
50 | Breakpoints.Add(bpt);
51 | Message("call build_command %x\n", (libsgmain_base + 0x9a14));
52 |
53 | bpt = Breakpoint();
54 | bpt.set_abs_bpt(libsgmain_base + 0x9D82); // do_command_native_inner
55 | Breakpoints.Add(bpt);
56 | Message("call memcpy %x\n", (libsgmain_base + 0x9D82));
57 |
58 |
59 | bpt = Breakpoint();
60 | bpt.set_abs_bpt(libsgmain_base + 0x7C4F4); // 創建全局objects
61 | Breakpoints.Add(bpt);
62 |
63 | bpt = Breakpoint();
64 | bpt.set_abs_bpt(libsgmain_base + 0x7C5B0); // goto_getEnv
65 | Breakpoints.Add(bpt);
66 |
67 | bpt = Breakpoint();
68 | bpt.set_abs_bpt(libsgmain_base + 0x72CCC); // goto_do_httpuitl
69 | Breakpoints.Add(bpt);
70 |
71 | bpt = Breakpoint();
72 | bpt.set_abs_bpt(libsgmain_base + 0x73634); // goto_do_umidAdapter
73 | Breakpoints.Add(bpt);
74 |
75 | bpt = Breakpoint();
76 | bpt.set_abs_bpt(libsgmain_base + 0x73E24); // goto_decrypt_entry
77 | Breakpoints.Add(bpt);
78 |
79 | bpt = Breakpoint();
80 | bpt.set_abs_bpt(libsgmain_base + 0xb534);
81 | Breakpoints.Add(bpt);
82 |
83 | bpt = Breakpoint();
84 | bpt.set_abs_bpt(libsgmain_base + 0xb538);
85 | Breakpoints.Add(bpt);
86 |
87 | bpt = Breakpoint();
88 | bpt.set_abs_bpt(libsgmain_base + 0x69D68);
89 | Breakpoints.Add(bpt);
90 |
91 | bpt = Breakpoint();
92 | bpt.set_abs_bpt(libsgmain_base + 0x197B4); // goto_do_DataReportJniBridgerer
93 | Breakpoints.Add(bpt);
94 |
95 | bpt = Breakpoint();
96 | bpt.set_abs_bpt(libsgmain_base + 0xE240);
97 | Breakpoints.Add(bpt);
98 |
99 | bpt = Breakpoint();
100 | bpt.set_abs_bpt(libsgmain_base + 0x9EE4);
101 | Breakpoints.Add(bpt);
102 |
103 | bpt = Breakpoint();
104 | bpt.set_abs_bpt(libsgmain_base + 0x71D68); // goto_do_SPUtility2
105 | Breakpoints.Add(bpt);
106 |
107 | bpt = Breakpoint();
108 | bpt.set_abs_bpt(libsgmain_base + 0xE7DC); // DeviceInfoCapturer
109 | Breakpoints.Add(bpt);
110 |
111 |
112 | bpt = Breakpoint();
113 | bpt.set_abs_bpt(libsgmain_base + 0xB8B0);
114 | Breakpoints.Add(bpt);
115 |
116 | bpt = Breakpoint();
117 | bpt.set_abs_bpt(libsgmain_base + 0x5F0F4);
118 | Breakpoints.Add(bpt);
119 |
120 | bpt = Breakpoint();
121 | bpt.set_abs_bpt(libsgmain_base + 0x70640);
122 | Breakpoints.Add(bpt);
123 |
124 | bpt = Breakpoint();
125 | bpt.set_abs_bpt(libsgmain_base + 0x11F3C); // android 原生類處理, context pm pkgmgr appinfo
126 | Breakpoints.Add(bpt);
127 |
128 |
129 | bpt = Breakpoint();
130 | bpt.set_abs_bpt(libsgmain_base + 0x21C3C);
131 | Breakpoints.Add(bpt);
132 |
133 | bpt = Breakpoint();
134 | bpt.set_abs_bpt(libsgmain_base + 0x2148C);
135 | Breakpoints.Add(bpt);
136 |
137 | bpt = Breakpoint();
138 | bpt.set_abs_bpt(libsgmain_base + 0x210E0);
139 | Breakpoints.Add(bpt);
140 |
141 | bpt = Breakpoint();
142 | bpt.set_abs_bpt(libsgmain_base + 0x41B58);
143 | Breakpoints.Add(bpt);
144 |
145 | bpt = Breakpoint();
146 | bpt.set_abs_bpt(libsgmain_base + 0x27920);
147 | Breakpoints.Add(bpt);
148 |
149 |
150 | bpt = Breakpoint();
151 | bpt.set_abs_bpt(libsgmain_base + 0x29918);
152 | Breakpoints.Add(bpt);
153 |
154 | bpt = Breakpoint();
155 | bpt.set_abs_bpt(libsgmain_base + 0x293E8); // unZip android pm appinfo
156 | Breakpoints.Add(bpt);
157 |
158 | bpt = Breakpoint();
159 | bpt.set_abs_bpt(libsgmain_base + 0x208F4); // do UserTrackMethodJniBridge
160 | Breakpoints.Add(bpt);
161 |
162 | bpt = Breakpoint();
163 | bpt.set_abs_bpt(libsgmain_base + 0xB7B0); // env->registerNatives
164 | Breakpoints.Add(bpt);
165 |
166 | bpt = Breakpoint();
167 | bpt.set_abs_bpt(libsgmain_base + 0xB69C); // doCommandNative
168 | Breakpoints.Add(bpt);
169 |
170 | bpt = Breakpoint();
171 | bpt.set_abs_bpt(libsgmain_base + 0x9D60); // goto_docommand_native_inner
172 | Breakpoints.Add(bpt);
173 |
174 | }
175 |
--------------------------------------------------------------------------------
/libsg6.4.36/doCommandNative.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int doCommandNative(JNIEnv *env, jobject obj, int command, jarray args)
14 | { // sub_B6F6
15 | int v5; // r5
16 | struc_2 *a5; // r6
17 | int v9; // r1
18 | int v11; // [sp+Ch] [bp-14h]
19 | int v12; // [sp+10h] [bp-10h]
20 | v5 = 0;
21 | v12 = *(_DWORD *)off_8AC00;
22 | v11 = 0;
23 | a5 = (struc_2 *)malloc(0x14u);
24 | if ( a5 )
25 | {
26 | a5->field_0 = 0;
27 | a5->field_4 = 0;
28 | a5->field_8 = 0;
29 | a5->field_C = 0;
30 | v9 = command % 10000 / 100;
31 | a5->field_0 = command / 10000;
32 | a5->field_4 = v9;
33 | a5->field_8 = command % 100;
34 | a5->field_C = env;
35 | a5->field_10 = args;
36 | v5 = goto_docommand_native_inner(command / 10000, v9, command % 100, 1, (int)a5, &v11);
37 | }
38 | free(v8);
39 | if ( !v5 && v22 )
40 | goto_throw_exception(v4, v22, (int)&byte_83ED7);
41 | if ( *(_DWORD *)off_8AC00 != v23 )
42 | _stack_chk_fail(*(_DWORD *)off_8AC00 - v23, v23);
43 | return v5;
44 | }
45 |
46 | 對著匯編逆向分析:
47 | struct command_arg {
48 | int arg1;
49 | int arg2;
50 | int arg3;
51 | JNIEnv* env;
52 | void* args;
53 | };
54 |
55 | int sub_B6F6(JNIEnv *env, jobject obj, int command, jarray args)
56 | { // doCommandNative
57 | int v4; // r8@1
58 | int v5; // r5@1
59 | int v6; // r9@1
60 | struct command_arg* v8; // r6@1
61 | int v17; // r0@2
62 | int v20; // r1@2
63 | int v22; // [sp+Ch] [bp-14h]@1
64 | int v23; // [sp+10h] [bp-10h]@1
65 |
66 | v4 = a1;
67 | v5 = 0;
68 | v6 = a4;
69 | _R4 = a3; // 10601
70 | v23 = *(_DWORD *)off_8AC00;
71 | v22 = 0;
72 | command_arg = (struct command_arg*) malloc(0x14u);
73 | if ( command_arg )
74 | {
75 | // 以一次調試爲例
76 | int _R4 = 12302; // command
77 | int _R0 = 0x68DB8BAD; // 68DB8BAD
78 | int _R2 = 0x51EB851F; // 51EB851F
79 |
80 | int r0 = _R0 * _R4; // 000013AE, SMMUL.W取高位
81 | int r3 = _R2 * _R4; // 00000F60, SMMUL.W取高位
82 | // (signed int)r0 >> 0xc) = (signed int) (13AE >> 0xc) = 00000001
83 | // r0 >> 31 = 0
84 | r0 = ((signed int)r0 >> 0xc) + (r0 >> 31); // 0x1, 參數1
85 | int r1 = _R4 - r0 * 10000 ; // 000008FE(2302)
86 | r1 = _R4 * r1; // 2E0, SMMUL.W取高位
87 | // ((signed int)r3 >> 5) = 0000007B(123)
88 | // (r3 >> 31) = 0
89 | r2 = _R4 - (((signed int)r3 >> 5) + (r3 >> 31)) * 100; // 2, 參數3
90 | r3 = (signed) r1 >> 5 = 00000017(23)
91 | r1 = r3 + (r1 >> 31) = 1; // 0x17, 參數2
92 |
93 | command_arg->arg1 = 1;
94 | command_arg->arg2 = 0x17;
95 | command_arg->arg3 = 2;
96 | command_arg->env = env;
97 | command_arg->args = args;
98 |
99 | v5 = sub_9D60(r0, r1, r2, 1, command_arg, v22);
100 | }
101 | free(command_arg);
102 | if ( !v5 && v22 )
103 | sub_7CF34(v4);
104 | if ( *(_DWORD *)off_8AC00 != v23 )
105 | _stack_chk_fail(*(_DWORD *)off_8AC00 - v23);
106 | return v5;
107 | }
108 |
109 | goto_docommand_native_inner
110 | sub_9D60->sub_9D82
111 | docommand_native_inner
--------------------------------------------------------------------------------
/libsg6.4.36/jni_load.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int __fastcall real_JNI_OnLoad(JavaVM *vm) {
14 | int result; // r0
15 | jclass clazz; // r0 MAPDST
16 | int v4; // r0
17 | JNIEnv *env; // r4
18 | int v6; // [sp-40h] [bp-5Ch]
19 | int v7; // [sp+Ch] [bp-10h]
20 | v7 = *(_DWORD *)off_8AC00;
21 | if ( !vm )
22 | goto LABEL_39;
23 | sub_7C4F4(); // 創建全局 jboolean, jinteger、jstring
24 | env = (JNIEnv *)sub_7C5B0(0); // 獲取env, goto_getenv()
25 | if ( !env )
26 | goto LABEL_39;
27 | v4 = sub_72CCC(); // goto_do_httpuitl
28 | sub_73634(v4); // goto_do_umidAdapter
29 | sub_73E24(&unk_83EA6, &v6, 49); // goto_decrypt_entry
30 | clazz = (jclass)((int (__fastcall *)(JNIEnv *, int *))(*env)->FindClass)(env, &v6);
31 | if ( clazz &&
32 | (sub_9EE4(), // goto_create_tmp1vdata_
33 | sub_71D68(env), // goto_do_SPUtility2
34 | sub_E7DC(env) >= 0 // 處理了DeviceInfoCapturer,pack_or_unpack_command
35 | && sub_69D68(env) >= 0 // 啥也沒乾
36 | && sub_197B4(env, clazz) >= 0 // 處理了DataReportJniBridgerer,pack_or_unpack_command
37 | && sub_E240(env, clazz) >= 0 // pack_or_unpack_command
38 | && sub_B8B0(env, clazz) >= 0 // pack_or_unpack_command
39 | && sub_5F0F4(env, clazz) >= 0 // pack_or_unpack_command
40 | && sub_70640(env, clazz) >= 0 // pack_or_unpack_command
41 | && sub_11F3C(env) >= 0 // 處理android相關類
42 | && sub_21C3C(env, clazz) >= 0 // pack_or_unpack_command
43 | && sub_2148C(env, clazz) >= 0 // pack_or_unpack_command
44 | && sub_210E0(env, clazz) >= 0 // pack_or_unpack_command
45 | && sub_41B58(env, clazz) >= 0 // pack_or_unpack_command
46 | && sub_27920(env, clazz) >= 0 // pack_or_unpack_command
47 | && sub_293E8(env, clazz) >= 0 // 處理ZipUtils、CallbackHelper和android相關類
48 | && sub_208F4(env, clazz) >= 0) ) // 處理UserTrackMethodJniBridge
49 | {
50 | result = (sub_B7B0(env, clazz) >> 31) | 0x10004; // 注冊doCommandNaitve
51 | } else {
52 | LABEL_39:
53 | result = -1;
54 | }
55 | return result;
56 | }
--------------------------------------------------------------------------------
/libsg6.4.36/libsgmainso-6.4.36分析:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | libsgmainso-6.4.36邏輯分析
14 |
15 | //////////////////////////////////////////////////////////////
16 |
17 | 難點:
18 |
19 | 動態跳轉
20 | 動態生成參數,參數變形
21 | 函數隱藏(需要通過一個類似的梉跳過去,函數地址加密)
22 | 函數前面加一段垃圾代碼
23 | 字符串加密
24 | 部分關鍵代碼存在llvm混淆
25 | 垃圾代碼,靜態分析對抗,擾亂ida分析
26 | 多種加密算法
27 | 核心函數如進入到do_command_native的函數不是連續的,函數的連續性被記錄到一系列的
28 | 結構體中,下一個塊需要的獲取需要重新執行do_command_inner
29 |
30 |
31 | LOAD:0000B110 JNI_OnLoad
32 | LOAD:0000B110
33 | LOAD:0000B110 var_4 = -4
34 | LOAD:0000B110 07 B5 PUSH {R0-R2,LR}
35 | LOAD:0000B112 07 A1 ADR R1, 0xB130 // B130
36 | LOAD:0000B114 09 00 MOVS R1, R1
37 | LOAD:0000B116 05 39 SUBS R1, #5 // B130 - 0X5 = B12B
38 | LOAD:0000B118 00 00 MOVS R0, R0
39 | LOAD:0000B11A 08 00 MOVS R0, R1 // B12B
40 | LOAD:0000B11C 12 00 MOVS R2, R2
41 | LOAD:0000B11E 10 30 ADDS R0, #0x10 // B12B + 0X10 = B13B
42 | LOAD:0000B120 03 90 STR R0, [SP,#0xC] // SP + 0XC = R0 = B13B
43 | LOAD:0000B122 07 BD POP {R0-R2,PC} // PC = sp + 0xc = B13B, thumb指令跳转到0000B13A
44 |
45 | 执行完上述代码,r0,r1,r2,lr值不变,变的仅仅是pc,cpu会马上执行pc处的指令
46 |
47 | =================================================================================================
48 | 代码段共56处匹配这样的特征,想办法patch这样的逻辑
49 | patch 后
50 | LOAD:0000B110 JNI_OnLoad
51 | LOAD:0000B122 B loc_B13A
52 | ===================================================================================================
53 |
54 | 因为是thumb指令,地址起始奇数
55 | LOAD:0000B13A ; ---------------------------------------------------------------------------
56 | 特徵
57 | LOAD:0000B13A CODE16
58 | LOAD:0000B13A PUSH {R0,R1,LR}
59 | LOAD:0000B13C LDR R0, =8
60 | LOAD:0000B13E LDR R1, loc_B140 // 沒有意義, nop掉
61 | LOAD:0000B140
62 | LOAD:0000B140 loc_B140
63 | LOAD:0000B140 BLX sub_494C /// 分发器
64 | LOAD:0000B140 ; ---------------------------------------------------------------------------
65 | LOAD:0000B144 dword_B144 DCD 8
66 | -------------------------------------------------------------------------------------------
67 | 跳轉表,共40個跳轉, 計算pc時的纍加值:
68 | LOAD:0000B144
69 | LOAD:0000B144 ;第一個index = 8
70 | LOAD:0000B144 ; 找到8對應的偏移,它下一個index即下一個邏輯
71 | LOAD:0000B148 A8 00 00 00 DCD 0xA8 ; b1ec
72 | LOAD:0000B14C BC 00 00 00 DCD 0xBC ; b200
73 | LOAD:0000B150 CC 00 00 00 DCD 0xCC ; b120
74 | LOAD:0000B154 E0 00 00 00 DCD 0xE0 ; b224
75 | LOAD:0000B158 F0 00 00 00 DCD 0xF0 ; b234
76 | LOAD:0000B15C 00 01 00 00 DCD 0x100 ; b244
77 | LOAD:0000B160 10 01 00 00 DCD 0x110 ; b254
78 | LOAD:0000B164 20 01 00 00 DCD 0x120 ; b264 偏移為8,表值為0x120,第一個對應lr + off = b144 + 0x120
79 | LOAD:0000B168 34 01 00 00 DCD 0x134 ; b278
80 | LOAD:0000B16C 4C 01 00 00 DCD 0x14C ; b290
81 | LOAD:0000B170 68 01 00 00 DCD 0x168 ; b2ac
82 | LOAD:0000B174 7C 01 00 00 DCD 0x17C ; b2c0
83 | LOAD:0000B178 94 01 00 00 DCD 0x194 ; b2d8
84 | LOAD:0000B17C AC 01 00 00 DCD 0x1AC ; b2f0
85 | LOAD:0000B180 D4 01 00 00 DCD 0x1D4 ; b318
86 | LOAD:0000B184 EC 01 00 00 DCD 0x1EC ; b330
87 | LOAD:0000B188 08 02 00 00 DCD 0x208 ; b34c
88 | LOAD:0000B18C 24 02 00 00 DCD 0x224 ; b368
89 | LOAD:0000B190 40 02 00 00 DCD 0x240 ; b384
90 | LOAD:0000B194 68 02 00 00 DCD 0x268 ; b3ac
91 | LOAD:0000B198 7C 02 00 00 DCD 0x27C ; b3c0
92 | LOAD:0000B19C 90 02 00 00 DCD 0x290 ; b3d4
93 | LOAD:0000B1A0 A4 02 00 00 DCD 0x2A4 ; b3e0
94 | LOAD:0000B1A4 B8 02 00 00 DCD 0x2B8 ; b3fc
95 | LOAD:0000B1A8 CC 02 00 00 DCD 0x2CC ; b410
96 | LOAD:0000B1AC E0 02 00 00 DCD 0x2E0 ; b424
97 | LOAD:0000B1B0 FC 02 00 00 DCD 0x2FC ; b440
98 | LOAD:0000B1B4 10 03 00 00 DCD 0x310 ; b454
99 | LOAD:0000B1B8 24 03 00 00 DCD 0x324 ; b468
100 | LOAD:0000B1BC 3C 03 00 00 DCD 0x33C ; b480
101 | LOAD:0000B1C0 58 03 00 00 DCD 0x358 ; b49c
102 | LOAD:0000B1C4 6C 03 00 00 DCD 0x36C ; b4b0
103 | LOAD:0000B1C8 90 03 00 00 DCD 0x390 ; b4d4
104 | LOAD:0000B1CC AC 03 00 00 DCD 0x3AC ; b4f0
105 | LOAD:0000B1D0 C4 03 00 00 DCD 0x3C4 ; b508
106 | LOAD:0000B1D4 D8 03 00 00 DCD 0x3D8 ; b51c
107 | LOAD:0000B1D8 F0 03 00 00 DCD 0x3F0 ; b534
108 | LOAD:0000B1DC 14 04 00 00 DCD 0x414 ; b558
109 | LOAD:0000B1E0 28 04 00 00 DCD 0x428 ; b56c
110 | LOAD:0000B1E4 40 04 00 00 DCD 0x440 ; b584
111 | LOAD:0000B1E8 5C 04 00 00 DCD 0x45C ; b5a0
112 | -------------------------------------------------------------------------------------------------------------
113 | 以第一次跳轉為例:
114 | LOAD:0000494C sub_494C
115 | LOAD:0000494C arg_8 = 8
116 | LOAD:0000494C BIC R1, LR, #1 // LR = B144 , 最低一位清零 R1 还是B144
117 | //LOAD:0000B164 DCD 0x120
118 | LOAD:00004950 00 11 91 E7 LDR R1, [R1,R0,LSL#2] // R1 = [B144 + 0x8 << 2] = [B144 + 0X20] = [B164] = 0x120
119 | LOAD:00004954 ADD R1, R1, LR // R1 = B144 + 0x120 = B264
120 | LOAD:00004958 LDR LR, [SP,#8] // LR = B144
121 | LOAD:0000495C STR R1, [SP,#8] // B264
122 | LOAD:00004960 03 80 BD E8 LDMFD SP!, {R0,R1,PC} // R0 = [SP], R1 = [SP + 4], PC = [SP + 8] 跳转到B264
123 | 隨便列舉幾個跳轉:
124 | 1 = 0xb264
125 | 2 = 0x1511c
126 | 3 = 0x24764
127 | 4 = 0x5f2ac
128 | 5 = 0x71e70
129 | 6 = 0x72dbc
130 | 7 = 0x9a14
131 | ...
132 | ---------------------------------------------------------------------------------------------
133 | 其他混淆跳轉輔助指令特徵:
134 | LOAD:0000494C
135 | LOAD:0000494C ; =============== S U B R O U T I N E =======================================
136 | LOAD:0000494C
137 | LOAD:0000494C
138 | LOAD:0000494C dyna_pc ; CODE XREF: j_dyna_pcj
139 | LOAD:0000494C ; LOAD:loc_4C20p ...
140 | LOAD:0000494C
141 | LOAD:0000494C arg_8 = 8
142 | LOAD:0000494C
143 | LOAD:0000494C 01 10 CE E3 BIC R1, LR, #1
144 | LOAD:00004950 00 11 91 E7 LDR R1, [R1,R0,LSL#2] ; lr(最低位清零) + (r0 << 2)
145 | LOAD:00004954 0E 10 81 E0 ADD R1, R1, LR
146 | LOAD:00004958 08 E0 9D E5 LDR LR, [SP,#8]
147 | LOAD:0000495C 08 10 8D E5 STR R1, [SP,#8]
148 | LOAD:00004960 03 80 BD E8 LDMFD SP!, {R0,R1,PC} ; 1 = 0xb264
149 | LOAD:00004960 ; End of function dyna_pc ; 2 = 0x1511c
150 | LOAD:00004960 ; 3 = 0x24764
151 | LOAD:00004960 ; 4 = 0x5f2ac
152 | LOAD:00004960 ; 5 = 0x71e70
153 | LOAD:00004960 ; 6 = 0x72dbc
154 | LOAD:00004960 ; 7 = 0x9a14
155 | LOAD:00004960 ; ...
156 | LOAD:00004964
157 | LOAD:00004964 ; =============== S U B R O U T I N E =======================================
158 | LOAD:00004964
159 | LOAD:00004964 ; 完成pc = pc + 8
160 | LOAD:00004964 ; 待彈出寄存器值為 lr + [lr]
161 | LOAD:00004964 ; 目的是完成動態生成函數參數
162 | LOAD:00004964
163 | LOAD:00004964 dyna_mkarg ; CODE XREF: sub_4ADC:loc_4AE0j
164 | LOAD:00004964 ; LOAD:00004D16p ...
165 | LOAD:00004964
166 | LOAD:00004964 anonymous_0 = 0
167 | LOAD:00004964 arg_C = 0xC
168 | LOAD:00004964 arg_10 = 0x10
169 | LOAD:00004964
170 | LOAD:00004964 01 00 CE E3 BIC R0, LR, #1
171 | LOAD:00004968 00 10 90 E5 LDR R1, [R0]
172 | LOAD:0000496C 01 10 90 E7 LDR R1, [R0,R1]
173 | LOAD:00004970 04 E0 8E E2 ADD LR, LR, #4
174 | LOAD:00004974 0C E0 8D E5 STR LR, [SP,#0xC] ; pc = lr + 4 ,下一條指令処
175 | LOAD:00004978 10 10 8D E5 STR R1, [SP,#0x10] ; 後面pop 寄存器的值
176 | LOAD:0000497C 03 C0 BD E8 LDMFD SP!, {R0,R1,LR,PC} ; pc = pc + 8
177 | LOAD:0000497C
178 | LOAD:00004980
179 | LOAD:00004980 ; =============== S U B R O U T I N E =======================================
180 | LOAD:00004980
181 | LOAD:00004980
182 | LOAD:00004980 sub_4980 ; CODE XREF: sub_4ABC:loc_4AC0j
183 | LOAD:00004980
184 | LOAD:00004980 arg_8 = 8
185 | LOAD:00004980
186 | LOAD:00004980 01 10 CE E3 BIC R1, LR, #1
187 | LOAD:00004984 00 11 91 E7 LDR R1, [R1,R0,LSL#2]
188 | LOAD:00004988 81 00 8E E0 ADD R0, LR, R1,LSL#1
189 | LOAD:0000498C 08 E0 9D E5 LDR LR, [SP,#arg_8]
190 | LOAD:00004990 08 00 8D E5 STR R0, [SP,#arg_8]
191 | LOAD:00004994 03 80 BD E8 LDMFD SP!, {R0,R1,PC}
192 | LOAD:00004994 ; End of function sub_4980
193 | LOAD:00004994
194 | LOAD:00004998
195 | LOAD:00004998 ; =============== S U B R O U T I N E =======================================
196 | LOAD:00004998
197 | LOAD:00004998
198 | LOAD:00004998 sub_4998 ; CODE XREF: sub_4AC4:loc_4AC8j
199 | LOAD:00004998 ; LOAD:000098FCp ...
200 | LOAD:00004998
201 | LOAD:00004998 arg_8 = 8
202 | LOAD:00004998
203 | LOAD:00004998 01 00 CE E3 BIC R0, LR, #1
204 | LOAD:0000499C 00 10 90 E5 LDR R1, [R0]
205 | LOAD:000049A0 0E 10 81 E0 ADD R1, R1, LR
206 | LOAD:000049A4 08 E0 9D E5 LDR LR, [SP,#arg_8]
207 | LOAD:000049A8 08 10 8D E5 STR R1, [SP,#arg_8]
208 | LOAD:000049AC 03 80 BD E8 LDMFD SP!, {R0,R1,PC}
209 | LOAD:000049AC ; End of function sub_4998
210 | LOAD:000049AC
211 | LOAD:000049B0
212 | LOAD:000049B0 ; =============== S U B R O U T I N E =======================================
213 | LOAD:000049B0
214 | LOAD:000049B0
215 | LOAD:000049B0 sub_49B0
216 | LOAD:000049B0
217 | LOAD:000049B0 arg_C = 0xC
218 | LOAD:000049B0 arg_10 = 0x10
219 | LOAD:000049B0
220 | LOAD:000049B0 01 00 CE E3 BIC R0, LR, #1
221 | LOAD:000049B4 00 10 90 E5 LDR R1, [R0]
222 | LOAD:000049B8 00 10 81 E0 ADD R1, R1, R0
223 | LOAD:000049BC 04 E0 8E E2 ADD LR, LR, #4
224 | LOAD:000049C0 0C E0 8D E5 STR LR, [SP,#arg_C]
225 | LOAD:000049C4 10 10 8D E5 STR R1, [SP,#arg_10]
226 | LOAD:000049C8 03 C0 BD E8 LDMFD SP!, {R0,R1,LR,PC}
227 | LOAD:000049C8 ; End of function sub_49B0
228 | LOAD:000049C8
229 | LOAD:000049CC
230 | LOAD:000049CC ; =============== S U B R O U T I N E =======================================
231 | LOAD:000049CC
232 | LOAD:000049CC
233 | LOAD:000049CC sub_49CC
234 | LOAD:000049CC
235 | LOAD:000049CC var_4 = -4
236 | LOAD:000049CC
237 | LOAD:000049CC 03 40 2D E9 STMFD SP!, {R0,R1,LR}
238 | LOAD:000049D0 0E 10 A0 E1 MOV R1, LR
239 | LOAD:000049D4 A1 10 A0 E1 MOV R1, R1,LSR#1
240 | LOAD:000049D8 81 10 A0 E1 MOV R1, R1,LSL#1
241 | LOAD:000049DC 01 00 A0 E1 MOV R0, R1
242 | LOAD:000049E0 00 10 91 E5 LDR R1, [R1]
243 | LOAD:000049E4 00 10 81 E0 ADD R1, R1, R0
244 | LOAD:000049E8 00 10 91 E5 LDR R1, [R1]
245 | LOAD:000049EC 08 10 8D E5 STR R1, [SP,#0xC+var_4]
246 | LOAD:000049F0 04 E0 8E E2 ADD LR, LR, #4
247 | LOAD:000049F4 03 80 BD E8 LDMFD SP!, {R0,R1,PC}
248 | LOAD:000049F4 ; End of function sub_49CC
249 | LOAD:000049F4
250 | LOAD:000049F8
251 | LOAD:000049F8 ; =============== S U B R O U T I N E =======================================
252 | LOAD:000049F8
253 | LOAD:000049F8
254 | LOAD:000049F8 sub_49F8
255 | LOAD:000049F8
256 | LOAD:000049F8 arg_4 = 4
257 | LOAD:000049F8
258 | LOAD:000049F8 04 E0 9D E5 LDR LR, [SP,#arg_4]
259 | LOAD:000049FC 04 00 8D E5 STR R0, [SP,#arg_4]
260 | LOAD:00004A00 01 80 BD E8 LDMFD SP!, {R0,PC}
261 | LOAD:00004A00 ; End of function sub_49F8
262 | LOAD:00004A00
263 | LOAD:00004A04
264 | LOAD:00004A04 ; =============== S U B R O U T I N E =======================================
265 | LOAD:00004A04
266 | LOAD:00004A04
267 | LOAD:00004A04 sub_4A04
268 | LOAD:00004A04
269 | LOAD:00004A04 arg_C = 0xC
270 | LOAD:00004A04 arg_10 = 0x10
271 | LOAD:00004A04 arg_14 = 0x14
272 | LOAD:00004A04
273 | LOAD:00004A04 0E 10 A0 E1 MOV R1, LR
274 | LOAD:00004A08 A1 10 A0 E1 MOV R1, R1,LSR#1
275 | LOAD:00004A0C 81 10 A0 E1 MOV R1, R1,LSL#1
276 | LOAD:00004A10 01 00 A0 E1 MOV R0, R1
277 | LOAD:00004A14 00 10 91 E5 LDR R1, [R1]
278 | LOAD:00004A18 00 10 81 E0 ADD R1, R1, R0
279 | LOAD:00004A1C 00 00 91 E5 LDR R0, [R1]
280 | LOAD:00004A20 04 10 91 E5 LDR R1, [R1,#4]
281 | LOAD:00004A24 10 00 8D E5 STR R0, [SP,#arg_10]
282 | LOAD:00004A28 14 10 8D E5 STR R1, [SP,#arg_14]
283 | LOAD:00004A2C 04 E0 8E E2 ADD LR, LR, #4
284 | LOAD:00004A30 0C E0 8D E5 STR LR, [SP,#arg_C]
285 | LOAD:00004A34 03 40 BD E8 LDMFD SP!, {R0,R1,LR}
286 | LOAD:00004A38 04 F0 9D E4 LDR PC, [SP-0xC+arg_C],#4
287 | LOAD:00004A38 ; End of function sub_4A04
288 | LOAD:00004A38
289 | LOAD:00004A3C
290 | LOAD:00004A3C ; =============== S U B R O U T I N E =======================================
291 | LOAD:00004A3C
292 | LOAD:00004A3C
293 | LOAD:00004A3C sub_4A3C ; CODE XREF: sub_4AE4:loc_4AE8j
294 | LOAD:00004A3C
295 | LOAD:00004A3C var_8 = -8
296 | LOAD:00004A3C var_4 = -4
297 | LOAD:00004A3C arg_8 = 8
298 | LOAD:00004A3C
299 | LOAD:00004A3C 04 70 2D E5 STR R7, [SP,#-4]!
300 | LOAD:00004A40 00 70 0F E1 MRS R7, CPSR
301 | LOAD:00004A44 04 20 2D E5 STR R2, [SP,#-4]!
302 | LOAD:00004A48 01 10 CE E3 BIC R1, LR, #1
303 | LOAD:00004A4C 80 01 B1 E7 LDR R0, [R1,R0,LSL#3]!
304 | LOAD:00004A50 04 10 91 E5 LDR R1, [R1,#4]
305 | LOAD:00004A54 00 00 51 E3 CMP R1, #0
306 | LOAD:00004A58 0E 00 00 0A BEQ loc_4A98
307 | LOAD:00004A5C 01 00 11 E3 TST R1, #1
308 | LOAD:00004A60 7F 20 A0 13 MOVNE R2, #0x7F ; ''
309 | LOAD:00004A64 21 22 02 10 ANDNE R2, R2, R1,LSR#4
310 | LOAD:00004A68 02 00 40 10 SUBNE R0, R0, R2
311 | LOAD:00004A6C 02 00 11 E3 TST R1, #2
312 | LOAD:00004A70 7F 20 A0 13 MOVNE R2, #0x7F ; ''
313 | LOAD:00004A74 A1 25 02 10 ANDNE R2, R2, R1,LSR#11
314 | LOAD:00004A78 02 00 80 10 ADDNE R0, R0, R2
315 | LOAD:00004A7C 04 00 11 E3 TST R1, #4
316 | LOAD:00004A80 FF 20 A0 13 MOVNE R2, #0xFF
317 | LOAD:00004A84 21 29 02 10 ANDNE R2, R2, R1,LSR#18
318 | LOAD:00004A88 02 00 20 10 EORNE R0, R0, R2
319 | LOAD:00004A8C 01 2E A0 E1 MOV R2, R1,LSL#28
320 | LOAD:00004A90 C2 0F 20 E0 EOR R0, R0, R2,ASR#31
321 | LOAD:00004A94 21 0D 80 E0 ADD R0, R0, R1,LSR#26
322 | LOAD:00004A98
323 | LOAD:00004A98 loc_4A98 ; CODE XREF: sub_4A3C+1Cj
324 | LOAD:00004A98 0E 00 80 E0 ADD R0, R0, LR
325 | LOAD:00004A9C 04 20 9D E4 LDR R2, [SP],#4
326 | LOAD:00004AA0 07 F0 29 E1 MSR CPSR_cf, R7
327 | LOAD:00004AA4 04 70 9D E4 LDR R7, [SP],#4
328 | LOAD:00004AA8 08 E0 9D E5 LDR LR, [SP,#8]
329 | LOAD:00004AAC 08 00 8D E5 STR R0, [SP,#8]
330 | LOAD:00004AB0 03 80 BD E8 LDMFD SP!, {R0,R1,PC}
331 | LOAD:00004AB0 ; End of function sub_4A3C
332 |
333 | ----------------------------------------------------------------------------------------------
334 | 在拿一個調整表做例子:
335 | LOAD:00009884 01 48 LDR R0, =5
336 | LOAD:00009888 FB F7 60 E8 BLX dyna_pc
337 | LOAD:0000988C 05 00 00 00 dword_988C DCD 5
338 | LOAD:00009890 1C 00 00 00 DCD 0x1C
339 | LOAD:00009894 40 00 00 00 DCD 0x40
340 | LOAD:00009898 E4 00 00 00 DCD 0xE4
341 | LOAD:0000989C 3C 01 00 00 DCD 0x13C
342 | LOAD:000098A0 88 01 00 00 DCD 0x188
343 | LOAD:000098A4 08 02 00 00 DCD 0x208
344 | 同上,規律是dyna_pc + 4 (即下一條指令地址[是r0的值] + offset[0 - 5], 因爲表大小為9890 - 98A4 共5個),
345 | 因此證明一共5個跳轉經過這裏,經證明確實如此:
346 | Down j LOAD:000098C4 BL loc_9888
347 | Down j LOAD:00009966 BL loc_9888
348 | Down j LOAD:000099BE BL loc_9888
349 | Down j LOAD:00009A0C BL loc_9888
350 | Down j LOAD:00009A8A BL loc_9888
351 | -------------------------------------------------------------------------------------------
352 | sub_494C的特征,代码段中仅存在一处
353 | LOAD:0000B264 ; ---------------------------------------------------------------------------
354 | LOAD:0000B264 PUSH.W {R4-R8,LR}
355 | LOAD:0000B268 ADD R7, SP, #0xC
356 | LOAD:0000B26A PUSH {R0,R1,LR}
357 | LOAD:0000B26C LDR R0, =0x20
358 | LOAD:0000B26E BL loc_B140 // 又跳回了LOAD:0000B140 BLX sub_494C
359 | LOAD:0000B26E ; ---------------------------------------------------------------------------
360 | 可以看到并想象程序中有多种类似的跳转,
361 | 特征:
362 | PUSH {R0,R1,LR}
363 | LDR R0, =number
364 | NOP
365 | patch代码摘自网络,被放置在put_unconditional_branch.py文件中,
366 | 在B26A处执行patch脚本,运行结果如下:B26A处指令变成了B loc_B4B0
367 | LOAD:0000B264 ; ---------------------------------------------------------------------------
368 | LOAD:0000B264 2D E9 F0 41 PUSH.W {R4-R8,LR}
369 | LOAD:0000B268 03 AF ADD R7, SP, #0xC
370 | LOAD:0000B26A 21 E1 B loc_B4B0
371 | LOAD:0000B26C 01 48 LDR R0, =0x20
372 | LOAD:0000B26E FF F7 67 FF BL loc_B140
373 | LOAD:0000B26E ; ---------------------------------------------------------------------------
374 |
375 | LOAD:0000B4B0 ; ---------------------------------------------------------------------------
376 | LOAD:0000B4B0
377 | LOAD:0000B4B0 loc_B4B0
378 | LOAD:0000B4B0 82 B0 SUB SP, SP, #8
379 | LOAD:0000B4B2 82 B0 SUB SP, SP, #8 // 这段代码包含一个blx跳转,该跳转
380 | LOAD:0000B4B4 03 B5 PUSH {R0,R1,LR} // 仅仅是完成了跳到下一个指令的位置
381 | LOAD:0000B4B6 F9 F7 56 EA BLX sub_4964 // 并且计算出指定寄存器的值
382 | LOAD:0000B4BA EA 00 LSLS R2, R5, #3 // 这段类似代码都可以被patch掉
383 | LOAD:0000B4BC 00 00 MOVS R0, R0 //
384 | LOAD:0000B4BE 02 BC POP {R1} //
385 | LOAD:0000B4C0 00 28 CMP R0, #0 //
386 | LOAD:0000B4C2 79 44 ADD R1, PC //
387 | LOAD:0000B4C4 09 68 LDR R1, [R1]
388 | LOAD:0000B4C6 03 B5 PUSH {R0,R1,LR}
389 | LOAD:0000B4C8 01 48 LDR R0, =0x27
390 | LOAD:0000B4CA FF F7 39 FE BL loc_B140
391 | LOAD:0000B4CA ; ---------------------------------------------------------------------------
392 |
393 |
394 |
395 | sub_4964处指令只是完成了 PC = R1 = B5A4, LR = B4BE(它下一条指令处), R0, R1略
396 | LOAD:00004964 ; =============== S U B R O U T I N E =======================================
397 | LOAD:00004964
398 | LOAD:00004964
399 | LOAD:00004964 sub_4964
400 | LOAD:00004964
401 | LOAD:00004964
402 | LOAD:00004964 arg_C = 0xC
403 | LOAD:00004964 arg_10 = 0x10
404 | LOAD:00004964
405 | LOAD:00004964 01 00 CE E3 BIC R0, LR, #1 // LR最低位清零,最终R0仍为B4BA
406 | LOAD:00004968 00 10 90 E5 LDR R1, [R0] // R1 = [B4BA] = 0XEA
407 | LOAD:0000496C 01 10 90 E7 LDR R1, [R0,R1] // R1 = B4BA + 0XEA = B5A4
408 | LOAD:00004970 04 E0 8E E2 ADD LR, LR, #4 // B4BA + 4 = B4BE
409 | LOAD:00004974 0C E0 8D E5 STR LR, [SP,#0xC]
410 | LOAD:00004978 10 10 8D E5 STR R1, [SP,#0x10]
411 | LOAD:0000497C 03 C0 BD E8 LDMFD SP!, {R0,R1,LR,PC} // PC = B4BE(它下一条指令处)
412 | LOAD:0000497C ; End of function sub_4964
413 | LOAD:0000497C
414 | LOAD:00004980 ; ---------------------------------------------------------------------------
415 |
416 | 特征如下:
417 | SUB SP, SP, #8
418 | PUSH {R0,R1,LR}
419 | ....
420 | POP xxx
421 | 摘自网络的patch代码见patches.py文件,在B4B2处进行patch后代码变化如下:
422 | LOAD:0000B4B0 ; ---------------------------------------------------------------------------
423 | LOAD:0000B4B0
424 | LOAD:0000B4B0 loc_B4B0
425 | LOAD:0000B4B0 82 B0 SUB SP, SP, #8
426 | LOAD:0000B4B2 00 BF NOP
427 | LOAD:0000B4B4 01 49 LDR R1, =0xB5A4 // = 0x7F73A
428 | LOAD:0000B4B6 09 68 LDR R1, [R1]
429 | LOAD:0000B4B8 02 E0 B loc_B4C0
430 | LOAD:0000B4B8 ; ---------------------------------------------------------------------------
431 | LOAD:0000B4BA EA 00 word_B4BA DCW 0xEA
432 | LOAD:0000B4BC A4 B5 00 00 dword_B4BC DCD 0xB5A4
433 | LOAD:0000B4C0 ; ---------------------------------------------------------------------------
434 | LOAD:0000B4C0
435 | LOAD:0000B4C0 loc_B4C0 ; CODE XREF: LOAD:0000B4B8j
436 | LOAD:0000B4C0 00 28 CMP R0, #0
437 | LOAD:0000B4C2 79 44 ADD R1, PC // __stack_chk_guard
438 | LOAD:0000B4C4 09 68 LDR R1, [R1]
439 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
440 | 另一块类似代码,特征:
441 |
442 | LOAD:0007203C 03 B5 PUSH {R0,R1,LR}
443 | LOAD:0007203E 00 BF NOP
444 | LOAD:00072040 92 F7 AA EC BLX sub_4998
445 | LOAD:00072044 0C 00 MOVS R4, R1
446 | -------------------------------------------------------------------------------------------------------------------
447 |
448 | LOAD:00004998
449 | LOAD:00004998
450 | LOAD:00004998 sub_4998
451 | LOAD:00004998
452 | LOAD:00004998
453 | LOAD:00004998 arg_8 = 8
454 | LOAD:00004998
455 | LOAD:00004998 01 00 CE E3 BIC R0, LR, #1 // 对LR = 0x72044最低位清零,仍为72044
456 | LOAD:0000499C 00 10 90 E5 LDR R1, [R0] // 取R1 = [0x72044] = 0xc
457 | LOAD:000049A0 0E 10 81 E0 ADD R1, R1, LR // 对LR = 0x72044 + 0xc = 0x72050
458 | LOAD:000049A4 08 E0 9D E5 LDR LR, [SP,#8]
459 | LOAD:000049A8 08 10 8D E5 STR R1, [SP,#8]
460 | LOAD:000049AC 03 80 BD E8 LDMFD SP!, {R0,R1,PC} // PC = 0x72050
461 | LOAD:000049AC ; End of function sub_4998
462 |
463 | ----------------------------------------------------------------------------------------------------------------
464 | 摘自网络命名位put_unconditional_branch1.py文件patch 0x7203C。
465 |
466 | LOAD:0007203C B loc_72050
467 | LOAD:0007203E NOP
468 | LOAD:00072040 BLX sub_4998
469 | LOAD:00072044 MOVS R4, R1
470 | LOAD:00072046 MOVS R0, R0
471 |
472 | ---------------------------------------------------------------------------------------------------------------
473 | 另一種計算pc的特徵:
474 | LOAD:00009A50 FA F7 A2 EF BLX sub_4998
475 | LOAD:00009A50 ; ---------------------------------------------------------------------------
476 | LOAD:00009A54 7A FF FF FF DCD 0xFFFFFF7A
477 | LOAD:00009A58 ; ---------------------------------------------------------------------------
478 |
479 | sub_4998
480 | LOAD:00004998 arg_8 = 8
481 | LOAD:00004998
482 | LOAD:00004998 01 00 CE E3 BIC R0, LR, #1 // lr = 9A54
483 | LOAD:0000499C 00 10 90 E5 LDR R1, [R0] // 0xFFFFFF7A
484 | LOAD:000049A0 0E 10 81 E0 ADD R1, R1, LR // 0x9ace = 9A54 + 0x7a
485 | LOAD:000049A4 08 E0 9D E5 LDR LR, [SP,#8]
486 | LOAD:000049A8 08 10 8D E5 STR R1, [SP,#8]
487 | LOAD:000049AC 03 80 BD E8 LDMFD SP!, {R0,R1,PC} // 0x9ace
488 | 以上指令等價於下面僞代碼:
489 | bl (lr + [lr])
490 | ---------------------------------------------------------------------------------------------------------------
491 | 另一種計算pc的特徵:
492 | LOAD:00009BBC 00 F0 0C B8 B.W loc_9BD8
493 | LOAD:00009BC0 ; ---------------------------------------------------------------------------
494 |
495 |
496 | LOAD:00009BD8 loc_9BD8
497 | LOAD:00009BD8
498 | LOAD:00009BD8 71 46 MOV R1, LR // lr = 9BC0
499 | LOAD:00009BDA 02 A5 ADR R5, 0x9BE4
500 | LOAD:00009BDC 55 F8 21 10 LDR.W R1, [R5,R1,LSL#2] ; 30ae4 = 0xFE6B
501 | LOAD:00009BE0 29 44 ADD R1, R5 ; 19A4F
502 | LOAD:00009BE2 08 47 BX R1 // 動態跳轉
503 | LOAD:00009BE2 ; ---------------------------------------------------------------------------
504 | LOAD:00009BE4 DD FF FF FF DCD 0xFFFFFFDD
505 | LOAD:00009BE8 ; ---------------------------------------------------------------------------
506 |
507 | ---------------------------------------------------------------------------------------------------------------
508 | 另一種計算pc的特徵(同時動態計算寄存器值,參數動態生成):
509 | LOAD:00004D12 82 B0 SUB SP, SP, #8
510 | LOAD:00004D14 03 B5 PUSH {R0,R1,LR}
511 | LOAD:00004D16 FF F7 26 EE BLX sub_4964
512 | LOAD:00004D16 ; ---------------------------------------------------------------------------
513 | LOAD:00004D1A EE 31 00 00 DCD 0x31EE
514 | LOAD:00004D1E ; ---------------------------------------------------------------------------
515 | LOAD:00004D1E 01 BC POP {R0} // pop xxx,動態生成參數
516 |
517 | sub_4964
518 | LOAD:00004964 01 00 CE E3 BIC R0, LR, #1 // 4D1A
519 | LOAD:00004968 00 10 90 E5 LDR R1, [R0] // 0x31EE
520 | LOAD:0000496C 01 10 90 E7 LDR R1, [R0,R1] // r1 = [4D1A + 0x31EE] = [7f08] = 0x85ECC
521 | LOAD:00004970 04 E0 8E E2 ADD LR, LR, #4 // lr = 4D1E
522 | LOAD:00004974 0C E0 8D E5 STR LR, [SP,#0xC] // lr + 4 ,下一條指令処
523 | LOAD:00004978 10 10 8D E5 STR R1, [SP,#0x10] // 待彈出寄存器值0x85ECC
524 | LOAD:0000497C 03 C0 BD E8 LDMFD SP!, {R0,R1,LR,PC} // pc = pc + 8
525 | 等同於僞代碼:
526 | arg_addr = [lr + [lr]]
527 | r{0-3} = arg_addr
528 | ---------------------------------------------------------------------------------------------------------------
529 | 程序JNI_OnLoad邏輯:
530 | libsgmainso_6.4.36.so B3F2D000 B3FB6000 R . X D . byte 00 public CODE 32 00 00
531 | sp = BE903640 B1200284 debug038:B1200284
532 | 第一個動態pc:
533 | libsgmainso_6.4.36.so:B3F38140 BLX dyna_pc
534 | 動態arg:
535 | libsgmainso_6.4.36.so:B3F384B6 BLX dyna_arg
536 | libsgmainso_6.4.36.so:AFE80210 BL loc_AFEF14F4(重命名為goto_create_global_objs)
537 | sub_7C4F4(); // 創建全局 jboolean, jinteger、jstring
538 |
539 | 调试时跳过这里,否则可能崩溃
540 | LOAD:0000B584 71 F0 14 F8 BL goto_getenv(7C5B0)
541 | ---------------------------------------------------------------------------------------------------------------
542 | #sub_72CCC(),被重命名為goto_do_httpuitl
543 | 主要完成對com/taobao/wireless/security/adapter/common/HttpUtil的各種方法的查找
544 | 獲取對應的MethodId並保存
545 |
546 | sub77dbc(), 代码複合patch代码第二種特征,但是这里应该不被patch,被patch的地方
547 | 82 B0 SUB SP, SP, #8
548 | 03 B5 PUSH {R0,R1,LR}
549 | 91 F7 CC ED BLX dyna_arg
550 | 32 01 LSLS R2, R6, #4
551 | 00 00 MOVS R0, R0
552 | 01 BC POP {R0}
553 | 应该满足两个SUB SP, SP, #8指令,因此運行patch代碼,patch整個代碼段
554 | 會出錯,它會把{R0,R1,LR}指令patch成b xxxx導致運行失敗。
555 | sp = BE903620 AFE80111 libsgmainso_6.4.36.so:AFE80111
556 | BL sub_B3FA0E24(sub_73e24(),被重命名為goto_decrypt_entry)
557 | arg:B3FB2FA9, BE9035C3,0x35 // 參數1為加密數據緩存區,參數2是解密數據緩存區
558 | sub_B3FA0E56(sub_73e56, 被重命名為decrypt_entry),比較重要的函數涉及創建容器結構體和解密
559 | BL unk_B3FA7F78(goto_create_vdata)
560 | BL sub_B3FA7FB6(create_vdata)
561 | arg:vdata1,"DcO/lcK+h?m3c*q@",0x10
562 | //vdata1->make_vdata 填充數據
563 | libsgmainso_6.4.36.so:B3FA0E94 98 47 BLX R3(7AA5D)
564 | 拷貝"DcO/lcK+h?m3c*vaq@"到vdata1的data1中
565 |
566 | 第二次調用make_vdata,arg:vdata2,B3FB2FA9,52 // 參數2是數據緩存區
567 | 這次是把下面這52個字節拷貝到vdata2的data2中
568 | 0xF9,0xA7,0x21,0x3D,0x8C,0x3E,0xFE,0x77,0x18,0x40,0xDB,0x2A,
569 | 0xAD,0x4A,0xC5,0xF9,0xA1,0x56,0x75,0x54,0x23,0xBE,0xC7,0xA6,
570 | 0x7A,0x35,0xEC,0x8E,0xB2,5,0x74,0x11,0x93,0x58,0x7F,0x6E,0x3A,
571 | 0xE3,0x4F,0x9D,0x54,3,0x7E,0x6B,0xFA,0x1B,0x5B,0xE3,0xF8,0xC1,2,0xF9
572 | dcryptdata:BE903578
573 | memset(BE903578, 0, 20)
574 | arg:BE903578,BE903594,20,20
575 | // 進入解密函數,dcryptdata結構對應内存
576 | [stack]:BE903578 DCD 0
577 | [stack]:BE90357C DCD 3 ; caseno
578 | [stack]:BE903580 DCD 0
579 | [stack]:BE903584 DCD 0
580 | [stack]:BE903588 DCD 0xACC1C890 ; vdata1
581 | [stack]:BE90358C DCD 0xACC1C8C8 ; vdata2
582 | libsgmainso_6.4.36.so:B3FA0ED8 BL sub_B3F8E15C(重命名為goto_dcrypto)
583 | goto_dcrypto(dcryptdata, )
584 | 進入sub_611b4(被重命名為decrypto)進行解密,解密出:
585 | "com/taobao/wireless/security/adapter/common/HttpUtil"
586 | libsgmainso_6.4.36.so AFE75000 AFEFE000 R . X D . byte 00 public CODE 32 00 00
587 | 調用findclass查找該class,調用NewGlobalRef創建該類的ref
588 | arg: httputilref,
589 | bl sub_72d60()
590 | // 參數1加密數據,參數2為解密緩衝區,參數3為長度
591 | BL goto_decrypt_entry(encdata, decdata, len);
592 | BL goto_create_vdata
593 | memset (BE9035A0, 0, 0x1d)
594 | 拷貝加密數據到vdata2
595 | memset dcryptdata 結構BE903558
596 | BL goto_dcrypto, 解密出字符串"sendSyncHttpGetRequestBridge"
597 | 調用env->getStaticMethodID,75F247D8
598 | sub_72e54()
599 | 解密出數據"sendSyncHttpPostRequestBridge"
600 | 調用env->getStaticMethodID, 75F24828
601 | 在解密出"downloadFileBridge"
602 | 調用env->getStaticMethodID, 75F24788
603 | 調用env->DeleteLocalRef刪除httputilref
604 | 至此sub_72CCC()結束
605 | ---------------------------------------------------------------------------------------------------------------
606 | sub_73634()被重命名為goto_do_umidAdapter
607 | 主要完成對com/taobao/wireless/security/adapter/umid/UmidAdapter的方法的查找
608 | 並保存其MethodId
609 | sub_7366A()
610 | BL goto_decrypt_entry(,, 54)
611 | 解密出"com/taobao/wireless/security/adapter/umid/UmidAdapter"
612 | 調用env->findclass找到UmidAdapterClass 00100025,調用env->NewGlobalRef UmidAdapterRef
613 | 調用env->DeleteLocalRef, 刪除UmidAdapterClass
614 | BL goto_decrypt_entry(AFEFB113, BE9035B8, 16)
615 | 解密出"umidInitAdapter"
616 | 調用env->getStaticMethodID(UmidAdapterRef, "umidInitAdapter") 75F248C8
617 | sub_73634()結束
618 | ---------------------------------------------------------------------------------------------------------------
619 | sub_73E24() goto_decrypt_entry(AFEF8EA6, BE9035E8, 49)
620 | 解密出"com/taobao/wireless/security/adapter/JNICLibrary"
621 | libsgmainso_6.4.36.so B3F2D000 B3FB7000 R . X D . byte 00 public CODE 32 00 00
622 | 調用env->findclass查找JNICLibrary 00200025
623 | bl 9EE4
624 | sub_9ee4() 被重命名為goto_create_command_vdata,主要是調用sub_9F1C完成創建兩個大的結構體
625 | sub_9F1C() // make_global_command_ptr
626 | 首先讀取off_90804処的值是否為NULL(被重命名為global_command_entryptr
627 | 它保存著下面的global_command_entry結構的指針)
628 |
629 | struct global_command_entry { // 記錄著生成和執行command的核心方法
630 | void* goto_make_command_entry; // 對應sub_9B3C; 生成command結構核心算法
631 | void* goto_do_command1; // // 對應sub_9d82; command_native_inner
632 | void* goto_do_command2; // 對應sub_9e7e; 和sub_9d82差不多
633 | };
634 |
635 | ACC11F60 = malloc(12); // 這是個什麽結構體,暫且命名為tmp_vdata
636 | debug014:ACC11F60 DCD 0xB3F36A99 // 對應sub_9B3C; 生成command結構核心算法
637 | debug014:ACC11F64 DCD 0xB3F36DF5 // 對應sub_9d82; command_native_inner
638 | debug014:ACC11F68 DCD 0xB3F36E49 // 對應sub_9e7e; 和sub_9d82差不多
639 | sub_7B86C(32,0) // 重命名為create_command_vdata(int len, int w); // len表示結構體大小,w未知
640 | struct command_nest {
641 | void* nf1;
642 | void* nf2;
643 | int len;
644 | };
645 |
646 | struct command_vdata {
647 | struct data** datalist; // 第一層$8bitstruct
648 | int data_count;
649 | int data_size;
650 | void* f1;
651 | void* f2;
652 | void* f3;
653 | struct command_nest* nest;
654 | };
655 |
656 | ACC3A3D0 = malloc(36);
657 | 創建command_vdata結構體,對應内存結構:
658 | debug014:ACC3A3D0 DCD 0xACC49300 ; command_vdata1
659 | debug014:ACC3A3D4 DCD 0
660 | debug014:ACC3A3D8 DCD 0x20
661 | debug014:ACC3A3DC DCD 0xB3FA88F9
662 | debug014:ACC3A3E0 DCD 0xB3FA89B5
663 | debug014:ACC3A3E4 DCD 0xB3FA89F5
664 | debug014:ACC3A3E8 DCD 0xB3FA8A81
665 | debug014:ACC3A3EC DCD 0xB3FA8AF1
666 | debug014:ACC3A3F0 DCD 0
667 | 創建data結構體(chunk)
668 | ACC49300 = malloc(128);
669 | 創建第二個command_vdata結構體ACC3A3A8
670 | debug014:ACC3A3A8 DCD 0xACC49280 ; command_vdata2
671 | debug014:ACC3A3AC DCD 0
672 | debug014:ACC3A3B0 DCD 0x20
673 | debug014:ACC3A3B4 DCD 0xB3FA88F9
674 | debug014:ACC3A3B8 DCD 0xB3FA89B5
675 | debug014:ACC3A3BC DCD 0xB3FA89F5
676 | debug014:ACC3A3C0 DCD 0xB3FA8A81
677 | debug014:ACC3A3C4 DCD 0xB3FA8AF1
678 | debug014:ACC3A3C8 DCD 0
679 | 創建第二個data結構體ACC49280
680 | 然後把它倆存儲在以下地方:
681 | off_8CA7C g_search_command_vdata DCD 0xACC3A3D0, do_command 第四個參數為0,查找
682 | off_8CA78 gcommand_build_vdata DCD 0xACC3A3A8, do_command 第四個參數為1,生成
683 | 在off_90804処保存global_command_entry指針
684 | ---------------------------------------------------------------------------------------------------------------
685 | bl sub_71D68(),重命名為goto_do_SPUtility2
686 | 主要是查找com/taobao/wireless/security/adapter/common/SPUtility2的一些methoidID
687 | sub_73DD4()啥也沒乾
688 |
689 | sub_71E70只是用來構造參數
690 | sub_72080()
691 | 解密得到"com/taobao/wireless/security/adapter/common/SPUtility2"
692 | 調用env->findclass找到SPUtility2Class 00000029
693 | 調用env->NewGlobalRef創建SPUtility2Ref 001003DA
694 | sub_72134()
695 | 解密"readFromSPUnified"
696 | 調用env-getStaticMethodID, 75F26B48
697 | 解密"saveToFileUnifiedForNative"
698 | 調用env-getStaticMethodID, 75F26C88
699 | sub_720C8()
700 | 解密出 "removeFromSPUnifiedp"
701 | 調用env-getStaticMethodID, 75F26BE8
702 | sub_71FD0()
703 | 解密出"readSS"
704 | 解密出"writeSS",調用env-getStaticMethodID, 75F26D78
705 | sub_71EB0()
706 | 調用env-getStaticMethodID("readSS"), 75F26B98
707 | 解密出"read", "write"
708 | 調用env-getStaticMethodID("read"),75F26AF8
709 | 調用env-getStaticMethodID("write"),75F26D28
710 | ---------------------------------------------------------------------------------------------------------------
711 | sub_e7dc()
712 | sub_E890()
713 | 解密出"(I)Ljava/lang/String;"
714 | 解密出"com/taobao/wireless/security/adapter/datacollection/DeviceInfoCapturer"
715 | 調用findclass,0010002D,調用NewGlobalRef創建該類的ref 001003DE
716 | 調用DeleteLocalRef, 刪除本地DeviceInfoCapturer類的ref
717 | 解密出"doCommandForString"
718 | 調用env-getStaticMethodID("doCommandForString"),75F27048 存儲在off_8CA94処
719 | 存儲在以下位置:
720 | off_8CA94 global_DeviceInfoCapturer_methodId DCD 0x75F27048
721 | off_8CA98 global_DeviceInfoCapturer_ref DCD 0xB6F33E04
722 |
723 | #########################################################################################
724 | #sub_9B3C
725 | 這是一個重要的函數,每個command依賴的數據結構都需要經過它來生成
726 | 這個函數經過了llvm混淆,在不去掉llvm混淆時分析起來還是比較費勁的。
727 | command 最主要的參數是三個:
728 | command / 10000 ; // n1
729 | command % 10000 / 100 ; // n2
730 | command % 100 ; // n2
731 | 由此三個參數構成了三層結構(由外向内順序是n1->n2->n3),其中最終的加密后的地址保存在
732 | n3層結構中(只是異或加密),解密密匙保存在n2層結構中(是用time做種子生成的隨機數,
733 | 每次都不一樣,每個app可能都不一樣)。
734 |
735 | 每個command相關地址并不是函數的實際地址(是包含實際地址的封裝),是執行函數的一個入口(梉),
736 | 這個入口需要進一步做處理才能跳轉到實際函數的地址。
737 | 一個函數會被分成不同的塊,由n3層結構決定,例如:
738 | command(1, 17, 1) { // 隨便假設的
739 | stub2->do_command_parser->real_func_addr
740 | stub1->do_command_parser->real_func_addr
741 | stub3->do_command_parser->real_func_addr
742 | stub4->do_command_parser->real_func_addr
743 | }
744 | 在上面的分析中我們已經看到它生成了一個全局的command_entryptr,它記錄著生產command相關結構
745 | 和反向按結構找到梉的算法。
746 | 同時還生成了兩個gcommand_vdata1和gcommand_vdata2的n1第一層指針結構(分別為查找和生成時使用)
747 |
748 | 主要結構如下(僞定義):
749 |
750 | n1 -> first struct{8 bit: n2_addr, count} -> n2 -> second {24 bit: n3_addr, count} -> n3 ->
751 | third {16 bit: stub_addr, count}
752 |
753 | 無論是正向生成command相關結構,還是反向依賴參數查找結構都需要這三個參數
754 | 1、正向生成command相關結構,傳遞的參數是1
755 | 2、反向查找command相關結構,傳遞的參數是0
756 |
757 | #後續在酌情添加
758 | 開始分析:
759 | sub_9B3C() // goto_make_command_entry
760 | 以第一次分析爲例(我只記錄關鍵邏輯):
761 | [stack]:BE8915C8 DCD 0xB3E7B2B5 ; sp
762 | [stack]:BE8915CC DCD 0x100025
763 | sub_9B3C(1, 9, 1, 1, build_addr) ->
764 | // goto_build_or_unpack_command
765 | sub_9854(gcommand_build_vdata, 1, 9, 1, 1, ...) ->
766 |
767 | sub_9a14(gcommand_build_vdata, 1, 9, 1, 1, build_addr = 0xB3E7B2B5) // build_addr = 0x102B5
768 |
769 | struct $8bitstruct { // 第一層結構
770 | int command_arg1; // command arg1
771 | struct command_vdata* vdata; // 指向第二層
772 | };
773 |
774 | struct $24bitstruct { // 第二層結構
775 | int command_arg1; // command arg1
776 | int command_arg2; // command arg2
777 | long time;
778 | int c; // (time >> 31)
779 | struct command_vdata* vdata; // 指向第三層
780 | int d; // 未知
781 | };
782 |
783 | struct $16bitstruct { // 第三層結構
784 | int command_arg1; // command arg1
785 | int command_arg2; // command arg2
786 | int command_arg3; // command arg3
787 | int xoraddr;
788 | };
789 |
790 | // w = 0代表查找, w = 1代表創建
791 | // n1, n2, n3 為command 三層索引
792 | // build_addr 正向時為被處理地址, 反向時為返回地址
793 | void* sub_9a14(command_vdata* g_build_vdata, int n1, int n2, int n3, w = 1, void* build_addr) {
794 |
795 | int data_count = g_build_vdata->data_count;
796 | int i = 0;
797 | if (data_count < 1) {
798 | if (w == 0) {
799 | return 0x26b0;
800 | }
801 |
802 | struct $8bitstruct* _8bitstruct = (struct $8bitstruct*) malloc(8); // B4E01130
803 | memset(_8bitstruct, 0, 8);
804 | _8bitstruct->command_arg1 = n1;
805 | // -> 7BB98
806 |
807 | // vdata = ACB4A3F8, datalist = ACB32980
808 | // vdata 初始化略; 默認data_size為120字節
809 | struct command_vdata* second_command_vdata = (struct command_vdata*) malloc(36);
810 |
811 | _8bitstruct->vdata = second_command_vdata;
812 | // make_command_vdata, 填充數據
813 | // 這裏僅僅執行了 vdata->datalist->d = _8bitstruct;
814 | // vdata->data_count++;
815 | g_build_vdata->f2(g_build_vdata, 0, _8bitstruct);
816 |
817 | if(second_command_vdata->data_count < 1) {
818 | if (w == NULL) {
819 | return 0x26B1;
820 | }
821 | // ACB12478
822 | struct $24bitstruct* _24bitstr = (struct $24bitstruct*) malloc(24);
823 | memset(_24bitstr, 0, 24);
824 | _24bitstr->command_arg1 = n1; // command arg1
825 | _24bitstr->command_arg2 = n2; // command arg2
826 | time_t seed;
827 | seed = time(NULL); // 5E58B699
828 | srand(seed);
829 | int random_time = (int) rand() >> 31; // 074D4C00
830 | int c = (int) random_time >> 31; // 0
831 | _24bitstr->time = random_time;
832 | _24bitstr->c = c;
833 | // 創建第三層command_vdata結構
834 | // vdata = ACB4A498; data = ACB32A00
835 | // vdata 初始化略
836 | struct command_vdata* third_command_vdata = (struct command_vdata*) malloc(36);
837 | _24bitstr->vdata = third_command_vdata;
838 | // 這裏僅僅執行了 vdata->datalist->d = _24bitstr;
839 | // vdata->data_count++;
840 | second_command_vdata->f2(second_command_vdata, _24bitstr); // make_command_vdata
841 | if (third_command_vdata->data_count < 1) {
842 | if (w == 0) {
843 | return 0x270F;
844 | }
845 | // ACB3B540
846 | struct $16bitstruct* _16bitstr = (struct $16bitstruct*) malloc(16);
847 | _16bitstr->command_arg1 = n1;
848 | _16bitstr->command_arg2 = n2;
849 | _16bitstr->command_arg3 = n3;
850 | // make_command_vdata, 填充數據
851 | // 這裏僅僅執行了 vdata->datalist->d = _16bitstr;
852 | // vdata->data_count++;
853 | third_command_vdata->f2(third_command_vdata, _16bitstr);// make_command_vdata
854 | // 異或加密地址存儲
855 | _16bitstr->xoraddr = _24bitstr->time ^ build_addr;
856 | return 0;
857 |
858 | } else {
859 | i = 0;
860 | while (i < third_command_vdata->data_count) {
861 | // 這裏後面在說
862 | }
863 | }
864 | } else {
865 | i = 0;
866 | while(i < second_command_vdata->data_count) {
867 | // 這裏後面在說
868 | }
869 |
870 | }
871 | } else {
872 | struct data** datalist = g_build_vdata->datalist;
873 | struct $8bitstruct* _8bitstr = NULL;
874 | for (int i = 0 ; i < g_build_vdata->data_count; i++) {
875 | _8bitstr = datalist[i];
876 | if(_8bitstr->command_arg1 == n1) {
877 | break;
878 | }
879 | }
880 | // 取第二層機構
881 | struct command_vdata* second_command_vdata = _8bitstr->vdata;
882 | if (second_command_vdata->data_count < 1 ) {
883 | return 0x26B1;
884 | }
885 |
886 | datalist = second_command_vdata->datalist;
887 | struct $24bitstruct* _24bitstr = NULL;
888 |
889 | for (int j = 0 ; j < second_command_vdata->data_count ; j++) {
890 | if((struct $24bitstruct*) datalist[i]->command_arg2 == n2) {
891 | _24bitstr = datalist[i];
892 | break;
893 | }
894 | }
895 |
896 | if (w == 0) {
897 | return ??;
898 | }
899 |
900 | if (_24bitstr == NULL) {
901 | _24bitstr = malloc(24);
902 | // 創建$24bitstruct 結構體
903 | // 創建third_command_vdata ACB4A4C0;同上
904 | // 更新second_command_vdata datalist同時data_count++等
905 | // ACB124C0 24bitstr,
906 | // 創建完后調用
907 | }
908 |
909 | // 取第三層
910 | struct $16bitstruct* _16bitstr = NULL;
911 | struct command_vdata* third_command_vdata = _24bitstr->vdata;
912 | if(third_command_vdata->data_count < 1) {
913 |
914 | }
915 |
916 | for (j = 0; j < third_command_vdata->data_count; j++) {
917 | if ((struct $16bitstruct*) third_command_vdata[j]->command_arg3 == n3) {
918 | _16bitstr = third_command_vdata[j];
919 | break;
920 | }
921 | }
922 |
923 | if (w == 0) {
924 | return ??;
925 | }
926 |
927 | if (_16bitstr == NULL) {
928 | _16bitstr = malloc(16);
929 | // ACB11F50
930 | // 創建$16bitstruct; 同上
931 | return 0;
932 | }
933 | }
934 | }
935 |
936 | #########################################################################################
937 | ---------------------------------------------------------------------------------------------------------------
938 | sub_69D68() 啥也沒乾
939 | ---------------------------------------------------------------------------------------------------------------
940 | sub_197B4() 被重命名為goto_do_DataReportJniBridgerer
941 | 主要是處理com/taobao/wireless/security/adapter/datareport/DataReportJniBridgerer這個類的方法,同上
942 | sub_1990C()
943 | 解密出"com/taobao/wireless/security/adapter/datareport/DataReportJniBridgerer"
944 | 調用findclass, 0000002D
945 | 調用NewGlobalRef創建該類的ref 001003E2
946 | sub_19998()
947 | 下面忘記下斷點了,丟失信息了
948 | 解密出"sendReportBridge", 調用getStaticMethodID, 忘記記錄了
949 | 解密出 "accsAvaiableBridge", 調用getStaticMethodID, 忘記記錄了
950 | 解密出"()I" , 調用getStaticMethodID, 忘記記錄了
951 | 解密出"registerAccsListnerBridge"
952 | 解密出"()I" , 調用getStaticMethodID, 忘記記錄了
953 | 他們被分別保存在off_8CB80起始的地址処
954 | sub_73D90() 讀取global_command_entry指針的值
955 | 繼續調用sub_9b3c(1, 0xb, 0x34, 1, build_addr = B3E84725 = 0x19725) 詳細分析見上面
956 | ---------------------------------------------------------------------------------------------------------------
957 | sub_E240()
958 | sub_e280()
959 | 又sub_9B3C(1, 7, 1, 1, build_addr = 0xB3E791D5 = off_E1D5)同上, 不在繼續分析
960 | ---------------------------------------------------------------------------------------------------------------
961 | sub_B8B0()
962 | 繼續調用sub_9B3C(1, 1, 1, 1, build_addr = 0xB3E76921 = off_B921) 同上略
963 | 繼續調用sub_9B3C(1, 1, 2, 1, build_addr = 0xB3E76FD9 = off_BFD9) 同上略
964 | ---------------------------------------------------------------------------------------------------------------
965 | sub_5F0F4()
966 | sub_5F11E()
967 | sub_9B3C() 同上略
968 | ---------------------------------------------------------------------------------------------------------------
969 | sub_5F0F4(env, clazz)
970 | sub_9B3C() 同上略
971 | sub_9B3C() 同上略
972 | ---------------------------------------------------------------------------------------------------------------
973 | sub_70640(env, clazz)
974 | sub_9B3C() 同上略
975 | sub_9B3C() 同上略
976 | ---------------------------------------------------------------------------------------------------------------
977 | sub_11F3C(env)
978 | sub_14FEE()
979 | sub_1511C(),中間很多調用findclass和調用都略
980 | 解密出"android/content/Context",調用findclass
981 | sub_151A4()
982 | 解密出"getPackageManager","()Landroid/content/pm/PackageManager;"
983 | 調用getStaticMethodID 70FC7458
984 | 解密出"getContentResolver", "()Landroid/content/ContentResolver;"
985 | 調用getStaticMethodID 70FC7458
986 | 解密出"getSystemService","(Ljava/lang/String;)Ljava/lang/Object;"
987 | 調用getStaticMethodID 70FC7BA8
988 | 解密出"WIFI_SERVICE","Ljava/lang/String;"
989 | 調用GetStaticFieldID 70FC66E8
990 | 調用NewGlobalRef創建該類的ref 001003E6
991 | 調用DeleteLocalRef刪除該類本地ref
992 | 解密出"android/content/pm/PackageManager", "getPackageInfo",,調用findclass
993 | "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"
994 | 調用getStaticMethodID 70FAFA30
995 | 調用DeleteLocalRef刪除該類本地ref
996 | 解密出"android/content/pm/PackageInfo"
997 | "applicationInfo", "Landroid/content/pm/ApplicationInfo;"
998 | 調用GetFieldID 71052F08
999 | 解密出 "firstInstallTime1","J"
1000 | 調用GetFieldID 71053100
1001 | 解密出"lastUpdateTime","J"
1002 | 調用GetFieldID 71053118
1003 | 調用DeleteLocalRef刪除該類本地ref
1004 | 解密出"android/content/pm/ApplicationInfo","flags","I"
1005 | 調用GetFieldID 71047168
1006 | 調用DeleteLocalRef刪除該類本地ref
1007 | 解密出"android/provider/Settings", "getString"
1008 | "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;"
1009 | 調用getStaticMethodID 7127C4E8
1010 | 調用NewGlobalRef創建該類的ref 001003EA
1011 | 調用DeleteLocalRef刪除該類本地ref
1012 | "java/util/List","get", "(I)Ljava/lang/Object;",
1013 | 調用getStaticMethodID 70B43A50
1014 | 解密出"size","()I"
1015 | 調用getStaticMethodID 70B43DF8
1016 | 調用DeleteLocalRef刪除該類本地ref
1017 | 解密出"android/net/wifi/WifiConfiguration","SSID","Ljava/lang/String;"
1018 | 調用GetFieldID 75F27C38
1019 | "networkId","I",調用GetFieldID 75F28078
1020 | "providerFriendlyName","Ljava/lang/String;",調用GetFieldID, 返回空
1021 | "BSSID","Ljava/lang/String;",調用GetFieldID, 75F27BF8
1022 | "FQDN","Ljava/lang/String;",調用GetFieldID, 75F27C18
1023 | "priority","I", 調用GetFieldID,75F282B8
1024 | "hiddenSSID","Z",調用GetFieldID, 75F27ED8
1025 | 調用NewGlobalRef創建該類的ref 001003EE
1026 | 調用DeleteLocalRef刪除該類本地ref
1027 | "android/net/wifi/WifiManager","getConfiguredNetworks","()Ljava/util/List;"
1028 | 調用getStaticMethodID 711FD720
1029 | "getDhcpInfo","()Landroid/net/DhcpInfo;",
1030 | 調用getStaticMethodID 711FD840
1031 | 調用DeleteLocalRef刪除該類本地ref
1032 | "android/net/DhcpInfo", "gateway","I",
1033 | 調用GetFieldID 75F29168
1034 | 調用DeleteLocalRef刪除該類本地ref
1035 | ---------------------------------------------------------------------------------------------------------------
1036 | sub_21C3C()
1037 | sub_21c70()
1038 | sub_9b3c() 同上略
1039 | ...
1040 | ---------------------------------------------------------------------------------------------------------------
1041 | sub_2148C()
1042 | sub_9b3c() 同上略
1043 | ...
1044 | ---------------------------------------------------------------------------------------------------------------
1045 | sub_210E0
1046 | sub_9b3c() 同上略
1047 | ...
1048 | ---------------------------------------------------------------------------------------------------------------
1049 | sub_41B58
1050 | sub_9b3c() 同上略
1051 | ...
1052 | ---------------------------------------------------------------------------------------------------------------
1053 | sub_27920
1054 | sub_9b3c() 同上略
1055 | ...
1056 | ---------------------------------------------------------------------------------------------------------------
1057 | sub_293E8()
1058 | sub_2941C()->sub_29708()->sub_29918()
1059 | 解密出"com/taobao/dp/util/ZipUtils","unZip","([B)[B"
1060 | findclass找到ZipUtilsClass 00100031
1061 | NewGlobalRef 001003F2
1062 | DeleteLocalRef
1063 | getMethodID 75F29618
1064 | 解密出"com/taobao/dp/util/CallbackHelper"
1065 | findclass找到CallbackHelper 00000031
1066 | NewGlobalRef 001003F6
1067 | DeleteLocalRef
1068 | getMethodID 75F29618
1069 | sub_2abf9()-->sub_2AC24()加綫程鎖
1070 | DeleteLocalRef
1071 | sub_29754()->sub_29BB4()
1072 | 解密出"getPackageManager", "()Landroid/content/pm/PackageManager;"
1073 | "android/content/Context","android/content/pm/PackageManager"
1074 | "getPackageInfo","(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"
1075 | "android/content/pm/PackageInfo","applicationInfo"
1076 | "Landroid/content/pm/ApplicationInfo;","firstInstallTime","lastUpdateTime"
1077 | "android/content/pm/ApplicationInfo","flags"
1078 | FindClass("android/content/Context") 00100031
1079 | NewGlobalRef 001003FA
1080 | getMethodID("getPackageManager") 70FC7968
1081 | FindClass("android/content/pm/PackageManager") 00000035
1082 | NewGlobalRef 001003FE
1083 | getMethodID("getPackageInfo") 70FAFA30
1084 | FindClass("android/content/pm/PackageInfo") 00000039 ??
1085 | NewGlobalRef 00100402
1086 | GetFieldID("applicationInfo") 71052F08
1087 | GetFieldID("firstInstallTime") 71053100
1088 | GetFieldID("lastUpdateTime") 71053118
1089 | FindClass("android/content/pm/ApplicationInfo") 0000003D
1090 | NewGlobalRef 00100406
1091 | GetFieldID("flags") 71047168
1092 | ---------------------------------------------------------------------------------------------------------------
1093 | sub_208F4
1094 | sub_20A0C()
1095 | 解密出"com/alibaba/wireless/security/framework/utils/UserTrackMethodJniBridge"
1096 | NewGlobalRef 0010040A, DeleteLocalRef
1097 | "utAvaiable","()I;",getStaticMethodID("utAvaiable") 75F28278
1098 | "addUtRecord","(Ljava/lang/String;IILjava/lang/String;JLjava/lang/String;"
1099 | "Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"
1100 | sprintf(, "%s%s", "(Ljava/lang/String;IILjava/lang/String;JLjava/lang/String;",
1101 | "Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I")
1102 | 得到"(Ljava/lang/String;IILjava/lang/String;JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
1103 | "Ljava/lang/String;Ljava/lang/String;)I"
1104 | getStaticMethodID("addUtRecord") 75F28188
1105 | "getStackTrace","(II)Ljava/lang/String;",getStaticMethodID("getStackTrace"), 75F281D8
1106 | 判斷獲取的methodId是否為空
1107 | ---------------------------------------------------------------------------------------------------------------
1108 | sub_B7B0
1109 | sub_b7f6() 被重命名為registerNatives
1110 | 解密出"doCommandNative","(I[Ljava/lang/Object;)Ljava/lang/Object;", fnPtr為sub_B69C()
1111 | 實際對應sub_B6F6(),重命名為doCommandNative,代碼摘自網絡
1112 | sub_9D60為goto_docommand_native_inner
1113 | 調用env->RegisterNatives()注冊這個doCommandNative
1114 | 至此JNI_OnLoad結束
1115 | ---------------------------------------------------------------------------------------------------------------
1116 | doCommandNative(12302, new Object[]{1, true}) 對應getSecToken
1117 | struct command_arg {
1118 | int arg1;
1119 | int arg2;
1120 | int arg3;
1121 | JNIEnv* env;
1122 | void* args;
1123 | };
1124 |
1125 | struct command_arg* = malloc(20); // ACB6A718
1126 |
1127 | int _R4 = 12302; // command
1128 | int _R0 = 0x68DB8BAD; // 68DB8BAD
1129 | int _R2 = 0x51EB851F; // 51EB851F
1130 |
1131 | int r0 = _R0 * _R4; // 000013AE
1132 | int r3 = _R2 * _R4; // 00000F60
1133 | // (signed int)r0 >> 0xc) = (signed int) (13AE >> 0xc) = 00000001
1134 | // r0 >> 31 = 0
1135 | r0 = ((signed int)r0 >> 0xc) + (r0 >> 31); // 0x1, 參數1
1136 | int r1 = _R4 - r0 * 10000 ; // 000008FE(2302)
1137 | r1 = _R4 * r1; // 2E0, SMMUL.W取高位
1138 | // ((signed int)r3 >> 5) = 0000007B(123)
1139 | // (r3 >> 31) = 0
1140 | r2 = _R4 - (((signed int)r3 >> 5) + (r3 >> 31)) * 100; // 2, 參數3
1141 | r3 = (signed) r1 >> 5 = 00000017(23)
1142 | r1 = r3 + (r1 >> 31) = 1; // 0x17, 參數2
1143 |
1144 | command_arg->arg1 = 1;
1145 | command_arg->arg2 = 0x17;
1146 | command_arg->arg3 = 2;
1147 | // [stack]:BE892160 DCD 0xACB6A748 sp command_arg
1148 | // [stack]:BE892164 DCD 0xBE89216C sp + 4, 棧指針
1149 | // [stack]:BE89216C DCD 0
1150 | sub_9D60->sub_9D82(1, 0x17, 2, w=1, command_arg, 一個棧變量指針)
1151 |
1152 |
1153 | // 非0時取這個
1154 | libsgmainso_6.4.36.so:B3EF7A78 dword_B3EF7A78 DCD 0xACB4A3D0
1155 | // 0時取這個
1156 | libsgmainso_6.4.36.so:B3EF7A7C dword_B3EF7A7C DCD 0xACB4A3A8
1157 | /////////////////////////////////////////////////////////////////
1158 | // 第一次w = 1 因此這個command_vdata沒有用到
1159 | debug021:ACB4A3A8 DCD 0xACB31C00
1160 | debug021:ACB4A3AC DCD 0
1161 | debug021:ACB4A3B0 DCD 0x20
1162 | debug021:ACB4A3B4 DCD 0xB3EE68F9
1163 | debug021:ACB4A3B8 DCD 0xB3EE69B5
1164 | debug021:ACB4A3BC DCD 0xB3EE69F5
1165 | debug021:ACB4A3C0 DCD 0xB3EE6A81
1166 | debug021:ACB4A3C4 DCD 0xB3EE6AF1
1167 | debug021:ACB4A3C8 DCD 0
1168 | //////////////////////////////////////////////////////////////////
1169 | // 用到了這個command_vdata
1170 | debug021:ACB4A3D0 DCD 0xACB31C80
1171 | debug021:ACB4A3D4 DCD 1
1172 | debug021:ACB4A3D8 DCD 0x20
1173 | debug021:ACB4A3DC DCD 0xB3EE68F9
1174 | debug021:ACB4A3E0 DCD 0xB3EE69B5
1175 | debug021:ACB4A3E4 DCD 0xB3EE69F5
1176 | debug021:ACB4A3E8 DCD 0xB3EE6A81
1177 | debug021:ACB4A3EC DCD 0xB3EE6AF1
1178 | debug021:ACB4A3F0 DCD 0
1179 | // data
1180 | debug021:ACB31C80 DCD 0xB4E01130
1181 | //
1182 | debug068:B4E01130 DCD 1
1183 | debug068:B4E01134 DCD 0xACB4A3F8
1184 | // command_vdata1
1185 | debug021:ACB4A3F8 DCD 0xACB31D00
1186 | debug021:ACB4A3FC DCD 0xC
1187 | debug021:ACB4A400 DCD 0x20
1188 | debug021:ACB4A404 DCD 0xB3EE68F9
1189 | debug021:ACB4A408 DCD 0xB3EE69B5
1190 | debug021:ACB4A40C DCD 0xB3EE69F5
1191 | debug021:ACB4A410 DCD 0xB3EE6A81
1192 | debug021:ACB4A414 DCD 0xB3EE6AF1
1193 | // 12個data
1194 | debug021:ACB31D00 DCD 0xACB125F8
1195 | debug021:ACB31D04 DCD 0xACB12610
1196 | debug021:ACB31D08 DCD 0xACB125E0
1197 | debug021:ACB31D0C DCD 0xACB124C0
1198 | debug021:ACB31D10 DCD 0xACB12490
1199 | debug021:ACB31D14 DCD 0xACB124F0
1200 | debug021:ACB31D18 DCD 0xACB12A00
1201 | debug021:ACB31D1C DCD 0xACB12778
1202 | debug021:ACB31D20 DCD 0xACB12910
1203 | debug021:ACB31D24 DCD 0xACB12AC0
1204 | debug021:ACB31D28 DCD 0xACB12970
1205 | debug021:ACB31D2C DCD 0xACB12BE0
1206 | // 最後取到的符合要求的 對應參數2的結構
1207 | debug021:ACB12BE0 DCD 1
1208 | debug021:ACB12BE4 DCD 0x17
1209 | debug021:ACB12BE8 DCD 0x7A005EB3
1210 | debug021:ACB12BEC DCD 0
1211 | debug021:ACB12BF0 DCD 0xACB4A7B8
1212 | debug021:ACB12BF4 DCD 0
1213 | debug021:ACB12BF8 DCD 0
1214 | debug021:ACB12BFC DCD 0
1215 | debug021:ACB12C00 DCD 0xACB12BC8
1216 | //最後取到的符合要求的 對應參數3的結構
1217 | debug021:ACB3B340 DCD 1
1218 | debug021:ACB3B344 DCD 0x17
1219 | debug021:ACB3B348 DCD 2
1220 | debug021:ACB3B34C DCD 0xC9E91B96
1221 | debug021:ACB3B350 DCD 1
1222 | debug021:ACB3B354 DCD 0x17
1223 | debug021:ACB3B358 DCD 1
1224 | debug021:ACB3B35C DCD 0xC9E91A22
1225 | debug021:ACB3B360 DCD 1
1226 | debug021:ACB3B364 DCD 0x17
1227 | debug021:ACB3B368 DCD 3
1228 | debug021:ACB3B36C DCD 0xC9E91B66
1229 | debug021:ACB3B370 DCD 1
1230 | debug021:ACB3B374 DCD 0x17
1231 | debug021:ACB3B378 DCD 4
1232 | debug021:ACB3B37C DCD 0xC9E9182E
1233 | /////////////////////////////////////////////////////////////
1234 |
1235 | stack
1236 | BE892140 00000000
1237 | BE892144 BE892148 [stack]:BE892148
1238 | BE892148 00000000 //r7 + 1c,後面用來存儲下一跳的地址
1239 | BE89214C B47A9038 dalvik_allocspace_allo
1240 | BE892150 0000300E
1241 | BE892154 00000000
1242 | BE892158 BE892180 [stack]:BE892180
1243 | BE89215C B3E76771 libsgmainso_6.4.36.so:
1244 | BE892160 ACB6A718 debug021:ACB6A718
1245 |
1246 | 我們設command變量從外到内依次為a、b、c
1247 | command_vdata-> {datalistaddr, data_count, ...}
1248 | datalist[0]->data[0]-> data{count, addr}->
1249 | command_vdata -> {datalistaddr, data_count, ...}->datalist[x]
1250 | ->24bitstruct{a, b, time(xorkey), ?, command_vdata,?}->
1251 | command_vdata -> {datalistaddr, data_count, ...}->
1252 | 16bitstruct{a, b, c, xoraddr}
1253 |
1254 | // goto_build_or_unpack_command
1255 | sub_9854(ACB4A3D0, 1, 0x17, 2, ...)
1256 | // goto_build_or_unpack_command
1257 | sub_9854->sub_9A14(a, b, c, ...) // a = arg1, b = arg2, c =arg3
1258 | //////////////////////////////////////////////////////////////
1259 | // 第一次 sub_9D82(1, 0x17, 2, 1, command_arg, 一個棧變量指針)
1260 | //////////////////////////////////////////////////////////////
1261 | ->sub_9d82(command, tmp2, tmp3, w, ...) // command_native_inner;獲取下一步跳轉地址
1262 |
1263 | // 首先找到全局command_vdata最外層指針,相對文件偏移dword_8CA7C和dword_8CA78
1264 | // 前面做處理時保存的, w!=0時取dword_8CA78,否則取dword_8CA7C
1265 | // 這裏面有很多函數, 其中還包括正向建立command_vdata過程,這裏略
1266 | sub_9d82(int n1, int n2, int n3, int w, struct command_arg* arg, int* next_addr) {
1267 | struct command_vdata* vdata = &dword_8CA7C;
1268 | if (w != 0) {
1269 | vdata = &dword_8CA78;
1270 | }
1271 |
1272 | // sub_9a14(command_vdata, n1, n2, n3, w, 0)
1273 | // 最外層
1274 | datalist = vdata->datalist;
1275 |
1276 | int i = 0;
1277 | struct $8bitstruct* _8bitstruct = NULL;
1278 | while(i < n1) {
1279 | _8bitstruct = datalist[i]->d; // 取第一層8bitstruct指針
1280 | int ra = _8bitstruct->command_arg1; // 第一層命令
1281 | if (ra == n1) { // 第一層對比相等
1282 | break;
1283 | }
1284 | i++;
1285 | }
1286 | // w不爲0,可能返回0x270F、0x26B0、0x26B1
1287 | // 這裏暫不做分析
1288 | if (_8bitstruct == NULL && w == 0) { // 沒找到的情況
1289 | return 0x26b0;
1290 | }
1291 | //獲取第二層
1292 | struct command_vdata* vdata1 = _8bitstruct->vdata;
1293 | int count = vdata1->data_count;
1294 | i = 0;
1295 | struct $24bitstruct _24bitstr = NULL;
1296 | while(i < count) {
1297 | _24bitstr = vdata1->datalist[i]->d;
1298 | int rb = _24bitstr->command_arg2;
1299 | if (rb = n2) { // 第二層對比
1300 | break;
1301 | }
1302 | i++;
1303 | }
1304 | // w不爲0,可能返回0x270F、0x26B0、0x26B1
1305 | // 這裏暫不做分析
1306 | if(_24bitstr == NULL && w == 0) { // 沒找到的情況
1307 | return 0x26b0;
1308 | }
1309 |
1310 | // 獲取第三層
1311 | struct command_vdata* vdata2 = _24bitstr->vdata;
1312 | count = vdata2->data_count;
1313 | i = 0;
1314 | struct $16bitstruct _16bitstr = NULL;
1315 | while(i < count) {
1316 | _16bitstr = vdata2->datalist[i]->d;
1317 | int rc = _16bitstr->command_arg3;
1318 | if(rc == n3) {
1319 | int xor_addr = _16bitstr->xoraddr ^ _24bitstr->time;
1320 | *next_addr = xor_addr;
1321 | break;
1322 | }
1323 | i++;
1324 | }
1325 | typedef (*func)(void* void*) nfunc;
1326 | nfunc nextf= (nfunc) next_addr;
1327 | return nextf(command_arg, next_addr);
1328 | }
1329 | sub_9a14用
1330 | [stack]:BE892158 DCD 0xBE892180
1331 | [stack]:BE89215C DCD 0xB3D72771
1332 | [stack]:BE892160 DCD 0xACB6A748
1333 | [stack]:BE892164 DCD 0xBE89216C // r7 + 0xc
1334 | [stack]:BE892168 DCD 0x12DE5080
1335 | [stack]:BE89216C DCD 0
1336 |
1337 | >> sub_9D60 結束
1338 |
1339 | arg1 = command_arg->arg1;
1340 | 跳轉到上面異或出來的地址処 // xor = time ^ sec; // B3E94525地址処,對應文件0x29524処
1341 | sub_2956C(command_arg, BE89216C); // 獲取傳遞參數arraylist 0xBE8921A0 -> 0x12E51660
1342 |
1343 | env = command_arg->env;
1344 | jobjectarray = command_arg->args;
1345 | 7E744 ->sub_7E784() // goto_getjarray_value
1346 | GetObjectArrayElement(env, jarray, index) // 返回jobject
1347 | 在通過GetObjectClass獲取對應jclass,在調用GetMethodID獲取對應取元素的方法
1348 | 在調用CallXXXMethod獲取數組中的value。
1349 |
1350 | 7E7EC(env, jarray, 1)->sub_7E830 // goto_getjarray_value1
1351 | functions->GetObjectArrayElement)()略,同上
1352 |
1353 | sp + 4 = 第一個數組元素對應的值
1354 | sp + 8 = 第二個數組元素對應的值
1355 | // vvarg1
1356 | [stack]:BE892118 DCD 0xACB6A748 ; sp0 command_arg
1357 | [stack]:BE89211C DCD 1 ; jarray value 1
1358 | [stack]:BE892120 DCD 1 ; jarray value 2
1359 | [stack]:BE892124 DCD 0xB47A9038
1360 | [stack]:BE892128 DCD 0xB3EF7A78 ; command_vdata1
1361 | [stack]:BE89212C DCD 0
1362 | [stack]:BE892130 DCD 0xACB6A748 // ;command_arg
1363 | // vvarg2
1364 | [stack]:BE89216C DCD 0
1365 | [stack]:BE892170 DCD 0xB47A9038
1366 | [stack]:BE892174 DCD 0x2DF
1367 | [stack]:BE892178 DCD 0x75F91FF0
1368 | [stack]:BE89217C DCD 0x12DDD080
1369 | [stack]:BE892180 DCD 0x716162A0
1370 | [stack]:BE892184 DCD 0x12E51660
1371 | [stack]:BE892188 DCD 0xB4E07800
1372 | [stack]:BE89218C DCD 0xA44E7263
1373 | [stack]:BE892190 DCD 0x75F24BF8
1374 | [stack]:BE892194 DCD 0xBE892438
1375 | [stack]:BE892198 DCD 2
1376 | [stack]:BE89219C DCD 0x12C357C0
1377 | 29FD4->sub_2A01E(vvarg1, vvarg2)
1378 |
1379 | if (vvarg1[1] != 0) { // 取第二個jarray的值, 這裏值為true
1380 | r5 = vvarg1[0]; // 取第一個jarray的值
1381 | // libsgmainso_6.4.36.so:B3E95042 BL loc_B3E9DC00
1382 | // 這應該是具體處理邏輯的函數了,分不分析無所謂了
1383 | 32C00()->sub_32C46(r5 = 1); { // 傳遞的jarray的第一個值
1384 | // 邏輯我就不細緻分析了,這個就涉及到具體算法了,我不想去花時間在逆向算法上
1385 | // 我們重點是搞清楚它都怎麽做的, 這裏我隨便記錄我想記錄的
1386 | // 分不分析看心情
1387 | 30590->sub_305BE(1,0)
1388 | // 9來自程序中寫死的
1389 | 30240->sub_3026A(1,9) // v2 = 1, v3 = 9 ; read_off_8AA50(off, index)
1390 | // 讀取:off_8AA50[108]數組某處的值, 這個值可能是一個結構指針,後面邏輯會把它free
1391 | // B3EF5A50 ; _DWORD dword_B3EF5A50[108]
1392 | // B3EF5A50 DCD 0xB3EF7E18, 0xB3EF7E24, 0, 0xB3EF7E30, 0, 0, 0, 0xB3EF7E3C, 0xB3EF7E48
1393 | // B3EF5A50 DCD 0xB3EF7E54, 0xB3EDE9D1, 0xB3EDE951, 0xB3EABEB9, 0, 0, 0, 0xB3EC2385
1394 | // B3EF5A50 DCD 0, 0x14, 0, 0xB3ED48C1, 0, 0, 0xB3EF2AB6, 0xB3EF0C73, 0xB3EF0CC4, 0xB3EF0D15
1395 | // B3EF5A50 DCD 0xB3EF2B08, 0xB3EDB6B1, 0, 0, 0, 3, 0x8AD2C, 2, 0x590, 0x17, 0x3B14
1396 | // B3EF5A50 DCD 0x14, 0x11, 0x11, 0x2704, 0x12, 0x1410, 0x13, 8, 0x6FFFFFFA, 0x276
1397 | // B3EF5A50 DCD 6, 0x18C, 0xB, 0x10, 5, 0x10FC, 0xA, 0xCA2, 4, 0x1DA0, 1, 0xC83, 1
1398 | // B3EF5A50 DCD 0xC8D, 1, 0x15, 1, 0x5A1, 1, 0xC95, 1, 0x181, 0xE, 0x1D, 0x1A, 0x8A2E0
1399 | // B3EF5A50 DCD 0x1C, 8, 0x19, 0x8AACC, 0x1B, 4, 0x1E, 8, 0x6FFFFFFB, 1, 0x6FFFFFF0
1400 | // B3EF5A50 DCD 0x2498, 0x6FFFFFFC, 0x2688, 0x6FFFFFFD, 1, 0x6FFFFFFE, 0x26A4, 0x6FFFFFFF
1401 | // B3EF5A50 DCD 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1402 | // 第一次計算off_8AA50[9] = 0xB3EF7E54 = 文件偏移8CE54
1403 | // 第二次計算 [0xB3EF7E54 + 4] = 0
1404 | // libsgmainso_6.4.36.so:B3EF7E58 DCD 0
1405 | v5 = *(_DWORD *)(off_8AA50[index] + 4 * off);
1406 | if ( v5 && *(_DWORD *)(v5 + 4) ) // 不成立
1407 | v6 = (*(int (**)(void))(v5 + 40))();
1408 | else
1409 | v6 = 0;
1410 | // 返回0
1411 | 2D228->sub_2D1DA(1,9)->
1412 | // goto_make_vdata6436
1413 | sub_301BC(1,9) -> 301DE(index = 1, off = 9)
1414 | // 大字符數組
1415 | // B3EF02FD aA0d11c6a829475d8 DCB "a0d11c6a829475d8",0
1416 | // B3EF030E aC558656c6b70ed21 DCB "c558656c6b70ed21",0
1417 | // B3EF031F aHardinfo DCB "hardinfo",0
1418 | // B3EF0328 a9e83acb65377eab4 DCB "9e83acb65377eab4",0
1419 | // B3EF0339 a835f56fa8c204d73 DCB "835f56fa8c204d73",0
1420 | // B3EF034A a711718eb73d90dc5 DCB "711718eb73d90dc5",0
1421 | // B3EF035B a68787a1ccce468bf DCB "68787a1ccce468bf",0
1422 | // B3EF036C a999b23355c8909c1 DCB "999b23355c8909c1",0
1423 | // B3EF037D aA9122d5b7873a0d3 DCB "a9122d5b7873a0d3",0
1424 | // B3EF038E aD8b057995e905838 DCB "d8b057995e905838",0
1425 | // B3EF039F a438e0bb7721e9d78 DCB "438e0bb7721e9d78",0
1426 | // B3EF03B0 a570bfc082fe96042 DCB "570BFC082FE96042",0
1427 | // B3EF03C1 aE87e68b3aea2d029 DCB "e87e68b3aea2d029",0
1428 | // B3EF03D2 aEa6c627ab40979d1 DCB "ea6c627ab40979d1",0
1429 | // B3EF03E3 a816f27e6be7ab193 DCB "816f27e6be7ab193",0
1430 | // B3EF03F4 aB7b03fe1a0a13745 DCB "b7b03fe1a0a13745",0
1431 | // B3EF0405 a4c60fa08664a7b66 DCB "4c60fa08664a7b66",0
1432 | // B3EF0416 a624b4d174ad35f2d DCB "624b4d174ad35f2d",0
1433 | // B3EF0427 a95ed8b0357989058 DCB "95ed8b0357989058",0
1434 | // B3EF0438 a00f3acddd00fa671 DCB "00f3acddd00fa671",0
1435 | // B3EF0449 a6c709c11d2d46a7b DCB "6c709c11d2d46a7b",0
1436 | // B3EF045A aDd7893586a493dc3 DCB "dd7893586a493dc3",0
1437 | // B3EF046B a58669b0e4dd2beb8 DCB "58669b0e4dd2beb8",0
1438 | // B3EF047C a85d32f14e4edccf2 DCB "85d32f14e4edccf2",0
1439 | // B3EF048D aE5c06c338bfa3568 DCB "e5c06c338bfa3568",0
1440 | // B3EF049E a8dd236e3120fdbea DCB "8dd236e3120fdbea",0
1441 | // B3EF04AF a8d8b035705995e98 DCB "8d8b035705995e98",0
1442 | // B3EF04C0 a0357995e9858d8b0 DCB "0357995e9858d8b0",0
1443 | // B3EF04D1 aPd DCB "pd",0
1444 | // B3EF04D4 aDj DCB "dj",0
1445 | // libsgmainso_6.4.36.so:B3EF59F8 dword_B3EF59F8 DCD 0xB3EF039F
1446 | arg1 = 1, 獲得數組為off_8A9F8
1447 | // libsgmainso_6.4.36.so:B3EF59D0 dword_B3EF59D0 DCD 0xB3EF02FD
1448 | arg1 = 2, 獲得數組為off_8A9D0
1449 | // libsgmainso_6.4.36.so:B3EF5A20 dword_B3EF5A20 DCD 0xB3EF0438
1450 | 否則,獲得數組為off_8AA20
1451 | // 這裏為1,即off_8A9F8
1452 | 取字符串off_8A9F8[9] = "d8b057995e905838"
1453 | // ACB1C9E0
1454 | //7AF78 goto_create_vdata6436
1455 | 7AF78->sub_7AFB6(0x11) //參數是字符串長度+1,該函數實際上就是create_vdata6436
1456 | // 實際上就是make_vdata6436
1457 | // debug023:ACB1C938 DCD 0xACB6A5F8
1458 | 調用vdata6436->f1(vdata6436, "d8b057995e905838", 0x10);
1459 | // 30240->sub_3026A(1,9)
1460 | 繼續調用goto_read_off_8AA50(1, 9) 得到結構指針為NULL
1461 | // 7B148 goto_free_data
1462 | 7B148->sub_7B17A(0); // free_data; 執行free
1463 | // goto_docommand_inner_contains_create_free_vdata32
1464 | // ACB1C938; goto_create_vdata32; do_command_inner; free_vdata32
1465 | 30D24->sub_30D60(vdata6436,9,1,0,0,1);
1466 | 7C218->sub_7C258("d8b057995e905838", 0x10) // geto_create_vdata32
1467 | struct vdata32_nest {
1468 | void* nf1;
1469 | void* nf2;
1470 | void* nf3;
1471 | void* nf4;
1472 | };
1473 |
1474 | struct vdata32 {
1475 | struct data* data128;
1476 | int data_count;
1477 | int chunk_size;
1478 | void* f1; // goto_make_vdata32;
1479 | struct vdata32_nest* nest;
1480 | };
1481 | // debug018:ACB6A5C8
1482 | 7C0D4->sub_7C10C("d8b057995e905838", 0x10); // A1619860; create_vdata32
1483 | 7C280->sub_7C2C8(vdata32, "d8b057995e905838", 0x10); // goto_make_vdata32
1484 | 73D90 // 讀取off_90804{讀取off_xxx}的值x,這是之前保存起來的
1485 | // debug018:ACB11E20 DCD 0xAFE7EA99
1486 | // debug018:ACB11E24 DCD 0xAFE7EDF5
1487 | // debug018:ACB11E28 DCD 0xAFE7EE49
1488 |
1489 | // 讀取[x + 4] = 0xAFE7EDF5,好像是fnPtr,後面跳到這個地址執行
1490 | [stack]:BE892078 DCD 0xBE89207C // sp
1491 | [stack]:BE89207C DCD 0
1492 | [stack]:BE892080 DCD 0xA1619860 // vdata32
1493 | {1, 0x15, 2, vdata32, 指向sp+4的指針}
1494 | sub_9E30重新設置參數
1495 | [stack]:BE892068 DCD 0xBE892080 sp
1496 | [stack]:BE89206C DCD 0xBE89207C sp + 4
1497 | 走到9D60最終走到sub_9D82(1, 0x15, 2, 0, vdata32p, &saved_addrp) // command_native_inner
1498 | // 不滿足查找條件,返回0x26b0
1499 | 存儲0x26b0到[stack]:BE89207C処
1500 | [stack]:BE89207C DCD 0x26B0
1501 | [stack]:BE892080 DCD 0xA1515580
1502 | [stack]:BE892084 DCD 1
1503 | [stack]:BE892088 DCD 7
1504 | [stack]:BE89208C DCD 0xB47A9038
1505 | [stack]:BE892090 DCD 1
1506 | [stack]:BE892094 DCD 9
1507 | [stack]:BE892098 DCD 0xBE8920AC
1508 | [stack]:BE89209C DCD 0xB3C98207
1509 | sub_9D82返回0x26b0
1510 | 7C34C->sub_7C3A4(vdata32) // free_data(vdata32); 沒用符合條件,vdata32就沒用到,把它free掉
1511 | 得到剛剛獲取的0x26b0並存儲
1512 | 7B148->sub_7B17A(0); // free_data; 執行free; free_vdata6436(vdata6436);
1513 |
1514 | 32cc8->sub_32DC4(0,1,5,2)->sub_32DF0
1515 | 32F14{goto_read_off_8CE6C}->sub_32F44(1) ; // read_off_8CE6C(1)
1516 | // B3EF7E6C ; _DWORD dword_B3EF7E6C[101]
1517 | // B3EF7E6C DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1518 | // B3EF7E6C DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1519 | // B3EF7E6C DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1520 | // B3EF7E6C DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1521 | // B3EF7E6C DCD 0, 0, 0, 0, 0, 0, 0, 0, 0
1522 | 返回0
1523 | 32D78; // 調用5次goto_free_data, free掉查找到的結構指針, 應該是這個command用到的相關塊的結構
1524 |
1525 | 7B148->sub_7B17A(0); // free_data; 執行free
1526 | 30240->sub_3026A(1,9); // 調用goto_read_off_8AA50(1); 同上略
1527 | 32cc8 // 繼續32cc8, 同上略
1528 | }
1529 | }
1530 |
1531 | // goto_do_commandx
1532 | 2B468->sub_2B4BE()->73D90{讀取off_xxx值} // get_do_command_fnptr_str; 準備執行do_command_inner
1533 | // 再次調試sub_9D60(1, 9, 2, 0, 0x6f, stackbuf = 0xBE8920CC)
1534 | // 返回調用到0x9854后返回0x26b0保存到0xBE8920CC
1535 | // 應該是讀取結構指針,然後釋放
1536 | // 7B148->sub_7B17A(0); // free_data; 執行free
1537 | // 9DF4(1, 9, 2, 111) // 結果返回0,結束
1538 | 7AF78->sub_7AFB6(0x19) //參數是字符串長度+1,該函數實際上就是create_vdata6436
1539 | 調用vdata6436->f1(vdata6436, "000000000000000000000000", 0x18); // ACB1C938
1540 | // goto_create_vstring
1541 | 7B5D4(vdata6436, "000000000000000000000000", 0, 0x30)->sub_7B606 // create_vstring ; AD2BEEE0
1542 | 29E98(stackbufp = BE8920EC, stack = BE89216C = NULL)->sub_11F3C(stackbufp, stack)
1543 | *(BE8920EC + 12) = 0;
1544 | *(BE8920EC) = 1;
1545 | 2ACB0->sub_2ACDE(arg = 1) // set_wt_flag; 如果arg <= 2 設置dword_8CE10為參數值
1546 | 304E4->(1,0,1)->sub_3052E(1, 0) // do_command_innerx1
1547 | //先get_do_command_fnptr_str 重新獲取下一個代碼塊,并執行
1548 | // 此次獲取了之前構造保存的塊, ACB3B360
1549 | // 再次執行do_command_inner(1, 8, 2, ...) 返回0
1550 | 30A04->sub_30A38(1)->
1551 | 2D504->sub_2D668(1)->2AC60->sub_2AC8A() ; // get_dword_8CE0C_classid
1552 | // B3E986A2 BL sub_B3E9DC00
1553 | 獲得dword_8CE0C = 0x1003F6; CallbackHelper
1554 | 再次調用32C00略 // 返回0, 實際也沒看到做什麽實質動作
1555 | 獲取env,sub_2D6B8調用解密
1556 | 解密出"onCallBack", "(ILjava/lang/String;I)V"
1557 | 調用GetStaticMethodID(env, 0x1003F6, "onCallBack");
1558 | 調用CallStaticVoidMethod(JNIEnv*, 0x1003F6, onCallBack, 1, NULL, 0x386);
1559 |
1560 | ------------------------------------------------------------------------------------------------------
1561 | 經過這一系列的逆向發現原來sub_9B3C()這個函數是用來做建立和查找command處理的
1562 | 最後把處理結果保存在一系列的嵌套的結構體中
1563 | 這些結構體涉及上面提到的command_vdata, 8bitstruct, 16bitstruct,24bitstruct等
1564 | 核心思路是把地址和一個隨機時間異或加密,然後把地址對應的command存儲在三層的結構體中
1565 | ,這樣每次保持的地址和時間值都不一樣,反過來根據command來查找對應加密的梉,後面解密。
1566 |
1567 | 它記錄的地址實際還不是真正的程序地址,是梉,它還需要進一步去unpack才能進入真正的邏輯。
1568 |
1569 | commandNative函數查找時,command 分爲三個主要參數 :
1570 | command / 10000,
1571 | command % 10000 / 100,
1572 | command % 100
1573 | 用這三個參數查找一個嵌套的結構體,找到與這三個結構體三層都一致的結構體
1574 | 然後用之前記錄的時間和異或后的值再次異或就得到了跳轉地址。
1575 |
1576 |
--------------------------------------------------------------------------------
/libsg6.4.36/patches.py:
--------------------------------------------------------------------------------
1 | patches = {}
2 | patches[0] = (0x00, 0xbf, 0x01, 0x48, 0x00, 0x68, 0x02, 0xe0)
3 | patches[1] = (0x00, 0xbf, 0x01, 0x49, 0x09, 0x68, 0x02, 0xe0)
4 | patches[2] = (0x00, 0xbf, 0x01, 0x4a, 0x12, 0x68, 0x02, 0xe0)
5 | patches[3] = (0x00, 0xbf, 0x01, 0x4b, 0x1b, 0x68, 0x02, 0xe0)
6 | patches[4] = (0x00, 0xbf, 0x01, 0x4c, 0x24, 0x68, 0x02, 0xe0)
7 | patches[5] = (0x00, 0xbf, 0x01, 0x4d, 0x2d, 0x68, 0x02, 0xe0)
8 | patches[8] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0x80, 0xd8, 0xf8, 0x00, 0x80, 0x01, 0xe0)
9 | patches[9] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0x90, 0xd9, 0xf8, 0x00, 0x90, 0x01, 0xe0)
10 | patches[10] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0xa0, 0xda, 0xf8, 0x00, 0xa0, 0x01, 0xe0)
11 | patches[11] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0xb0, 0xdb, 0xf8, 0x00, 0xb0, 0x01, 0xe0)
12 |
13 | ea = here()
14 |
15 | if (Word(ea) == 0xb082 #SUB SP, SP, #8
16 | and Word(ea + 2) == 0xb503): #PUSH {R0,R1,LR}
17 | if GetOpType(ea + 4, 0) == 7:
18 | pop = GetManyBytes(ea + 12, 4, 0)
19 | if ord(pop[1]) == 0xbc:
20 | register = -1
21 | r = Byte(ea + 12)
22 | for i in range(8):
23 | if r == (1 << i):
24 | register = i
25 | break
26 | if register == -1:
27 | print "Unable to detect register"
28 | else:
29 | address = Dword(ea + 8) + ea + 8
30 | for b in patches[register]:
31 | PatchByte(ea, b)
32 | ea += 1
33 | if ea % 4 != 0:
34 | ea += 2
35 | PatchDword(ea, address)
36 | elif ord(pop[:3]) == 0x4f85d:
37 | register = ord(pop[3]) >> 4
38 | if register in patches:
39 | address = Dword(ea + 8) + ea + 8
40 | for b in patches[register]:
41 | PatchByte(ea, b)
42 | ea += 1
43 | PatchDword(ea, address)
44 | else:
45 | print "POP instruction not found"
46 | else:
47 | print "Wrong operand type on +4:", GetOpType(ea + 4, 0)
48 | else:
49 | print "Unable to detect first instructions"
--------------------------------------------------------------------------------
/libsg6.4.36/put_unconditional_branch.py:
--------------------------------------------------------------------------------
1 | from idaapi import *
2 | import idc
3 | import idautils
4 |
5 | def put_unconditional_branch(source, destination):
6 | offset = (destination - source - 4) >> 1
7 | if offset > 2097151 or offset < -2097152:
8 | raise RuntimeError("Invalid offset")
9 | if offset > 1023 or offset < -1024:
10 | instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
11 | instruction2 = 0xb800 | (offset & 0x7ff)
12 | patch_word(source, instruction1)
13 | patch_word(source + 2, instruction2)
14 | else:
15 | instruction = 0xe000 | (offset & 0x7ff)
16 | patch_word(source, instruction)
17 |
18 | ea = here()
19 | if Word(ea) == 0xb503: #PUSH {R0,R1,LR}
20 | ea1 = ea + 2
21 | if Word(ea1) == 0xbf00: #NOP
22 | ea1 += 2
23 | if GetOpType(ea1, 0) == 1 and GetOperandValue(ea1, 0) == 0 and GetOpType(ea1, 1) == 2:
24 | index = Dword(GetOperandValue(ea1, 1))
25 | print "index =", hex(index)
26 | ea1 += 2
27 | if GetOpType(ea1, 0) == 7:
28 | table = GetOperandValue(ea1, 0) + 4
29 | elif GetOpType(ea1, 1) == 2:
30 | table = GetOperandValue(ea1, 1) + 4
31 | else:
32 | print "Wrong operand type on", hex(ea1), "-", GetOpType(ea1, 0), GetOpType(ea1, 1)
33 | table = None
34 | if table is None:
35 | print "Unable to find table"
36 | else:
37 | print "table =", hex(table)
38 | offset = Dword(table + (index << 2))
39 | put_unconditional_branch(ea, table + offset)
40 | else:
41 | print "Unknown code", GetOpType(ea1, 0), GetOperandValue(ea1, 0), GetOpType(ea1, 1) == 2
42 | else:
43 | print "Unable to detect first instruction"
--------------------------------------------------------------------------------
/libsg6.4.36/put_unconditional_branch1.py:
--------------------------------------------------------------------------------
1 | def put_unconditional_branch1(source, destination):
2 | offset = (destination - source - 4) >> 1
3 | if offset > 2097151 or offset < -2097152:
4 | raise RuntimeError("Invalid offset")
5 | if offset > 1023 or offset < -1024:
6 | instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
7 | instruction2 = 0xb800 | (offset & 0x7ff)
8 | PatchWord(source, instruction1)
9 | PatchWord(source + 2, instruction2)
10 | else:
11 | instruction = 0xe000 | (offset & 0x7ff)
12 | PatchWord(source, instruction)
13 |
14 | # ea = here()
15 | def patch1(ea):
16 | ea0 = ea
17 | if Word(ea) == 0xb503: #PUSH {R0,R1,LR}
18 | ea1 = ea + 6
19 | if Word(ea + 2) == 0xbf00: #NOP
20 | ea1 += 2
21 | offset = Dword(ea1)
22 | put_unconditional_branch1(ea, (ea1 + offset) & 0xffffffff)
23 | ea0 = ea1 - ea0
24 | else:
25 | print "Unable to detect first instruction"
26 |
27 | return ea0
28 |
29 |
30 | code_start = 0xb110 # JNI_OnLoad
31 | code_end = 0x886e0
32 | while (code_start <= code_end):
33 | flag = patch1(code_start)
34 | if (flag == 8) :
35 | code_start = code_start + 8
36 | else:
37 | code_start = code_start + 1
38 |
--------------------------------------------------------------------------------
/libsg6.4.36/sub_14FEE.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int sub_14FEE(_JNIEnv *a1, int a2, int a3, int a4)
14 | {
15 | _JNIEnv *v4; // r4@1
16 | int v5; // r5@3
17 | const struct JNINativeInterface *v6; // r1@3
18 | int v7; // r2@3
19 | char v8; // r1@5
20 | int *v9; // r0@5
21 | int v11; // [sp+0h] [bp-8h]@0
22 | int v12; // [sp+4h] [bp-4h]@0
23 | int savedregs; // [sp+8h] [bp+0h]@0
24 | int savedregs_4; // [sp+Ch] [bp+4h]@0
25 |
26 | v4 = a1;
27 | if ( !a1 )
28 | {
29 | v8 = 0;
30 | v9 = &dword_B3EB5B04;
31 | LABEL_7:
32 | *(_BYTE *)v9 = v8;
33 | return 0;
34 | }
35 | if ( !(_BYTE)dword_B3EB5B04 )
36 | {
37 | v5 = 0;
38 | v6 = a1->functions;
39 | dword_B3EB5B0C = (int)a1->functions->GetFieldID;
40 | dword_B3EB5B1C = (int)v6->GetStaticFieldID;
41 | v7 = (int)v6->GetMethodID;
42 | dword_B3EB5B10 = (int)v6->GetMethodID;
43 | dword_B3EB5B20 = (int)v6->GetStaticMethodID;
44 | do
45 | sub_1511C((int)v4, v5++, v7, a4, v11, v12, savedregs, savedregs_4);
46 | while ( v5 != 9 );
47 | v8 = 1;
48 | v9 = &dword_B3EB5B04;
49 | goto LABEL_7;
50 | }
51 | return 0;
52 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_1511C.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int sub_1511C(_JNIEnv *a1, int a2, int a3)
14 | {
15 | int v4; // lr@0
16 | _JNIEnv *v5; // r11@1
17 | int v6; // r1@1
18 | int v7; // r4@1
19 | int v8; // r2@1
20 | int *v9; // r2@1
21 | _BYTE *v10; // r0@1
22 | int v11; // t1@1
23 | int v12; // r0@1
24 | int v13; // r1@1
25 | int v14; // r2@1
26 | int v15; // [sp-20h] [bp-38h]@1
27 | int v16; // [sp-1Ch] [bp-34h]@1
28 | _JNIEnv *v17; // [sp-14h] [bp-2Ch]@1
29 | int v18; // [sp-10h] [bp-28h]@1
30 | int v19; // [sp-Ch] [bp-24h]@1
31 | int v20; // [sp+4h] [bp-14h]@1
32 | _BYTE savedregs[24]; // [sp+18h] [bp+0h]@4
33 |
34 | v5 = a1;
35 | v17 = a1;
36 | v18 = a2;
37 | v19 = v4;
38 | dyna_arg(a1, a2, a3);
39 | v7 = v6;
40 | v15 = v6;
41 | v16 = v4;
42 | v9 = *(int **)(dyna_arg(v17, v6, v8) - 1276911288);
43 | v10 = *(_BYTE **)((char *)&v17[4 * v7 - 319227820] - 2);
44 | v20 = *v9;
45 | v11 = *v10;
46 | // 解密出"android/content/Context"
47 | goto_dcrypto_entry(v10 + 1, (char *)&v15 - (((_WORD)v11 + 8) & 0x1F8), v11 + 1);
48 | ((void (__fastcall *)(_JNIEnv *, char *))v5->functions->FindClass)(v5, (char *)&v15 - (((_WORD)v11 + 8) & 0x1F8));
49 | v12 = ((int (__fastcall *)(_JNIEnv *))goto_check_exception)(v5);
50 | if ( !v12 )
51 | {
52 | dyna_arg(0, v13, v14);
53 | dyna_pc(3);
54 | JUMPOUT(2);
55 | }
56 | *(_DWORD *)&savedregs[4] = v12;
57 | *(_DWORD *)&savedregs[8] = v13;
58 | *(_DWORD *)&savedregs[12] = v4;
59 | dyna_arg(v12, v13, v14);
60 | return **(_DWORD **)(*(_DWORD *)&savedregs[4] - 1276911362) - v20;
61 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_2A01E.c:
--------------------------------------------------------------------------------
1 | int sub_2A01E(int a1, int a2)
2 | { // 參數1是第一個jarray的值,參數2不知道是啥,第一次傳0
3 | int v2; // r8@1
4 | int v3; // r5@2
5 | int v4; // r0@4
6 | int v5; // r6@4
7 | int v6; // r0@6
8 | int v7; // r0@6
9 | int v8; // r0@8
10 | int v9; // r4@10
11 | int v11; // [sp+4h] [bp-20h]@14
12 | int v12; // [sp+8h] [bp-1Ch]@14
13 | int v13; // [sp+Ch] [bp-18h]@14
14 | int v14; // [sp+10h] [bp-14h]@14
15 | int v15; // [sp+14h] [bp-10h]@1
16 |
17 | v2 = a2;
18 | v15 = *(_DWORD *)off_8AC00;
19 | if ( *(_DWORD *)(a1 + 4) )
20 | v3 = *(_DWORD *)a1;
21 | else
22 | v3 = sub_2AD20();
23 | v4 = sub_32C00(v3);
24 | v5 = v4;
25 | if ( v4 && *(_DWORD *)(v4 + 4) >= 32 )
26 | {
27 | v9 = sub_7B5D4(v4);
28 | goto LABEL_15;
29 | }
30 | v6 = goto_free_vdata(v4);
31 | v7 = sub_2B468(v6);
32 | v5 = v7;
33 | if ( !v7 || !*(_DWORD *)(v7 + 4) )
34 | {
35 | goto_free_vdata(v7);
36 | v8 = go_create_vadata(25);
37 | v5 = v8;
38 | if ( !v8 )
39 | {
40 | v9 = 0;
41 | v5 = 0;
42 | goto LABEL_14;
43 | }
44 | (*(void (**)(void))(v8 + 12))();
45 | if ( !*(_DWORD *)(v5 + 4) )
46 | {
47 | v9 = 0;
48 | goto LABEL_14;
49 | }
50 | }
51 | v9 = sub_7B5D4(v5);
52 | LABEL_14:
53 | v11 = v3;
54 | v12 = 0;
55 | v13 = 0;
56 | v14 = 1;
57 | sub_29E98(&v11, v2);
58 | LABEL_15:
59 | goto_free_vdata(v5);
60 | if ( *(_DWORD *)off_8AC00 != v15 )
61 | _stack_chk_fail(*(_DWORD *)off_8AC00 - v15, v15);
62 | return v9;
63 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_2AC24.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | signed int sub_2AC24(int a1)
14 | {
15 | int v1; // r4@1
16 |
17 | v1 = a1;
18 | if ( a1 )
19 | {
20 | pthread_mutex_lock(&plock);
21 | if ( !dword_B3FB9E0C )
22 | dword_B3FB9E0C = v1;
23 | pthread_mutex_unlock(&plock);
24 | }
25 | return 1;
26 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_2B4BE.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int call_docommand_innerx()
14 | {
15 | int v0; // r4@1
16 | int v1; // r0@1
17 | const char *v2; // r5@1
18 | size_t v3; // r0@3
19 | void (__fastcall *v4)(int, const char *, size_t); // r6@4
20 | size_t v5; // r0@4
21 | int v7; // [sp+4h] [bp-14h]@1
22 | int v8; // [sp+8h] [bp-10h]@1
23 |
24 | v0 = 0;
25 | v8 = *(_DWORD *)off_8AC00;
26 | v7 = 0;
27 | sub_73D90(); // 保存著包含do_command_inner的結構
28 | // v1 + 4 指向的是do_command_inner的函數指針
29 | v2 = (const char *)(*(int (__fastcall **)(signed int, signed int, signed int, signed int))(v1 + 4))(1, 9, 2, 111);
30 | if ( v2 )
31 | { // 調試時返回0
32 | if ( *v2 && (v3 = strlen(v2), (v0 = goto_create_vadata(v3 + 1)) != 0) ) // 這裏應該包含一個解密,解密出一個結構
33 | {
34 | v4 = *(void (__fastcall **)(int, const char *, size_t))(v0 + 12);
35 | v5 = strlen(v2);
36 | v4(v0, v2, v5);
37 | }
38 | else
39 | {
40 | v0 = 0;
41 | }
42 | free((void *)v2);
43 | }
44 | if ( *(_DWORD *)off_8AC00 != v8 )
45 | _stack_chk_fail(*(_DWORD *)off_8AC00 - v8, v8);
46 | return v0;
47 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_2D1DA.c:
--------------------------------------------------------------------------------
1 | int __fastcall sub_2D1DA(unsigned int a1, int a2)
2 | { // 參數1是jarray第一個值,參數2是程序傳遞下來的9
3 | int v2; // r5@1
4 | unsigned int v3; // r4@1
5 | int v4; // r8@1
6 | int v5; // r0@1
7 | int v6; // r6@1
8 | int v7; // r0@3
9 |
10 | v2 = a2;
11 | v3 = a1;
12 | v4 = goto_make_vdata6436(a1, a2);
13 | v5 = goto_read_off_8AA50(v3, v2);
14 | v6 = v5;
15 | if ( !v5 || !*(_DWORD *)(v5 + 4) )
16 | {
17 | goto_free_vdata(v5);
18 | v7 = sub_30D24(v4);
19 | v6 = v7;
20 | if ( v7 )
21 | {
22 | if ( *(_DWORD *)(v7 + 4) )
23 | sub_302C8(v7, v3, v2);
24 | }
25 | else
26 | {
27 | v6 = 0;
28 | }
29 | }
30 | goto_free_vdata(v4);
31 | return v6;
32 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_301DE.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | vdata* sub_301DE(unsigned int a1, unsigned int a2)
14 | { // 參數1是jarray第一個值,參數2是程序傳遞下來的9
15 | unsigned __int8 v2; // cf@1
16 | char v3; // zf@1
17 | vdata *v4; // r4@1
18 | int *v5; // r0@6
19 | int v6; // r5@9
20 | int v7; // r0@9
21 | void (__fastcall *v8)(vdata *, int, int); // r6@9
22 | int v9; // r0@9
23 |
24 | v2 = a1 >= 2;
25 | v3 = a1 == 2;
26 | v4 = 0;
27 | if ( a1 <= 2 )
28 | {
29 | v2 = a2 >= 9;
30 | v3 = a2 == 9;
31 | }
32 | if ( !(!v3 & v2) )
33 | {
34 | if ( a1 == 2 )
35 | {
36 | v5 = (int *)&off_8A9F8; // off_8A9F8
37 | }
38 | else if ( a1 == 1 )
39 | {
40 | v5 = &off_8A9D0; // off_8A9D0
41 | }
42 | else
43 | {
44 | v5 = &off_8AA20; // off_8AA20
45 | }
46 | v6 = v5[a2]; // "d8b057995e905838"
47 | v7 = strlen(v5[a2]);
48 | v4 = (vdata *)goto_create_vdata(v7 + 1);
49 | v8 = (void (__fastcall *)(vdata *, int, int))v4->f1;
50 | v9 = strlen(v6);
51 | v8(v4, v6, v9); // make_vdata
52 | }
53 | return v4;
54 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_3026A.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int __fastcall read_off_8AA50(unsigned int off, int index)
14 | {
15 | unsigned int v2; // r4@1
16 | int v3; // r5@1
17 | bool v4; // zf@2
18 | int v5; // r0@6
19 | int v6; // r4@8
20 |
21 | v2 = off;
22 | v3 = index;
23 | if ( off > 2 )
24 | goto LABEL_15;
25 | v4 = (index | 4) == 7;
26 | if ( (index | 4) != 7 )
27 | v4 = (index | 9) == 9;
28 | if ( v4 )
29 | {
30 | pthread_mutex_lock((pthread_mutex_t *)&pthread_lock);
31 | // 第一次計算off_8AA50[9] = 0xB3EF7E54 = 文件偏移8CE54
32 | // 第二次計算 [0xB3EF7E54 + 4] = 0
33 | // libsgmainso_6.4.36.so:B3EF7E58 DCD 0
34 | v5 = *(_DWORD *)(off_8AA50[index] + 4 * off);
35 | if ( v5 && *(_DWORD *)(v5 + 4) ) // 不成立
36 | v6 = (*(int (**)(void))(v5 + 40))();
37 | else
38 | v6 = 0; // 返回0
39 | pthread_mutex_unlock((pthread_mutex_t *)&pthread_lock);
40 | }
41 | else
42 | {
43 | LABEL_15:
44 | v6 = 0;
45 | }
46 | return v6;
47 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_305BE.c:
--------------------------------------------------------------------------------
1 | int __fastcall sub_305BE(unsigned int a1, signed int a2)
2 | {
3 | unsigned int v2; // r5@1
4 | signed int v3; // r6@1
5 | int v4; // r4@2
6 | int v5; // r0@3
7 | int v6; // r0@5
8 |
9 | v2 = a1;
10 | v3 = a2;
11 | if ( a1 <= 2 )
12 | {
13 | v5 = goto_read_off_8AA50(a1, 9);
14 | v4 = v5;
15 | if ( !v5 || !*(_DWORD *)(v5 + 4) )
16 | {
17 | v6 = sub_2D228(v2);
18 | v4 = v6;
19 | if ( v6 && *(_DWORD *)(v6 + 4) )
20 | {
21 | sub_302C8(v6, v2, 9);
22 | }
23 | else if ( v3 >= 1 )
24 | {
25 | sub_304E4(v2, 0);
26 | }
27 | }
28 | }
29 | else
30 | {
31 | v4 = 0;
32 | }
33 | return v4;
34 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_30D60.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int sub_30D60(vdata_6436 *a1)
14 | {
15 | __int64 v1; // kr00_8@1
16 | int v2; // r5@1
17 | int v3; // r0@1
18 | int v4; // r4@1
19 | int v6; // [sp+4h] [bp-1Ch]@1
20 | int v7; // [sp+8h] [bp-18h]@1
21 | int v8; // [sp+Ch] [bp-14h]@1
22 | int v9; // [sp+10h] [bp-10h]@1
23 | int v10; // [sp+14h] [bp-Ch]@1
24 |
25 | v10 = *(_DWORD *)off_8AC00;
26 | v6 = 0;
27 | v1 = *(_QWORD *)&a1->data;
28 | v2 = geto_create_vdata32(a1->data, a1->data_len); // sub_7C258
29 | v7 = v2; // vdata32
30 | v8 = 1;
31 | v9 = 7;
32 | v3 = sub_73D90(); // 讀取90804的值到寄存器r0, 調試時為ACB3B600
33 | // v3 + 4 = 0x9df5, 最終是sub_9E30,即goto_docommand_native_inner
34 | v4 = (*(int (__fastcall **)(signed int, signed int, signed int, int *))(v3 + 4))(1, 21, 2, &v7);
35 | goto_callfree(v2);
36 | if ( *(_DWORD *)off_8AC00 != v10 )
37 | _stack_chk_fail(*(_DWORD *)off_8AC00 - v10, v10);
38 | return v4;
39 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_32C46.c:
--------------------------------------------------------------------------------
1 | int __fastcall sub_32C46(unsigned int a1)
2 | { // 第一個jarray的值,這裏為1
3 | unsigned int v1; // r6@1
4 | int v2; // r4@2
5 | int v3; // r2@3
6 | int v4; // r5@3
7 | int v5; // r0@4
8 | int v7; // r0@9
9 | int v8; // r8@9
10 | int v9; // r2@9
11 | int v10; // r0@9
12 | int v11; // r6@9
13 |
14 | v1 = a1;
15 | if ( a1 > 2 )
16 | return 0;
17 | v4 = sub_30590();
18 | if ( v4 || (sub_32CC8(0, v1, v3), (v4 = v5) != 0) && *(_DWORD *)(v5 + 4) )
19 | {
20 | v2 = (*(int (__fastcall **)(int))(v4 + 40))(v4);
21 | LABEL_7:
22 | goto_free_vdata(v4);
23 | return v2;
24 | }
25 | goto_free_vdata(v5);
26 | v2 = 0;
27 | v7 = sub_30240(v1, 0);
28 | v8 = v7;
29 | sub_32CC8(v7, v1, v9);
30 | v11 = v10;
31 | v4 = 0;
32 | if ( v10 )
33 | {
34 | if ( *(_DWORD *)(v10 + 4) )
35 | v2 = (*(int (__fastcall **)(int))(v10 + 40))(v10);
36 | else
37 | v2 = 0;
38 | v4 = v11;
39 | }
40 | if ( v8 )
41 | goto_free_vdata(v8);
42 | if ( v4 )
43 | goto LABEL_7;
44 | return v2;
45 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_32F44.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int __fastcall sub_32F44(unsigned int a1)
14 | {
15 | unsigned int v1; // r4@1
16 | int v2; // r0@2
17 | int v3; // r4@4
18 |
19 | v1 = a1;
20 | pthread_mutex_lock((pthread_mutex_t *)&pthread_lock_0);
21 | if ( v1 <= 2 && (v2 = dword_8CE6C[v1]) != 0 && *(_DWORD *)(v2 + 4) )
22 | v3 = (*(int (**)(void))(v2 + 40))();
23 | else
24 | v3 = 0;
25 | pthread_mutex_unlock((pthread_mutex_t *)&pthread_lock_0);
26 | return v3;
27 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_72080.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | void sub_72080(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
14 | {
15 | int v9; // r1@4
16 | _JNIEnv *v10; // r4@0
17 | int v11; // r5@0
18 | int v12; // r7@0
19 | int v13; // r2@1
20 | int v14; // ST08_4@2
21 | int v15; // r1@2
22 | int v16; // r2@2
23 |
24 | *(_DWORD *)(v12 - 16) = a1;
25 | goto_decrypt_entry(a2 + 1, v11, a3);
26 | // "com/taobao/wireless/security/adapter/common/SPUtility2"
27 | if ( ((int (__fastcall *)(_JNIEnv *, int))v10->functions->FindClass)(v10, v11) )
28 | {
29 | v14 = ((int (__fastcall *)(_JNIEnv *))v10->functions->NewGlobalRef)(v10);
30 | *(_DWORD *)(v14 - 1275465542) = dyna_arg(v14, v15, v16);
31 | JUMPOUT(&goto_dynapc2);
32 | }
33 | dyna_arg(0, 0, v13);
34 | v9 = *(_DWORD *)(v12 - 16);
35 | JUMPOUT(__CS__, a9);
36 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_73668.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | signed int __fastcall sub_73668(int a1, int a2, int a3, int a4)
14 | {
15 | signed int v4; // r5@1
16 | int v5; // r3@1
17 | _JNIEnv *v6; // r0@1
18 | _JNIEnv *v7; // r4@1
19 | int v8; // r0@2
20 | int v9; // r5@2
21 | int v10; // r3@3
22 | int v12; // [sp+0h] [bp-10h]@2
23 | int v13; // [sp+4h] [bp-Ch]@1
24 | int v14; // [sp+8h] [bp-8h]@2
25 | int v15; // [sp+Ch] [bp-4h]@2
26 |
27 | v4 = 0;
28 | goto_getenv(0, a2, a3, a4, *(_DWORD *)off_8AC00, v13);
29 | v7 = v6;
30 | if ( v6 )
31 | {
32 | call_decrypto_entry((int)&unk_860DC, (int)(&v12 - 14), 54, v5, v12, v13, v14, v15);
33 | // "com/taobao/wireless/security/adapter/umid/UmidAdapter"
34 | v8 = ((int (__fastcall *)(_JNIEnv *, int *))v7->functions->FindClass)(v7, &v12 - 14);
35 | v9 = v8;
36 | if ( v8 )
37 | {
38 | UmidAdapterRef = ((int (__fastcall *)(_JNIEnv *, int))v7->functions->NewGlobalRef)(v7, v8);
39 | ((void (__fastcall *)(_JNIEnv *, int))v7->functions->DeleteLocalRef)(v7, v9);
40 | call_decrypto_entry((int)&unk_86113, (int)(&v12 - 4), 16, v10, v12, v13, v14, v15);
41 | v4 = 1;
42 | // umidInitAdapter methodID
43 | umidInitAdapterMethodId = ((int (__fastcall *)(_JNIEnv *, int, int *, const char *))v7->functions->GetStaticMethodID)(
44 | v7,
45 | UmidAdapterRef,
46 | &v12 - 4,
47 | "(I)I");
48 | }
49 | else
50 | {
51 | v4 = 0;
52 | }
53 | }
54 | if ( *(_DWORD *)off_8AC00 != v12 )
55 | _stack_chk_fail(*(_DWORD *)off_8AC00 - v12, v12);
56 | return v4;
57 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_73e56.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int __fastcall decrypt_entry(int encdata, int decdata, int datalen)
14 | {
15 | int v3; // r10@1
16 | int v4; // r6@1
17 | int v5; // r5@1
18 | int v6; // r8@1
19 | vdata *v7; // r11@1
20 | vdata *v8; // r9@1
21 | int v9; // r4@4
22 | int v10; // r5@5
23 | int v11; // r0@5
24 | struct dcryptdata* v13; // [sp+0h] [bp-30h]@5
25 | int v14; // [sp+4h] [bp-2Ch]@5
26 | vdata *v15; // [sp+10h] [bp-20h]@5
27 | vdata *v16; // [sp+14h] [bp-1Ch]@5
28 | int v17; // [sp+1Ch] [bp-14h]@1
29 | int v18; // [sp+20h] [bp-10h]@1
30 |
31 | v3 = encdata;
32 | v4 = 0;
33 | v5 = datalen;
34 | v6 = decdata;
35 | v18 = _stack_chk_guard;
36 | v17 = 0;
37 | v7 = (vdata *)goto_create_vdata(17);
38 | v8 = (vdata *)goto_create_vdata(v5);
39 | if ( !v7 )
40 | {
41 | v9 = 0;
42 | goto LABEL_12;
43 | }
44 | // make_vdata 填充數據
45 | ((void (__fastcall *)(vdata *, const char *, signed int))v7->f1)(v7, "DcO/lcK+h?m3c*q@", 16);
46 | if ( !v8 )
47 | {
48 | LABEL_9:
49 | v4 = 0;
50 | goto LABEL_10;
51 | }
52 | v4 = 0;
53 | if ( !v3 )
54 | {
55 | LABEL_10:
56 | v9 = 0;
57 | goto LABEL_11;
58 | }
59 | v9 = 0;
60 | if ( v6 )
61 | {
62 | ((void (__fastcall *)(int, int))memset0)(v6, v5);
63 | v10 = v5 - 1;
64 | // make_vdata 填充數據
65 | ((void (__fastcall *)(vdata *, int, int))v8->f1)(v8, v3, v10);
66 | ((void (__fastcall *)(int *, signed int))memset0)(&v13, 20);
67 | v14 = 3;
68 | v15 = v7;
69 | v16 = v8;
70 | // 調用rc4解密
71 | // 解密出"com/taobao/wireless/security/adapter/common/HttpUtil"
72 | v11 = ((int (__fastcall *)(int *, int *))goto_dcrypto)(&v13, &v17);
73 | v9 = v11;
74 | if ( v11 )
75 | {
76 | if ( *(_DWORD *)(v11 + 4) != v10 )
77 | goto LABEL_19;
78 | // 拷貝到傳入的緩衝區
79 | ((void (__fastcall *)(int, _DWORD, int))memcpy)(v6, *(_DWORD *)v11, v10);
80 | v4 = *(_DWORD *)(v9 + 4);
81 | goto LABEL_11;
82 | }
83 | goto LABEL_9;
84 | }
85 | LABEL_11:
86 | while ( 1 )
87 | {
88 | ((void (__fastcall *)(vdata *))goto_free_vdata)(v7);
89 | LABEL_12:
90 | if ( v8 )
91 | ((void (__fastcall *)(vdata *))goto_free_vdata)(v8);
92 | if ( v9 )
93 | ((void (__fastcall *)(int))goto_free_vdata)(v9);
94 | if ( _stack_chk_guard == v18 )
95 | break;
96 | ((void (__fastcall *)(int))unk_B3F3113C)(_stack_chk_guard - v18);
97 | LABEL_19:
98 | v4 = 0;
99 | }
100 | return v4;
101 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_77dbc.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | void sub77dbc(int a1, int a2, int a3) {
14 | int v3; // r0@5
15 | int v4; // r5@0
16 | int v5; // r6@0
17 | int v6; // lr@0
18 | _JNIEnv *v7; // r4@1
19 | int v8; // ST38_4@1
20 | int v9; // r1@1
21 | int v10; // r0@1
22 | int v11; // r1@1
23 | int v12; // r2@1
24 | int v13; // r0@2
25 | int v14; // ST18_4@2
26 | int v15; // r1@2
27 | int v16; // r2@2
28 | int v17; // r0@2
29 | int v18; // r1@2
30 | int v19; // r2@2
31 | char v20; // [sp+37h] [bp-45h]@1
32 | int v21; // [sp+6Ch] [bp-10h]@1
33 | _BYTE savedregs[24]; // [sp+7Ch] [bp+0h]@4
34 |
35 | v7 = (_JNIEnv *)a1;
36 | v8 = a1;
37 | dyna_arg(a1, a2, a3);
38 | dyna_arg(v8, v9, 16 * v5);
39 | v21 = **(_DWORD **)(16 * v4 - 1275462166);
40 | goto_decrypt_entry(v8 - 1275462161, &v20, 53);
41 | // "com/taobao/wireless/security/adapter/common/HttpUtil"
42 | v10 = ((int (__fastcall *)(_JNIEnv *, char *))v7->functions->FindClass)(v7, &v20);
43 | if ( v10 )
44 | {
45 | // 創建HttpUtil class
46 | v13 = ((int (__fastcall *)(_JNIEnv *, int))v7->functions->NewGlobalRef)(v7, v10);
47 | v14 = v13;
48 | v17 = dyna_arg(v13, v15, v16);
49 | *(_DWORD *)(v14 - 1275462080) = dyna_arg(v17, v18, v19);
50 | dyna_pc(2);
51 | JUMPOUT(3);
52 | }
53 | *(_DWORD *)&savedregs[4] = 0;
54 | *(_DWORD *)&savedregs[8] = v11;
55 | *(_DWORD *)&savedregs[12] = v6;
56 | dyna_arg(0, v11, v12);
57 | v3 = **(_DWORD **)(*(_DWORD *)&savedregs[4] - 1275462336);
58 | JUMPOUT(__CS__, *(_DWORD *)&savedregs[20]);
59 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_7AFB6.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | struct vdata_6436_nest {
14 | void* nf1;
15 | void* nf2;
16 | void* nf3;
17 | };
18 |
19 | struct vdata_6436 { // 對應版本6.4.36
20 | struct data* data;
21 | int data_len;
22 | int data_mlen; // = len + 1
23 | void* f1;
24 | void* f2;
25 | void* f3;
26 | void* f4;
27 | void* f5;
28 | void* f6;
29 | void* f7;
30 | void* f8;
31 | struct vdata_6436_nest* nest6436;
32 | };
33 |
34 | vdata_6436 *__fastcall create_vdata6436(signed int datalen)
35 | {
36 | int v1; // r5@1
37 | vdata_6436 *v2; // r4@2
38 | vdata_6436 *v3; // r6@2
39 | data *v4; // r6@3
40 | vdata_6436_nest *v5; // r3@4
41 |
42 | v1 = datalen;
43 | if ( datalen < 1 )
44 | goto LABEL_6;
45 | v2 = (vdata_6436 *)malloc(56);
46 | v3 = 0;
47 | if ( v2 )
48 | {
49 | memset(v2, 0, 56);
50 | v2->data_mlen = v1;
51 | v2->data = 0;
52 | v4 = (data *)malloc(v1);
53 | if ( v4 )
54 | {
55 | memset(v4, 0, v1);
56 | v2->data = v4;
57 | v2->data_len = 0;
58 | v2->f1 = &dword_B3EE5A5D;
59 | v2->f3 = sub_B3EE5AE0;
60 | v2->f4 = sub_B3EE5B7C;
61 | v2->f5 = sub_B3EE5BC8;
62 | v5 = (vdata_6436_nest *)&v2->nest6436;
63 | v2->f6 = sub_B3EE5C34;
64 | v2->f7 = sub_B3EE5C9C;
65 | v2->f8 = sub_B3EE5D0C;
66 | v2->f2 = &unk_B3EE5D75;
67 | v3 = v2;
68 | v5->nf1 = sub_B3EE5DE8;
69 | v5->nf2 = sub_B3EE5E38;
70 | v5->nf3 = sub_B3EE5E9C;
71 | return v3;
72 | }
73 | free(v2);
74 | LABEL_6:
75 | v3 = 0;
76 | }
77 | return v3;
78 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_7B606.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | vstring *__fastcall create_vstring(vdata *a1)
14 | {
15 | vdata *v1; // r5@1
16 | vstring *v2; // r4@2
17 | vstring *result; // r0@2
18 | char *v4; // r8@3
19 | void *v5; // r0@4
20 | int v6; // r6@4
21 |
22 | v1 = a1;
23 | if ( !a1 )
24 | return 0;
25 | v2 = (vstring *)malloc(8u);
26 | result = 0;
27 | if ( v2 )
28 | {
29 | v2->str = 0;
30 | v2->len = 0;
31 | result = v2;
32 | v4 = (char *)v1->data_len;
33 | if ( v4 )
34 | {
35 | v5 = malloc((size_t)(v4 + 1));
36 | v6 = (int)v5;
37 | if ( v5 )
38 | {
39 | memset(v5, v4 + 1);
40 | v2->len = v6;
41 | _aeabi_memcpy(v6, v1->data, v4);
42 | v2->str = v4;
43 | return v2;
44 | }
45 | free(v2);
46 | return 0;
47 | }
48 | }
49 | return result;
50 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_7B86C.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | struct data {
14 | char* d;
15 | };
16 |
17 | struct tmp1_nest_struct {
18 | void* tmp1_nf1;
19 | void* tmp1_nf2;
20 | int len;
21 | };
22 |
23 | struct tmp1_vdata {
24 | struct data* datalist;
25 | int chunk_count;
26 | int chunk_size;
27 | void* tmp1_f1;
28 | void* tmp1_f2;
29 | void* tmp1_f3;
30 | struct tmp1_nest_struct tmp1_nest;
31 | };
32 |
33 | tmp1_vdata* sub_7B86C(signed int a1, int a2)
34 | { // create_tmp1_vdata, 第一次傳入0x20, 0
35 | signed int v2; // r5@1
36 | int v3; // r8@1
37 | tmp1_vdata *v4; // r0@2
38 | tmp1_vdata *v5; // r4@2
39 | struct data *v6; // r0@3
40 | struct data *v7; // r6@3
41 | tmp1_nest_struct *v8; // r0@4
42 |
43 | v2 = a1; // 傳入為0x20
44 | v3 = a2;
45 | if ( a1 < 1 )
46 | return 0;
47 | v4 = (tmp1_vdata *)malloc(0x24u);
48 | v5 = v4;
49 | if ( !v4 )
50 | return 0;
51 | memset(v4, 36);
52 | v6 = (struct data *)malloc(4 * v2); // 0x80 = 128
53 | v7 = v6;
54 | if ( !v6 )
55 | {
56 | free(v5);
57 | return 0;
58 | }
59 | memset(v6, 4 * v2);
60 | v5->data = v7;
61 | v5->chunk_count = 0;
62 | v5->chunk_size = v2;
63 | v5->tmp1_f1 = sub_7B8F8;
64 | v8 = &v5->tmp1_nest;
65 | v5->tmp1_f2 = sub_7B9B4;
66 | v5->tmp1_f3 = byte_7B9F5;
67 | v8->tmp1_nf1 = sub_7BA80;
68 | v8->tmp1_nf2 = sub_7BAF0;
69 | v8->len = v3;
70 | return v5;
71 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_7B93A.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | signed int __fastcall make_command_vdata(command_vdata *vdata, int index, $8bitstruct *a3)
14 | {
15 | command_vdata *gcommand_build_vdata; // r4@1
16 | $8bitstruct *first_8bitstr_ptr; // r9@1
17 | int v5; // r6@1
18 | signed int result; // r0@2
19 | int data_count; // r1@3
20 | int new_extend_data; // r0@5
21 | int data_size; // r8@6
22 | int v10; // r0@8
23 | int v11; // r2@8
24 |
25 | gcommand_build_vdata = vdata;
26 | first_8bitstr_ptr = a3;
27 | v5 = index;
28 | if ( !vdata )
29 | return 0;
30 | result = 0;
31 | if ( index < 0 )
32 | return result;
33 | data_count = gcommand_build_vdata->data_count;
34 | if ( data_count < v5 )
35 | return result;
36 | if ( data_count == gcommand_build_vdata->data_size )
37 | {
38 | new_extend_data = realloc(gcommand_build_vdata->datalist, 4 * data_count + 128);
39 | if ( new_extend_data )
40 | {
41 | gcommand_build_vdata->datalist = (struct data **)new_extend_data;
42 | data_size = gcommand_build_vdata->data_size;
43 | memset(new_extend_data + 4 * data_size, 128);
44 | gcommand_build_vdata->data_size = data_size + 32;
45 | data_count = gcommand_build_vdata->data_count;
46 | goto LABEL_7;
47 | }
48 | return 0;
49 | }
50 | LABEL_7:
51 | if ( data_count != v5 )
52 | { // 雖然這段代碼可能不會執行,但是感覺這段代碼明顯存在bug
53 | // 應該是while(v10) 可能永遠為true
54 | v10 = v5 - data_count;
55 | v11 = data_count;
56 | do
57 | {
58 | ++v10;
59 | gcommand_build_vdata->datalist[v11] = gcommand_build_vdata->datalist[v11 - 1];
60 | --v11;
61 | }
62 | while ( v10 );
63 | }
64 | gcommand_build_vdata->datalist[v5] = (struct data *) first_8bitstr_ptr;
65 | gcommand_build_vdata->data_count = data_count + 1;
66 | return 1;
67 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_7C10C.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | struct vdata32_nest {
14 | void* nf1;
15 | void* nf2;
16 | void* nf3;
17 | void* nf4;
18 | };
19 |
20 | struct vdata32 {
21 | struct data* data128;
22 | int data_count;
23 | int chunk_size;
24 | void* f1; // goto_make_vdata32;
25 | struct vdata32_nest* nest;
26 | };
27 |
28 | vdata32 *create_vdata32()
29 | {
30 | vdata32 *v0; // r0@1
31 | vdata32 *v1; // r4@1
32 | struct data *v2; // r0@2
33 | struct data *v3; // r5@2
34 | vdata32_nest *v4; // r12@3
35 |
36 | v0 = (vdata32 *)malloc(0x20u);
37 | v1 = v0;
38 | if ( !v0 )
39 | return 0;
40 | memset(v0, 32);
41 | v2 = (struct data *)malloc(0x80u);
42 | v3 = v2;
43 | if ( !v2 )
44 | {
45 | free(v1);
46 | return 0;
47 | }
48 | memset(v2, 128);
49 | v4 = (vdata32_nest *)&v1->nest;
50 | v1->data128 = v3;
51 | v1->chunk_size = 128;
52 | v1->f1 = sub_7C180;
53 | v4->nf1 = sub_7C3C0;
54 | v4->nf2 = sub_7C280; // make_vdata32
55 | v4->nf3 = sub_7C43C;
56 | v4->nf4 = sub_7C49C;
57 | return v1;
58 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_9970.c:
--------------------------------------------------------------------------------
1 | void sub_9970()
2 | {
3 | int v0; // r5@0
4 | int v1; // r6@0
5 | int v2; // r9@0
6 | int v3; // r1@1
7 | int v4; // r2@1
8 | int v5; // r3@1
9 | int v6; // r4@1
10 | int v7; // r1@2
11 | int v8; // r0@3
12 | int v9; // r0@3
13 | int v10; // ST04_4@3
14 |
15 | v6 = malloc(24);
16 | if ( !v6 )
17 | {
18 | sub_B3F31998(0, v3, v4, v5);
19 | v6 = v7;
20 | }
21 | ((void (__fastcall *)(int, signed int))memset0)(v6, 24);
22 | *(_DWORD *)v6 = v1;
23 | *(_DWORD *)(v6 + 4) = v2;
24 | v8 = time(0);
25 | v9 = srand48(v8);
26 | *(_QWORD *)(v6 + 8) = lrand48(v9);
27 | *(_DWORD *)(v6 + 16) = goto_create_tmp1vdata(0);
28 | (*(void (__cdecl **)(_DWORD, int))(*(_DWORD *)(v0 + 4) + 16))(*(_DWORD *)(v0 + 4), v6);
29 | v10 = *(_DWORD *)(*(_DWORD *)(v6 + 16) + 4);
30 | dyna_pc(2);
31 | JUMPOUT(5);
32 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_9D82.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int sub_9d82(int n1, int n2, int n3, int w, struct command_arg* arg, int* next_addr) {
14 | // arg 有時候是vdata32類型
15 | struct tmp1_vdata* vdata = &dword_8CA7C;
16 | if (w != 0) {
17 | vdata = &dword_8CA78;
18 | }
19 | // sub_9a14(tmp1_vdata, n1, n2, n3, w, 0)
20 | if(w != 0) {
21 | // create 8bitstruct 正序建立結構
22 | }
23 | // 最外層
24 | datalist = vdata->datalist;
25 |
26 | int i = 0;
27 | struct $8bitstruct* _8bitstruct = NULL;
28 | while(i < n1) {
29 | _8bitstruct = datalist[i]->d; // 取第一層8bitstruct指針
30 | int ra = _8bitstruct->command_arg1; // 第一層命令
31 | if (ra == n1) { // 第一層對比相等
32 | break;
33 | }
34 | i++;
35 | }
36 | // w不爲0,可能返回0x270F、0x26B0、0x26B1
37 | // 這裏暫不做分析
38 | if (_8bitstruct == NULL && w == 0) { // 沒找到的情況
39 | return 0x26b0;
40 | }
41 | //獲取第二層
42 | struct tmp1_vdata* vdata1 = _8bitstruct->vdata;
43 | int count = vdata1->data_count;
44 | i = 0;
45 | struct $24bitstruct _24bitstr = NULL;
46 | while(i < count) {
47 | _24bitstr = vdata1->datalist[i]->d;
48 | int rb = _24bitstr->command_arg2;
49 | if (rb = n2) { // 第二層對比
50 | break;
51 | }
52 | i++;
53 | }
54 | // w不爲0,可能返回0x270F、0x26B0、0x26B1
55 | // 這裏暫不做分析
56 | if(_24bitstr == NULL && w == 0) { // 沒找到的情況
57 | return 0x26b0;
58 | }
59 |
60 | // 獲取第三層
61 | struct tmp1_vdata* vdata2 = _24bitstr->vdata;
62 | count = vdata2->data_count;
63 | i = 0;
64 | struct $16bitstruct _16bitstr = NULL;
65 | while(i < count) {
66 | _16bitstr = vdata2->datalist[i]->d;
67 | int rc = _16bitstr->command_arg3;
68 | if(rc == n3) {
69 | int xor_addr = _16bitstr->xoraddr ^ _24bitstr->time;
70 | *next_addr = xor_addr;
71 | break;
72 | }
73 | i++;
74 | }
75 |
76 |
77 | typedef (*func)(void* void*) nfunc;
78 | nfunc nextf= (nfunc) next_addr;
79 | return nextf(command_arg, next_addr);
80 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_9a14.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | // w = 0代表查找, w = 1代表創建
14 | // n1, n2, n3 為command 三層索引
15 | // build_addr 正向時為被處理地址, 反向時為返回地址
16 | void* pack_or_unpack_command(command_vdata* g_build_vdata, int n1, int n2, int n3, w = 1, void* build_addr) {
17 |
18 | int data_count = g_build_vdata->data_count;
19 | int i = 0;
20 | if (data_count < 1) {
21 | if (w == 0) {
22 | return 0x26b0;
23 | }
24 |
25 | struct $8bitstruct* _8bitstruct = (struct $8bitstruct*) malloc(8); // B4E01130
26 | memset(_8bitstruct, 0, 8);
27 | _8bitstruct->command_arg1 = n1;
28 | // -> 7BB98
29 |
30 | // vdata = ACB4A3F8, datalist = ACB32980
31 | // vdata 初始化略; 默認data_size為120字節
32 | struct command_vdata* second_command_vdata = (struct command_vdata*) malloc(36);
33 |
34 | _8bitstruct->vdata = second_command_vdata;
35 | // make_command_vdata, 填充數據
36 | // 這裏僅僅執行了 vdata->datalist->d = _8bitstruct;
37 | // vdata->data_count++;
38 | g_build_vdata->f2(g_build_vdata, 0, _8bitstruct);
39 |
40 | if(second_command_vdata->data_count < 1) {
41 | if (w == NULL) {
42 | return 0x26B1;
43 | }
44 | // ACB12478
45 | struct $24bitstruct* _24bitstr = (struct $24bitstruct*) malloc(24);
46 | memset(_24bitstr, 0, 24);
47 | _24bitstr->command_arg1 = n1; // command arg1
48 | _24bitstr->command_arg2 = n2; // command arg2
49 | time_t seed;
50 | seed = time(NULL); // 5E58B699
51 | srand(seed);
52 | int random_time = (int) rand() >> 31; // 074D4C00
53 | int c = (int) random_time >> 31; // 0
54 | _24bitstr->time = random_time;
55 | _24bitstr->c = c;
56 | // 創建第三層command_vdata結構
57 | // vdata = ACB4A498; data = ACB32A00
58 | // vdata 初始化略
59 | struct command_vdata* third_command_vdata = (struct command_vdata*) malloc(36);
60 | _24bitstr->vdata = third_command_vdata;
61 | // 這裏僅僅執行了 vdata->datalist->d = _24bitstr;
62 | // vdata->data_count++;
63 | second_command_vdata->f2(second_command_vdata, _24bitstr); // make_command_vdata
64 | if (third_command_vdata->data_count < 1) {
65 | if (w == 0) {
66 | return 0x270F;
67 | }
68 | // ACB3B540
69 | struct $16bitstruct* _16bitstr = (struct $16bitstruct*) malloc(16);
70 | _16bitstr->command_arg1 = n1;
71 | _16bitstr->command_arg2 = n2;
72 | _16bitstr->command_arg3 = n3;
73 | // make_command_vdata, 填充數據
74 | // 這裏僅僅執行了 vdata->datalist->d = _16bitstr;
75 | // vdata->data_count++;
76 | third_command_vdata->f2(third_command_vdata, _16bitstr);// make_command_vdata
77 | // 異或加密地址存儲
78 | _16bitstr->xoraddr = _24bitstr->time ^ build_addr;
79 | return 0;
80 |
81 | } else {
82 | i = 0;
83 | while (i < third_command_vdata->data_count) {
84 | // 這裏後面在說
85 | }
86 | }
87 | } else {
88 | i = 0;
89 | while(i < second_command_vdata->data_count) {
90 | // 這裏後面在說
91 | }
92 |
93 | }
94 | } else {
95 | struct data** datalist = g_build_vdata->datalist;
96 | struct $8bitstruct* _8bitstr = NULL;
97 | for (int i = 0 ; i < g_build_vdata->data_count; i++) {
98 | _8bitstr = datalist[i];
99 | if(_8bitstr->command_arg1 == n1) {
100 | break;
101 | }
102 | }
103 | // 取第二層機構
104 | struct command_vdata* second_command_vdata = _8bitstr->vdata;
105 | if (second_command_vdata->data_count < 1 ) {
106 | return 0x26B1;
107 | }
108 |
109 | datalist = second_command_vdata->datalist;
110 | struct $24bitstruct* _24bitstr = NULL;
111 |
112 | for (int j = 0 ; j < second_command_vdata->data_count ; j++) {
113 | if((struct $24bitstruct*) datalist[i]->command_arg2 == n2) {
114 | _24bitstr = datalist[i];
115 | break;
116 | }
117 | }
118 |
119 | if (w == 0) {
120 | return ??;
121 | }
122 |
123 | if (_24bitstr == NULL) {
124 | _24bitstr = malloc(24);
125 | // 創建$24bitstruct 結構體
126 | // 創建third_command_vdata ACB4A4C0;同上
127 | // 更新second_command_vdata datalist同時data_count++等
128 | // ACB124C0 24bitstr,
129 | // 創建完后調用
130 | }
131 |
132 | // 取第三層
133 | struct $16bitstruct* _16bitstr = NULL;
134 | struct command_vdata* third_command_vdata = _24bitstr->vdata;
135 | if(third_command_vdata->data_count < 1) {
136 |
137 | }
138 |
139 | for (j = 0; j < third_command_vdata->data_count; j++) {
140 | if ((struct $16bitstruct*) third_command_vdata[j]->command_arg3 == n3) {
141 | _16bitstr = third_command_vdata[j];
142 | break;
143 | }
144 | }
145 |
146 | if (w == 0) {
147 | return ??;
148 | }
149 |
150 | if (_16bitstr == NULL) {
151 | _16bitstr = malloc(16);
152 | // ACB11F50
153 | // 創建$16bitstruct; 同上
154 | return 0;
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/libsg6.4.36/sub_9f1c.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | struct global_command_entry { // 記錄著生成和執行command的核心方法
14 | void* goto_make_command_entry; // 對應sub_9B3C; 生成command結構核心算法
15 | void* goto_do_command1; // // 對應sub_9d82; command_native_inner
16 | void* goto_do_command2; // 對應sub_9e7e; 和sub_9d82差不多
17 | };
18 |
19 | signed int make_global_command_ptr()
20 | {
21 | struct global_command_entry *v0; // r4@2
22 | signed int result; // r0@2
23 |
24 | if ( !get_global_command_entryptr() ) // 全局
25 | {
26 | v0 = (global_command_entry *)malloc(12);
27 | result = 0;
28 | if ( !v0 )
29 | return result;
30 | v0->goto_do_command1 = 0;
31 | v0->goto_make_command_entry = 0;
32 | gcommand_vdata1 = goto_create_tmp1vdata_(0); // 全局,記錄有關command結構指針
33 | gcommand_vdata2 = goto_create_tmp1vdata_(0); // 全局,記錄有關command結構指針
34 | v0->goto_make_command_entry = sub_B3E74A98;
35 | v0->goto_do_command1 = sub_B3E74DF4;
36 | v0->goto_do_command2 = sub_B3E74E48;
37 | set_global_command_entryptr(v0);
38 | }
39 | return 1;
40 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_E890.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | int sub_E890(int a1, int a2, int a3, int a4)
14 | {
15 | _JNIEnv *v4; // r4@1
16 | int v5; // r3@1
17 | int v6; // r0@1
18 | int v7; // r5@1
19 | int v8; // r3@2
20 | int result; // r0@3
21 | int v10; // [sp+0h] [bp-70h]@1
22 | int v11; // [sp+4h] [bp-6Ch]@1
23 | int v12; // [sp+8h] [bp-68h]@1
24 | int v13; // [sp+Ch] [bp-64h]@1
25 | char v14; // [sp+4Ah] [bp-26h]@1
26 | int v15; // [sp+60h] [bp-10h]@1
27 |
28 | v4 = (_JNIEnv *)a1;
29 | v15 = *(_DWORD *)off_8AC00;
30 | // "(I)Ljava/lang/String;"
31 | goto_decrypt_entry((int)&unk_841F3, (int)&v14, 22, a4, v10, v11, v12, v13);
32 | // "com/taobao/wireless/security/adapter/datacollection/DeviceInfoCapturer"
33 | goto_decrypt_entry((int)&unk_8420A, (int)&v10 + 3, 71, v5, v10, v11, v12, v13);
34 | v6 = ((int (__fastcall *)(_JNIEnv *, char *))v4->functions->FindClass)(v4, (char *)&v10 + 3);
35 | v7 = v6;
36 | if ( v6 )
37 | {
38 | global_DeviceInfoCapturer_ref = ((int (__fastcall *)(_JNIEnv *, int))v4->functions->NewGlobalRef)(v4, v6);
39 | ((void (__fastcall *)(_JNIEnv *, int))v4->functions->DeleteLocalRef)(v4, v7);
40 | goto_decrypt_entry((int)&unk_84252, (int)(&v10 - 6), 19, v8, v10, v11, v12, v13);
41 | global_DeviceInfoCapturer_methodId = ((int (__fastcall *)(_JNIEnv *, int, int *, char *))v4->functions->GetStaticMethodID)(
42 | v4,
43 | dword_8CA98,
44 | &v10 - 6,
45 | &v14);
46 | }
47 | result = *(_DWORD *)off_8AC00 - v15;
48 | if ( *(_DWORD *)off_8AC00 != v15 )
49 | _stack_chk_fail(result, v15);
50 | return result;
51 | }
--------------------------------------------------------------------------------
/libsg6.4.36/sub_b7f6.c:
--------------------------------------------------------------------------------
1 | /**
2 | * Author: sp00f
3 | * 本人聲明: 該項目僅用於學習和交流目的,不能用於其他目的,否則後果自負;
4 | * 另外該項目所有權僅屬於我個人,你可以下載或者fork該項目,但不能用於其他目的(如發表文章、出書、投稿等),否則必究。
5 | * 你可以吐槽我,不过还是希望尊重我的辛苦成果,有不对的地方,可以指出,大家互相探讨
6 | * 对于逆向我也是个小学生,水平有限,还请大佬们一笑而过
7 | * 出于时间考虑,我分析完之后,没有对调试过程返回来看,但应该大致描述清楚了
8 | * 如果纰漏,请见谅
9 | *
10 | */
11 |
12 |
13 | signed int registerNatives(int a1, int a2)
14 | {
15 | _JNIEnv *v2; // r5@1
16 | void *v3; // r8@1
17 | signed int v4; // r0@1
18 | char v6; // [sp+7h] [bp-55h]@1
19 | char v7; // [sp+30h] [bp-2Ch]@1
20 | char *v8; // [sp+40h] [bp-1Ch]@1
21 | char *v9; // [sp+44h] [bp-18h]@1
22 | void (*v10)(); // [sp+48h] [bp-14h]@1
23 | int v11; // [sp+4Ch] [bp-10h]@1
24 |
25 | v2 = (_JNIEnv *)a1;
26 | v3 = (void *)a2;
27 | v11 = _stack_chk_guard;
28 | ((void (__fastcall *)(void *, char *, signed int))goto_dcrypto_entry)(&unk_B3EEEED9, &v7, 16);
29 | ((void (__fastcall *)(void *, char *, signed int))goto_dcrypto_entry)(&unk_B3EEEEEA, &v6, 41);
30 | v8 = &v7;
31 | v9 = &v6;
32 | v10 = sub_B3E7669C;
33 | v4 = v2->functions->RegisterNatives((JNIEnv *)v2, v3, (const JNINativeMethod *)&v8, 1);
34 | if ( _stack_chk_guard != v11 )
35 | sub_B3E6F13C(v4, _stack_chk_guard - v11);
36 | return v4 >> 31;
37 | }
--------------------------------------------------------------------------------