├── .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 | } --------------------------------------------------------------------------------