From bd8ca5821db23b88ebac9b6dd3c77a18378ffe98 Mon Sep 17 00:00:00 2001 From: xiaochou164 Date: Sat, 12 Aug 2023 17:14:31 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes LICENSE | 674 ++++++++++++++++++ Navicat-Cracker/CollectInformation.cpp | 33 + Navicat-Cracker/GenerateLicense.cpp | 201 ++++++ Navicat-Cracker/NavicatCracker.aps | Bin 0 -> 424976 bytes Navicat-Cracker/NavicatCracker.cpp | 107 +++ Navicat-Cracker/NavicatCracker.h | 32 + Navicat-Cracker/NavicatCracker.rc | Bin 0 -> 20074 bytes Navicat-Cracker/NavicatCracker.vcxproj | 415 +++++++++++ .../NavicatCracker.vcxproj.filters | 141 ++++ Navicat-Cracker/NavicatCracker.vcxproj.user | 7 + Navicat-Cracker/NavicatCrackerDlg.cpp | 563 +++++++++++++++ Navicat-Cracker/NavicatCrackerDlg.h | 126 ++++ Navicat-Cracker/amd64_emulator.cpp | 200 ++++++ Navicat-Cracker/amd64_emulator.hpp | 159 +++++ Navicat-Cracker/base32_rfc4648.cpp | 120 ++++ Navicat-Cracker/base32_rfc4648.hpp | 39 + Navicat-Cracker/base64_rfc4648.cpp | 103 +++ Navicat-Cracker/base64_rfc4648.hpp | 20 + Navicat-Cracker/framework.h | 49 ++ Navicat-Cracker/i386_emulator.cpp | 160 +++++ Navicat-Cracker/i386_emulator.hpp | 152 ++++ Navicat-Cracker/image_interpreter.cpp | 302 ++++++++ Navicat-Cracker/image_interpreter.hpp | 202 ++++++ Navicat-Cracker/keystone_assembler.cpp | 38 + Navicat-Cracker/keystone_assembler.hpp | 54 ++ Navicat-Cracker/navicat_serial_generator.cpp | 194 +++++ Navicat-Cracker/navicat_serial_generator.hpp | 80 +++ Navicat-Cracker/patch_solution.hpp | 19 + Navicat-Cracker/patch_solution_since.hpp | 9 + .../patch_solution_since_16.0.7.0.amd64.cpp | 608 ++++++++++++++++ .../patch_solution_since_16.0.7.0.generic.cpp | 16 + .../patch_solution_since_16.0.7.0.hpp | 35 + .../patch_solution_since_16.0.7.0.i386.cpp | 629 ++++++++++++++++ Navicat-Cracker/pch.cpp | 5 + Navicat-Cracker/pch.h | 13 + Navicat-Cracker/res/620.png | Bin 0 -> 95407 bytes Navicat-Cracker/res/MAINICON.ico | Bin 0 -> 285478 bytes Navicat-Cracker/res/NavicatCracker.rc2 | Bin 0 -> 686 bytes Navicat-Cracker/resource.h | 46 ++ Navicat-Cracker/targetver.h | 8 + README.md | 38 +- README.zh-CN.md | 34 + common/common.vcxitems | 59 ++ common/common.vcxitems.user | 6 + common/cp_converter.hpp | 79 ++ common/exception.hpp | 86 +++ common/exceptions/index_exception.hpp | 10 + common/exceptions/key_exception.hpp | 10 + .../exceptions/not_implemented_exception.hpp | 10 + common/exceptions/openssl_exception.cpp | 20 + common/exceptions/openssl_exception.hpp | 34 + .../operation_canceled_exception.hpp | 10 + common/exceptions/overflow_exception.hpp | 10 + common/exceptions/win32_exception.cpp | 30 + common/exceptions/win32_exception.hpp | 35 + .../cxx_dynamic_array_traits.hpp | 21 + common/resource_traits/cxx_object_traits.hpp | 21 + .../keystone/keystone_handle.hpp | 35 + common/resource_traits/openssl/bignum.hpp | 21 + common/resource_traits/openssl/bio.hpp | 21 + common/resource_traits/openssl/bio_chain.hpp | 21 + .../resource_traits/openssl/decoder_ctx.hpp | 21 + .../resource_traits/openssl/encoder_ctx.hpp | 21 + .../openssl/evp_cipher_ctx.hpp | 21 + common/resource_traits/openssl/evp_pkey.hpp | 21 + .../resource_traits/openssl/evp_pkey_ctx.hpp | 21 + common/resource_traits/openssl/rsa.hpp | 21 + .../unicorn/unicorn_handle.hpp | 21 + common/resource_traits/win32/file_handle.hpp | 21 + .../resource_traits/win32/generic_handle.hpp | 21 + common/resource_traits/win32/local_alloc.hpp | 21 + common/resource_traits/win32/map_view_ptr.hpp | 21 + common/resource_wrapper.hpp | 245 +++++++ common/rsa_cipher.cpp | 625 ++++++++++++++++ common/rsa_cipher.hpp | 161 +++++ doc/how-does-it-work.md | 284 ++++++++ doc/how-does-it-work.zh-CN.md | 282 ++++++++ doc/how-to-build.md | 60 ++ doc/how-to-build.zh-CN.md | 54 ++ doc/how-to-use.md | 196 +++++ doc/how-to-use.zh-CN.md | 194 +++++ doc/screenshot.png | Bin 0 -> 341881 bytes navicat-keygen.sln | 90 +++ navicat-keygen/CollectInformation.cpp | 131 ++++ navicat-keygen/GenerateLicense.cpp | 237 ++++++ navicat-keygen/base32_rfc4648.cpp | 120 ++++ navicat-keygen/base32_rfc4648.hpp | 39 + navicat-keygen/base64_rfc4648.cpp | 103 +++ navicat-keygen/base64_rfc4648.hpp | 20 + navicat-keygen/navicat-keygen.vcxproj | 187 +++++ navicat-keygen/navicat-keygen.vcxproj.filters | 48 ++ navicat-keygen/navicat-keygen.vcxproj.user | 6 + navicat-keygen/navicat_serial_generator.cpp | 190 +++++ navicat-keygen/navicat_serial_generator.hpp | 80 +++ navicat-keygen/wmain.cpp | 121 ++++ navicat-patcher/amd64_emulator.cpp | 200 ++++++ navicat-patcher/amd64_emulator.hpp | 159 +++++ navicat-patcher/i386_emulator.cpp | 160 +++++ navicat-patcher/i386_emulator.hpp | 152 ++++ navicat-patcher/image_interpreter.cpp | 302 ++++++++ navicat-patcher/image_interpreter.hpp | 202 ++++++ navicat-patcher/keystone_assembler.cpp | 38 + navicat-patcher/keystone_assembler.hpp | 54 ++ navicat-patcher/navicat-patcher.vcxproj | 210 ++++++ .../navicat-patcher.vcxproj.filters | 66 ++ navicat-patcher/navicat-patcher.vcxproj.user | 6 + navicat-patcher/patch_solution.hpp | 19 + navicat-patcher/patch_solution_since.hpp | 9 + .../patch_solution_since_16.0.7.0.amd64.cpp | 591 +++++++++++++++ .../patch_solution_since_16.0.7.0.generic.cpp | 16 + .../patch_solution_since_16.0.7.0.hpp | 35 + .../patch_solution_since_16.0.7.0.i386.cpp | 629 ++++++++++++++++ navicat-patcher/wmain.cpp | 295 ++++++++ 114 files changed, 13016 insertions(+), 1 deletion(-) create mode 100644 .DS_Store create mode 100644 LICENSE create mode 100644 Navicat-Cracker/CollectInformation.cpp create mode 100644 Navicat-Cracker/GenerateLicense.cpp create mode 100644 Navicat-Cracker/NavicatCracker.aps create mode 100644 Navicat-Cracker/NavicatCracker.cpp create mode 100644 Navicat-Cracker/NavicatCracker.h create mode 100644 Navicat-Cracker/NavicatCracker.rc create mode 100644 Navicat-Cracker/NavicatCracker.vcxproj create mode 100644 Navicat-Cracker/NavicatCracker.vcxproj.filters create mode 100644 Navicat-Cracker/NavicatCracker.vcxproj.user create mode 100644 Navicat-Cracker/NavicatCrackerDlg.cpp create mode 100644 Navicat-Cracker/NavicatCrackerDlg.h create mode 100644 Navicat-Cracker/amd64_emulator.cpp create mode 100644 Navicat-Cracker/amd64_emulator.hpp create mode 100644 Navicat-Cracker/base32_rfc4648.cpp create mode 100644 Navicat-Cracker/base32_rfc4648.hpp create mode 100644 Navicat-Cracker/base64_rfc4648.cpp create mode 100644 Navicat-Cracker/base64_rfc4648.hpp create mode 100644 Navicat-Cracker/framework.h create mode 100644 Navicat-Cracker/i386_emulator.cpp create mode 100644 Navicat-Cracker/i386_emulator.hpp create mode 100644 Navicat-Cracker/image_interpreter.cpp create mode 100644 Navicat-Cracker/image_interpreter.hpp create mode 100644 Navicat-Cracker/keystone_assembler.cpp create mode 100644 Navicat-Cracker/keystone_assembler.hpp create mode 100644 Navicat-Cracker/navicat_serial_generator.cpp create mode 100644 Navicat-Cracker/navicat_serial_generator.hpp create mode 100644 Navicat-Cracker/patch_solution.hpp create mode 100644 Navicat-Cracker/patch_solution_since.hpp create mode 100644 Navicat-Cracker/patch_solution_since_16.0.7.0.amd64.cpp create mode 100644 Navicat-Cracker/patch_solution_since_16.0.7.0.generic.cpp create mode 100644 Navicat-Cracker/patch_solution_since_16.0.7.0.hpp create mode 100644 Navicat-Cracker/patch_solution_since_16.0.7.0.i386.cpp create mode 100644 Navicat-Cracker/pch.cpp create mode 100644 Navicat-Cracker/pch.h create mode 100644 Navicat-Cracker/res/620.png create mode 100644 Navicat-Cracker/res/MAINICON.ico create mode 100644 Navicat-Cracker/res/NavicatCracker.rc2 create mode 100644 Navicat-Cracker/resource.h create mode 100644 Navicat-Cracker/targetver.h create mode 100644 README.zh-CN.md create mode 100644 common/common.vcxitems create mode 100644 common/common.vcxitems.user create mode 100644 common/cp_converter.hpp create mode 100644 common/exception.hpp create mode 100644 common/exceptions/index_exception.hpp create mode 100644 common/exceptions/key_exception.hpp create mode 100644 common/exceptions/not_implemented_exception.hpp create mode 100644 common/exceptions/openssl_exception.cpp create mode 100644 common/exceptions/openssl_exception.hpp create mode 100644 common/exceptions/operation_canceled_exception.hpp create mode 100644 common/exceptions/overflow_exception.hpp create mode 100644 common/exceptions/win32_exception.cpp create mode 100644 common/exceptions/win32_exception.hpp create mode 100644 common/resource_traits/cxx_dynamic_array_traits.hpp create mode 100644 common/resource_traits/cxx_object_traits.hpp create mode 100644 common/resource_traits/keystone/keystone_handle.hpp create mode 100644 common/resource_traits/openssl/bignum.hpp create mode 100644 common/resource_traits/openssl/bio.hpp create mode 100644 common/resource_traits/openssl/bio_chain.hpp create mode 100644 common/resource_traits/openssl/decoder_ctx.hpp create mode 100644 common/resource_traits/openssl/encoder_ctx.hpp create mode 100644 common/resource_traits/openssl/evp_cipher_ctx.hpp create mode 100644 common/resource_traits/openssl/evp_pkey.hpp create mode 100644 common/resource_traits/openssl/evp_pkey_ctx.hpp create mode 100644 common/resource_traits/openssl/rsa.hpp create mode 100644 common/resource_traits/unicorn/unicorn_handle.hpp create mode 100644 common/resource_traits/win32/file_handle.hpp create mode 100644 common/resource_traits/win32/generic_handle.hpp create mode 100644 common/resource_traits/win32/local_alloc.hpp create mode 100644 common/resource_traits/win32/map_view_ptr.hpp create mode 100644 common/resource_wrapper.hpp create mode 100644 common/rsa_cipher.cpp create mode 100644 common/rsa_cipher.hpp create mode 100644 doc/how-does-it-work.md create mode 100644 doc/how-does-it-work.zh-CN.md create mode 100644 doc/how-to-build.md create mode 100644 doc/how-to-build.zh-CN.md create mode 100644 doc/how-to-use.md create mode 100644 doc/how-to-use.zh-CN.md create mode 100644 doc/screenshot.png create mode 100644 navicat-keygen.sln create mode 100644 navicat-keygen/CollectInformation.cpp create mode 100644 navicat-keygen/GenerateLicense.cpp create mode 100644 navicat-keygen/base32_rfc4648.cpp create mode 100644 navicat-keygen/base32_rfc4648.hpp create mode 100644 navicat-keygen/base64_rfc4648.cpp create mode 100644 navicat-keygen/base64_rfc4648.hpp create mode 100644 navicat-keygen/navicat-keygen.vcxproj create mode 100644 navicat-keygen/navicat-keygen.vcxproj.filters create mode 100644 navicat-keygen/navicat-keygen.vcxproj.user create mode 100644 navicat-keygen/navicat_serial_generator.cpp create mode 100644 navicat-keygen/navicat_serial_generator.hpp create mode 100644 navicat-keygen/wmain.cpp create mode 100644 navicat-patcher/amd64_emulator.cpp create mode 100644 navicat-patcher/amd64_emulator.hpp create mode 100644 navicat-patcher/i386_emulator.cpp create mode 100644 navicat-patcher/i386_emulator.hpp create mode 100644 navicat-patcher/image_interpreter.cpp create mode 100644 navicat-patcher/image_interpreter.hpp create mode 100644 navicat-patcher/keystone_assembler.cpp create mode 100644 navicat-patcher/keystone_assembler.hpp create mode 100644 navicat-patcher/navicat-patcher.vcxproj create mode 100644 navicat-patcher/navicat-patcher.vcxproj.filters create mode 100644 navicat-patcher/navicat-patcher.vcxproj.user create mode 100644 navicat-patcher/patch_solution.hpp create mode 100644 navicat-patcher/patch_solution_since.hpp create mode 100644 navicat-patcher/patch_solution_since_16.0.7.0.amd64.cpp create mode 100644 navicat-patcher/patch_solution_since_16.0.7.0.generic.cpp create mode 100644 navicat-patcher/patch_solution_since_16.0.7.0.hpp create mode 100644 navicat-patcher/patch_solution_since_16.0.7.0.i386.cpp create mode 100644 navicat-patcher/wmain.cpp diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5787501ab2cce2b1a1ecce18944d887e71bf9025 GIT binary patch literal 6148 zcmeHK%SyvQ6g|@xtq8Wb5=6+xr3L>W)^<_QF6 + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) 2017 {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + navicat-keygen Copyright (C) 2017 Double Helix + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/Navicat-Cracker/CollectInformation.cpp b/Navicat-Cracker/CollectInformation.cpp new file mode 100644 index 0000000..2da3112 --- /dev/null +++ b/Navicat-Cracker/CollectInformation.cpp @@ -0,0 +1,33 @@ +#include "navicat_serial_generator.hpp" +#include +#include "exceptions/operation_canceled_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\CollectInformation.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + [[nodiscard]] + navicat_serial_generator CollectInformationNormal(int procution_type, int language, int version) { + navicat_serial_generator sn_generator; + + sn_generator.set_software_type(static_cast(procution_type)); + sn_generator.set_software_language(static_cast(language)); + sn_generator.set_software_version(version); + + return sn_generator; + } + + [[nodiscard]] + navicat_serial_generator CollectInformationAdvanced(std::uint8_t procution_type, std::uint8_t lang1, std::uint8_t lang2, int version) { + navicat_serial_generator sn_generator; + + sn_generator.set_software_type(procution_type); + sn_generator.set_software_language(lang1, lang2); + sn_generator.set_software_version(version); + + return sn_generator; + } +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/Navicat-Cracker/GenerateLicense.cpp b/Navicat-Cracker/GenerateLicense.cpp new file mode 100644 index 0000000..854c65c --- /dev/null +++ b/Navicat-Cracker/GenerateLicense.cpp @@ -0,0 +1,201 @@ +#include "exception.hpp" +#include "exceptions/operation_canceled_exception.hpp" +#include "exceptions/win32_exception.hpp" + +#include "resource_wrapper.hpp" +#include "resource_traits/win32/file_handle.hpp" + +#include "cp_converter.hpp" +#include "base64_rfc4648.hpp" +#include "navicat_serial_generator.hpp" +#include "rsa_cipher.hpp" + +#include +#include + +#include +#include +#include + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\GenerateLicense.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + std::wstring GenerateLicenseText(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator, std::wstring username, + std::wstring organization, std::wstring b64_request_code) { + + std::string u8_username; + std::string u8_organization; + + std::vector request_code; + std::string u8_request_info; + std::string u8_response_info; + std::vector response_code; + std::wstring b64_response_code; + + u8_username = cp_converter<-1, CP_UTF8>::convert(username); + + u8_organization = cp_converter<-1, CP_UTF8>::convert(organization); + + if (b64_request_code.empty()) { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Nothing inputs, abort!"); + } + + request_code = base64_rfc4648::decode(cp_converter<-1, CP_UTF8>::convert(b64_request_code)); + + u8_request_info.resize((cipher.bits() + 7) / 8); + u8_request_info.resize(cipher.private_decrypt(request_code.data(), request_code.size(), u8_request_info.data(), RSA_PKCS1_PADDING)); + while (u8_request_info.back() == '\x00') { + u8_request_info.pop_back(); + } + + rapidjson::Document json; + rapidjson::Value N_Key; + rapidjson::Value N_Value; + rapidjson::Value O_Key; + rapidjson::Value O_Value; + rapidjson::Value T_Key; + rapidjson::Value T_Value; + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + + // + // begin to parse + // + json.Parse(u8_request_info.c_str()); + + // + // remove "Platform" info + // + json.RemoveMember(u8"P"); + + // + // set "Name" info + // + N_Key.SetString(u8"N", 1); + N_Value.SetString(u8_username.c_str(), static_cast(u8_username.length())); + + // + // set "Organization" info + // + O_Key.SetString(u8"O", 1); + O_Value.SetString(u8_organization.c_str(), static_cast(u8_organization.length())); + + // + // set "Time" info + // + T_Key.SetString(u8"T", 1); + T_Value.SetUint(static_cast(std::time(nullptr))); + + // + // add "Name", "Organization" and "Time" + // + json.AddMember(N_Key, N_Value, json.GetAllocator()); + json.AddMember(O_Key, O_Value, json.GetAllocator()); + json.AddMember(T_Key, T_Value, json.GetAllocator()); + + // + // flush + // + json.Accept(writer); + + if (buffer.GetSize() > 240) { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Response Info is too long."); + } + + u8_response_info.assign(buffer.GetString(), buffer.GetSize()); + + response_code.resize((cipher.bits() + 7) / 8); + response_code.resize(cipher.private_encrypt(u8_response_info.data(), u8_response_info.size(), response_code.data(), RSA_PKCS1_PADDING)); + b64_response_code = cp_converter::convert(base64_rfc4648::encode(response_code)); + + return b64_response_code; + } + + void GenerateLicenseBinary(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator) { + std::string utf8SerialNumber = sn_generator.serial_number(); + + std::wstring username; + std::wstring organization; + std::string u8_username; + std::string u8_organization; + + std::string u8_response_info; + std::vector response_code; + + std::wcout << L"[*] Your name: "; + if (!std::getline(std::wcin, username)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } else { + u8_username = cp_converter<-1, CP_UTF8>::convert(username); + } + + std::wcout << L"[*] Your organization: "; + if (!std::getline(std::wcin, organization)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } else { + u8_organization = cp_converter<-1, CP_UTF8>::convert(organization); + } + + rapidjson::Document json; + rapidjson::Value N_Key; + rapidjson::Value N_Value; + rapidjson::Value O_Key; + rapidjson::Value O_Value; + rapidjson::Value T_Key; + rapidjson::Value T_Value; + rapidjson::Value K_Key; + rapidjson::Value K_Value; + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + + json.Parse("{}"); + K_Key.SetString("K", 1); + K_Value.SetString(utf8SerialNumber.c_str(), static_cast(utf8SerialNumber.length())); + N_Key.SetString("N", 1); + N_Value.SetString(u8_username.c_str(), static_cast(u8_username.length())); + O_Key.SetString("O", 1); + O_Value.SetString(u8_organization.c_str(), static_cast(u8_organization.length())); + T_Key.SetString("T", 1); + T_Value.SetUint(static_cast(std::time(nullptr))); + + json.AddMember(K_Key, K_Value, json.GetAllocator()); + json.AddMember(N_Key, N_Value, json.GetAllocator()); + json.AddMember(O_Key, O_Value, json.GetAllocator()); + json.AddMember(T_Key, T_Value, json.GetAllocator()); + + // + // flush + // + json.Accept(writer); + + if (buffer.GetSize() > 240) { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Response Info is too long."); + } + + u8_response_info.assign(buffer.GetString(), buffer.GetSize()); + + std::wcout << L"[*] Response Info:" << std::endl; + std::wcout << cp_converter::convert(u8_response_info) << std::endl; + std::wcout << std::endl; + + response_code.resize((cipher.bits() + 7) / 8); + response_code.resize(cipher.private_encrypt(u8_response_info.data(), u8_response_info.size(), response_code.data(), RSA_PKCS1_PADDING)); + + resource_wrapper license_file{ resource_traits::win32::file_handle{}, CreateFileW(L"license_file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) }; + if (license_file.is_valid() == false) { + throw exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"CreateFileW failed."); + } + + if (DWORD _; WriteFile(license_file.get(), response_code.data(), static_cast(response_code.size()), &_, NULL) == FALSE) { + throw exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"WriteFile failed."); + } + + std::wcout << L"[+] license_file has been generated." << std::endl; + } + +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/Navicat-Cracker/NavicatCracker.aps b/Navicat-Cracker/NavicatCracker.aps new file mode 100644 index 0000000000000000000000000000000000000000..f971835e399e772b7ea14b09e5f1af45ec9779db GIT binary patch literal 424976 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�iMUZ%5^LXEk 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

%}^~AUh5D0mAjJCF~6qQt8~sgiS}s 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%0AK_j^c7=(foKCtMPL< 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�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

N1L!3o-`$M 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 +#include "exceptions/operation_canceled_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\CollectInformation.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + [[nodiscard]] + static int read_int(int min_val, int max_val, std::wstring_view prompt, std::wstring_view error_msg) { + int val; + + for (std::wstring s;;) { + std::wcout << prompt; + if (!std::getline(std::wcin, s)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } + + if (s.empty()) + continue; + + try { + val = std::stoi(s, nullptr, 0); + if (min_val <= val && val <= max_val) { + return val; + } else { + throw std::invalid_argument(u8""); + } + } catch (std::invalid_argument&) { + std::wcout << error_msg << std::endl; + } + } + } + + [[nodiscard]] + static int read_int(int min_val, int max_val, int default_val, std::wstring_view prompt, std::wstring_view error_msg) { + int val; + + for (std::wstring s;;) { + std::wcout << prompt; + if (!std::getline(std::wcin, s)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } + + if (s.empty()) { + return default_val; + } + + try { + val = std::stoi(s, nullptr, 0); + if (min_val <= val && val <= max_val) { + return val; + } else { + throw std::invalid_argument(u8""); + } + } catch (std::invalid_argument&) { + std::wcout << error_msg << std::endl; + } + } + } + + [[nodiscard]] + navicat_serial_generator CollectInformationNormal() { + navicat_serial_generator sn_generator; + + std::wcout << L"[*] Select Navicat product:" << std::endl; + std::wcout << L" 0. DataModeler" << std::endl; + std::wcout << L" 1. Premium" << std::endl; + std::wcout << L" 2. MySQL" << std::endl; + std::wcout << L" 3. PostgreSQL" << std::endl; + std::wcout << L" 4. Oracle" << std::endl; + std::wcout << L" 5. SQLServer" << std::endl; + std::wcout << L" 6. SQLite" << std::endl; + std::wcout << L" 7. MariaDB" << std::endl; + std::wcout << L" 8. MongoDB" << std::endl; + std::wcout << L" 9. ReportViewer" << std::endl; + std::wcout << std::endl; + sn_generator.set_software_type(static_cast(read_int(0, 9, L"(Input index)> ", L"Invalid index."))); + std::wcout << std::endl; + + std::wcout << L"[*] Select product language:" << std::endl; + std::wcout << L" 0. English" << std::endl; + std::wcout << L" 1. Simplified Chinese" << std::endl; + std::wcout << L" 2. Traditional Chinese" << std::endl; + std::wcout << L" 3. Japanese" << std::endl; + std::wcout << L" 4. Polish" << std::endl; + std::wcout << L" 5. Spanish" << std::endl; + std::wcout << L" 6. French" << std::endl; + std::wcout << L" 7. German" << std::endl; + std::wcout << L" 8. Korean" << std::endl; + std::wcout << L" 9. Russian" << std::endl; + std::wcout << L" 10. Portuguese" << std::endl; + std::wcout << std::endl; + sn_generator.set_software_language(static_cast(read_int(0, 10, L"(Input index)> ", L"Invalid index."))); + std::wcout << std::endl; + + std::wcout << L"[*] Input major version number:" << std::endl; + sn_generator.set_software_version(read_int(11, 16, 16, L"(range: 11 ~ 16, default: 16)> ", L"Invalid number.")); + std::wcout << std::endl; + + return sn_generator; + } + + [[nodiscard]] + navicat_serial_generator CollectInformationAdvanced() { + navicat_serial_generator sn_generator; + + std::wcout << L"[*] Navicat Product Signature:" << std::endl; + sn_generator.set_software_type(static_cast(read_int(0x00, 0xff, L"(range: 0x00 ~ 0xFF)> ", L"Invalid number."))); + std::wcout << std::endl; + + std::wcout << L"[*] Navicat Language Signature 0:" << std::endl; + auto s1 = static_cast(read_int(0x00, 0xff, L"(range: 0x00 ~ 0xFF)> ", L"Invalid number.")); + std::wcout << std::endl; + + std::wcout << L"[*] Navicat Language Signature 1:" << std::endl; + auto s2 = static_cast(read_int(0x00, 0xff, L"(range: 0x00 ~ 0xFF)> ", L"Invalid number.")); + sn_generator.set_software_language(s1, s2); + std::wcout << std::endl; + + std::wcout << L"[*] Input major version number:" << std::endl; + sn_generator.set_software_version(read_int(11, 16, 16, L"(range: 11 ~ 16, default: 16)> ", L"Invalid number.")); + std::wcout << std::endl; + + return sn_generator; + } +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/navicat-keygen/GenerateLicense.cpp b/navicat-keygen/GenerateLicense.cpp new file mode 100644 index 0000000..fc48f83 --- /dev/null +++ b/navicat-keygen/GenerateLicense.cpp @@ -0,0 +1,237 @@ +#include "exception.hpp" +#include "exceptions/operation_canceled_exception.hpp" +#include "exceptions/win32_exception.hpp" + +#include "resource_wrapper.hpp" +#include "resource_traits/win32/file_handle.hpp" + +#include "cp_converter.hpp" +#include "base64_rfc4648.hpp" +#include "navicat_serial_generator.hpp" +#include "rsa_cipher.hpp" + +#include +#include + +#include +#include +#include + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\GenerateLicense.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + void GenerateLicenseText(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator) { + std::wstring username; + std::wstring organization; + std::string u8_username; + std::string u8_organization; + + std::wstring b64_request_code; + std::vector request_code; + std::string u8_request_info; + std::string u8_response_info; + std::vector response_code; + std::wstring b64_response_code; + + std::wcout << L"[*] Your name: "; + if (!std::getline(std::wcin, username)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } else { + u8_username = cp_converter<-1, CP_UTF8>::convert(username); + } + + std::wcout << L"[*] Your organization: "; + if (!std::getline(std::wcin, organization)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } else { + u8_organization = cp_converter<-1, CP_UTF8>::convert(organization); + } + + std::wcout << std::endl; + std::wcout << L"[*] Input request code in Base64: (Input empty line to end)" << std::endl; + while (true) { + std::wstring s; + if (!std::getline(std::wcin, s)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } + + if (s.empty()) { + break; + } + + b64_request_code.append(s); + } + + if (b64_request_code.empty()) { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Nothing inputs, abort!"); + } + + request_code = base64_rfc4648::decode(cp_converter<-1, CP_UTF8>::convert(b64_request_code)); + + u8_request_info.resize((cipher.bits() + 7) / 8); + u8_request_info.resize(cipher.private_decrypt(request_code.data(), request_code.size(), u8_request_info.data(), RSA_PKCS1_PADDING)); + while (u8_request_info.back() == '\x00') { + u8_request_info.pop_back(); + } + + std::wcout << L"[*] Request Info:" << std::endl; + std::wcout << cp_converter::convert(u8_request_info) << std::endl; + std::wcout << std::endl; + + rapidjson::Document json; + rapidjson::Value N_Key; + rapidjson::Value N_Value; + rapidjson::Value O_Key; + rapidjson::Value O_Value; + rapidjson::Value T_Key; + rapidjson::Value T_Value; + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + + // + // begin to parse + // + json.Parse(u8_request_info.c_str()); + + // + // remove "Platform" info + // + json.RemoveMember(u8"P"); + + // + // set "Name" info + // + N_Key.SetString(u8"N", 1); + N_Value.SetString(u8_username.c_str(), static_cast(u8_username.length())); + + // + // set "Organization" info + // + O_Key.SetString(u8"O", 1); + O_Value.SetString(u8_organization.c_str(), static_cast(u8_organization.length())); + + // + // set "Time" info + // + T_Key.SetString(u8"T", 1); + T_Value.SetUint(static_cast(std::time(nullptr))); + + // + // add "Name", "Organization" and "Time" + // + json.AddMember(N_Key, N_Value, json.GetAllocator()); + json.AddMember(O_Key, O_Value, json.GetAllocator()); + json.AddMember(T_Key, T_Value, json.GetAllocator()); + + // + // flush + // + json.Accept(writer); + + if (buffer.GetSize() > 240) { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Response Info is too long."); + } + + u8_response_info.assign(buffer.GetString(), buffer.GetSize()); + + std::wcout << L"[*] Response Info:" << std::endl; + std::wcout << cp_converter::convert(u8_response_info) << std::endl; + std::wcout << std::endl; + + response_code.resize((cipher.bits() + 7) / 8); + response_code.resize(cipher.private_encrypt(u8_response_info.data(), u8_response_info.size(), response_code.data(), RSA_PKCS1_PADDING)); + b64_response_code = cp_converter::convert(base64_rfc4648::encode(response_code)); + + std::wcout << L"[*] Activation Code:" << std::endl; + std::wcout << b64_response_code << std::endl; + std::wcout << std::endl; + } + + void GenerateLicenseBinary(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator) { + std::string utf8SerialNumber = sn_generator.serial_number(); + + std::wstring username; + std::wstring organization; + std::string u8_username; + std::string u8_organization; + + std::string u8_response_info; + std::vector response_code; + + std::wcout << L"[*] Your name: "; + if (!std::getline(std::wcin, username)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } else { + u8_username = cp_converter<-1, CP_UTF8>::convert(username); + } + + std::wcout << L"[*] Your organization: "; + if (!std::getline(std::wcin, organization)) { + throw exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Operation is canceled by user."); + } else { + u8_organization = cp_converter<-1, CP_UTF8>::convert(organization); + } + + rapidjson::Document json; + rapidjson::Value N_Key; + rapidjson::Value N_Value; + rapidjson::Value O_Key; + rapidjson::Value O_Value; + rapidjson::Value T_Key; + rapidjson::Value T_Value; + rapidjson::Value K_Key; + rapidjson::Value K_Value; + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + + json.Parse("{}"); + K_Key.SetString("K", 1); + K_Value.SetString(utf8SerialNumber.c_str(), static_cast(utf8SerialNumber.length())); + N_Key.SetString("N", 1); + N_Value.SetString(u8_username.c_str(), static_cast(u8_username.length())); + O_Key.SetString("O", 1); + O_Value.SetString(u8_organization.c_str(), static_cast(u8_organization.length())); + T_Key.SetString("T", 1); + T_Value.SetUint(static_cast(std::time(nullptr))); + + json.AddMember(K_Key, K_Value, json.GetAllocator()); + json.AddMember(N_Key, N_Value, json.GetAllocator()); + json.AddMember(O_Key, O_Value, json.GetAllocator()); + json.AddMember(T_Key, T_Value, json.GetAllocator()); + + // + // flush + // + json.Accept(writer); + + if (buffer.GetSize() > 240) { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Response Info is too long."); + } + + u8_response_info.assign(buffer.GetString(), buffer.GetSize()); + + std::wcout << L"[*] Response Info:" << std::endl; + std::wcout << cp_converter::convert(u8_response_info) << std::endl; + std::wcout << std::endl; + + response_code.resize((cipher.bits() + 7) / 8); + response_code.resize(cipher.private_encrypt(u8_response_info.data(), u8_response_info.size(), response_code.data(), RSA_PKCS1_PADDING)); + + resource_wrapper license_file{ resource_traits::win32::file_handle{}, CreateFileW(L"license_file", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) }; + if (license_file.is_valid() == false) { + throw exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"CreateFileW failed."); + } + + if (DWORD _; WriteFile(license_file.get(), response_code.data(), static_cast(response_code.size()), &_, NULL) == FALSE) { + throw exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"WriteFile failed."); + } + + std::wcout << L"[+] license_file has been generated." << std::endl; + } + +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/navicat-keygen/base32_rfc4648.cpp b/navicat-keygen/base32_rfc4648.cpp new file mode 100644 index 0000000..97f7c35 --- /dev/null +++ b/navicat-keygen/base32_rfc4648.cpp @@ -0,0 +1,120 @@ +#include "base32_rfc4648.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\base32_rfc4648.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + char base32_rfc4648::symbol(alphabet_index_t idx) { + return alphabet[idx]; + } + + base32_rfc4648::alphabet_index_t base32_rfc4648::reverse_symbol(char c) { + if ('A' <= c && c <= 'Z') { + return c - 'A'; + } else if ('2' <= c && c <= '7') { + return c - '2' + 26; + } else { + throw decoding_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Non-base32 digit is found"); + } + } + + std::string base32_rfc4648::encode(const std::vector& data) { + return encode(data.data(), data.size()); + } + + std::string base32_rfc4648::encode(const void* data_ptr, size_t data_size) { + std::string retval; + + if (data_size) { + retval.reserve((data_size * 8 + 4) / 5); + + auto p = reinterpret_cast(data_ptr); + alphabet_index_t left_bits = 0; + alphabet_index_t bit_buffer = 0; + for (size_t i = 0; i < data_size; ++i) { + bit_buffer = (bit_buffer << 8) | p[i]; + left_bits += 8; + + while (left_bits >= 5) { + alphabet_index_t idx = (bit_buffer >> (left_bits - 5)) & 0x1f; + retval.push_back(symbol(idx)); + left_bits -= 5; + } + } + + if (left_bits > 0) { + alphabet_index_t idx = (bit_buffer << (5 - left_bits)) & 0x1f; + retval.push_back(symbol(idx)); + } + + switch (data_size % 5) { + case 0: + break; + case 1: + retval.append(6, padding_character); + break; + case 2: + retval.append(4, padding_character); + break; + case 3: + retval.append(3, padding_character); + break; + case 4: + retval.append(1, padding_character); + break; + default: + __assume(false); + } + } + + return retval; + } + + std::vector base32_rfc4648::decode(std::string_view b32_string) { + if (b32_string.length() % 8 == 0) { + std::vector retval; + + size_t count_of_padding = std::distance(b32_string.crbegin(), std::find_if_not(b32_string.crbegin(), b32_string.crend(), [](char c) -> bool { return c == padding_character; })); + switch (count_of_padding) { + case 1: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 4)); + break; + case 3: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 3)); + break; + case 4: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 2)); + break; + case 6: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 1)); + break; + default: + throw decoding_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Incorrect padding"); + } + + size_t count_of_encoded = b32_string.length() - count_of_padding; + + alphabet_index_t left_bits = 0; + alphabet_index_t bit_buffer = 0; + for (size_t i = 0; i < count_of_encoded; ++i) { + bit_buffer = (bit_buffer << 5) | reverse_symbol(b32_string[i]); + left_bits += 5; + + while (left_bits >= 8) { + auto val = static_cast((bit_buffer >> (left_bits - 8)) & 0xff); + retval.push_back(val); + left_bits -= 8; + } + } + + return retval; + } else { + throw decoding_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Incorrect padding"); + } + } + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-keygen/base32_rfc4648.hpp b/navicat-keygen/base32_rfc4648.hpp new file mode 100644 index 0000000..1e36fee --- /dev/null +++ b/navicat-keygen/base32_rfc4648.hpp @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include +#include +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\base32_rfc4648.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + struct base32_rfc4648 { + using alphabet_index_t = size_t; + + static constexpr const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + static constexpr const char padding_character = '='; + + class decoding_error : public ::nkg::exception { + public: + decoding_error(std::string_view file, int line, std::string_view message) noexcept : + ::nkg::exception(file, line, message) {} + }; + + static char symbol(alphabet_index_t idx); + + static alphabet_index_t reverse_symbol(char c); + + static std::string encode(const std::vector& data); + + static std::string encode(const void* data_ptr, size_t data_size); + + static std::vector decode(std::string_view b32_string); + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-keygen/base64_rfc4648.cpp b/navicat-keygen/base64_rfc4648.cpp new file mode 100644 index 0000000..9884cf7 --- /dev/null +++ b/navicat-keygen/base64_rfc4648.cpp @@ -0,0 +1,103 @@ +#include "base64_rfc4648.hpp" + +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/openssl/bio.hpp" +#include "resource_traits/openssl/bio_chain.hpp" + +#pragma comment(lib, "libcrypto") +#pragma comment(lib, "crypt32") // required by libcrypto.lib +#pragma comment(lib, "ws2_32") // required by libcrypto.lib + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\base64_rfc4648.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + std::string base64_rfc4648::encode(const std::vector& data) { + resource_wrapper bio_b64{ resource_traits::openssl::bio_chain{}, BIO_new(BIO_f_base64()) }; + if (bio_b64.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_set_flags(bio_b64.get(), BIO_FLAGS_BASE64_NO_NL); + + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_push(bio_b64.get(), bio_memory.get()); + + for (size_t written_size = 0, left_size = data.size(); left_size != 0;) { + int size_to_write = static_cast(std::min(left_size, static_cast(INT_MAX))); + + int r = BIO_write(bio_b64.get(), data.data() + written_size, size_to_write); + if (r > 0) { + written_size += r; + left_size -= r; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_write failed."); + } + } + + BIO_flush(bio_b64.get()); + + const char* pch = nullptr; + long lch = BIO_get_mem_data(bio_memory.get(), &pch); + + bio_memory.discard(); // the bio_chain `bio_b64` will free it + + return std::string(pch, lch); + } + + std::vector base64_rfc4648::decode(std::string_view b64_string) { + resource_wrapper bio_b64{ resource_traits::openssl::bio_chain{}, BIO_new(BIO_f_base64()) }; + if (bio_b64.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_set_flags(bio_b64.get(), BIO_FLAGS_BASE64_NO_NL); + + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_push(bio_b64.get(), bio_memory.get()); + + for (size_t written_length = 0, left_length = b64_string.length(); left_length != 0;) { + int length_to_write = static_cast(std::min(left_length, static_cast(INT_MAX))); + + int r = BIO_write(bio_memory.get(), b64_string.data() + written_length, length_to_write); + if (r > 0) { + written_length += r; + left_length -= r; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_write failed."); + } + } + + std::vector retval; + retval.reserve(b64_string.length() * 3 / 4 + 1); + + for (uint8_t buf[256];;) { + auto len = BIO_read(bio_b64.get(), buf, sizeof(buf)); + if (len > 0) { + retval.insert(retval.end(), buf, buf + len); + } else { + break; + } + } + + bio_memory.discard(); // the bio_chain `bio_b64` will free it + + return retval; + } + +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/navicat-keygen/base64_rfc4648.hpp b/navicat-keygen/base64_rfc4648.hpp new file mode 100644 index 0000000..04c0aed --- /dev/null +++ b/navicat-keygen/base64_rfc4648.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include "exception.hpp" + +namespace nkg { + + struct base64_rfc4648 { + + class backend_error : public ::nkg::exception { + public: + backend_error(std::string_view file, int line, std::string_view message) noexcept : + ::nkg::exception(file, line, message) {} + }; + + static std::string encode(const std::vector& data); + static std::vector decode(std::string_view str_b64); + }; + +} diff --git a/navicat-keygen/navicat-keygen.vcxproj b/navicat-keygen/navicat-keygen.vcxproj new file mode 100644 index 0000000..2878007 --- /dev/null +++ b/navicat-keygen/navicat-keygen.vcxproj @@ -0,0 +1,187 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {6d262af4-5dac-4f0c-b3d6-23c9cbea9756} + navicatkeygen + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + + true + + + true + + + true + + + true + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreaded + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/navicat-keygen/navicat-keygen.vcxproj.filters b/navicat-keygen/navicat-keygen.vcxproj.filters new file mode 100644 index 0000000..aa885aa --- /dev/null +++ b/navicat-keygen/navicat-keygen.vcxproj.filters @@ -0,0 +1,48 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/navicat-keygen/navicat-keygen.vcxproj.user b/navicat-keygen/navicat-keygen.vcxproj.user new file mode 100644 index 0000000..966b4ff --- /dev/null +++ b/navicat-keygen/navicat-keygen.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/navicat-keygen/navicat_serial_generator.cpp b/navicat-keygen/navicat_serial_generator.cpp new file mode 100644 index 0000000..f808845 --- /dev/null +++ b/navicat-keygen/navicat_serial_generator.cpp @@ -0,0 +1,190 @@ +#include "navicat_serial_generator.hpp" +#include + +#include +#include +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x +#include +#endif + +#include "resource_wrapper.hpp" +#include "resource_traits/openssl/evp_cipher_ctx.hpp" + +#include +#include "base32_rfc4648.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\navicat_serial_generator.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + char navicat_serial_generator::_replace_confusing_chars(char c) noexcept { + if (c == 'I') { + return '8'; + } else if (c == 'O') { + return '9'; + } else { + return c; + } + }; + + navicat_serial_generator::navicat_serial_generator() noexcept : + m_data{ 0x68 , 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32 }, m_des_key{} {} + + void navicat_serial_generator::set_software_language(navicat_software_language lang) noexcept { + switch (lang) { + case navicat_software_language::English: + m_data[5] = 0xAC; // Must be 0xAC for English version. + m_data[6] = 0x88; // Must be 0x88 for English version. + break; + case navicat_software_language::SimplifiedChinese: + m_data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version. + m_data[6] = 0x32; // Must be 0x32 for Simplified Chinese version. + break; + case navicat_software_language::TraditionalChinese: + m_data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version. + m_data[6] = 0x99; // Must be 0x99 for Traditional Chinese version. + break; + case navicat_software_language::Japanese: + m_data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee + m_data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee + break; + case navicat_software_language::Polish: + m_data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee + m_data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee + break; + case navicat_software_language::Spanish: + m_data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee + m_data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee + break; + case navicat_software_language::French: + m_data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79 + m_data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79 + break; + case navicat_software_language::German: + m_data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee + m_data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee + break; + case navicat_software_language::Korean: + m_data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee + m_data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee + break; + case navicat_software_language::Russian: + m_data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee + m_data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee + break; + case navicat_software_language::Portuguese: + m_data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee + m_data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee + break; + default: + break; + } + } + + void navicat_serial_generator::set_software_language(uint8_t lang_sig0, uint8_t lang_sig1) noexcept { + m_data[5] = lang_sig0; + m_data[6] = lang_sig1; + } + + void navicat_serial_generator::set_software_type(navicat_software_type software_type) noexcept { + switch (software_type) { + case navicat_software_type::DataModeler: + m_data[7] = 0x84; + break; + case navicat_software_type::Premium: + m_data[7] = 0x65; + break; + case navicat_software_type::MySQL: + m_data[7] = 0x68; + break; + case navicat_software_type::PostgreSQL: + m_data[7] = 0x6C; + break; + case navicat_software_type::Oracle: + m_data[7] = 0x70; + break; + case navicat_software_type::SQLServer: + m_data[7] = 0x74; + break; + case navicat_software_type::SQLite: + m_data[7] = 0x78; + break; + case navicat_software_type::MariaDB: + m_data[7] = 0x7C; + break; + case navicat_software_type::MongoDB: + m_data[7] = 0x80; + break; + case navicat_software_type::ReportViewer: + m_data[7] = 0xb; + break; + default: + break; + } + } + + void navicat_serial_generator::set_software_type(uint8_t software_type_sig) noexcept { + m_data[7] = software_type_sig; + } + + void navicat_serial_generator::set_software_version(int ver) { + if (11 <= ver && ver < 16) { + static_assert(sizeof(m_des_key) == sizeof(s_des_key0)); + + m_data[8] = static_cast((ver << 4) | (m_data[8] & 0x0f)); + memcpy(m_des_key, s_des_key0, sizeof(s_des_key0)); + } else if (16 <= ver && ver < 32) { + static_assert(sizeof(m_des_key) == sizeof(s_des_key1)); + + m_data[8] = static_cast(((ver - 16) << 4) | (m_data[8] & 0x0f)); + memcpy(m_des_key, s_des_key1, sizeof(s_des_key1)); + } else { + throw version_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid navicat version."); + } + } + + void navicat_serial_generator::generate() { + RAND_bytes(m_data + 2, 3); + +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + if (!OSSL_PROVIDER_available(nullptr, "legacy")) { + if (OSSL_PROVIDER_load(nullptr, "legacy") == nullptr) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_PROVIDER_load failed."); + } + } +#endif + + resource_wrapper evp_cipher_context{ resource_traits::openssl::evp_cipher_ctx{}, EVP_CIPHER_CTX_new() }; + if (!evp_cipher_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_CIPHER_CTX_new failed."); + } + + if (EVP_EncryptInit(evp_cipher_context.get(), EVP_des_ecb(), m_des_key, nullptr) <= 0) { // return 1 for success and 0 for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_EncryptInit failed."); + } + + if (int _; EVP_EncryptUpdate(evp_cipher_context.get(), m_data + 2, &_, m_data + 2, 8) <= 0) { // return 1 for success and 0 for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_EncryptUpdate failed."); + } + + m_serial_number = base32_rfc4648::encode(m_data, sizeof(m_data)); + std::transform(m_serial_number.begin(), m_serial_number.end(), m_serial_number.begin(), _replace_confusing_chars); + + std::string_view sn = m_serial_number; + m_serial_number_formatted = fmt::format("{}-{}-{}-{}", sn.substr(0, 4), sn.substr(4, 4), sn.substr(8, 4), sn.substr(12, 4)); + } + + [[nodiscard]] + const std::string& navicat_serial_generator::serial_number() const noexcept { + return m_serial_number; + } + + [[nodiscard]] + const std::string& navicat_serial_generator::serial_number_formatted() const noexcept { + return m_serial_number_formatted; + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-keygen/navicat_serial_generator.hpp b/navicat-keygen/navicat_serial_generator.hpp new file mode 100644 index 0000000..07b0847 --- /dev/null +++ b/navicat-keygen/navicat_serial_generator.hpp @@ -0,0 +1,80 @@ +#pragma once +#include +#include +#include "exception.hpp" + +namespace nkg { + + enum class navicat_software_language { + English, + SimplifiedChinese, + TraditionalChinese, + Japanese, + Polish, + Spanish, + French, + German, + Korean, + Russian, + Portuguese + }; + + enum class navicat_software_type { + DataModeler, + Premium, + MySQL, + PostgreSQL, + Oracle, + SQLServer, + SQLite, + MariaDB, + MongoDB, + ReportViewer + }; + + class navicat_serial_generator { + public: + class version_error; + class backend_error; + + private: + static inline const uint8_t s_des_key0[8] = {0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27}; + static inline const uint8_t s_des_key1[8] = {0xE9, 0x7F, 0xB0, 0x60, 0x77, 0x45, 0x90, 0xAE}; + + uint8_t m_data[10]; + uint8_t m_des_key[8]; + std::string m_serial_number; + std::string m_serial_number_formatted; + + static char _replace_confusing_chars(char c) noexcept; + + public: + navicat_serial_generator() noexcept; + + void set_software_language(navicat_software_language lang) noexcept; + void set_software_language(uint8_t lang_sig0, uint8_t lang_sig1) noexcept; + + void set_software_type(navicat_software_type software_type) noexcept; + void set_software_type(uint8_t software_type_sig) noexcept; + + void set_software_version(int Version); + + void generate(); + + [[nodiscard]] + const std::string& serial_number() const noexcept; + + [[nodiscard]] + const std::string& serial_number_formatted() const noexcept; + }; + + class navicat_serial_generator::version_error : public ::nkg::exception { + using ::nkg::exception::exception; + }; + + class navicat_serial_generator::backend_error : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} + diff --git a/navicat-keygen/wmain.cpp b/navicat-keygen/wmain.cpp new file mode 100644 index 0000000..e33d9ea --- /dev/null +++ b/navicat-keygen/wmain.cpp @@ -0,0 +1,121 @@ +#include +#include + +#include "exception.hpp" +#include "exceptions/operation_canceled_exception.hpp" + +#include "cp_converter.hpp" +#include "base64_rfc4648.hpp" +#include "navicat_serial_generator.hpp" +#include "rsa_cipher.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\wmain.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + using fnCollectInformation = std::function; + using fnGenerateLicense = std::function; + + navicat_serial_generator CollectInformationNormal(); + navicat_serial_generator CollectInformationAdvanced(); + void GenerateLicenseText(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator); + void GenerateLicenseBinary(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator); +} + +static void welcome() { + _putws(L"***************************************************"); + _putws(L"* navicat-keygen by @DoubleLabyrinth *"); + _putws(L"* version: 16.0.7.0-1 *"); + _putws(L"***************************************************"); + _putws(L""); +} + +static void help() { + _putws(L"Usage:"); + _putws(L" navicat-keygen.exe <-bin|-text> [-adv] "); + _putws(L""); + _putws(L" <-bin|-text> Specify \"-bin\" to generate \"license_file\" used by Navicat 11."); + _putws(L" Specify \"-text\" to generate base64-encoded activation code."); + _putws(L" This parameter is mandatory."); + _putws(L""); + _putws(L" [-adv] Enable advance mode."); + _putws(L" This parameter is optional."); + _putws(L""); + _putws(L" A path to an RSA-2048 private key file."); + _putws(L" This parameter is mandatory."); + _putws(L""); + _putws(L"Example:"); + _putws(L" navicat-keygen.exe -text .\\RegPrivateKey.pem"); +} + +int wmain(int argc, wchar_t* argv[]) { + welcome(); + + if (argc == 3 || argc == 4) { + nkg::fnCollectInformation lpfnCollectInformation; + nkg::fnGenerateLicense lpfnGenerateLicense; + + if (_wcsicmp(argv[1], L"-bin") == 0) { + lpfnGenerateLicense = nkg::GenerateLicenseBinary; + } else if (_wcsicmp(argv[1], L"-text") == 0) { + lpfnGenerateLicense = nkg::GenerateLicenseText; + } else { + help(); + return -1; + } + + if (argc == 3) { + lpfnCollectInformation = nkg::CollectInformationNormal; + } else if (argc == 4 && _wcsicmp(argv[2], L"-adv") == 0) { + lpfnCollectInformation = nkg::CollectInformationAdvanced; + } else { + help(); + return -1; + } + + try { + nkg::rsa_cipher cipher; + + cipher.import_private_key_file(nkg::cp_converter<-1, CP_UTF8>::convert(argv[argc - 1])); + if (cipher.bits() != 2048) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"RSA key length != 2048 bits.") + .push_hint(u8"You must provide an RSA key whose modulus length is 2048 bits."); + } + + auto sn_generator = lpfnCollectInformation(); + sn_generator.generate(); + + _putws(L"[*] Serial number:"); + _putws(nkg::cp_converter::convert(sn_generator.serial_number_formatted()).c_str()); + _putws(L""); + + lpfnGenerateLicense(cipher, sn_generator); + + return 0; + } catch (nkg::exceptions::operation_canceled_exception&) { + return -1; + } catch (nkg::exception& e) { + wprintf_s(L"[-] %s:%d ->\n", nkg::cp_converter::convert(e.source_file()).c_str(), e.source_line()); + wprintf_s(L" %s\n", nkg::cp_converter::convert(e.custom_message()).c_str()); + + if (e.error_code_exists()) { + wprintf_s(L" %s (0x%zx)\n", nkg::cp_converter::convert(e.error_string()).c_str(), e.error_code()); + } + + for (auto& hint : e.hints()) { + wprintf_s(L" Hints: %s\n", nkg::cp_converter::convert(hint).c_str()); + } + + return -1; + } catch (std::exception& e) { + wprintf_s(L"[-] %s\n", nkg::cp_converter::convert(e.what()).c_str()); + return -1; + } + } else { + help(); + return -1; + } +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/navicat-patcher/amd64_emulator.cpp b/navicat-patcher/amd64_emulator.cpp new file mode 100644 index 0000000..49fb0f0 --- /dev/null +++ b/navicat-patcher/amd64_emulator.cpp @@ -0,0 +1,200 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "amd64_emulator.hpp" +#include "exceptions/key_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\amd64_emulator.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + void amd64_emulator::_unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) { + auto hook_stub_ctx = reinterpret_cast(user_data); + hook_stub_ctx->self->m_unicorn_hook_cbs_hookcode[hook_stub_ctx->unicorn_hook_handle](address, size); + } + + void amd64_emulator::_unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = reinterpret_cast(user_data); + hook_stub_ctx->self->m_unicorn_hook_cbs_hookmem[hook_stub_ctx->unicorn_hook_handle](type, address, static_cast(size), value); + } + + bool amd64_emulator::_unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = reinterpret_cast(user_data); + return hook_stub_ctx->self->m_unicorn_hook_cbs_eventmem[hook_stub_ctx->unicorn_hook_handle](type, address, static_cast(size), value); + } + + amd64_emulator::amd64_emulator() { + auto err = uc_open(UC_ARCH_X86, UC_MODE_64, m_unicorn_engine.unsafe_addressof()); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_open failed."); + } + } + + void amd64_emulator::reg_read(int regid, void* value) { + auto err = uc_reg_read(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_read failed."); + } + } + + void amd64_emulator::reg_write(int regid, const void* value) { + auto err = uc_reg_write(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + } + + uint64_t amd64_emulator::msr_read(uint32_t rid) { + uc_x86_msr msr; + msr.rid = rid; + + auto err = uc_reg_read(m_unicorn_engine.get(), UC_X86_REG_MSR, &msr); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + + return msr.value; + } + + void amd64_emulator::msr_write(uint32_t rid, uint64_t value) { + uc_x86_msr msr; + msr.rid = rid; + msr.value = value; + + auto err = uc_reg_write(m_unicorn_engine.get(), UC_X86_REG_MSR, &msr); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + } + + void amd64_emulator::mem_map(uint64_t address, size_t size, uint32_t perms) { + auto err = uc_mem_map(m_unicorn_engine.get(), address, size, perms); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_map failed."); + } + } + + void amd64_emulator::mem_unmap(uint64_t address, size_t size) { + auto err = uc_mem_unmap(m_unicorn_engine.get(), address, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_unmap failed."); + } + } + + void amd64_emulator::mem_read(uint64_t address, void* buf, size_t size) { + auto err = uc_mem_read(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + } + + std::vector amd64_emulator::mem_read(uint64_t address, size_t size) { + std::vector ret_buf(size); + + auto err = uc_mem_read(m_unicorn_engine.get(), address, ret_buf.data(), ret_buf.size()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + + return ret_buf; + } + + void amd64_emulator::mem_write(uint64_t address, const void* buf, size_t size) { + auto err = uc_mem_write(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_write failed."); + } + } + + void amd64_emulator::mem_write(uint64_t address, const std::vector& buf) { + mem_write(address, buf.data(), buf.size()); + } + + void amd64_emulator::hook_del(uc_hook hook_handle) { + auto iter_of_hook_stub_ctxs = m_unicorn_hook_stub_ctxs.find(hook_handle); + if (iter_of_hook_stub_ctxs == m_unicorn_hook_stub_ctxs.end()) { + throw exceptions::key_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target hook is not found."); + } + + auto iter_of_hook_cbs_hookcode = m_unicorn_hook_cbs_hookcode.find(hook_handle); + if (iter_of_hook_cbs_hookcode != m_unicorn_hook_cbs_hookcode.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_cbs_hookcode.erase(iter_of_hook_cbs_hookcode); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + auto iter_of_hook_cbs_hookmem = m_unicorn_hook_cbs_hookmem.find(hook_handle); + if (iter_of_hook_cbs_hookmem != m_unicorn_hook_cbs_hookmem.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_cbs_hookmem.erase(iter_of_hook_cbs_hookmem); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + auto iter_of_hook_cbs_eventmem = m_unicorn_hook_cbs_eventmem.find(hook_handle); + if (iter_of_hook_cbs_eventmem != m_unicorn_hook_cbs_eventmem.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_cbs_eventmem.erase(iter_of_hook_cbs_eventmem); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + __assume(false); + } + + void amd64_emulator::emu_start(uint64_t begin_address, uint64_t end_address, uint64_t timeout, size_t count) { + auto err = uc_emu_start(m_unicorn_engine.get(), begin_address, end_address, timeout, count); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"emu_start failed."); + } + } + + void amd64_emulator::emu_stop() { + auto err = uc_emu_stop(m_unicorn_engine.get()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_emu_stop failed."); + } + } + + //void amd64_emulator::create_gdt_entry(uint64_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags) { + // struct { + // uint16_t limit0; + // uint16_t base0; + // uint8_t base1; + // uint8_t access_byte; + // uint8_t limit1 : 4; + // uint8_t flags : 4; + // uint8_t base2; + // } segment_descriptor; + + // static_assert(sizeof(segment_descriptor) == 8); + + // segment_descriptor.limit0 = limit & 0xffff; + // segment_descriptor.base0 = base & 0xffff; + // segment_descriptor.base1 = (base >> 16) & 0xff; + // segment_descriptor.access_byte = access_byte; + // segment_descriptor.limit1 = (limit >> 16) & 0xf; + // segment_descriptor.flags = flags & 0xf; + // segment_descriptor.base2 = (base >> 24) & 0xff; + + // auto err = uc_mem_write(m_unicorn_engine.get(), gdt_entry_address, &segment_descriptor, sizeof(segment_descriptor)); + // if (err != UC_ERR_OK) { + // throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_write failed."); + // } + //} +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-patcher/amd64_emulator.hpp b/navicat-patcher/amd64_emulator.hpp new file mode 100644 index 0000000..b4bfa82 --- /dev/null +++ b/navicat-patcher/amd64_emulator.hpp @@ -0,0 +1,159 @@ +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/unicorn/unicorn_handle.hpp" + +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\amd64_emulator.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + class amd64_emulator { + public: + class backend_error : public ::nkg::exception { + public: + using error_code_t = uc_err; + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, error_code_t unicorn_err, std::string_view message) noexcept : + ::nkg::exception(file, line, message), m_error_code(unicorn_err), m_error_string(uc_strerror(unicorn_err)) {} + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + + using hookcode_cb_t = void(uint64_t address, size_t size); + using hookmem_cb_t = void(uc_mem_type type, uint64_t address, size_t size, int64_t value); + using eventmem_cb_t = bool(uc_mem_type type, uint64_t address, size_t size, int64_t value); + + private: + struct hook_stub_context_t { + amd64_emulator* self; + uc_hook unicorn_hook_handle; + }; + + resource_wrapper m_unicorn_engine; + std::unordered_map m_unicorn_user_ctx; + + std::unordered_map> m_unicorn_hook_stub_ctxs; + + std::unordered_map> m_unicorn_hook_cbs_hookcode; + std::unordered_map> m_unicorn_hook_cbs_hookmem; + std::unordered_map> m_unicorn_hook_cbs_eventmem; + + static void _unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data); + static void _unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + static bool _unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + + public: + amd64_emulator(); + + void reg_read(int regid, void* buf); + + void reg_write(int regid, const void* buf); + + uint64_t msr_read(uint32_t rid); + + void msr_write(uint32_t rid, uint64_t value); + + void mem_map(uint64_t address, size_t size, uint32_t perms); + + void mem_unmap(uint64_t address, size_t size); + + void mem_read(uint64_t address, void* buf, size_t size); + + std::vector mem_read(uint64_t address, size_t size); + + void mem_write(uint64_t address, const void* buf, size_t size); + + void mem_write(uint64_t address, const std::vector& buf); + + template + uc_hook hook_add(callable_t&& hook_callback, uint64_t begin_address = 1, uint64_t end_address = 0) { + uc_err err; + + auto hook_stub_ctx = std::make_unique(); + hook_stub_ctx->self = this; + hook_stub_ctx->unicorn_hook_handle = 0; + + if constexpr (hook_type == UC_HOOK_CODE) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookcode_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_cbs_hookcode.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::forward(hook_callback))); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_VALID) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_cbs_hookmem.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::forward(hook_callback))); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_eventmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_cbs_eventmem.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::forward(hook_callback))); + } else { + static_assert( + hook_type == UC_HOOK_CODE || + (hook_type & ~UC_HOOK_MEM_VALID) == 0 || + (hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0, "Unsupported hook type."); + } + + return m_unicorn_hook_stub_ctxs.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::move(hook_stub_ctx))).first->first; + } + + void hook_del(uc_hook hook_handle); + + void emu_start(uint64_t begin_address, uint64_t end_address = 0, uint64_t timeout = 0, size_t count = 0); + + void emu_stop(); + + // void create_gdt_entry(uint64_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags); + + template + void context_set(const std::string& name, val_t&& value) { + m_unicorn_user_ctx[name] = std::forward(value); + } + + template + val_t context_get(const std::string& name) { + return std::any_cast(m_unicorn_user_ctx[name]); + } + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-patcher/i386_emulator.cpp b/navicat-patcher/i386_emulator.cpp new file mode 100644 index 0000000..d1182f4 --- /dev/null +++ b/navicat-patcher/i386_emulator.cpp @@ -0,0 +1,160 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "i386_emulator.hpp" +#include "exceptions/key_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\i386_emulator.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + void i386_emulator::_unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) { + auto hook_stub_ctx = + reinterpret_cast(user_data); + + auto& hook_callback = + std::any_cast&>(hook_stub_ctx->self->m_unicorn_hook_callbacks[hook_stub_ctx->unicorn_hook_handle]); + + hook_callback(static_cast(address), size); + } + + void i386_emulator::_unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = + reinterpret_cast(user_data); + + auto& hook_callback = + std::any_cast&>(hook_stub_ctx->self->m_unicorn_hook_callbacks[hook_stub_ctx->unicorn_hook_handle]); + + hook_callback(type, static_cast(address), static_cast(size), static_cast(value)); + } + + bool i386_emulator::_unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = + reinterpret_cast(user_data); + + auto& hook_callback = + std::any_cast&>(hook_stub_ctx->self->m_unicorn_hook_callbacks[hook_stub_ctx->unicorn_hook_handle]); + + return hook_callback(type, static_cast(address), static_cast(size), static_cast(value)); + } + + i386_emulator::i386_emulator() { + auto err = uc_open(UC_ARCH_X86, UC_MODE_32, m_unicorn_engine.unsafe_addressof()); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_open failed."); + } + } + + void i386_emulator::reg_read(int regid, void* value) { + auto err = uc_reg_read(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_read failed."); + } + } + + void i386_emulator::reg_write(int regid, const void* value) { + auto err = uc_reg_write(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + } + + void i386_emulator::mem_map(uint32_t address, size_t size, uint32_t perms) { + auto err = uc_mem_map(m_unicorn_engine.get(), address, size, perms); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_map failed."); + } + } + + void i386_emulator::mem_unmap(uint32_t address, size_t size) { + auto err = uc_mem_unmap(m_unicorn_engine.get(), address, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_unmap failed."); + } + } + + void i386_emulator::mem_read(uint32_t address, void* buf, size_t size) { + auto err = uc_mem_read(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + } + + std::vector i386_emulator::mem_read(uint32_t address, size_t size) { + std::vector ret_buf(size); + + auto err = uc_mem_read(m_unicorn_engine.get(), address, ret_buf.data(), ret_buf.size()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + + return ret_buf; + } + + void i386_emulator::mem_write(uint32_t address, const void* buf, size_t size) { + auto err = uc_mem_write(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_write failed."); + } + } + + void i386_emulator::mem_write(uint32_t address, const std::vector& buf) { + mem_write(address, buf.data(), buf.size()); + } + + void i386_emulator::hook_del(uc_hook hook_handle) { + auto iter_of_hook_stub_ctxs = m_unicorn_hook_stub_ctxs.find(hook_handle); + if (iter_of_hook_stub_ctxs == m_unicorn_hook_stub_ctxs.end()) { + throw exceptions::key_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target hook is not found."); + } + + auto iter_of_hook_callbacks = m_unicorn_hook_callbacks.find(hook_handle); + if (iter_of_hook_callbacks != m_unicorn_hook_callbacks.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_callbacks.erase(iter_of_hook_callbacks); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + __assume(false); + } + + void i386_emulator::create_gdt_entry(uint32_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags) { + struct { + uint64_t limit0 : 16; + uint64_t base0 : 24; + uint64_t access_byte : 8; + uint64_t limit1 : 4; + uint64_t flags : 4; + uint64_t base1 : 8; + } gdt_entry; + + gdt_entry.limit0 = limit & 0xffff; + gdt_entry.base0 = base & 0xffffff; + gdt_entry.access_byte = access_byte; + gdt_entry.flags = flags & 0xf; + gdt_entry.base1 = (base & 0xff000000) >> 24; + + mem_write(gdt_entry_address, &gdt_entry, sizeof(gdt_entry)); + } + + void i386_emulator::emu_start(uint32_t begin_address, uint32_t end_address, uint64_t timeout, size_t count) { + auto err = uc_emu_start(m_unicorn_engine.get(), begin_address, end_address, timeout, count); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"emu_start failed."); + } + } + + void i386_emulator::emu_stop() { + auto err = uc_emu_stop(m_unicorn_engine.get()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_emu_stop failed."); + } + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-patcher/i386_emulator.hpp b/navicat-patcher/i386_emulator.hpp new file mode 100644 index 0000000..acfe2e3 --- /dev/null +++ b/navicat-patcher/i386_emulator.hpp @@ -0,0 +1,152 @@ +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/unicorn/unicorn_handle.hpp" + +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\i386_emulator.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + class i386_emulator { + public: + class backend_error : public ::nkg::exception { + public: + using error_code_t = uc_err; + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, error_code_t unicorn_err, std::string_view message) noexcept : + ::nkg::exception(file, line, message), m_error_code(unicorn_err), m_error_string(uc_strerror(unicorn_err)) {} + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + + using hookcode_cb_t = void(uint32_t address, size_t size); + using hookmem_cb_t = void(uc_mem_type type, uint32_t address, size_t size, int32_t value); + using eventmem_cb_t = bool(uc_mem_type type, uint32_t address, size_t size, int32_t value); + + private: + struct hook_stub_context_t { + i386_emulator* self; + uc_hook unicorn_hook_handle; + }; + + resource_wrapper m_unicorn_engine; + std::unordered_map m_unicorn_user_ctx; + + std::unordered_map> m_unicorn_hook_stub_ctxs; + std::unordered_map m_unicorn_hook_callbacks; + + static void _unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data); + static void _unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + static bool _unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + + public: + i386_emulator(); + + void reg_read(int regid, void* value); + + void reg_write(int regid, const void* value); + + void mem_map(uint32_t address, size_t size, uint32_t perms); + + void mem_unmap(uint32_t address, size_t size); + + void mem_read(uint32_t address, void* buf, size_t size); + + std::vector mem_read(uint32_t address, size_t size); + + void mem_write(uint32_t address, const void* buf, size_t size); + + void mem_write(uint32_t address, const std::vector& buf); + + template + uc_hook hook_add(callable_t&& hook_callback, uint32_t begin_address = 1, uint32_t end_address = 0) { + uc_err err; + + auto hook_stub_ctx = std::make_unique(); + hook_stub_ctx->self = this; + hook_stub_ctx->unicorn_hook_handle = 0; + + if constexpr (hook_type == UC_HOOK_CODE) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookcode_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_callbacks.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::function{ std::forward(hook_callback) })); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_VALID) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_callbacks.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::function{ std::forward(hook_callback) })); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_eventmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_callbacks.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::function{ std::forward(hook_callback) })); + } else { + static_assert( + hook_type == UC_HOOK_CODE || + (hook_type & ~UC_HOOK_MEM_VALID) == 0 || + (hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0, "Unsupported hook type."); + } + + return m_unicorn_hook_stub_ctxs.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::move(hook_stub_ctx))).first->first; + } + + void hook_del(uc_hook hook_handle); + + void create_gdt_entry(uint32_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags); + + void emu_start(uint32_t begin_address, uint32_t end_address = 0, uint64_t timeout = 0, size_t count = 0); + + void emu_stop(); + + template + void context_set(const std::string& name, val_t&& value) { + m_unicorn_user_ctx[name] = std::forward(value); + } + + template + val_t context_get(const std::string& name) { + return std::any_cast(m_unicorn_user_ctx[name]); + } + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-patcher/image_interpreter.cpp b/navicat-patcher/image_interpreter.cpp new file mode 100644 index 0000000..576ccf9 --- /dev/null +++ b/navicat-patcher/image_interpreter.cpp @@ -0,0 +1,302 @@ +#include "image_interpreter.hpp" +#include +#include "exceptions/index_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\image_interpreter.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + image_interpreter::image_interpreter() : + m_dos_header(nullptr), + m_nt_headers(nullptr), + m_section_header_table(nullptr), + m_vs_fixed_file_info(nullptr) {} + + [[nodiscard]] + image_interpreter image_interpreter::parse(void* image_base, bool parse_relocation) { + image_interpreter new_image; + + new_image.m_dos_header = reinterpret_cast(image_base); + if (new_image.m_dos_header->e_magic != IMAGE_DOS_SIGNATURE) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: DOS signature check failure") + .push_hint(u8"Are you sure you DO provide a valid WinPE file?"); + } + + new_image.m_nt_headers = reinterpret_cast(reinterpret_cast(image_base) + new_image.m_dos_header->e_lfanew); + if (new_image.m_nt_headers->Signature != IMAGE_NT_SIGNATURE) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: NT signature check failure") + .push_hint(u8"Are you sure you DO provide a valid WinPE file?"); + } + +#if defined(_M_AMD64) + if (new_image.m_nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: optional header magic check failure") + .push_hint(u8"Are you sure you DO provide a valid 64-bits WinPE file?"); + } + if (new_image.m_nt_headers->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: machine check failure") + .push_hint(u8"Are you sure you DO provide a valid 64-bits WinPE file?"); + } +#elif defined(_M_IX86) + if (new_image.m_nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid Image. (Optional header magic check failure)") + .push_hint(u8"Are you sure you DO provide a valid 32-bits WinPE file?"); + } + if (new_image.m_nt_headers->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid Image. (Machine check failure)") + .push_hint(u8"Are you sure you DO provide a valid 32-bits WinPE file?"); + } +#else +#error "image_interpreter.cpp: unsupported architecture." +#endif + + new_image.m_section_header_table = + reinterpret_cast(reinterpret_cast(&new_image.m_nt_headers->OptionalHeader) + new_image.m_nt_headers->FileHeader.SizeOfOptionalHeader); + + for (WORD i = 0; i < new_image.m_nt_headers->FileHeader.NumberOfSections; ++i) { + auto section_name = make_section_name(new_image.m_section_header_table[i].Name); + + if (new_image.m_section_header_name_lookup_table.find(section_name) == new_image.m_section_header_name_lookup_table.end()) { + new_image.m_section_header_name_lookup_table[section_name] = &new_image.m_section_header_table[i]; + } + + new_image.m_section_header_rva_lookup_table[new_image.m_section_header_table[i].VirtualAddress] = &new_image.m_section_header_table[i]; + new_image.m_section_header_fo_lookup_table[new_image.m_section_header_table[i].PointerToRawData] = &new_image.m_section_header_table[i]; + } + + if (parse_relocation && new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) { + auto relocation_table = + new_image.convert_rva_to_ptr(new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); + + while (relocation_table->VirtualAddress != 0) { + rva_t rva = relocation_table->VirtualAddress; + auto reloc_items = reinterpret_cast(relocation_table + 1); + auto reloc_items_count = (relocation_table->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); + + for (DWORD i = 0; i < reloc_items_count; ++i) { + auto reloc_type = reloc_items[i] >> 12; + + switch (reloc_type) { + case IMAGE_REL_BASED_ABSOLUTE: + break; + case IMAGE_REL_BASED_HIGH: + case IMAGE_REL_BASED_LOW: + case IMAGE_REL_BASED_HIGHADJ: + new_image.m_relocation_rva_lookup_table[rva + (reloc_items[i] & 0x0fff)] = 2; + break; + case IMAGE_REL_BASED_HIGHLOW: + new_image.m_relocation_rva_lookup_table[rva + (reloc_items[i] & 0x0fff)] = 4; + break; +#if defined(IMAGE_REL_BASED_DIR64) + case IMAGE_REL_BASED_DIR64: + new_image.m_relocation_rva_lookup_table[rva + (reloc_items[i] & 0x0fff)] = 8; + break; +#endif + default: + break; + } + } + + relocation_table = reinterpret_cast(&reloc_items[reloc_items_count]); + } + } + + if (new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) { + rva_t import_rva = new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + auto import_descriptors = new_image.convert_rva_to_ptr(import_rva); + for (size_t i = 0; import_descriptors[i].OriginalFirstThunk != 0; ++i) { + auto import_lookup_table = new_image.convert_rva_to_ptr(import_descriptors[i].OriginalFirstThunk); + rva_t import_address_table_rva = import_descriptors[i].FirstThunk; + + for (size_t j = 0; import_lookup_table[j].u1.Ordinal != 0; ++j) { + new_image.m_iat_rva_lookup_table[import_address_table_rva + j * sizeof(IMAGE_THUNK_DATA)] = std::make_pair(&import_descriptors[i], &import_lookup_table[j]); + } + } + } + + if (new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) { + rva_t resource_rva = new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; + + auto res_type_directory = new_image.convert_rva_to_ptr(resource_rva); + auto res_type_name_entries = reinterpret_cast(res_type_directory + 1); + auto res_type_id_entries = res_type_name_entries + res_type_directory->NumberOfNamedEntries; + + for (WORD i = 0; i < res_type_directory->NumberOfIdEntries && new_image.m_vs_fixed_file_info == nullptr; ++i) { + if (res_type_id_entries[i].Id == reinterpret_cast(RT_VERSION) && res_type_id_entries[i].DataIsDirectory) { + auto res_name_directory = new_image.convert_rva_to_ptr(resource_rva + res_type_id_entries[i].OffsetToDirectory); + auto res_name_name_entries = reinterpret_cast(res_name_directory + 1); + auto res_name_id_entries = res_name_name_entries + res_name_directory->NumberOfNamedEntries; + + for (WORD j = 0; j < res_name_directory->NumberOfIdEntries && new_image.m_vs_fixed_file_info == nullptr; ++j) { + if (res_name_id_entries[j].Id == VS_VERSION_INFO && res_name_id_entries[j].DataIsDirectory) { + auto res_lang_directory = new_image.convert_rva_to_ptr(resource_rva + res_name_id_entries[j].OffsetToDirectory); + auto res_lang_name_entries = reinterpret_cast(res_lang_directory + 1); + auto res_lang_id_entries = res_lang_name_entries + res_lang_directory->NumberOfNamedEntries; + + for (WORD k = 0; k < res_lang_directory->NumberOfIdEntries && new_image.m_vs_fixed_file_info == nullptr; ++k) { + constexpr WORD neutral_lang_id = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); + constexpr WORD english_lang_id = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + + if ((res_lang_id_entries[k].Id == neutral_lang_id || res_lang_id_entries[k].Id == english_lang_id) && !res_lang_id_entries[k].DataIsDirectory) { + auto res_data_entry = new_image.convert_rva_to_ptr(resource_rva + res_lang_id_entries[k].OffsetToData); + + auto vs_version_info = new_image.convert_rva_to_ptr(res_data_entry->OffsetToData); + auto vs_version_info_key = reinterpret_cast(vs_version_info + 6); // vs_version_info->szKey + if (_wcsicmp(vs_version_info_key, L"VS_VERSION_INFO") == 0) { + auto p = reinterpret_cast(vs_version_info_key + _countof(L"VS_VERSION_INFO")); + while (new_image.convert_ptr_to_rva(p) % sizeof(DWORD)) { + ++p; + } + + auto vs_fixed_file_info = reinterpret_cast(p); + + if (vs_fixed_file_info->dwSignature == VS_FFI_SIGNATURE) { + new_image.m_vs_fixed_file_info = vs_fixed_file_info; + } + } + } + } + } + } + } + } + } + + return new_image; + } + + [[nodiscard]] + PIMAGE_DOS_HEADER image_interpreter::image_dos_header() const noexcept { + return m_dos_header; + } + + [[nodiscard]] + PIMAGE_NT_HEADERS image_interpreter::image_nt_headers() const noexcept { + return m_nt_headers; + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_table() const noexcept { + return m_section_header_table; + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header(size_t n) const { + if (n < m_nt_headers->FileHeader.NumberOfSections) { + return m_section_header_table + n; + } else { + throw exceptions::index_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Section index is out of range."); + } + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header(std::string_view section_name) const { + if (section_name.length() <= 8) { + std::array name{}; + + std::copy(section_name.begin(), section_name.end(), name.begin()); + + auto it = m_section_header_name_lookup_table.find(name); + if (it != m_section_header_name_lookup_table.end()) { + return it->second; + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), fmt::format(u8"Target section header is not found: section_name = {}", section_name)); + } + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target section header is not found: section_name is too long."); + } + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_from_rva(rva_t rva) const { + auto it = m_section_header_rva_lookup_table.upper_bound(rva); + if (it != m_section_header_rva_lookup_table.begin()) { + --it; + } + + rva_t section_rva_begin = it->second->VirtualAddress; + rva_t section_rva_end = section_rva_begin + it->second->Misc.VirtualSize; + + if (section_rva_begin <= rva && rva < section_rva_end) { + return it->second; + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target section header is not found.") + .push_hint(fmt::format("rva = 0x{:x}", rva)); + } + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_from_va(va_t va) const { + return image_section_header_from_rva(static_cast(va - m_nt_headers->OptionalHeader.ImageBase)); + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_from_fo(fo_t file_offset) const { + auto it = m_section_header_fo_lookup_table.upper_bound(file_offset); + if (it != m_section_header_fo_lookup_table.begin()) { + --it; + } + + uintptr_t section_fo_begin = it->second->PointerToRawData; + uintptr_t section_fo_end = section_fo_begin + it->second->SizeOfRawData; + + if (section_fo_begin <= file_offset && file_offset < section_fo_end) { + return it->second; + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target section header is not found.") + .push_hint(fmt::format(u8"file_offset = 0x{:x}", file_offset)); + } + } + + [[nodiscard]] + image_interpreter::va_t image_interpreter::convert_rva_to_va(rva_t rva) const noexcept { + return rva + m_nt_headers->OptionalHeader.ImageBase; + } + + [[nodiscard]] + image_interpreter::fo_t image_interpreter::convert_rva_to_fo(rva_t rva) const { + auto section_header = image_section_header_from_rva(rva); + return section_header->PointerToRawData + (rva - static_cast(section_header->VirtualAddress)); + } + + [[nodiscard]] + image_interpreter::rva_t image_interpreter::convert_fo_to_rva(fo_t file_offset) const { + auto section_header = image_section_header_from_fo(file_offset); + return section_header->VirtualAddress + (file_offset - section_header->PointerToRawData); + } + + [[nodiscard]] + image_interpreter::va_t image_interpreter::convert_fo_to_va(fo_t file_offset) const { + return convert_fo_to_rva(file_offset) + m_nt_headers->OptionalHeader.ImageBase; + } + + [[nodiscard]] + image_interpreter::rva_t image_interpreter::convert_va_to_rva(va_t va) const noexcept { + return va - m_nt_headers->OptionalHeader.ImageBase; + } + + [[nodiscard]] + image_interpreter::fo_t image_interpreter::convert_va_to_fo(va_t va) const { + return image_section_header_from_va(va)->PointerToRawData; + } + + [[nodiscard]] + size_t image_interpreter::number_of_sections() const noexcept { + return m_nt_headers->FileHeader.NumberOfSections; + } + + PIMAGE_IMPORT_DESCRIPTOR image_interpreter::import_descriptor_from_rva(rva_t rva) { + auto it = m_iat_rva_lookup_table.find(rva); + return it != m_iat_rva_lookup_table.end() ? it->second.first : nullptr; + } + + PIMAGE_THUNK_DATA image_interpreter::import_lookup_entry_from_rva(rva_t rva) { + auto it = m_iat_rva_lookup_table.find(rva); + return it != m_iat_rva_lookup_table.end() ? it->second.second : nullptr; + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-patcher/image_interpreter.hpp b/navicat-patcher/image_interpreter.hpp new file mode 100644 index 0000000..7d437ae --- /dev/null +++ b/navicat-patcher/image_interpreter.hpp @@ -0,0 +1,202 @@ +#pragma once +#include +#include +#include +#include + +#include "exception.hpp" + +namespace nkg { + + class image_interpreter { + public: + using va_t = uintptr_t; + using rva_t = uintptr_t; + using fo_t = uintptr_t; + + private: + PIMAGE_DOS_HEADER m_dos_header; + PIMAGE_NT_HEADERS m_nt_headers; + PIMAGE_SECTION_HEADER m_section_header_table; + + std::map, PIMAGE_SECTION_HEADER> m_section_header_name_lookup_table; + std::map m_section_header_rva_lookup_table; + std::map m_section_header_fo_lookup_table; + + std::map m_relocation_rva_lookup_table; + + std::map> m_iat_rva_lookup_table; + + VS_FIXEDFILEINFO* m_vs_fixed_file_info; + + image_interpreter(); + + static std::array make_section_name(const BYTE (&name)[8]) { + std::array retval; + std::copy(std::begin(name), std::end(name), retval.begin()); + return retval; + } + + public: + class parse_error : public ::nkg::exception { + public: + parse_error(std::string_view file, int line, std::string_view message) noexcept : + ::nkg::exception(file, line, message) {} + }; + + [[nodiscard]] + static image_interpreter parse(void* image_base, bool parse_relocation); + + template + [[nodiscard]] + ptr_t image_base() const noexcept { + static_assert(std::is_pointer_v); + return reinterpret_cast(m_dos_header); + } + + [[nodiscard]] + PIMAGE_DOS_HEADER image_dos_header() const noexcept; + + [[nodiscard]] + PIMAGE_NT_HEADERS image_nt_headers() const noexcept; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_table() const noexcept; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header(size_t n) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header(std::string_view name) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_from_rva(rva_t rva) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_from_va(va_t va) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_from_fo(fo_t file_offset) const; + + [[nodiscard]] + va_t convert_rva_to_va(rva_t rva) const noexcept; + + [[nodiscard]] + fo_t convert_rva_to_fo(rva_t rva) const; + + template + [[nodiscard]] + ptr_t convert_rva_to_ptr(rva_t rva) const { + static_assert(std::is_pointer_v); + return convert_fo_to_ptr(convert_rva_to_fo(rva)); + } + + [[nodiscard]] + rva_t convert_fo_to_rva(fo_t file_offset) const; + + [[nodiscard]] + va_t convert_fo_to_va(fo_t file_offset) const; + + template + [[nodiscard]] + ptr_t convert_fo_to_ptr(fo_t file_offset) const noexcept { + static_assert(std::is_pointer_v); + return reinterpret_cast(image_base() + file_offset); + } + + [[nodiscard]] + rva_t convert_va_to_rva(va_t va) const noexcept; + + [[nodiscard]] + fo_t convert_va_to_fo(va_t va) const; + + template + [[nodiscard]] + ptr_t convert_va_to_ptr(va_t va) const noexcept { + return convert_rva_to_ptr(convert_va_to_rva(va)); + } + + template + [[nodiscard]] + fo_t convert_ptr_to_fo(ptr_t ptr) const noexcept { + static_assert(std::is_pointer_v); + return reinterpret_cast(ptr) - image_base(); + } + + template + [[nodiscard]] + rva_t convert_ptr_to_rva(ptr_t ptr) const { + return convert_fo_to_rva(convert_ptr_to_fo(ptr)); + } + + template + [[nodiscard]] + va_t convert_ptr_to_va(ptr_t ptr) const { + return convert_fo_to_va(convert_ptr_to_fo(ptr)); + } + + [[nodiscard]] + size_t number_of_sections() const noexcept; + + template + [[nodiscard]] + ptr_t image_section_view(size_t n, size_t offset = 0) const { + static_assert(std::is_pointer_v); + return reinterpret_cast(image_base() + image_section_header(n)->PointerToRawData + offset); + } + + template + [[nodiscard]] + ptr_t image_section_view(std::string_view section_name, size_t offset = 0) const { + static_assert(std::is_pointer_v); + return reinterpret_cast(image_base() + image_section_header(section_name)->PointerToRawData + offset); + } + + template + [[nodiscard]] + ptr_t search_section(size_t n, pred_func_t&& pred_func) const { + static_assert(std::is_pointer_v); + + auto section_header = image_section_header(n); + + auto begin = image_base() + section_header->PointerToRawData; + auto end = begin + section_header->Misc.VirtualSize; + + for (; begin < end; ++begin) { + if (pred_func(begin, end - begin)) { + return reinterpret_cast(const_cast(begin)); + } + } + + return nullptr; + } + + template + [[nodiscard]] + ptr_t search_section(std::string_view section_name, pred_func_t&& pred_func) const { + static_assert(std::is_pointer_v); + + auto section_header = image_section_header(section_name); + + auto begin = image_base() + section_header->PointerToRawData; + auto end = begin + section_header->Misc.VirtualSize; + + for (; begin < end; ++begin) { + if (pred_func(begin, end - begin)) { + return reinterpret_cast(const_cast(begin)); + } + } + + return nullptr; + } + + PIMAGE_IMPORT_DESCRIPTOR import_descriptor_from_rva(rva_t rva); + + PIMAGE_THUNK_DATA import_lookup_entry_from_rva(rva_t rva); + + auto& relocation_distribute() { + return m_relocation_rva_lookup_table; + } + }; + +} diff --git a/navicat-patcher/keystone_assembler.cpp b/navicat-patcher/keystone_assembler.cpp new file mode 100644 index 0000000..0b16c68 --- /dev/null +++ b/navicat-patcher/keystone_assembler.cpp @@ -0,0 +1,38 @@ +#include "keystone_assembler.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\keystone_assembler.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + keystone_assembler::keystone_assembler(ks_arch architecture, ks_mode mode) { + auto err = ks_open(architecture, mode, m_keystone_engine.unsafe_addressof()); + if (err != KS_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_open failed."); + } + } + + void keystone_assembler::option(ks_opt_type option_type, size_t option_value) { + auto err = ks_option(m_keystone_engine.get(), option_type, option_value); + if (err != KS_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_option failed."); + } + } + + std::vector keystone_assembler::assemble(std::string_view asm_string, uint64_t asm_address) const { + resource_wrapper machine_code{ resource_traits::keystone::keystone_alloc{} }; + size_t machine_code_size = 0; + size_t stat_count = 0; + + if (ks_asm(m_keystone_engine.get(), asm_string.data(), asm_address, machine_code.unsafe_addressof(), &machine_code_size, &stat_count) < 0) { + auto err = ks_errno(m_keystone_engine.get()); + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_option failed."); + } + + return std::vector(machine_code.get(), machine_code.get() + machine_code_size); + } + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/navicat-patcher/keystone_assembler.hpp b/navicat-patcher/keystone_assembler.hpp new file mode 100644 index 0000000..4015ef6 --- /dev/null +++ b/navicat-patcher/keystone_assembler.hpp @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/keystone/keystone_handle.hpp" + +#include "exception.hpp" + +namespace nkg { + + class keystone_assembler { + public: + class backend_error : public ::nkg::exception { + public: + using error_code_t = ks_err; + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, error_code_t keystone_err, std::string_view message) noexcept : + ::nkg::exception(file, line, message), m_error_code(keystone_err), m_error_string(ks_strerror(keystone_err)) {} + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + + private: + resource_wrapper m_keystone_engine; + + public: + keystone_assembler(ks_arch architecture, ks_mode mode); + + void option(ks_opt_type option_type, size_t option_value); + + std::vector assemble(std::string_view asm_string, uint64_t asm_address = 0) const; + }; + +} diff --git a/navicat-patcher/navicat-patcher.vcxproj b/navicat-patcher/navicat-patcher.vcxproj new file mode 100644 index 0000000..07115dd --- /dev/null +++ b/navicat-patcher/navicat-patcher.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {1b6920eb-e6ed-465f-9600-b5f816752375} + navicatpatcher + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + true + + + true + + + true + + + true + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreaded + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + MultiThreaded + + + Console + true + true + true + + + + + true + true + + + + + true + true + + + true + true + + + + true + true + + + + + + true + true + + + + + + + + true + true + + + + + + \ No newline at end of file diff --git a/navicat-patcher/navicat-patcher.vcxproj.filters b/navicat-patcher/navicat-patcher.vcxproj.filters new file mode 100644 index 0000000..c20ed40 --- /dev/null +++ b/navicat-patcher/navicat-patcher.vcxproj.filters @@ -0,0 +1,66 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/navicat-patcher/navicat-patcher.vcxproj.user b/navicat-patcher/navicat-patcher.vcxproj.user new file mode 100644 index 0000000..966b4ff --- /dev/null +++ b/navicat-patcher/navicat-patcher.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/navicat-patcher/patch_solution.hpp b/navicat-patcher/patch_solution.hpp new file mode 100644 index 0000000..24fded6 --- /dev/null +++ b/navicat-patcher/patch_solution.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "rsa_cipher.hpp" + +namespace nkg { + + class patch_solution { + public: + [[nodiscard]] + virtual bool find_patch() = 0; + + [[nodiscard]] + virtual bool check_rsa_privkey(const rsa_cipher& cipher) = 0; + + virtual void make_patch(const rsa_cipher& cipher) = 0; + + virtual ~patch_solution() = default; + }; + +} diff --git a/navicat-patcher/patch_solution_since.hpp b/navicat-patcher/patch_solution_since.hpp new file mode 100644 index 0000000..1e17cee --- /dev/null +++ b/navicat-patcher/patch_solution_since.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "patch_solution.hpp" + +namespace nkg { + + template + class patch_solution_since; + +} diff --git a/navicat-patcher/patch_solution_since_16.0.7.0.amd64.cpp b/navicat-patcher/patch_solution_since_16.0.7.0.amd64.cpp new file mode 100644 index 0000000..745bf24 --- /dev/null +++ b/navicat-patcher/patch_solution_since_16.0.7.0.amd64.cpp @@ -0,0 +1,591 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "amd64_emulator.hpp" +#include "keystone_assembler.hpp" +#include "patch_solution_since_16.0.7.0.hpp" +#include +#include + +namespace nkg { + + patch_solution_since<16, 0, 7, 0>::patch_solution_since(image_interpreter& libcc_interpreter) : + m_libcc_interpreter(libcc_interpreter), + m_va_CSRegistrationInfoFetcher_WIN_vtable(0), + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey(0), + m_va_iat_entry_malloc(0) {} + + bool patch_solution_since<16, 0, 7, 0>::find_patch() { + auto CSRegistrationInfoFetcher_WIN_type_descriptor_name = + m_libcc_interpreter.search_section( + ".data", + [](const uint8_t* p, size_t s) { + if (s < sizeof(".?AVCSRegistrationInfoFetcher_WIN@@")) { + return false; + } + + return strcmp(reinterpret_cast(p), ".?AVCSRegistrationInfoFetcher_WIN@@") == 0; + } + ); + + if (CSRegistrationInfoFetcher_WIN_type_descriptor_name == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 0)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor = CSRegistrationInfoFetcher_WIN_type_descriptor_name - 0x10; + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_rva = m_libcc_interpreter.convert_ptr_to_rva(CSRegistrationInfoFetcher_WIN_rtti_type_descriptor); + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor = + m_libcc_interpreter.search_section( + ".rdata", + [this, CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_rva](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint32_t) != 0) { + return false; + } + + if (s < sizeof(uint32_t)) { + return false; + } + + if (*reinterpret_cast(p) != CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_rva) { + return false; + } + + if (s < sizeof(uint32_t) * 2) { + return false; + } + + auto maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_rva = reinterpret_cast(p)[1]; + + try { + return memcmp(m_libcc_interpreter.image_section_header_from_rva(maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_rva)->Name, ".rdata\x00\x00", 8) == 0; + } catch (nkg::exception&) { + return false; + } + } + ); + + if (CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 1)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator = CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor - 0xC; + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator); + + auto CSRegistrationInfoFetcher_WIN_vtable_before = + m_libcc_interpreter.search_section( + ".rdata", + [CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint64_t) != 0) { + return false; + } + + if (s < sizeof(uint64_t)) { + return false; + } + + return *reinterpret_cast(p) == CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va; + } + ); + + if (CSRegistrationInfoFetcher_WIN_vtable_before == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Vftable for CSRegistrationInfoFetcher_WIN is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_vtable = + reinterpret_cast(CSRegistrationInfoFetcher_WIN_vtable_before + sizeof(image_interpreter::va_t)); + + m_va_CSRegistrationInfoFetcher_WIN_vtable = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_vtable); + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = CSRegistrationInfoFetcher_WIN_vtable[6]; + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_vtable = 0x%016llx\n", m_va_CSRegistrationInfoFetcher_WIN_vtable); + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = 0x%016llx\n", m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + amd64_emulator x64_emulator; + + x64_emulator.context_set("heap_base", uint64_t{ 0x00007fff00000000 }); + x64_emulator.context_set("heap_size", size_t{ 0x1000 * 32 }); + x64_emulator.context_set("heap_records", std::map{}); + + x64_emulator.context_set("stack_base", uint64_t{ 0x00007fffffff0000 }); + x64_emulator.context_set("stack_size", size_t{ 0x1000 * 32 }); + x64_emulator.context_set("stack_top", uint64_t{ x64_emulator.context_get("stack_base") - x64_emulator.context_get("stack_size") }); + + x64_emulator.context_set("dead_area_base", uint64_t{ 0xfffffffffffff000 }); + x64_emulator.context_set("dead_area_size", size_t{ 0x1000 }); + + x64_emulator.context_set("iat_base", uint64_t{ m_libcc_interpreter.convert_rva_to_va(m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) }); + x64_emulator.context_set("iat_size", size_t{ m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size }); + + x64_emulator.context_set("external_api_stub_area_base", uint64_t{ 0xffff800000000000 }); + x64_emulator.context_set("external_api_stub_area_size", size_t{ (x64_emulator.context_get("iat_size") / 8 + 0xfff) / 0x1000 * 0x1000 }); + + x64_emulator.context_set("external_api_impl", std::map{}); + x64_emulator.context_set("external_api_impl_area_base", uint64_t{ 0xffff900000000000 }); + x64_emulator.context_set("external_api_impl_area_size", size_t{ 0 }); + + x64_emulator.context_set("gs_base", uint64_t{ 0xffffa00000000000 }); + x64_emulator.context_set("gs_size", size_t{ 0x1000 }); + + x64_emulator.context_set("start_address", static_cast(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey)); + x64_emulator.context_set("dead_address", x64_emulator.context_get("dead_area_base")); + + // allocate heap + x64_emulator.mem_map(x64_emulator.context_get("heap_base"), x64_emulator.context_get("heap_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate stack + x64_emulator.mem_map(x64_emulator.context_get("stack_top"), x64_emulator.context_get("stack_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate dead area + x64_emulator.mem_map(x64_emulator.context_get("dead_area_base"), x64_emulator.context_get("dead_area_size"), UC_PROT_READ | UC_PROT_EXEC); + + // allocate and hook read access to IAT + { + auto iat_base = x64_emulator.context_get("iat_base"); + auto iat_size = x64_emulator.context_get("iat_size"); + auto external_api_stub_area_base = x64_emulator.context_get("external_api_stub_area_base"); + + auto iat_page_base = iat_base / 0x1000 * 0x1000; + auto iat_page_count = (iat_base - iat_page_base + iat_size + 0xfff) / 0x1000; + + x64_emulator.mem_map(iat_page_base, iat_page_count * 0x1000, UC_PROT_READ); + + x64_emulator.hook_add( + [this, &x64_emulator, iat_base, external_api_stub_area_base](uc_mem_type type, uint64_t address, size_t size, int64_t value) { + auto rva = m_libcc_interpreter.convert_va_to_rva(address); + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(rva); + + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "memcpy") == 0) { + uint64_t impl_address = x64_emulator.context_get&>("external_api_impl")["memcpy"]; + x64_emulator.mem_write(address, &impl_address, sizeof(impl_address)); + } else if (strcmp(import_by_name_entry->Name, "memcmp") == 0) { + uint64_t impl_address = x64_emulator.context_get&>("external_api_impl")["memcmp"]; + x64_emulator.mem_write(address, &impl_address, sizeof(impl_address)); + } else { + uint64_t stub_address = external_api_stub_area_base + (address - iat_base) / sizeof(IMAGE_THUNK_DATA); + x64_emulator.mem_write(address, &stub_address, sizeof(stub_address)); + } + } else { + x64_emulator.emu_stop(); + } + }, + iat_base, + iat_base + iat_size - 1 + ); + } + + // allocate and setup external api stub area + { + auto external_api_stub_area_base = x64_emulator.context_get("external_api_stub_area_base"); + auto external_api_stub_area_size = x64_emulator.context_get("external_api_stub_area_size"); + + x64_emulator.mem_map(external_api_stub_area_base, external_api_stub_area_size, UC_PROT_READ | UC_PROT_EXEC); + x64_emulator.mem_write(external_api_stub_area_base, std::vector(external_api_stub_area_size, 0xc3)); // c3 -> ret + + x64_emulator.hook_add( + [this, &x64_emulator, external_api_stub_area_base](uint64_t address, size_t size) { + auto iat_base = x64_emulator.context_get("iat_base"); + auto from_va = iat_base + (address - external_api_stub_area_base) * sizeof(IMAGE_THUNK_DATA); + auto from_rva = m_libcc_interpreter.convert_va_to_rva(from_va); + + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(from_rva); + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "malloc") == 0) { + m_va_iat_entry_malloc = from_va; + + uint64_t alloc_size; + x64_emulator.reg_read(UC_X86_REG_RCX, &alloc_size); + + auto& heap_records = x64_emulator.context_get&>("heap_records"); + + auto predecessor_chunk = + std::adjacent_find( + heap_records.begin(), + heap_records.end(), + [alloc_size](const auto& chunk0, const auto& chunk1) { return chunk1.first - (chunk0.first + chunk0.second) >= alloc_size; } + ); + + uint64_t alloc_p; + if (predecessor_chunk != heap_records.end()) { + alloc_p = predecessor_chunk->first + predecessor_chunk->second; + } else { + auto heap_base = x64_emulator.context_get("heap_base"); + auto heap_size = x64_emulator.context_get("heap_size"); + + auto free_space_base = heap_records.size() > 0 ? heap_records.rbegin()->first + heap_records.rbegin()->second : heap_base; + auto free_space_size = heap_base + heap_size - free_space_base; + + if (free_space_size < alloc_size) { + auto heap_expand_base = heap_base + heap_size; + auto heap_expand_size = (alloc_size - free_space_size + 0xfff) / 0x1000 * 0x1000; + x64_emulator.mem_map(heap_expand_base, heap_expand_size, UC_PROT_READ | UC_PROT_WRITE); + } + + alloc_p = free_space_base; + } + + heap_records[alloc_p] = alloc_size; + + x64_emulator.reg_write(UC_X86_REG_RAX, &alloc_p); + } else if (strcmp(import_by_name_entry->Name, "free") == 0) { + uint64_t alloc_p; + x64_emulator.reg_read(UC_X86_REG_RCX, &alloc_p); + + auto& heap_records = x64_emulator.context_get&>("heap_records"); + + auto chunk = heap_records.find(alloc_p); + if (chunk != heap_records.end()) { + heap_records.erase(chunk); + } else { + x64_emulator.emu_stop(); + } + } else { + x64_emulator.emu_stop(); + } + } else { + x64_emulator.emu_stop(); + } + }, + external_api_stub_area_base, + external_api_stub_area_base + external_api_stub_area_size - 1 + ); + } + + // allocate and setup external api impl area + { + keystone_assembler x64_assembler{ KS_ARCH_X86, KS_MODE_64 }; + + std::map> machine_code_list = + { + std::make_pair( + "memcpy", + x64_assembler.assemble( + "push rdi;" + "push rsi;" + "mov rdi, rcx;" + "mov rsi, rdx;" + "mov rcx, r8;" + "rep movs byte ptr [rdi], byte ptr [rsi];" + "pop rsi;" + "pop rdi;" + "ret;" + ) + ), + std::make_pair( + "memcmp", + x64_assembler.assemble( + " push rdi;" + " push rsi;" + " mov rsi, rcx;" + " mov rdi, rdx;" + " mov rcx, r8;" + " cmp rcx, rcx;" + " repe cmps byte ptr [rsi], byte ptr [rdi];" + " jz cmp_eq;" + "cmp_not_eq:" + " movsx eax, byte ptr [rsi - 1];" + " movsx ecx, byte ptr [rdi - 1];" + " sub eax, ecx;" + " jmp final;" + "cmp_eq:" + " xor eax, eax;" + "final:" + " pop rsi;" + " pop rdi;" + " ret;" + ) + ), + std::make_pair( + "memmove", + x64_assembler.assemble( + " push rdi;" + " push rsi;" + " cmp rdx, rcx;" + " jb reverse_copy;" + "copy:" + " mov rdi, rcx;" + " mov rsi, rdx;" + " mov rcx, r8;" + " rep movsb byte ptr[rdi], byte ptr[rsi];" + " jmp final;" + "reverse_copy:" + " std;" + " lea rdi, qword ptr[rcx + r8 - 1];" + " lea rsi, qword ptr[rdx + r8 - 1];" + " mov rcx, r8;" + " rep movsb byte ptr[rdi], byte ptr[rsi];" + " cld;" + "final:" + " pop rsi;" + " pop rdi;" + " ret;" + ) + ) + }; + + auto& external_api_impl = x64_emulator.context_get&>("external_api_impl"); + auto& external_api_impl_area_base = x64_emulator.context_get("external_api_impl_area_base"); + auto& external_api_impl_area_size = x64_emulator.context_get("external_api_impl_area_size"); + + auto p = external_api_impl_area_base; + for (const auto& name_code_pair : machine_code_list) { + external_api_impl[name_code_pair.first] = p; + p = (p + name_code_pair.second.size() + 0xf) / 0x10 * 0x10; + } + + external_api_impl_area_size = (p + 0xfff) / 0x1000 * 0x1000 - external_api_impl_area_base; + + x64_emulator.mem_map(external_api_impl_area_base, external_api_impl_area_size, UC_PROT_READ | UC_PROT_EXEC); + for (const auto& name_code_pair : machine_code_list) { + x64_emulator.mem_write(external_api_impl[name_code_pair.first], name_code_pair.second); + } + } + + // allocate and hook access to gs area + x64_emulator.mem_map(x64_emulator.context_get("gs_base"), x64_emulator.context_get("gs_size"), UC_PROT_READ | UC_PROT_WRITE); + x64_emulator.msr_write(0xC0000101, x64_emulator.context_get("gs_base")); // set gs base address + + x64_emulator.hook_add( + [this, &x64_emulator](uc_mem_type access, uint64_t address, size_t size, int64_t value) { + auto gs_base = x64_emulator.context_get("gs_base"); + switch (address - gs_base) { + case 0x10: // qword ptr gs:[0x10] -> Stack Limit / Ceiling of stack (low address) + { + uint64_t val = x64_emulator.context_get("stack_top"); + x64_emulator.mem_write(address, &val, size); + } + break; + default: + x64_emulator.emu_stop(); + break; + } + }, + x64_emulator.context_get("gs_base"), + x64_emulator.context_get("gs_base") + x64_emulator.context_get("gs_size") - 1 + ); + + // x64_emulator.hook_add([](uint64_t address, size_t size) { wprintf_s(L"code_trace, address = 0x%016zx\n", address); }); + + x64_emulator.hook_add( + [this, &x64_emulator](uc_mem_type access, uint64_t address, size_t size, int64_t value) -> bool { + try { + auto fault_section = m_libcc_interpreter.image_section_header_from_va(address); + + auto page_base = address / 0x1000 * 0x1000; + auto page_size = 0x1000; + uint32_t page_perms = UC_PROT_NONE; + + if (fault_section->Characteristics & IMAGE_SCN_MEM_READ) { + page_perms |= UC_PROT_READ; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_WRITE) { + page_perms |= UC_PROT_WRITE; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_EXECUTE) { + page_perms |= UC_PROT_EXEC; + } + + x64_emulator.mem_map(page_base, page_size, page_perms); + x64_emulator.mem_write(page_base, m_libcc_interpreter.convert_va_to_ptr(page_base), page_size); + + return true; + } catch (::nkg::exception&) { + return false; + } + } + ); + + // set rbp, rsp + uint64_t init_rbp = x64_emulator.context_get("stack_base") - x64_emulator.context_get("stack_size") / 4; + uint64_t init_rsp = x64_emulator.context_get("stack_base") - x64_emulator.context_get("stack_size") / 2; + + x64_emulator.reg_write(UC_X86_REG_RBP, &init_rbp); + x64_emulator.reg_write(UC_X86_REG_RSP, &init_rsp); + + // set return address + auto retaddr = x64_emulator.context_get("dead_address"); + x64_emulator.mem_write(init_rsp, &retaddr, sizeof(retaddr)); + + // set argument registers + uint64_t init_rcx = 0; // `this` pointer of CSRegistrationInfoFetcher_WIN, but we don't need it for now. + uint64_t init_rdx = init_rsp + 0x40; // a pointer to stack memory which stores return value + x64_emulator.reg_write(UC_X86_REG_RCX, &init_rcx); + x64_emulator.reg_write(UC_X86_REG_RDX, &init_rdx); + + // + // start emulate + // + try { + x64_emulator.emu_start(x64_emulator.context_get("start_address"), x64_emulator.context_get("dead_address")); + } catch (nkg::exception&) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Code emulation failed.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_iat_entry_malloc = 0x%016llx\n", m_va_iat_entry_malloc); + + // + // get result + // + // on AMD64 platform, `std::string` has follow memory layout: + // ------------------------------ + // | offset | size | + // ------------------------------ + // | +0 | 0x10 | `char[16]: a small string buffer` OR `char*: a large string buffer pointer` + // ------------------------------ + // | +0x10 | 0x8 | size_t: string length + // ------------------------------ + // | +0x18 | 0x8 | size_t: capacity + // ------------------------------ + // + uint64_t encoded_key_length; + x64_emulator.mem_read(init_rdx + 0x10, &encoded_key_length, sizeof(encoded_key_length)); + if (encoded_key_length != official_encoded_key.length()) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: unexpected encoded key length(%llu).\n", encoded_key_length); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + uint64_t encoded_key_ptr; + x64_emulator.mem_read(init_rdx, &encoded_key_ptr, sizeof(encoded_key_ptr)); + + auto encoded_key = x64_emulator.mem_read(encoded_key_ptr, encoded_key_length); + if (memcmp(encoded_key.data(), official_encoded_key.data(), encoded_key.size()) == 0) { + wprintf_s(L"[+] patch_solution_since<16, 0, 7, 0>: official encoded key is found.\n"); + return true; + } else { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: official encoded key is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + } + + bool patch_solution_since<16, 0, 7, 0>::check_rsa_privkey(const rsa_cipher& cipher) { + return true; // no requirements + } + + void patch_solution_since<16, 0, 7, 0>::make_patch(const rsa_cipher& cipher) { + auto encoded_key = _build_encoded_key(cipher); + + auto CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = + m_libcc_interpreter.convert_va_to_ptr(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + std::vector patch_code_chunks; + patch_code_chunks.emplace_back("push rdi;"); + patch_code_chunks.emplace_back("push rsi;"); + patch_code_chunks.emplace_back("push rbx;"); + patch_code_chunks.emplace_back("push rbp;"); + patch_code_chunks.emplace_back("mov rbp, rsp;"); + patch_code_chunks.emplace_back("mov rbx, rdx;"); + patch_code_chunks.emplace_back("sub rsp, 0x20;"); + patch_code_chunks.emplace_back(fmt::format("mov rcx, {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back(fmt::format("call qword ptr [{:#016x}];", m_va_iat_entry_malloc)); + patch_code_chunks.emplace_back("add rsp, 0x20;"); + { + std::vector push_values((encoded_key.length() + 1 + 7) / 8, 0); + memcpy(push_values.data(), encoded_key.data(), encoded_key.length()); + + std::for_each( + push_values.crbegin(), + push_values.crend(), + [&patch_code_chunks](uint64_t x) { + patch_code_chunks.emplace_back(fmt::format("mov rdx, {:#016x};", x)); + patch_code_chunks.emplace_back("push rdx;"); + } + ); + } + patch_code_chunks.emplace_back("mov rdi, rax;"); + patch_code_chunks.emplace_back("mov rsi, rsp;"); + patch_code_chunks.emplace_back(fmt::format("mov rcx, {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("rep movs byte ptr [rdi], byte ptr [rsi];"); + patch_code_chunks.emplace_back("mov qword ptr [rbx], rax;"); + patch_code_chunks.emplace_back(fmt::format("mov qword ptr [rbx + 0x10], {:#x};", encoded_key.length())); + patch_code_chunks.emplace_back(fmt::format("mov qword ptr [rbx + 0x18], {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("mov rax, rbx;"); + patch_code_chunks.emplace_back("leave;"); + patch_code_chunks.emplace_back("pop rbx;"); + patch_code_chunks.emplace_back("pop rsi;"); + patch_code_chunks.emplace_back("pop rdi;"); + patch_code_chunks.emplace_back("ret;"); + + //auto patch_code = keystone_assembler{ KS_ARCH_X86, KS_MODE_64 } + // .assemble( + // fmt::format( + // " push rdi;" + // " push rsi;" + // " push rbx;" + // " mov rbx, rdx;" + // "allocate_string_buf:" + // " mov rcx, {encoded_key_length:#x} + 1;" + // " sub rsp, 0x20;" + // " call qword ptr [{m_va_iat_entry_malloc:#x}];" + // " add rsp, 0x20;" + // "write_our_own_key_to_string_buf:" + // " mov rdi, rax;" + // " lea rsi, qword ptr [end_of_code + rip];" + // " mov rcx, 0x188;" + // " rep movs byte ptr [rdi], byte ptr [rsi];" + // " mov byte ptr [rdi], 0;" + // "craft_std_string:" + // " mov qword ptr [rbx], rax;" + // " mov qword ptr [rbx + 0x10], {encoded_key_length:#x};" + // " mov qword ptr [rbx + 0x18], {encoded_key_length:#x} + 1;" + // "final:" + // " mov rax, rbx;" + // " pop rbx;" + // " pop rsi;" + // " pop rdi;" + // " ret;" + // "end_of_code:", + // fmt::arg("encoded_key_length", encoded_key.length()), + // fmt::arg("m_va_iat_entry_malloc", m_va_iat_entry_malloc) + // ), + // m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey + // ); + + std::vector assembled_patch_code; + { + keystone_assembler x86_assembler{ KS_ARCH_X86, KS_MODE_64 }; + + auto current_va = m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey; + auto next_reloc = m_libcc_interpreter.relocation_distribute().lower_bound(m_libcc_interpreter.convert_va_to_rva(current_va)); + for (const auto& patch_code_chunk : patch_code_chunks) { + auto assembled_patch_code_chunk = x86_assembler.assemble(patch_code_chunk, current_va); + + while (true) { + auto next_reloc_va = m_libcc_interpreter.convert_rva_to_va(next_reloc->first); + auto next_reloc_size = next_reloc->second; + + if (current_va + assembled_patch_code_chunk.size() + 2 <= next_reloc_va) { // 2 -> size of machine code "jmp rel8" + assembled_patch_code.insert(assembled_patch_code.end(), assembled_patch_code_chunk.begin(), assembled_patch_code_chunk.end()); + current_va += assembled_patch_code_chunk.size(); + break; + } else if (current_va + 2 <= next_reloc_va) { + auto next_va = next_reloc_va + next_reloc_size; + auto assembled_jmp = x86_assembler.assemble(fmt::format("jmp {:#016x};", next_va), current_va); + auto assembled_padding = std::vector(next_va - (current_va + assembled_jmp.size()), 0xcc); // 0xcc -> int3 + assembled_patch_code.insert(assembled_patch_code.end(), assembled_jmp.begin(), assembled_jmp.end()); + assembled_patch_code.insert(assembled_patch_code.end(), assembled_padding.begin(), assembled_padding.end()); + current_va = next_va; + ++next_reloc; + } else { + __assume(false); // impossible to reach here + } + } + } + } + + memcpy(CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey, assembled_patch_code.data(), assembled_patch_code.size()); + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: Patch has been done.\n"); + } + +} diff --git a/navicat-patcher/patch_solution_since_16.0.7.0.generic.cpp b/navicat-patcher/patch_solution_since_16.0.7.0.generic.cpp new file mode 100644 index 0000000..878c014 --- /dev/null +++ b/navicat-patcher/patch_solution_since_16.0.7.0.generic.cpp @@ -0,0 +1,16 @@ +#include "patch_solution_since_16.0.7.0.hpp" +#include + +namespace nkg { + + std::string patch_solution_since<16, 0, 7, 0>::_build_encoded_key(const rsa_cipher& cipher) { + auto encoded_key = cipher.export_public_key_string_pem(); + + encoded_key = std::regex_replace(encoded_key, std::regex("-----BEGIN PUBLIC KEY-----"), ""); + encoded_key = std::regex_replace(encoded_key, std::regex("-----END PUBLIC KEY-----"), ""); + encoded_key = std::regex_replace(encoded_key, std::regex("\n"), ""); + + return encoded_key; + } + +} diff --git a/navicat-patcher/patch_solution_since_16.0.7.0.hpp b/navicat-patcher/patch_solution_since_16.0.7.0.hpp new file mode 100644 index 0000000..7447d66 --- /dev/null +++ b/navicat-patcher/patch_solution_since_16.0.7.0.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "patch_solution_since.hpp" +#include "image_interpreter.hpp" +#include +#include +#include + +namespace nkg { + + template<> + class patch_solution_since<16, 0, 7, 0> final : public patch_solution { + private: + static inline std::string_view official_encoded_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889IqdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginva5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOFR0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmtYyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQawIDAQAB"; + + image_interpreter& m_libcc_interpreter; + image_interpreter::va_t m_va_CSRegistrationInfoFetcher_WIN_vtable; + image_interpreter::va_t m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey; + image_interpreter::va_t m_va_iat_entry_malloc; + + std::string _build_encoded_key(const rsa_cipher& cipher); + + public: + patch_solution_since(image_interpreter& libcc_interpreter); + + [[nodiscard]] + virtual bool find_patch() override; + + [[nodiscard]] + virtual bool check_rsa_privkey(const rsa_cipher& cipher) override; + + virtual void make_patch(const rsa_cipher& cipher) override; + + }; + +} diff --git a/navicat-patcher/patch_solution_since_16.0.7.0.i386.cpp b/navicat-patcher/patch_solution_since_16.0.7.0.i386.cpp new file mode 100644 index 0000000..7a2eea8 --- /dev/null +++ b/navicat-patcher/patch_solution_since_16.0.7.0.i386.cpp @@ -0,0 +1,629 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "i386_emulator.hpp" +#include "keystone_assembler.hpp" +#include "patch_solution_since_16.0.7.0.hpp" +#include +#include + +namespace nkg { + + patch_solution_since<16, 0, 7, 0>::patch_solution_since(image_interpreter& libcc_interpreter) : + m_libcc_interpreter(libcc_interpreter), + m_va_CSRegistrationInfoFetcher_WIN_vtable(0), + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey(0), + m_va_iat_entry_malloc(0) {} + + bool patch_solution_since<16, 0, 7, 0>::find_patch() { + auto CSRegistrationInfoFetcher_WIN_type_descriptor_name = + m_libcc_interpreter.search_section( + ".data", + [](const uint8_t* p, size_t s) { + if (s < sizeof(".?AVCSRegistrationInfoFetcher_WIN@@")) { + return false; + } + + return strcmp(reinterpret_cast(p), ".?AVCSRegistrationInfoFetcher_WIN@@") == 0; + } + ); + + if (CSRegistrationInfoFetcher_WIN_type_descriptor_name == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 0)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor = CSRegistrationInfoFetcher_WIN_type_descriptor_name - 0x8; + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_va = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_rtti_type_descriptor); + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor = + m_libcc_interpreter.search_section( + ".rdata", + [this, CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_va](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint32_t) != 0) { + return false; + } + + if (s < sizeof(uint32_t)) { + return false; + } + + if (*reinterpret_cast(p) != CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_va) { + return false; + } + + if (s < sizeof(uint32_t) * 2) { + return false; + } + + auto maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_va = reinterpret_cast(p)[1]; + + try { + return memcmp(m_libcc_interpreter.image_section_header_from_va(maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_va)->Name, ".rdata\x00\x00", 8) == 0; + } catch (nkg::exception&) { + return false; + } + } + ); + + if (CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 1)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator = CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor - 0xC; + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator); + + auto CSRegistrationInfoFetcher_WIN_vtable_before = + m_libcc_interpreter.search_section( + ".rdata", + [CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint32_t) != 0) { + return false; + } + + if (s < sizeof(uint32_t)) { + return false; + } + + return *reinterpret_cast(p) == CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va; + } + ); + + if (CSRegistrationInfoFetcher_WIN_vtable_before == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Vftable for CSRegistrationInfoFetcher_WIN is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_vtable = + reinterpret_cast(CSRegistrationInfoFetcher_WIN_vtable_before + sizeof(uint32_t)); + + m_va_CSRegistrationInfoFetcher_WIN_vtable = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_vtable); + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = CSRegistrationInfoFetcher_WIN_vtable[6]; + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_vtable = 0x%08x\n", m_va_CSRegistrationInfoFetcher_WIN_vtable); + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = 0x%08x\n", m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + + i386_emulator x86_emulator; + + x86_emulator.context_set("heap_base", uint32_t{ 0x7f000000 }); + x86_emulator.context_set("heap_size", size_t{ 0x1000 * 32 }); + x86_emulator.context_set("heap_records", std::map{}); + + x86_emulator.context_set("stack_base", uint32_t{ 0x7fff0000 }); + x86_emulator.context_set("stack_size", size_t{ 0x1000 * 32 }); + x86_emulator.context_set("stack_top", uint32_t{ x86_emulator.context_get("stack_base") - x86_emulator.context_get("stack_size") }); + + x86_emulator.context_set("r0_to_r3_stub_area_base", uint32_t{ 0xffffe000 }); + x86_emulator.context_set("r0_to_r3_stub_area_size", size_t{ 0x1000 }); + + x86_emulator.context_set("dead_area_base", uint32_t{ 0xfffff000 }); + x86_emulator.context_set("dead_area_size", size_t{ 0x1000 }); + + x86_emulator.context_set("iat_base", uint32_t{ m_libcc_interpreter.convert_rva_to_va(m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) }); + x86_emulator.context_set("iat_size", size_t{ m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size }); + + x86_emulator.context_set("external_api_stub_area_base", uint32_t{ 0x80000000 }); + x86_emulator.context_set("external_api_stub_area_size", size_t{ (x86_emulator.context_get("iat_size") / 8 + 0xfff) / 0x1000 * 0x1000 }); + + x86_emulator.context_set("external_api_impl", std::map{}); + x86_emulator.context_set("external_api_impl_area_base", uint32_t{ 0x90000000 }); + x86_emulator.context_set("external_api_impl_area_size", size_t{ 0 }); + + x86_emulator.context_set("gdt_base", uint32_t{ 0xffff0000 }); + x86_emulator.context_set("gdt_size", size_t{ 0x1000 }); + + x86_emulator.context_set("fs_base", uint32_t{ 0xa0000000 }); + x86_emulator.context_set("fs_size", size_t{ 0x1000 }); + + x86_emulator.context_set("start_address", static_cast(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey)); + x86_emulator.context_set("dead_address", x86_emulator.context_get("dead_area_base")); + + // allocate heap + x86_emulator.mem_map(x86_emulator.context_get("heap_base"), x86_emulator.context_get("heap_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate stack + x86_emulator.mem_map(x86_emulator.context_get("stack_top"), x86_emulator.context_get("stack_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate r0_to_r3_stub area + x86_emulator.mem_map(x86_emulator.context_get("r0_to_r3_stub_area_base"), x86_emulator.context_get("r0_to_r3_stub_area_size"), UC_PROT_READ | UC_PROT_EXEC); + x86_emulator.mem_write(x86_emulator.context_get("r0_to_r3_stub_area_base"), keystone_assembler{ KS_ARCH_X86, KS_MODE_32 }.assemble("iretd;")); + + // allocate dead area + x86_emulator.mem_map(x86_emulator.context_get("dead_area_base"), x86_emulator.context_get("dead_area_size"), UC_PROT_READ | UC_PROT_EXEC); + + // allocate and hook read access to IAT + { + auto iat_base = x86_emulator.context_get("iat_base"); + auto iat_size = x86_emulator.context_get("iat_size"); + auto external_api_stub_area_base = x86_emulator.context_get("external_api_stub_area_base"); + + auto iat_page_base = iat_base / 0x1000 * 0x1000; + auto iat_page_count = (iat_base - iat_page_base + iat_size + 0xfff) / 0x1000; + + x86_emulator.mem_map(iat_page_base, iat_page_count * 0x1000, UC_PROT_READ); + + x86_emulator.hook_add( + [this, &x86_emulator, iat_base, external_api_stub_area_base](uc_mem_type type, uint32_t address, size_t size, int32_t value) { + auto rva = m_libcc_interpreter.convert_va_to_rva(address); + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(rva); + + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "memcpy") == 0) { + uint32_t impl_address = x86_emulator.context_get&>("external_api_impl")["memcpy"]; + x86_emulator.mem_write(address, &impl_address, sizeof(impl_address)); + } else { + uint32_t stub_address = external_api_stub_area_base + (address - iat_base) / sizeof(IMAGE_THUNK_DATA); + x86_emulator.mem_write(address, &stub_address, sizeof(stub_address)); + } + } else { + x86_emulator.emu_stop(); + } + }, + iat_base, + iat_base + iat_size - 1 + ); + } + + // allocate and setup external api stub area + { + auto external_api_stub_area_base = x86_emulator.context_get("external_api_stub_area_base"); + auto external_api_stub_area_size = x86_emulator.context_get("external_api_stub_area_size"); + + x86_emulator.mem_map(external_api_stub_area_base, external_api_stub_area_size, UC_PROT_READ | UC_PROT_EXEC); + x86_emulator.mem_write(external_api_stub_area_base, std::vector(external_api_stub_area_size, 0xc3)); // c3 -> ret + + x86_emulator.hook_add( + [this, &x86_emulator, external_api_stub_area_base](uint32_t address, size_t size) { + auto iat_base = x86_emulator.context_get("iat_base"); + auto from_va = iat_base + (address - external_api_stub_area_base) * sizeof(IMAGE_THUNK_DATA); + auto from_rva = m_libcc_interpreter.convert_va_to_rva(from_va); + + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(from_rva); + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "malloc") == 0) { + m_va_iat_entry_malloc = from_va; + + uint32_t esp; + x86_emulator.reg_read(UC_X86_REG_ESP, &esp); + + uint32_t alloc_size; + x86_emulator.mem_read(esp + 4, &alloc_size, sizeof(alloc_size)); + + auto& heap_records = x86_emulator.context_get&>("heap_records"); + + auto predecessor_chunk = + std::adjacent_find( + heap_records.begin(), + heap_records.end(), + [alloc_size](const auto& chunk0, const auto& chunk1) { return chunk1.first - (chunk0.first + chunk0.second) >= alloc_size; } + ); + + uint32_t alloc_p; + if (predecessor_chunk != heap_records.end()) { + alloc_p = predecessor_chunk->first + predecessor_chunk->second; + } else { + auto heap_base = x86_emulator.context_get("heap_base"); + auto heap_size = x86_emulator.context_get("heap_size"); + + auto free_space_base = heap_records.size() > 0 ? heap_records.rbegin()->first + heap_records.rbegin()->second : heap_base; + auto free_space_size = heap_base + heap_size - free_space_base; + + if (free_space_size < alloc_size) { + auto heap_expand_base = heap_base + heap_size; + auto heap_expand_size = (alloc_size - free_space_size + 0xfff) / 0x1000 * 0x1000; + x86_emulator.mem_map(heap_expand_base, heap_expand_size, UC_PROT_READ | UC_PROT_WRITE); + } + + alloc_p = free_space_base; + } + + heap_records[alloc_p] = alloc_size; + + x86_emulator.reg_write(UC_X86_REG_EAX, &alloc_p); + } else if (strcmp(import_by_name_entry->Name, "free") == 0) { + uint32_t esp; + x86_emulator.reg_read(UC_X86_REG_ESP, &esp); + + uint32_t alloc_p; + x86_emulator.mem_read(esp + 4, &alloc_p, sizeof(alloc_p)); + + auto& heap_records = x86_emulator.context_get&>("heap_records"); + + auto chunk = heap_records.find(alloc_p); + if (chunk != heap_records.end()) { + heap_records.erase(chunk); + } else { + x86_emulator.emu_stop(); + } + } else { + x86_emulator.emu_stop(); + } + } else { + x86_emulator.emu_stop(); + } + }, + external_api_stub_area_base, + external_api_stub_area_base + external_api_stub_area_size - 1 + ); + } + + // allocate and setup external api impl area + { + keystone_assembler x86_assembler{ KS_ARCH_X86, KS_MODE_32 }; + + std::map> machine_code_list = + { + std::make_pair( + "memcpy", + x86_assembler.assemble( + "push edi;" + "push esi;" + "mov eax, dword ptr [esp + 0x8 + 0x4];" + "mov edi, eax;" + "mov esi, dword ptr [esp + 0x8 + 0x8];" + "mov ecx, dword ptr [esp + 0x8 + 0xc];" + "rep movs byte ptr [edi], byte ptr [esi];" + "pop esi;" + "pop edi;" + "ret;" + ) + ) + }; + + auto& external_api_impl = x86_emulator.context_get&>("external_api_impl"); + auto& external_api_impl_area_base = x86_emulator.context_get("external_api_impl_area_base"); + auto& external_api_impl_area_size = x86_emulator.context_get("external_api_impl_area_size"); + + auto p = external_api_impl_area_base; + for (const auto& name_code_pair : machine_code_list) { + external_api_impl[name_code_pair.first] = p; + p = (p + name_code_pair.second.size() + 0xf) / 0x10 * 0x10; + } + + external_api_impl_area_size = (p + 0xfff) / 0x1000 * 0x1000 - external_api_impl_area_base; + + x86_emulator.mem_map(external_api_impl_area_base, external_api_impl_area_size, UC_PROT_READ | UC_PROT_EXEC); + for (const auto& name_code_pair : machine_code_list) { + x86_emulator.mem_write(external_api_impl[name_code_pair.first], name_code_pair.second); + } + } + + // allocate and setup GDT, segment registers + { + auto gdt_base = x86_emulator.context_get("gdt_base"); + auto gdt_size = x86_emulator.context_get("gdt_size"); + x86_emulator.mem_map(gdt_base, gdt_size, UC_PROT_READ | UC_PROT_WRITE); + + x86_emulator.create_gdt_entry(gdt_base, 0, 0, 0, 0); // null segment descriptor + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (0 << 5) -> DPL is set to 0 + // 0x10 -> code/data segment + // 0x08 -> executable segment + // !(0x4) -> not conforming code segment + // 0x02 -> code segment is readable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 1 * 0x8, 0x00000000, 0xfffff, 0x80 | (0 << 5) | 0x10 | 0x08 | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // kernel code segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (0 << 5) -> DPL is set to 0 + // 0x10 -> code/data segment + // !(0x08) -> data segment + // !(0x4) -> segment grows up + // 0x02 -> data segment is writable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 2 * 0x8, 0x00000000, 0xfffff, 0x80 | (0 << 5) | 0x10 | !(0x08) | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // kernel data segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (3 << 5) -> DPL is set to 3 + // 0x10 -> code/data segment + // 0x08 -> executable segment + // !(0x4) -> not conforming code segment + // 0x02 -> code segment is readable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 3 * 0x8, 0x00000000, 0xfffff, 0x80 | (3 << 5) | 0x10 | 0x08 | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // user code segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (3 << 5) -> DPL is set to 3 + // 0x10 -> code/data segment + // !(0x08) -> data segment + // !(0x4) -> segment grows up + // 0x02 -> data segment is writable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 4 * 0x8, 0x00000000, 0xfffff, 0x80 | (3 << 5) | 0x10 | !(0x08) | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // user data segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (3 << 5) -> DPL is set to 3 + // 0x10 -> code/data segment + // !(0x08) -> data segment + // !(0x4) -> segment grows up + // 0x02 -> data segment is writable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // !(0x08) -> 1-byte granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + auto fs_base = x86_emulator.context_get("fs_base"); + auto fs_size = x86_emulator.context_get("fs_size"); + x86_emulator.create_gdt_entry(gdt_base + 7 * 0x8, fs_base, fs_size - 1, 0x80 | (3 << 5) | 0x10 | !(0x08) | !(0x04) | 0x02 | !(0x01), !(0x08) | 0x04 | !(0x01)); // user fs segment + + uc_x86_mmr gdtr = {}; + gdtr.base = gdt_base; + gdtr.limit = gdt_base + gdt_size - 1; + x86_emulator.reg_write(UC_X86_REG_GDTR, &gdtr); + + uint16_t cs, ds, es, fs, gs, ss; + cs = (1 << 3) | (0 << 2) | (0); // use kernel code segmet + ss = (2 << 3) | (0 << 2) | (0); // use kernel data segmet + ds = es = (4 << 3) | (0 << 2) | (3); // use user data segment + fs = (7 << 3) | (0 << 2) | (3); // use user fs segment + gs = 0; // not used + + uint32_t eflags; + x86_emulator.reg_read(UC_X86_REG_EFLAGS, &eflags); + x86_emulator.reg_write(UC_X86_REG_CS, &cs); + x86_emulator.reg_write(UC_X86_REG_SS, &ss); + x86_emulator.reg_write(UC_X86_REG_DS, &ds); + x86_emulator.reg_write(UC_X86_REG_ES, &es); + x86_emulator.reg_write(UC_X86_REG_FS, &fs); + x86_emulator.reg_write(UC_X86_REG_GS, &gs); + + } + + // allocate and hook access to fs area + { + auto fs_base = x86_emulator.context_get("fs_base"); + auto fs_size = x86_emulator.context_get("fs_size"); + x86_emulator.mem_map(fs_base, fs_size, UC_PROT_READ | UC_PROT_WRITE); + + x86_emulator.hook_add( + [this, &x86_emulator, fs_base](uc_mem_type access, uint32_t address, size_t size, int64_t value) { + switch (address - fs_base) { + case 0: + if (size == 4) { + // Current Structured Exception Handling (SEH) frame, leave it NULL + } else { + x86_emulator.emu_stop(); + } + break; + default: + x86_emulator.emu_stop(); + break; + } + }, + fs_base, + fs_base + fs_size - 1 + ); + } + + // x86_emulator.hook_add([](uint32_t address, uint32_t size) { wprintf_s(L"code_trace, address = 0x%08x\n", address); }); + + x86_emulator.hook_add( + [this, &x86_emulator](uc_mem_type access, uint32_t address, size_t size, int64_t value) -> bool { + try { + auto fault_section = m_libcc_interpreter.image_section_header_from_va(address); + + auto page_base = address / 0x1000 * 0x1000; + auto page_size = 0x1000; + uint32_t page_perms = UC_PROT_NONE; + + if (fault_section->Characteristics & IMAGE_SCN_MEM_READ) { + page_perms |= UC_PROT_READ; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_WRITE) { + page_perms |= UC_PROT_WRITE; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_EXECUTE) { + page_perms |= UC_PROT_EXEC; + } + + x86_emulator.mem_map(page_base, page_size, page_perms); + x86_emulator.mem_write(page_base, m_libcc_interpreter.convert_va_to_ptr(page_base), page_size); + + return true; + } catch (::nkg::exception&) { + return false; + } + } + ); + + // set ebp, esp + uint32_t init_ebp = x86_emulator.context_get("stack_base") - x86_emulator.context_get("stack_size") / 4; + uint32_t init_esp = x86_emulator.context_get("stack_base") - x86_emulator.context_get("stack_size") / 2; + + x86_emulator.reg_write(UC_X86_REG_EBP, &init_ebp); + x86_emulator.reg_write(UC_X86_REG_ESP, &init_esp); + + // setup iretd context + uint32_t ring3_eip = x86_emulator.context_get("start_address"); + uint32_t ring3_cs = (3 << 3) | (0 << 2) | (3); // use user code segment + uint32_t ring3_eflags; x86_emulator.reg_read(UC_X86_REG_EFLAGS, &ring3_eflags); + uint32_t ring3_esp = init_esp + 5 * 4; + uint32_t ring3_ss = (4 << 3) | (0 << 2) | (3); // use user data segment + x86_emulator.mem_write(init_esp, &ring3_eip, sizeof(ring3_eip)); + x86_emulator.mem_write(init_esp + 0x4, &ring3_cs, sizeof(ring3_cs)); + x86_emulator.mem_write(init_esp + 0x8, &ring3_eflags, sizeof(ring3_eflags)); + x86_emulator.mem_write(init_esp + 0xc, &ring3_esp, sizeof(ring3_esp)); + x86_emulator.mem_write(init_esp + 0x10, &ring3_ss, sizeof(ring3_ss)); + + // set ring3 retaddr + uint32_t ring3_retaddr = x86_emulator.context_get("dead_address"); + x86_emulator.mem_write(ring3_esp, &ring3_retaddr, sizeof(ring3_retaddr)); + + // set argument registers + uint32_t init_ecx = 0; // `this` pointer of CSRegistrationInfoFetcher_WIN, but we don't need it for now. + uint32_t retval_addr = ring3_esp + 0x40; // a pointer to stack memory which stores return value + x86_emulator.reg_write(UC_X86_REG_ECX, &init_ecx); + x86_emulator.mem_write(ring3_esp + 4, &retval_addr, sizeof(retval_addr)); // write to dword ptr [ring3_esp + 4] + + // + // start emulate + // + try { + x86_emulator.emu_start(x86_emulator.context_get("r0_to_r3_stub_area_base"), x86_emulator.context_get("dead_address")); + } catch (nkg::exception&) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Code emulation failed.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_iat_entry_malloc = 0x%08x\n", m_va_iat_entry_malloc); + + // + // get result + // + // on I386 platform, `std::string` has follow memory layout: + // ------------------------------ + // | offset | size | + // ------------------------------ + // | +0 | 0x10 | `char[16]: a small string buffer` OR `char*: a large string buffer pointer` + // ------------------------------ + // | +0x10 | 0x4 | size_t: string length + // ------------------------------ + // | +0x14 | 0x4 | size_t: capacity + // ------------------------------ + // + uint32_t encoded_key_length; + x86_emulator.mem_read(retval_addr + 0x10, &encoded_key_length, sizeof(encoded_key_length)); + if (encoded_key_length != official_encoded_key.length()) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Unexpected encoded key length(%u).\n", encoded_key_length); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + uint32_t encoded_key_ptr; + x86_emulator.mem_read(retval_addr, &encoded_key_ptr, sizeof(encoded_key_ptr)); + + auto encoded_key = x86_emulator.mem_read(encoded_key_ptr, encoded_key_length); + if (memcmp(encoded_key.data(), official_encoded_key.data(), encoded_key.size()) == 0) { + wprintf_s(L"[+] patch_solution_since<16, 0, 7, 0>: Official encoded key is found.\n"); + return true; + } else { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Official encoded key is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + } + + bool patch_solution_since<16, 0, 7, 0>::check_rsa_privkey(const rsa_cipher& cipher) { + return true; // no requirements + } + + void patch_solution_since<16, 0, 7, 0>::make_patch(const rsa_cipher& cipher) { + auto encoded_key = _build_encoded_key(cipher); + + auto CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = + m_libcc_interpreter.convert_va_to_ptr(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + std::vector patch_code_chunks; + patch_code_chunks.emplace_back("push edi;"); + patch_code_chunks.emplace_back("push esi;"); + patch_code_chunks.emplace_back("push ebx;"); + patch_code_chunks.emplace_back("push ebp;"); + patch_code_chunks.emplace_back("mov ebp, esp;"); + patch_code_chunks.emplace_back("call label; label: pop ebx; sub ebx, label;"); // ebx <- relocation shift value + patch_code_chunks.emplace_back(fmt::format("mov eax, {:#08x};", m_va_iat_entry_malloc)); + patch_code_chunks.emplace_back("add eax, ebx;"); + patch_code_chunks.emplace_back("mov eax, dword ptr [eax];"); // eax <- address of `malloc` + patch_code_chunks.emplace_back(fmt::format("push {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("call eax;"); + patch_code_chunks.emplace_back("add esp, 0x4;"); + { + std::vector push_values((encoded_key.length() + 1 + 3) / 4, 0); + memcpy(push_values.data(), encoded_key.data(), encoded_key.length()); + std::for_each(push_values.crbegin(), push_values.crend(), [&patch_code_chunks](uint32_t x) { patch_code_chunks.emplace_back(fmt::format("push {:#08x};", x)); }); + } + patch_code_chunks.emplace_back("mov edi, eax;"); + patch_code_chunks.emplace_back("mov esi, esp;"); + patch_code_chunks.emplace_back(fmt::format("mov ecx, {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("rep movs byte ptr [edi], byte ptr [esi];"); + patch_code_chunks.emplace_back("mov edx, dword ptr [ebp + 0x14];"); + patch_code_chunks.emplace_back("mov dword ptr [edx], eax;"); + patch_code_chunks.emplace_back(fmt::format("mov dword ptr [edx + 0x10], {:#x};", encoded_key.length())); + patch_code_chunks.emplace_back(fmt::format("mov dword ptr [edx + 0x14], {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("mov eax, edx;"); + patch_code_chunks.emplace_back("leave;"); + patch_code_chunks.emplace_back("pop ebx;"); + patch_code_chunks.emplace_back("pop esi;"); + patch_code_chunks.emplace_back("pop edi;"); + patch_code_chunks.emplace_back("ret 4;"); + + std::vector assembled_patch_code; + { + keystone_assembler x86_assembler{ KS_ARCH_X86, KS_MODE_32 }; + + auto current_va = m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey; + auto next_reloc = m_libcc_interpreter.relocation_distribute().lower_bound(m_libcc_interpreter.convert_va_to_rva(current_va)); + for (const auto& patch_code_chunk : patch_code_chunks) { + auto assembled_patch_code_chunk = x86_assembler.assemble(patch_code_chunk, current_va); + + while (true) { + auto next_reloc_va = m_libcc_interpreter.convert_rva_to_va(next_reloc->first); + auto next_reloc_size = next_reloc->second; + + if (current_va + assembled_patch_code_chunk.size() + 2 <= next_reloc_va) { // 2 -> size of machine code "jmp rel8" + assembled_patch_code.insert(assembled_patch_code.end(), assembled_patch_code_chunk.begin(), assembled_patch_code_chunk.end()); + current_va += assembled_patch_code_chunk.size(); + break; + } else if (current_va + 2 <= next_reloc_va) { + auto next_va = next_reloc_va + next_reloc_size; + auto assembled_jmp = x86_assembler.assemble(fmt::format("jmp {:#08x};", next_va), current_va); + auto assembled_padding = std::vector(next_va - (current_va + assembled_jmp.size()), 0xcc); // 0xcc -> int3 + assembled_patch_code.insert(assembled_patch_code.end(), assembled_jmp.begin(), assembled_jmp.end()); + assembled_patch_code.insert(assembled_patch_code.end(), assembled_padding.begin(), assembled_padding.end()); + current_va = next_va; + ++next_reloc; + } else { + __assume(false); // impossible to reach here + } + } + } + } + + memcpy(CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey, assembled_patch_code.data(), assembled_patch_code.size()); + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: Patch has been done.\n"); + } + +} diff --git a/navicat-patcher/wmain.cpp b/navicat-patcher/wmain.cpp new file mode 100644 index 0000000..f4bb48f --- /dev/null +++ b/navicat-patcher/wmain.cpp @@ -0,0 +1,295 @@ +#include +#include +#include +#include +#include + +#include "cp_converter.hpp" + +#include "resource_wrapper.hpp" +#include "resource_traits/cxx_object_traits.hpp" +#include "resource_traits/win32/file_handle.hpp" +#include "resource_traits/win32/generic_handle.hpp" +#include "resource_traits/win32/map_view_ptr.hpp" + +#include "rsa_cipher.hpp" +#include "image_interpreter.hpp" +#include "patch_solution.hpp" +#include "patch_solution_since_16.0.7.0.hpp" + +#include "exception.hpp" +#include "exceptions/operation_canceled_exception.hpp" +#include "exceptions/win32_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\wmain.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +void welcome() { + _putws(L"***************************************************"); + _putws(L"* navicat-patcher by @DoubleLabyrinth *"); + _putws(L"* version: 16.0.7.0-1 *"); + _putws(L"***************************************************"); + _putws(L""); +} + + +void help() { + _putws(L"Usage:"); + _putws(L" navicat-patcher.exe [-dry-run] [RSA-2048 PEM File Path]"); + _putws(L""); + _putws(L" [-dry-run] Run patcher without applying any patches."); + _putws(L" This parameter is optional."); + _putws(L""); + _putws(L" Path to a directory where Navicat is installed."); + _putws(L" This parameter is mandatory."); + _putws(L""); + _putws(L" [RSA-2048 PEM File Path] Path to an RSA-2048 private key file."); + _putws(L" If not specified, an RSA-2048 private key file"); + _putws(L" named \"RegPrivateKey.pem\" will be generated."); + _putws(L" This parameter is optional."); + _putws(L""); + _putws(L"Example:"); + _putws(L" navicat-patcher.exe \"C:\\Program Files\\PremiumSoft\\Navicat Premium 12\""); + _putws(L""); +} + +bool parse_cmdline(int argc, wchar_t* argv[], bool& dry_run, std::filesystem::path& navicat_install_path, std::filesystem::path& rsa_privkey_filepath) { + if (argc == 2) { + dry_run = false; + navicat_install_path = argv[1]; + rsa_privkey_filepath.clear(); + return true; + } else if (argc == 3) { + if (_wcsicmp(argv[1], L"-dry-run") == 0) { + dry_run = true; + navicat_install_path = argv[2]; + rsa_privkey_filepath.clear(); + return true; + } else { + dry_run = false; + navicat_install_path = argv[1]; + rsa_privkey_filepath = argv[2]; + return true; + } + } else if (argc == 4) { + if (_wcsicmp(argv[1], L"-dry-run") == 0) { + dry_run = true; + navicat_install_path = argv[2]; + rsa_privkey_filepath = argv[3]; + return true; + } else { + return false; + } + } else { + return false; + } +} + +void select_patch_solutions + (nkg::resource_wrapper>& solution0) +{ + return; +} + +void load_rsa_privkey(nkg::rsa_cipher& cipher, std::filesystem::path& rsa_privkey_filepath, nkg::patch_solution* solution0) { + if (!rsa_privkey_filepath.empty()) { + wprintf_s(L"[*] Import RSA-2048 private key from\n"); + wprintf_s(L" %s\n", rsa_privkey_filepath.native().c_str()); + + cipher.import_private_key_file(rsa_privkey_filepath); + + if (solution0 && !solution0->check_rsa_privkey(cipher)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"The RSA private key you provide cannot be used."); + } + } else { + wprintf_s(L"[*] Generating new RSA private key, it may take a long time...\n"); + + do { + cipher.generate_key(2048); + } while (solution0 && !solution0->check_rsa_privkey(cipher)); // re-generate RSA key if one of `check_rsa_privkey` returns false + } + + wprintf_s(L"[*] Your RSA private key:\n%s\n", nkg::cp_converter::convert(cipher.export_private_key_string()).c_str()); +} + +template +bool all_patch_solutions_are_suppressed(args_t&&... args) { + return (!args.is_valid() && ...); +} + +void detect_backup(const std::filesystem::path& file_path) { + std::filesystem::path backup_path = file_path.native() + L".bak"; + if (std::filesystem::is_regular_file(backup_path)) { + while (true) { + wprintf_s(L"[*] Previous backup %s is detected. Delete? (y/n)", backup_path.native().c_str()); + + auto select = getwchar(); + while (select != L'\n' && getwchar() != L'\n') {} + + if (select == L'Y' || select == L'y') { + std::filesystem::remove(backup_path); + break; + } else if (select == TEXT('N') || select == TEXT('n')) { + throw nkg::exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Backup file still exists. Patch abort!"); + } else { + continue; + } + } + } +} + +void make_backup(const std::filesystem::path& file_path) { + std::filesystem::path backup_path = file_path.native() + L".bak"; + if (std::filesystem::exists(backup_path)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Previous backup is detected.") + .push_hint(fmt::format(u8"Please delete {} and try again.", nkg::cp_converter<-1, CP_UTF8>::convert(backup_path.native()))); + } else { + std::filesystem::copy_file(file_path, backup_path); + } +} + +int wmain(int argc, wchar_t* argv[]) { + welcome(); + + bool dry_run = false; + std::filesystem::path navicat_install_path; + std::filesystem::path rsa_privkey_filepath; + + if (parse_cmdline(argc, argv, dry_run, navicat_install_path, rsa_privkey_filepath)) { + try { + if (!std::filesystem::is_directory(navicat_install_path)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Navicat install path doesn't point to a directory.") + .push_hint(u8"Are you sure the path you specified is correct?") + .push_hint(fmt::format(u8"The path you specified: {}", nkg::cp_converter<-1, CP_UTF8>::convert(navicat_install_path.native()))); + } + + if (!rsa_privkey_filepath.empty() && !std::filesystem::is_regular_file(rsa_privkey_filepath)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"RSA key file path doesn't point to a file.") + .push_hint(u8"Are you sure the path you specified is correct?") + .push_hint(fmt::format(u8"The path you specified: {}", nkg::cp_converter<-1, CP_UTF8>::convert(rsa_privkey_filepath.native()))); + } + + nkg::rsa_cipher cipher; + + std::filesystem::path libcc_filepath = navicat_install_path / "libcc.dll"; + nkg::resource_wrapper libcc_handle{ nkg::resource_traits::win32::file_handle{} }; + nkg::resource_wrapper libcc_map_handle{ nkg::resource_traits::win32::generic_handle{} }; + nkg::resource_wrapper libcc_map_view{ nkg::resource_traits::win32::map_view_ptr{} }; + std::optional libcc_interpreter; + + nkg::resource_wrapper solution0{ nkg::resource_traits::cxx_object_traits{} }; + + // open libcc.dll + libcc_handle.set(CreateFileW(libcc_filepath.native().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)); + if (libcc_handle.is_valid()) { + wprintf_s(L"[+] Try to open libcc.dll ... OK!\n"); + } else { + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + wprintf_s(L"[-] Try to open libcc.dll ... NOT FOUND!\n"); + } else { + throw nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"Failed to open libcc.dll"); + } + } + + if (libcc_handle.is_valid()) { + libcc_map_handle.set(CreateFileMapping(libcc_handle.get(), NULL, PAGE_READWRITE, 0, 0, NULL)); + if (!libcc_map_handle.is_valid()) { + throw nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"CreateFileMapping failed."); + } + + libcc_map_view.set(MapViewOfFile(libcc_map_handle.get(), FILE_MAP_ALL_ACCESS, 0, 0, 0)); + if (!libcc_map_view.is_valid()) { + throw nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"MapViewOfFile failed."); + } + + libcc_interpreter = nkg::image_interpreter::parse(libcc_map_view.get(), true); + + solution0.set(new nkg::patch_solution_since<16, 0, 7, 0>(libcc_interpreter.value())); + } + + _putws(L""); + + // find patch and decide which solution will be applied + if (solution0.is_valid()) { + auto patch_found = solution0->find_patch(); + _putws(L""); + + if (!patch_found) { + solution0.release(); + } + } + + select_patch_solutions(solution0); + + if (all_patch_solutions_are_suppressed(solution0)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"All patch solutions are suppressed. Patch abort!") + .push_hint(u8"Are you sure your navicat has not been patched/modified before?"); + } + + // load key + load_rsa_privkey(cipher, rsa_privkey_filepath, solution0.get()); + + // apply patch solutions + if (dry_run) { + _putws(L"*******************************************************"); + _putws(L"* DRY-RUN MODE ENABLE! *"); + _putws(L"* NO PATCH WILL BE APPLIED! *"); + _putws(L"*******************************************************"); + } else { + // save private key if not given + if (rsa_privkey_filepath.empty()) { + cipher.export_private_key_file(u8"RegPrivateKey.pem"); + } + + // detecting backups + if (solution0.is_valid()) { + detect_backup(libcc_filepath); + } + + // make backup + if (solution0.is_valid()) { + make_backup(libcc_filepath); + } + + // make patch + // no way to go back from here :-) + if (solution0.is_valid()) { + solution0->make_patch(cipher); + } + + // print new key file path + if (rsa_privkey_filepath.empty()) { + wprintf_s(L"[*] New RSA-2048 private key has been saved to\n"); + wprintf_s(L" %s\n", (std::filesystem::current_path() / L"RegPrivateKey.pem").c_str()); + wprintf_s(L"\n"); + } + + _putws(L""); + _putws(L"*******************************************************"); + _putws(L"* PATCH HAS BEEN DONE SUCCESSFULLY! *"); + _putws(L"* HAVE FUN AND ENJOY~ *"); + _putws(L"*******************************************************"); + } + + return 0; + } catch (nkg::exception& e) { + wprintf_s(L"[-] %s:%d ->\n", nkg::cp_converter::convert(e.source_file()).c_str(), e.source_line()); + wprintf_s(L" %s\n", nkg::cp_converter::convert(e.custom_message()).c_str()); + if (e.error_code_exists()) { + wprintf_s(L" %s (0x%zx)\n", nkg::cp_converter::convert(e.error_string()).c_str(), e.error_code()); + } + + for (auto& hint : e.hints()) { + wprintf_s(L" HINT: %s\n", nkg::cp_converter::convert(hint).c_str()); + } + + return -1; + } + } else { + help(); + return -1; + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE

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 P{DtBLqJ}2x@wD_`uUevg literal 0 HcmV?d00001 diff --git a/Navicat-Cracker/NavicatCracker.vcxproj b/Navicat-Cracker/NavicatCracker.vcxproj new file mode 100644 index 0000000..2ce45bb --- /dev/null +++ b/Navicat-Cracker/NavicatCracker.vcxproj @@ -0,0 +1,415 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {759AFCD1-1227-4070-B12E-4658EC908FE3} + MFCProj + NavicatCracker + 10.0 + + + + Application + true + v143 + Unicode + Static + + + Application + false + v143 + true + Unicode + Static + + + Application + true + v143 + Unicode + Static + + + Application + false + v143 + true + Unicode + Static + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\ + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\bin\$(PlatformTarget)-$(Configuration)\New + $(SolutionDir)\obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ + + + true + + + true + + + true + + + true + + + + Use + Level3 + true + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + pch.h + stdcpp17 + MultiThreaded + + + Windows + true + uafxcw.lib;LIBCMT.lib + + + uafxcw.lib;LIBCMT.lib + + + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0804 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + true + true + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + pch.h + stdcpp17 + MultiThreaded + + + Windows + true + true + true + uafxcw.lib;LIBCMT.lib + + + uafxcw.lib;LIBCMT.lib + + + RequireAdministrator + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0804 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + _WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + pch.h + stdcpp17 + MultiThreaded + + + Windows + true + uafxcw.lib;LIBCMT.lib + + + uafxcw.lib;LIBCMT.lib + + + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0804 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + pch.h + stdcpp17 + MultiThreaded + $(MSBuildThisFileDirectory);%(AdditionalIncludeDirectories) + MaxSpeed + + + Windows + true + true + false + uafxcw.lib;LIBCMT.lib + + + uafxcw.lib;LIBCMT.lib + + + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0804 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + + + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + + + Create + Create + Create + Create + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + + + true + true + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + true + true + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + + + true + true + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + true + true + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + NotUsing + MultiThreaded + MultiThreaded + MultiThreaded + MultiThreaded + NotUsing + + + + + + + + + + + true + true + + + + + + + + true + true + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Navicat-Cracker/NavicatCracker.vcxproj.filters b/Navicat-Cracker/NavicatCracker.vcxproj.filters new file mode 100644 index 0000000..ac729b6 --- /dev/null +++ b/Navicat-Cracker/NavicatCracker.vcxproj.filters @@ -0,0 +1,141 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + + + 资源文件 + + + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/Navicat-Cracker/NavicatCracker.vcxproj.user b/Navicat-Cracker/NavicatCracker.vcxproj.user new file mode 100644 index 0000000..b167062 --- /dev/null +++ b/Navicat-Cracker/NavicatCracker.vcxproj.user @@ -0,0 +1,7 @@ + + + + NavicatCracker.rc + true + + \ No newline at end of file diff --git a/Navicat-Cracker/NavicatCrackerDlg.cpp b/Navicat-Cracker/NavicatCrackerDlg.cpp new file mode 100644 index 0000000..2fb9235 --- /dev/null +++ b/Navicat-Cracker/NavicatCrackerDlg.cpp @@ -0,0 +1,563 @@ + +// NavicatCrackerDlg.cpp: 实现文件 +// + +#include "pch.h" +#include "framework.h" +#include "NavicatCracker.h" +#include "NavicatCrackerDlg.h" +#include "afxdialogex.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +#define NKG_CURRENT_SOURCE_FILE() u8".\\Navicat-Cracker\\NavicatCrackerDlg.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + + +void select_patch_solutions +(nkg::resource_wrapper>& solution0) +{ + return; +} + +void load_rsa_privkey(nkg::rsa_cipher& cipher, std::filesystem::path& rsa_privkey_filepath, nkg::patch_solution* solution0) { + if (!rsa_privkey_filepath.empty()) { + cipher.import_private_key_file(rsa_privkey_filepath); + + if (solution0 && !solution0->check_rsa_privkey(cipher)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"The RSA private key you provide cannot be used."); + } + } + else { + do { + cipher.generate_key(2048); + } while (solution0 && !solution0->check_rsa_privkey(cipher)); // re-generate RSA key if one of `check_rsa_privkey` returns false + } +} + +template +bool all_patch_solutions_are_suppressed(args_t&&... args) { + return (!args.is_valid() && ...); +} + +void detect_backup(const std::filesystem::path& file_path) { + std::filesystem::path backup_path = file_path.native() + L".bak"; + if (std::filesystem::is_regular_file(backup_path)) { + while (true) { + wprintf_s(L"[*] Previous backup %s is detected. Delete? (y/n)", backup_path.native().c_str()); + + auto select = getwchar(); + while (select != L'\n' && getwchar() != L'\n') {} + + if (select == L'Y' || select == L'y') { + std::filesystem::remove(backup_path); + break; + } + else if (select == TEXT('N') || select == TEXT('n')) { + throw nkg::exceptions::operation_canceled_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Backup file still exists. Patch abort!"); + } + else { + continue; + } + } + } +} + +void make_backup(const std::filesystem::path& file_path) { + std::filesystem::path backup_path = file_path.native() + L".bak"; + if (std::filesystem::exists(backup_path)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Previous backup is detected.") + .push_hint(fmt::format(u8"Please delete {} and try again.", nkg::cp_converter<-1, CP_UTF8>::convert(backup_path.native()))); + } + else { + std::filesystem::copy_file(file_path, backup_path); + } +} + + +CNavicatCrackerDlg::CNavicatCrackerDlg(CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_NavicatCracker_DIALOG, pParent) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CNavicatCrackerDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_ActivationCode, m_actcode); + DDX_Control(pDX, IDC_CopyBTN, m_copy); + DDX_Control(pDX, IDC_GenActBTN, m_genact); + DDX_Control(pDX, IDC_GenerateBTN, m_genkey); + DDX_Control(pDX, IDC_InstallPath, m_path); + DDX_Control(pDX, IDC_Key, m_key); + DDX_Control(pDX, IDC_LanguageBox, m_lang); + DDX_Control(pDX, IDC_Organ, m_org); + DDX_Control(pDX, IDC_PatchBTN, m_patch); + DDX_Control(pDX, IDC_InstallPath, m_path); + DDX_Control(pDX, IDC_ProductionBox, m_product); + DDX_Control(pDX, IDC_RequestCode, m_reqcode); + DDX_Control(pDX, IDC_UserName, m_name); + DDX_Control(pDX, IDC_VersionBox, m_ver); + DDX_Control(pDX, IDC_KeyFile, m_keyfile); + DDX_Control(pDX, IDC_OpenKeyBTN, m_open); + DDX_Control(pDX, IDC_CheckKey, m_checkkey); + DDX_Control(pDX, IDC_ADVANCE, m_checkadv); + DDX_Control(pDX, IDC_LangHex1, m_langhex1); + DDX_Control(pDX, IDC_LangHex2, m_langhex2); + DDX_Control(pDX, IDC_ProdHex, m_prodhex); + DDX_Control(pDX, IDC_hosts, m_hosts); + DDX_Control(pDX, IDC_Logo, m_logo); +} + +BEGIN_MESSAGE_MAP(CNavicatCrackerDlg, CDialogEx) + + ON_BN_CLICKED(IDC_PatchBTN, &CNavicatCrackerDlg::OnClickedPatchbtn) + ON_BN_CLICKED(IDC_GenerateBTN, &CNavicatCrackerDlg::OnClickedGeneratebtn) + ON_BN_CLICKED(IDC_GenActBTN, &CNavicatCrackerDlg::OnClickedGenActbtn) + ON_BN_CLICKED(IDC_CopyBTN, &CNavicatCrackerDlg::OnClickedCopybtn) + ON_BN_CLICKED(IDC_CheckKey, &CNavicatCrackerDlg::OnClickedCheckKey) + ON_BN_CLICKED(IDC_OpenKeyBTN, &CNavicatCrackerDlg::OnClickedOpenKeybtn) + ON_BN_CLICKED(IDC_OpenPath, &CNavicatCrackerDlg::OnBnClickedOpenpath) + ON_BN_CLICKED(IDC_ADVANCE, &CNavicatCrackerDlg::OnBnClickedAdvance) + ON_BN_CLICKED(IDC_About, &CNavicatCrackerDlg::OnBnClickedAbout) + ON_BN_CLICKED(IDC_hosts, &CNavicatCrackerDlg::OnBnClickedhosts) +END_MESSAGE_MAP() + + +// CNavicatCrackerDlg 消息处理程序 + +BOOL CNavicatCrackerDlg::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // 将“关于...”菜单项添加到系统菜单中。 + + // IDM_ABOUTBOX 必须在系统命令范围内。 + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != nullptr) + { + BOOL bNameValid; + CString strAboutMenu; + bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); + ASSERT(bNameValid); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 + // 执行此操作 + SetIcon(m_hIcon, TRUE); // 设置大图标 + SetIcon(m_hIcon, FALSE); // 设置小图标 + + ShowWindow(SW_NORMAL); + + // 初始化代码 + m_ver.SetCurSel(0); + m_product.SetCurSel(1); + m_lang.SetCurSel(1); + + m_path.SetWindowTextW(defaultpath); + m_name.SetWindowTextW(username); + m_org.SetWindowTextW(organization); + + m_keyfile.SetWindowTextW(keyfile); + + // setup logo png + CBitmap bitmap_logo; + CPngImage png_image; + png_image.Load(IDB_PNG1, nullptr); + bitmap_logo.Attach(png_image.Detach()); + m_logo.SetBitmap(bitmap_logo); + + m_hosts.SetCheck(TRUE); + + return TRUE; // 除非将焦点设置到控件,否则返回 TRUE +} + + +void CNavicatCrackerDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // 用于绘制的设备上下文 + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // 使图标在工作区矩形中居中 + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // 绘制图标 + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialogEx::OnPaint(); + } +} + +//当用户拖动最小化窗口时系统调用此函数取得光标 +//显示。 +HCURSOR CNavicatCrackerDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} + + + +void CNavicatCrackerDlg::OnClickedPatchbtn() +{ + CString pathData; + m_path.GetWindowTextW(pathData); + // patcher + navicat_install_path = pathData.GetString(); + try { + if (!std::filesystem::is_directory(navicat_install_path)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Navicat install path doesn't point to a directory.") + .push_hint(u8"Are you sure the path you specified is correct?") + .push_hint(fmt::format(u8"The path you specified: {}", nkg::cp_converter<-1, CP_UTF8>::convert(navicat_install_path.native()))); + } + + std::filesystem::path libcc_filepath = navicat_install_path / "libcc.dll"; + nkg::resource_wrapper libcc_handle{ nkg::resource_traits::win32::file_handle{} }; + nkg::resource_wrapper libcc_map_handle{ nkg::resource_traits::win32::generic_handle{} }; + nkg::resource_wrapper libcc_map_view{ nkg::resource_traits::win32::map_view_ptr{} }; + std::optional libcc_interpreter; + nkg::resource_wrapper solution0{ nkg::resource_traits::cxx_object_traits{} }; + + // open libcc.dll + libcc_handle.set(CreateFileW(libcc_filepath.native().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)); + if (!libcc_handle.is_valid()) { + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Try to open libcc.dll ... NOT FOUND!"); + } + else { + throw nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"Failed to open libcc.dll"); + } + } + + if (libcc_handle.is_valid()) { + libcc_map_handle.set(CreateFileMapping(libcc_handle.get(), NULL, PAGE_READWRITE, 0, 0, NULL)); + if (!libcc_map_handle.is_valid()) { + throw nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"CreateFileMapping failed."); + } + + libcc_map_view.set(MapViewOfFile(libcc_map_handle.get(), FILE_MAP_ALL_ACCESS, 0, 0, 0)); + if (!libcc_map_view.is_valid()) { + throw nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"MapViewOfFile failed."); + } + + libcc_interpreter = nkg::image_interpreter::parse(libcc_map_view.get(), true); + + solution0.set(new nkg::patch_solution_since<16, 0, 7, 0>(libcc_interpreter.value())); + } + + // find patch and decide which solution will be applied + if (solution0.is_valid()) { + auto patch_found = solution0->find_patch(); + + if (!patch_found) { + solution0.release(); + } + } + + select_patch_solutions(solution0); + + if (all_patch_solutions_are_suppressed(solution0)) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"All patch solutions are suppressed. Patch abort!") + .push_hint(u8"Are you sure your navicat has not been patched/modified before?"); + } + + // load key + if (m_checkkey.GetCheck()) { + CString cs_keypath{}; + m_keyfile.GetWindowTextW(cs_keypath); + rsa_privkey_filepath = cs_keypath.GetString(); + if (!PathFileExists(rsa_privkey_filepath.c_str())) { + m_checkkey.SetCheck(FALSE); + OnClickedCheckKey(); + rsa_privkey_filepath.clear(); + } + } + load_rsa_privkey(cipher, rsa_privkey_filepath, solution0.get()); + + // detecting backups + if (solution0.is_valid()) { + detect_backup(libcc_filepath); + } + + // make backup + if (solution0.is_valid()) { + make_backup(libcc_filepath); + } + + // make patch + // no way to go back from here :-) + if (solution0.is_valid()) { + solution0->make_patch(cipher); + } + + // patch hosts + if (m_hosts.GetCheck()) { + LPCWSTR lpshosts = _T("C:\\Windows\\System32\\drivers\\etc\\hosts"); + SetFileAttributesW(lpshosts, GetFileAttributes(lpshosts) & ~FILE_ATTRIBUTE_READONLY); + CStdioFile hosts; + if (hosts.Open(lpshosts, CFile::modeWrite)) { + hosts.SeekToEnd(); + hosts.WriteString(_T("127.0.0.1\tactivate.navicat.com\n")); + } + else { + AfxMessageBox(L"Can't modify HOSTS file!\nPlease check your permission!", MB_ICONSTOP); + } + hosts.Close(); + } + + // private key export + if (!m_checkkey.GetCheck()) { + if(AfxMessageBox(L"Patch Success Applied to libcc.dll!\nDO You Want to Export Private Key?", MB_ICONINFORMATION | MB_YESNOCANCEL) == IDYES){ + cipher.export_private_key_file(u8"Navicat_2048bit_rsa_private_key.pem"); + } + } + else { + AfxMessageBox(L"Patch Success Applied to libcc.dll!\n", MB_ICONINFORMATION | MB_OK); + } + PATCH = TRUE; + } + catch (nkg::exception& e) { + catched_message.Format(L"[-] %s:%d ->\n", nkg::cp_converter::convert(e.source_file()).c_str(), e.source_line()); + catched_message.AppendFormat(L" %s\n", nkg::cp_converter::convert(e.custom_message()).c_str()); + if (e.error_code_exists()) { + catched_message.AppendFormat(L" %s (0x%zx)\n", nkg::cp_converter::convert(e.error_string()).c_str(), e.error_code()); + } + for (auto& hint : e.hints()) { + catched_message.AppendFormat(L" HINT: %s\n", nkg::cp_converter::convert(hint).c_str()); + } + + AfxMessageBox(catched_message, MB_ICONSTOP); + } + catch (std::exception& e) { + catched_message.Format(L"[-] %s\n", nkg::cp_converter::convert(e.what()).c_str()); + AfxMessageBox(catched_message, MB_ICONSTOP); + } +} + + +void CNavicatCrackerDlg::OnClickedGeneratebtn() +{ + int verData; + CString strData; + verData = 16 - m_ver.GetCurSel(); + try { + if (!m_checkadv.GetCheck()) { + int proData = m_product.GetCurSel(); + int langData = m_lang.GetCurSel(); + + lpfnCollectInformation = nkg::CollectInformationNormal; + sn_generator = lpfnCollectInformation(proData, langData, verData); + } + else { + CString temp; + std::uint8_t prod, lang1, lang2; + m_prodhex.GetWindowTextW(temp); + prod = static_cast(std::stoul(temp.GetString(), nullptr, 16)); + m_langhex1.GetWindowTextW(temp); + lang1 = static_cast(std::stoul(temp.GetString(), nullptr, 16)); + m_langhex2.GetWindowTextW(temp); + lang2 = static_cast(std::stoul(temp.GetString(), nullptr, 16)); + + sn_generator = nkg::CollectInformationAdvanced(prod, lang1, lang2, verData); + } + sn_generator.generate(); + m_key.SetWindowTextW(nkg::cp_converter::convert(sn_generator.serial_number_formatted()).c_str()); + KEYGEN = TRUE; + } + catch (nkg::exception& e) { + catched_message.Format(L"[-] %s:%d ->\n", nkg::cp_converter::convert(e.source_file()).c_str(), e.source_line()); + catched_message.AppendFormat(L" %s\n", nkg::cp_converter::convert(e.custom_message()).c_str()); + if (e.error_code_exists()) { + catched_message.AppendFormat(L" %s (0x%zx)\n", nkg::cp_converter::convert(e.error_string()).c_str(), e.error_code()); + } + for (auto& hint : e.hints()) { + catched_message.AppendFormat(L" HINT: %s\n", nkg::cp_converter::convert(hint).c_str()); + } + + AfxMessageBox(catched_message, MB_ICONSTOP); + } + catch (std::exception& e) { + catched_message.Format(L"[-] %s\n", nkg::cp_converter::convert(e.what()).c_str()); + if (m_checkadv.GetCheck()) { + catched_message.AppendFormat(L"In ADV mode Production should be 0x00~0xFF.\n"); + catched_message.AppendFormat(L"In ADV mode Language(each part) should be 0x00~0xFF."); + } + AfxMessageBox(catched_message, MB_ICONSTOP); + } + catched_message.Empty(); +} + + +void CNavicatCrackerDlg::OnClickedGenActbtn() +{ + try { + if (!PATCH) { + if (!m_checkkey.GetCheck()) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Can't Generate Activation Code.") + .push_hint(u8"Please Patch first Or Specified RSA private key."); + } + else { + CString private_path; + m_keyfile.GetWindowTextW(private_path); + cipher.import_private_key_file(nkg::cp_converter<-1, CP_UTF8>::convert(private_path.GetString())); + } + } + if (!KEYGEN) { + throw nkg::exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Can't Generate Activation Code.") + .push_hint(u8"Please Generate a key!"); + } + lpfnGenerateLicense = nkg::GenerateLicenseText; + m_name.GetWindowTextW(username); + m_org.GetWindowTextW(organization); + m_reqcode.GetWindowTextW(reqcode); + actcode = lpfnGenerateLicense(cipher, sn_generator, username.GetString(), organization.GetString(), reqcode.GetString()).c_str(); + m_actcode.SetWindowTextW(actcode); + } + catch (nkg::exception& e) { + catched_message.Format(L"[-] %s:%d ->\n", nkg::cp_converter::convert(e.source_file()).c_str(), e.source_line()); + catched_message.AppendFormat(L" %s\n", nkg::cp_converter::convert(e.custom_message()).c_str()); + if (e.error_code_exists()) { + catched_message.AppendFormat(L" %s (0x%zx)\n", nkg::cp_converter::convert(e.error_string()).c_str(), e.error_code()); + } + for (auto& hint : e.hints()) { + catched_message.AppendFormat(L" HINT: %s\n", nkg::cp_converter::convert(hint).c_str()); + } + + AfxMessageBox(catched_message, MB_ICONSTOP); + } + catch (std::exception& e) { + catched_message.Format(L"[-] %s\n", nkg::cp_converter::convert(e.what()).c_str()); + AfxMessageBox(catched_message, MB_ICONSTOP); + } + catched_message.Empty(); +} + + +void CNavicatCrackerDlg::OnClickedCopybtn() +{ + CString source; + m_key.GetWindowTextW(source); + if (OpenClipboard()) + { + //防止非ASCII语言复制到剪切板为乱码 + int buff_size = source.GetLength(); + CStringW strWide = CStringW(source); + int nLen = strWide.GetLength(); + HANDLE clipbuffer = ::GlobalAlloc(GMEM_MOVEABLE, (nLen + 1) * 2); + if (!clipbuffer) + { + ::CloseClipboard(); + return; + } + char* buffer = (char*)::GlobalLock(clipbuffer); + if (buffer != 0) { + memset(buffer, 0, (static_cast(nLen) + 1) * 2); + memcpy_s(buffer, nLen * 2, strWide.GetBuffer(0), nLen * 2); + strWide.ReleaseBuffer(); + ::GlobalUnlock(clipbuffer); + ::EmptyClipboard(); + ::SetClipboardData(CF_UNICODETEXT, clipbuffer); + ::CloseClipboard(); + } + else { + ::CloseClipboard(); + return; + } + } +} + + +void CNavicatCrackerDlg::OnClickedCheckKey() +{ + if (m_checkkey.GetCheck()) { + m_keyfile.EnableWindow(); + m_open.EnableWindow(); + } + else { + m_keyfile.EnableWindow(0); + m_open.EnableWindow(0); + } +} + + +void CNavicatCrackerDlg::OnClickedOpenKeybtn() +{ + CFileDialog openFileDlg(FALSE, L".", L"PrivateKey.pem", OFN_HIDEREADONLY | OFN_READONLY, L"Private Key (*.pem)|*.pem||", NULL); + INT_PTR result = openFileDlg.DoModal(); + if (result == IDOK) { + m_keyfile.SetWindowTextW(openFileDlg.GetPathName()); + } + // 失焦解决方法:"https://kira-96.github.io/" 一些基本没什么用的MFC技巧 + ::SetForegroundWindow(::GetDesktopWindow()); + this->SetForegroundWindow(); +} + + + +void CNavicatCrackerDlg::OnBnClickedOpenpath() +{ + CFolderPickerDialog openFolderDlg; + + openFolderDlg.m_ofn.lpstrTitle = L"Choose The Navicat Installation Path:"; + openFolderDlg.m_ofn.lpstrInitialDir = L"."; + + INT_PTR result = openFolderDlg.DoModal(); + if (result == IDOK) { + m_path.SetWindowTextW(openFolderDlg.GetPathName()); + } + ::SetForegroundWindow(::GetDesktopWindow()); + this->SetForegroundWindow(); +} + + +void CNavicatCrackerDlg::OnBnClickedAdvance() +{ + if (m_checkadv.GetCheck()) { + m_lang.ShowWindow(SW_HIDE); + m_product.ShowWindow(SW_HIDE); + m_prodhex.ShowWindow(SW_SHOW); + m_langhex1.ShowWindow(SW_SHOW); + m_langhex2.ShowWindow(SW_SHOW); + } + else { + m_lang.ShowWindow(SW_SHOW); + m_product.ShowWindow(SW_SHOW); + m_prodhex.ShowWindow(SW_HIDE); + m_langhex1.ShowWindow(SW_HIDE); + m_langhex2.ShowWindow(SW_HIDE); + } +} + + +void CNavicatCrackerDlg::OnBnClickedAbout() +{ + AfxMessageBox(L"Author : tgMrZ\nBased on DoubleSine's work\n\n\nDoubleSine yyds!!!", MB_OK | MB_ICONQUESTION); +} + + +void CNavicatCrackerDlg::OnBnClickedhosts() +{ + if (m_hosts.GetCheck()) { + AfxMessageBox(L"Please make sure you have permission to modify HOSTS file!"); + } +} diff --git a/Navicat-Cracker/NavicatCrackerDlg.h b/Navicat-Cracker/NavicatCrackerDlg.h new file mode 100644 index 0000000..6a3299f --- /dev/null +++ b/Navicat-Cracker/NavicatCrackerDlg.h @@ -0,0 +1,126 @@ + +// NavicatCrackerDlg.h: 头文件 +// + +#pragma once +#include + +#include +#include +#include +#include +#include + +#include "cp_converter.hpp" + +#include "resource_wrapper.hpp" +#include "resource_traits/cxx_object_traits.hpp" +#include "resource_traits/win32/file_handle.hpp" +#include "resource_traits/win32/generic_handle.hpp" +#include "resource_traits/win32/map_view_ptr.hpp" + +#include "rsa_cipher.hpp" +#include "image_interpreter.hpp" +#include "patch_solution.hpp" +#include "patch_solution_since_16.0.7.0.hpp" + +#include "exception.hpp" +#include "exceptions/operation_canceled_exception.hpp" +#include "exceptions/win32_exception.hpp" + +#include "base64_rfc4648.hpp" +#include "navicat_serial_generator.hpp" + + +namespace nkg { + using fnCollectInformation = std::function; + using fnGenerateLicense = std::function; + + navicat_serial_generator CollectInformationNormal(int procution_type, int language, int version); + navicat_serial_generator CollectInformationAdvanced(std::uint8_t procution_type, std::uint8_t lang1, std::uint8_t lang2, int version); + std::wstring GenerateLicenseText(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator, std::wstring _username, + std::wstring _organization, std::wstring _redcode); + //void GenerateLicenseBinary(const rsa_cipher& cipher, const navicat_serial_generator& sn_generator); +} + +// CNavicatCrackerDlg 对话框 +class CNavicatCrackerDlg : public CDialogEx +{ +// 构造 +public: + CNavicatCrackerDlg(CWnd* pParent = nullptr); // 标准构造函数 + +// 对话框数据 +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_NavicatCracker_DIALOG }; +#endif + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + +public: + std::filesystem::path navicat_install_path; + std::filesystem::path rsa_privkey_filepath; + + nkg::rsa_cipher cipher; + nkg::navicat_serial_generator sn_generator; + nkg::fnCollectInformation lpfnCollectInformation; + nkg::fnGenerateLicense lpfnGenerateLicense; + CString catched_message{ }; + + CString defaultpath{ "C:\\Program Files\\PremiumSoft\\Navicat Premium 16" }; + CString username{ "tgMrZ" }; + CString organization{ "DoubleSine" }; + CString reqcode; + CString actcode; + CString keyfile{ "Navicat_2048bit_rsa_private_key.pem" }; + BOOL PATCH{ FALSE }; // patched + BOOL KEYGEN{ FALSE }; // keygened + +// 实现 +protected: + HICON m_hIcon; + + // 生成的消息映射函数 + virtual BOOL OnInitDialog(); + //afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + DECLARE_MESSAGE_MAP() +public: + CEdit m_actcode; + CButton m_copy; + CButton m_genact; + CButton m_genkey; + CEdit m_key; + CComboBox m_lang; + CEdit m_org; + CButton m_patch; + CEdit m_path; + CComboBox m_product; + CEdit m_reqcode; + CEdit m_name; + CComboBox m_ver; + afx_msg void OnClickedPatchbtn(); + afx_msg void OnClickedGeneratebtn(); + afx_msg void OnClickedGenActbtn(); + afx_msg void OnClickedCopybtn(); + + CEdit m_keyfile; + CBitmapButton m_open; + CButton m_checkkey; + CButton m_checkadv; + CEdit m_langhex1; + CEdit m_langhex2; + CEdit m_prodhex; + CButton m_hosts; + + afx_msg void OnClickedCheckKey(); + afx_msg void OnClickedOpenKeybtn(); + afx_msg void OnBnClickedOpenpath(); + afx_msg void OnBnClickedAdvance(); + afx_msg void OnBnClickedAbout(); + afx_msg void OnBnClickedhosts(); + CStatic m_logo; +}; diff --git a/Navicat-Cracker/amd64_emulator.cpp b/Navicat-Cracker/amd64_emulator.cpp new file mode 100644 index 0000000..49fb0f0 --- /dev/null +++ b/Navicat-Cracker/amd64_emulator.cpp @@ -0,0 +1,200 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "amd64_emulator.hpp" +#include "exceptions/key_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\amd64_emulator.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + void amd64_emulator::_unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) { + auto hook_stub_ctx = reinterpret_cast(user_data); + hook_stub_ctx->self->m_unicorn_hook_cbs_hookcode[hook_stub_ctx->unicorn_hook_handle](address, size); + } + + void amd64_emulator::_unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = reinterpret_cast(user_data); + hook_stub_ctx->self->m_unicorn_hook_cbs_hookmem[hook_stub_ctx->unicorn_hook_handle](type, address, static_cast(size), value); + } + + bool amd64_emulator::_unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = reinterpret_cast(user_data); + return hook_stub_ctx->self->m_unicorn_hook_cbs_eventmem[hook_stub_ctx->unicorn_hook_handle](type, address, static_cast(size), value); + } + + amd64_emulator::amd64_emulator() { + auto err = uc_open(UC_ARCH_X86, UC_MODE_64, m_unicorn_engine.unsafe_addressof()); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_open failed."); + } + } + + void amd64_emulator::reg_read(int regid, void* value) { + auto err = uc_reg_read(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_read failed."); + } + } + + void amd64_emulator::reg_write(int regid, const void* value) { + auto err = uc_reg_write(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + } + + uint64_t amd64_emulator::msr_read(uint32_t rid) { + uc_x86_msr msr; + msr.rid = rid; + + auto err = uc_reg_read(m_unicorn_engine.get(), UC_X86_REG_MSR, &msr); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + + return msr.value; + } + + void amd64_emulator::msr_write(uint32_t rid, uint64_t value) { + uc_x86_msr msr; + msr.rid = rid; + msr.value = value; + + auto err = uc_reg_write(m_unicorn_engine.get(), UC_X86_REG_MSR, &msr); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + } + + void amd64_emulator::mem_map(uint64_t address, size_t size, uint32_t perms) { + auto err = uc_mem_map(m_unicorn_engine.get(), address, size, perms); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_map failed."); + } + } + + void amd64_emulator::mem_unmap(uint64_t address, size_t size) { + auto err = uc_mem_unmap(m_unicorn_engine.get(), address, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_unmap failed."); + } + } + + void amd64_emulator::mem_read(uint64_t address, void* buf, size_t size) { + auto err = uc_mem_read(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + } + + std::vector amd64_emulator::mem_read(uint64_t address, size_t size) { + std::vector ret_buf(size); + + auto err = uc_mem_read(m_unicorn_engine.get(), address, ret_buf.data(), ret_buf.size()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + + return ret_buf; + } + + void amd64_emulator::mem_write(uint64_t address, const void* buf, size_t size) { + auto err = uc_mem_write(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_write failed."); + } + } + + void amd64_emulator::mem_write(uint64_t address, const std::vector& buf) { + mem_write(address, buf.data(), buf.size()); + } + + void amd64_emulator::hook_del(uc_hook hook_handle) { + auto iter_of_hook_stub_ctxs = m_unicorn_hook_stub_ctxs.find(hook_handle); + if (iter_of_hook_stub_ctxs == m_unicorn_hook_stub_ctxs.end()) { + throw exceptions::key_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target hook is not found."); + } + + auto iter_of_hook_cbs_hookcode = m_unicorn_hook_cbs_hookcode.find(hook_handle); + if (iter_of_hook_cbs_hookcode != m_unicorn_hook_cbs_hookcode.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_cbs_hookcode.erase(iter_of_hook_cbs_hookcode); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + auto iter_of_hook_cbs_hookmem = m_unicorn_hook_cbs_hookmem.find(hook_handle); + if (iter_of_hook_cbs_hookmem != m_unicorn_hook_cbs_hookmem.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_cbs_hookmem.erase(iter_of_hook_cbs_hookmem); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + auto iter_of_hook_cbs_eventmem = m_unicorn_hook_cbs_eventmem.find(hook_handle); + if (iter_of_hook_cbs_eventmem != m_unicorn_hook_cbs_eventmem.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_cbs_eventmem.erase(iter_of_hook_cbs_eventmem); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + __assume(false); + } + + void amd64_emulator::emu_start(uint64_t begin_address, uint64_t end_address, uint64_t timeout, size_t count) { + auto err = uc_emu_start(m_unicorn_engine.get(), begin_address, end_address, timeout, count); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"emu_start failed."); + } + } + + void amd64_emulator::emu_stop() { + auto err = uc_emu_stop(m_unicorn_engine.get()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_emu_stop failed."); + } + } + + //void amd64_emulator::create_gdt_entry(uint64_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags) { + // struct { + // uint16_t limit0; + // uint16_t base0; + // uint8_t base1; + // uint8_t access_byte; + // uint8_t limit1 : 4; + // uint8_t flags : 4; + // uint8_t base2; + // } segment_descriptor; + + // static_assert(sizeof(segment_descriptor) == 8); + + // segment_descriptor.limit0 = limit & 0xffff; + // segment_descriptor.base0 = base & 0xffff; + // segment_descriptor.base1 = (base >> 16) & 0xff; + // segment_descriptor.access_byte = access_byte; + // segment_descriptor.limit1 = (limit >> 16) & 0xf; + // segment_descriptor.flags = flags & 0xf; + // segment_descriptor.base2 = (base >> 24) & 0xff; + + // auto err = uc_mem_write(m_unicorn_engine.get(), gdt_entry_address, &segment_descriptor, sizeof(segment_descriptor)); + // if (err != UC_ERR_OK) { + // throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_write failed."); + // } + //} +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/amd64_emulator.hpp b/Navicat-Cracker/amd64_emulator.hpp new file mode 100644 index 0000000..b4bfa82 --- /dev/null +++ b/Navicat-Cracker/amd64_emulator.hpp @@ -0,0 +1,159 @@ +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/unicorn/unicorn_handle.hpp" + +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\amd64_emulator.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + class amd64_emulator { + public: + class backend_error : public ::nkg::exception { + public: + using error_code_t = uc_err; + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, error_code_t unicorn_err, std::string_view message) noexcept : + ::nkg::exception(file, line, message), m_error_code(unicorn_err), m_error_string(uc_strerror(unicorn_err)) {} + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + + using hookcode_cb_t = void(uint64_t address, size_t size); + using hookmem_cb_t = void(uc_mem_type type, uint64_t address, size_t size, int64_t value); + using eventmem_cb_t = bool(uc_mem_type type, uint64_t address, size_t size, int64_t value); + + private: + struct hook_stub_context_t { + amd64_emulator* self; + uc_hook unicorn_hook_handle; + }; + + resource_wrapper m_unicorn_engine; + std::unordered_map m_unicorn_user_ctx; + + std::unordered_map> m_unicorn_hook_stub_ctxs; + + std::unordered_map> m_unicorn_hook_cbs_hookcode; + std::unordered_map> m_unicorn_hook_cbs_hookmem; + std::unordered_map> m_unicorn_hook_cbs_eventmem; + + static void _unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data); + static void _unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + static bool _unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + + public: + amd64_emulator(); + + void reg_read(int regid, void* buf); + + void reg_write(int regid, const void* buf); + + uint64_t msr_read(uint32_t rid); + + void msr_write(uint32_t rid, uint64_t value); + + void mem_map(uint64_t address, size_t size, uint32_t perms); + + void mem_unmap(uint64_t address, size_t size); + + void mem_read(uint64_t address, void* buf, size_t size); + + std::vector mem_read(uint64_t address, size_t size); + + void mem_write(uint64_t address, const void* buf, size_t size); + + void mem_write(uint64_t address, const std::vector& buf); + + template + uc_hook hook_add(callable_t&& hook_callback, uint64_t begin_address = 1, uint64_t end_address = 0) { + uc_err err; + + auto hook_stub_ctx = std::make_unique(); + hook_stub_ctx->self = this; + hook_stub_ctx->unicorn_hook_handle = 0; + + if constexpr (hook_type == UC_HOOK_CODE) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookcode_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_cbs_hookcode.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::forward(hook_callback))); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_VALID) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_cbs_hookmem.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::forward(hook_callback))); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_eventmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_cbs_eventmem.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::forward(hook_callback))); + } else { + static_assert( + hook_type == UC_HOOK_CODE || + (hook_type & ~UC_HOOK_MEM_VALID) == 0 || + (hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0, "Unsupported hook type."); + } + + return m_unicorn_hook_stub_ctxs.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::move(hook_stub_ctx))).first->first; + } + + void hook_del(uc_hook hook_handle); + + void emu_start(uint64_t begin_address, uint64_t end_address = 0, uint64_t timeout = 0, size_t count = 0); + + void emu_stop(); + + // void create_gdt_entry(uint64_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags); + + template + void context_set(const std::string& name, val_t&& value) { + m_unicorn_user_ctx[name] = std::forward(value); + } + + template + val_t context_get(const std::string& name) { + return std::any_cast(m_unicorn_user_ctx[name]); + } + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/base32_rfc4648.cpp b/Navicat-Cracker/base32_rfc4648.cpp new file mode 100644 index 0000000..97f7c35 --- /dev/null +++ b/Navicat-Cracker/base32_rfc4648.cpp @@ -0,0 +1,120 @@ +#include "base32_rfc4648.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\base32_rfc4648.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + char base32_rfc4648::symbol(alphabet_index_t idx) { + return alphabet[idx]; + } + + base32_rfc4648::alphabet_index_t base32_rfc4648::reverse_symbol(char c) { + if ('A' <= c && c <= 'Z') { + return c - 'A'; + } else if ('2' <= c && c <= '7') { + return c - '2' + 26; + } else { + throw decoding_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Non-base32 digit is found"); + } + } + + std::string base32_rfc4648::encode(const std::vector& data) { + return encode(data.data(), data.size()); + } + + std::string base32_rfc4648::encode(const void* data_ptr, size_t data_size) { + std::string retval; + + if (data_size) { + retval.reserve((data_size * 8 + 4) / 5); + + auto p = reinterpret_cast(data_ptr); + alphabet_index_t left_bits = 0; + alphabet_index_t bit_buffer = 0; + for (size_t i = 0; i < data_size; ++i) { + bit_buffer = (bit_buffer << 8) | p[i]; + left_bits += 8; + + while (left_bits >= 5) { + alphabet_index_t idx = (bit_buffer >> (left_bits - 5)) & 0x1f; + retval.push_back(symbol(idx)); + left_bits -= 5; + } + } + + if (left_bits > 0) { + alphabet_index_t idx = (bit_buffer << (5 - left_bits)) & 0x1f; + retval.push_back(symbol(idx)); + } + + switch (data_size % 5) { + case 0: + break; + case 1: + retval.append(6, padding_character); + break; + case 2: + retval.append(4, padding_character); + break; + case 3: + retval.append(3, padding_character); + break; + case 4: + retval.append(1, padding_character); + break; + default: + __assume(false); + } + } + + return retval; + } + + std::vector base32_rfc4648::decode(std::string_view b32_string) { + if (b32_string.length() % 8 == 0) { + std::vector retval; + + size_t count_of_padding = std::distance(b32_string.crbegin(), std::find_if_not(b32_string.crbegin(), b32_string.crend(), [](char c) -> bool { return c == padding_character; })); + switch (count_of_padding) { + case 1: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 4)); + break; + case 3: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 3)); + break; + case 4: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 2)); + break; + case 6: + retval.reserve(b32_string.length() / 8 * 5 - (5 - 1)); + break; + default: + throw decoding_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Incorrect padding"); + } + + size_t count_of_encoded = b32_string.length() - count_of_padding; + + alphabet_index_t left_bits = 0; + alphabet_index_t bit_buffer = 0; + for (size_t i = 0; i < count_of_encoded; ++i) { + bit_buffer = (bit_buffer << 5) | reverse_symbol(b32_string[i]); + left_bits += 5; + + while (left_bits >= 8) { + auto val = static_cast((bit_buffer >> (left_bits - 8)) & 0xff); + retval.push_back(val); + left_bits -= 8; + } + } + + return retval; + } else { + throw decoding_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Incorrect padding"); + } + } + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/base32_rfc4648.hpp b/Navicat-Cracker/base32_rfc4648.hpp new file mode 100644 index 0000000..1e36fee --- /dev/null +++ b/Navicat-Cracker/base32_rfc4648.hpp @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include +#include +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\base32_rfc4648.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + struct base32_rfc4648 { + using alphabet_index_t = size_t; + + static constexpr const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + static constexpr const char padding_character = '='; + + class decoding_error : public ::nkg::exception { + public: + decoding_error(std::string_view file, int line, std::string_view message) noexcept : + ::nkg::exception(file, line, message) {} + }; + + static char symbol(alphabet_index_t idx); + + static alphabet_index_t reverse_symbol(char c); + + static std::string encode(const std::vector& data); + + static std::string encode(const void* data_ptr, size_t data_size); + + static std::vector decode(std::string_view b32_string); + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/base64_rfc4648.cpp b/Navicat-Cracker/base64_rfc4648.cpp new file mode 100644 index 0000000..9884cf7 --- /dev/null +++ b/Navicat-Cracker/base64_rfc4648.cpp @@ -0,0 +1,103 @@ +#include "base64_rfc4648.hpp" + +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/openssl/bio.hpp" +#include "resource_traits/openssl/bio_chain.hpp" + +#pragma comment(lib, "libcrypto") +#pragma comment(lib, "crypt32") // required by libcrypto.lib +#pragma comment(lib, "ws2_32") // required by libcrypto.lib + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\base64_rfc4648.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + std::string base64_rfc4648::encode(const std::vector& data) { + resource_wrapper bio_b64{ resource_traits::openssl::bio_chain{}, BIO_new(BIO_f_base64()) }; + if (bio_b64.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_set_flags(bio_b64.get(), BIO_FLAGS_BASE64_NO_NL); + + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_push(bio_b64.get(), bio_memory.get()); + + for (size_t written_size = 0, left_size = data.size(); left_size != 0;) { + int size_to_write = static_cast(std::min(left_size, static_cast(INT_MAX))); + + int r = BIO_write(bio_b64.get(), data.data() + written_size, size_to_write); + if (r > 0) { + written_size += r; + left_size -= r; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_write failed."); + } + } + + BIO_flush(bio_b64.get()); + + const char* pch = nullptr; + long lch = BIO_get_mem_data(bio_memory.get(), &pch); + + bio_memory.discard(); // the bio_chain `bio_b64` will free it + + return std::string(pch, lch); + } + + std::vector base64_rfc4648::decode(std::string_view b64_string) { + resource_wrapper bio_b64{ resource_traits::openssl::bio_chain{}, BIO_new(BIO_f_base64()) }; + if (bio_b64.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_set_flags(bio_b64.get(), BIO_FLAGS_BASE64_NO_NL); + + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + BIO_push(bio_b64.get(), bio_memory.get()); + + for (size_t written_length = 0, left_length = b64_string.length(); left_length != 0;) { + int length_to_write = static_cast(std::min(left_length, static_cast(INT_MAX))); + + int r = BIO_write(bio_memory.get(), b64_string.data() + written_length, length_to_write); + if (r > 0) { + written_length += r; + left_length -= r; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_write failed."); + } + } + + std::vector retval; + retval.reserve(b64_string.length() * 3 / 4 + 1); + + for (uint8_t buf[256];;) { + auto len = BIO_read(bio_b64.get(), buf, sizeof(buf)); + if (len > 0) { + retval.insert(retval.end(), buf, buf + len); + } else { + break; + } + } + + bio_memory.discard(); // the bio_chain `bio_b64` will free it + + return retval; + } + +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/Navicat-Cracker/base64_rfc4648.hpp b/Navicat-Cracker/base64_rfc4648.hpp new file mode 100644 index 0000000..04c0aed --- /dev/null +++ b/Navicat-Cracker/base64_rfc4648.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include "exception.hpp" + +namespace nkg { + + struct base64_rfc4648 { + + class backend_error : public ::nkg::exception { + public: + backend_error(std::string_view file, int line, std::string_view message) noexcept : + ::nkg::exception(file, line, message) {} + }; + + static std::string encode(const std::vector& data); + static std::vector decode(std::string_view str_b64); + }; + +} diff --git a/Navicat-Cracker/framework.h b/Navicat-Cracker/framework.h new file mode 100644 index 0000000..5672fb5 --- /dev/null +++ b/Navicat-Cracker/framework.h @@ -0,0 +1,49 @@ +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的 + +// 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息 +#define _AFX_ALL_WARNINGS + +#include // MFC 核心组件和标准组件 +#include // MFC 扩展 + + +#include // MFC 自动化类 + + + +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC 对 Internet Explorer 4 公共控件的支持 +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC 对 Windows 公共控件的支持 +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC 支持功能区和控制条 + + + + + + + + + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif + + diff --git a/Navicat-Cracker/i386_emulator.cpp b/Navicat-Cracker/i386_emulator.cpp new file mode 100644 index 0000000..d1182f4 --- /dev/null +++ b/Navicat-Cracker/i386_emulator.cpp @@ -0,0 +1,160 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "i386_emulator.hpp" +#include "exceptions/key_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\i386_emulator.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + void i386_emulator::_unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) { + auto hook_stub_ctx = + reinterpret_cast(user_data); + + auto& hook_callback = + std::any_cast&>(hook_stub_ctx->self->m_unicorn_hook_callbacks[hook_stub_ctx->unicorn_hook_handle]); + + hook_callback(static_cast(address), size); + } + + void i386_emulator::_unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = + reinterpret_cast(user_data); + + auto& hook_callback = + std::any_cast&>(hook_stub_ctx->self->m_unicorn_hook_callbacks[hook_stub_ctx->unicorn_hook_handle]); + + hook_callback(type, static_cast(address), static_cast(size), static_cast(value)); + } + + bool i386_emulator::_unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data) { + auto hook_stub_ctx = + reinterpret_cast(user_data); + + auto& hook_callback = + std::any_cast&>(hook_stub_ctx->self->m_unicorn_hook_callbacks[hook_stub_ctx->unicorn_hook_handle]); + + return hook_callback(type, static_cast(address), static_cast(size), static_cast(value)); + } + + i386_emulator::i386_emulator() { + auto err = uc_open(UC_ARCH_X86, UC_MODE_32, m_unicorn_engine.unsafe_addressof()); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_open failed."); + } + } + + void i386_emulator::reg_read(int regid, void* value) { + auto err = uc_reg_read(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_read failed."); + } + } + + void i386_emulator::reg_write(int regid, const void* value) { + auto err = uc_reg_write(m_unicorn_engine.get(), regid, value); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_reg_write failed."); + } + } + + void i386_emulator::mem_map(uint32_t address, size_t size, uint32_t perms) { + auto err = uc_mem_map(m_unicorn_engine.get(), address, size, perms); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_map failed."); + } + } + + void i386_emulator::mem_unmap(uint32_t address, size_t size) { + auto err = uc_mem_unmap(m_unicorn_engine.get(), address, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_unmap failed."); + } + } + + void i386_emulator::mem_read(uint32_t address, void* buf, size_t size) { + auto err = uc_mem_read(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + } + + std::vector i386_emulator::mem_read(uint32_t address, size_t size) { + std::vector ret_buf(size); + + auto err = uc_mem_read(m_unicorn_engine.get(), address, ret_buf.data(), ret_buf.size()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_read failed."); + } + + return ret_buf; + } + + void i386_emulator::mem_write(uint32_t address, const void* buf, size_t size) { + auto err = uc_mem_write(m_unicorn_engine.get(), address, buf, size); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_mem_write failed."); + } + } + + void i386_emulator::mem_write(uint32_t address, const std::vector& buf) { + mem_write(address, buf.data(), buf.size()); + } + + void i386_emulator::hook_del(uc_hook hook_handle) { + auto iter_of_hook_stub_ctxs = m_unicorn_hook_stub_ctxs.find(hook_handle); + if (iter_of_hook_stub_ctxs == m_unicorn_hook_stub_ctxs.end()) { + throw exceptions::key_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target hook is not found."); + } + + auto iter_of_hook_callbacks = m_unicorn_hook_callbacks.find(hook_handle); + if (iter_of_hook_callbacks != m_unicorn_hook_callbacks.end()) { + auto err = uc_hook_del(m_unicorn_engine.get(), hook_handle); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"hook_del failed."); + } + + m_unicorn_hook_callbacks.erase(iter_of_hook_callbacks); + m_unicorn_hook_stub_ctxs.erase(iter_of_hook_stub_ctxs); + return; + } + + __assume(false); + } + + void i386_emulator::create_gdt_entry(uint32_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags) { + struct { + uint64_t limit0 : 16; + uint64_t base0 : 24; + uint64_t access_byte : 8; + uint64_t limit1 : 4; + uint64_t flags : 4; + uint64_t base1 : 8; + } gdt_entry; + + gdt_entry.limit0 = limit & 0xffff; + gdt_entry.base0 = base & 0xffffff; + gdt_entry.access_byte = access_byte; + gdt_entry.flags = flags & 0xf; + gdt_entry.base1 = (base & 0xff000000) >> 24; + + mem_write(gdt_entry_address, &gdt_entry, sizeof(gdt_entry)); + } + + void i386_emulator::emu_start(uint32_t begin_address, uint32_t end_address, uint64_t timeout, size_t count) { + auto err = uc_emu_start(m_unicorn_engine.get(), begin_address, end_address, timeout, count); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"emu_start failed."); + } + } + + void i386_emulator::emu_stop() { + auto err = uc_emu_stop(m_unicorn_engine.get()); + if (err) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_emu_stop failed."); + } + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/i386_emulator.hpp b/Navicat-Cracker/i386_emulator.hpp new file mode 100644 index 0000000..acfe2e3 --- /dev/null +++ b/Navicat-Cracker/i386_emulator.hpp @@ -0,0 +1,152 @@ +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/unicorn/unicorn_handle.hpp" + +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\i386_emulator.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + class i386_emulator { + public: + class backend_error : public ::nkg::exception { + public: + using error_code_t = uc_err; + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, error_code_t unicorn_err, std::string_view message) noexcept : + ::nkg::exception(file, line, message), m_error_code(unicorn_err), m_error_string(uc_strerror(unicorn_err)) {} + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + + using hookcode_cb_t = void(uint32_t address, size_t size); + using hookmem_cb_t = void(uc_mem_type type, uint32_t address, size_t size, int32_t value); + using eventmem_cb_t = bool(uc_mem_type type, uint32_t address, size_t size, int32_t value); + + private: + struct hook_stub_context_t { + i386_emulator* self; + uc_hook unicorn_hook_handle; + }; + + resource_wrapper m_unicorn_engine; + std::unordered_map m_unicorn_user_ctx; + + std::unordered_map> m_unicorn_hook_stub_ctxs; + std::unordered_map m_unicorn_hook_callbacks; + + static void _unicorn_hookcode_cb_stub(uc_engine* uc, uint64_t address, uint32_t size, void* user_data); + static void _unicorn_hookmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + static bool _unicorn_eventmem_cb_stub(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, void* user_data); + + public: + i386_emulator(); + + void reg_read(int regid, void* value); + + void reg_write(int regid, const void* value); + + void mem_map(uint32_t address, size_t size, uint32_t perms); + + void mem_unmap(uint32_t address, size_t size); + + void mem_read(uint32_t address, void* buf, size_t size); + + std::vector mem_read(uint32_t address, size_t size); + + void mem_write(uint32_t address, const void* buf, size_t size); + + void mem_write(uint32_t address, const std::vector& buf); + + template + uc_hook hook_add(callable_t&& hook_callback, uint32_t begin_address = 1, uint32_t end_address = 0) { + uc_err err; + + auto hook_stub_ctx = std::make_unique(); + hook_stub_ctx->self = this; + hook_stub_ctx->unicorn_hook_handle = 0; + + if constexpr (hook_type == UC_HOOK_CODE) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookcode_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_callbacks.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::function{ std::forward(hook_callback) })); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_VALID) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_hookmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_callbacks.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::function{ std::forward(hook_callback) })); + } else if constexpr ((hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0) { + err = uc_hook_add(m_unicorn_engine.get(), &hook_stub_ctx->unicorn_hook_handle, hook_type, _unicorn_eventmem_cb_stub, hook_stub_ctx.get(), begin_address, end_address); + if (err != UC_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"uc_hook_add failed."); + } + + m_unicorn_hook_callbacks.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::function{ std::forward(hook_callback) })); + } else { + static_assert( + hook_type == UC_HOOK_CODE || + (hook_type & ~UC_HOOK_MEM_VALID) == 0 || + (hook_type & ~UC_HOOK_MEM_UNMAPPED) == 0, "Unsupported hook type."); + } + + return m_unicorn_hook_stub_ctxs.emplace(std::make_pair(hook_stub_ctx->unicorn_hook_handle, std::move(hook_stub_ctx))).first->first; + } + + void hook_del(uc_hook hook_handle); + + void create_gdt_entry(uint32_t gdt_entry_address, uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flags); + + void emu_start(uint32_t begin_address, uint32_t end_address = 0, uint64_t timeout = 0, size_t count = 0); + + void emu_stop(); + + template + void context_set(const std::string& name, val_t&& value) { + m_unicorn_user_ctx[name] = std::forward(value); + } + + template + val_t context_get(const std::string& name) { + return std::any_cast(m_unicorn_user_ctx[name]); + } + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/image_interpreter.cpp b/Navicat-Cracker/image_interpreter.cpp new file mode 100644 index 0000000..576ccf9 --- /dev/null +++ b/Navicat-Cracker/image_interpreter.cpp @@ -0,0 +1,302 @@ +#include "image_interpreter.hpp" +#include +#include "exceptions/index_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\image_interpreter.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + image_interpreter::image_interpreter() : + m_dos_header(nullptr), + m_nt_headers(nullptr), + m_section_header_table(nullptr), + m_vs_fixed_file_info(nullptr) {} + + [[nodiscard]] + image_interpreter image_interpreter::parse(void* image_base, bool parse_relocation) { + image_interpreter new_image; + + new_image.m_dos_header = reinterpret_cast(image_base); + if (new_image.m_dos_header->e_magic != IMAGE_DOS_SIGNATURE) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: DOS signature check failure") + .push_hint(u8"Are you sure you DO provide a valid WinPE file?"); + } + + new_image.m_nt_headers = reinterpret_cast(reinterpret_cast(image_base) + new_image.m_dos_header->e_lfanew); + if (new_image.m_nt_headers->Signature != IMAGE_NT_SIGNATURE) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: NT signature check failure") + .push_hint(u8"Are you sure you DO provide a valid WinPE file?"); + } + +#if defined(_M_AMD64) + if (new_image.m_nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: optional header magic check failure") + .push_hint(u8"Are you sure you DO provide a valid 64-bits WinPE file?"); + } + if (new_image.m_nt_headers->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid image: machine check failure") + .push_hint(u8"Are you sure you DO provide a valid 64-bits WinPE file?"); + } +#elif defined(_M_IX86) + if (new_image.m_nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid Image. (Optional header magic check failure)") + .push_hint(u8"Are you sure you DO provide a valid 32-bits WinPE file?"); + } + if (new_image.m_nt_headers->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { + throw parse_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid Image. (Machine check failure)") + .push_hint(u8"Are you sure you DO provide a valid 32-bits WinPE file?"); + } +#else +#error "image_interpreter.cpp: unsupported architecture." +#endif + + new_image.m_section_header_table = + reinterpret_cast(reinterpret_cast(&new_image.m_nt_headers->OptionalHeader) + new_image.m_nt_headers->FileHeader.SizeOfOptionalHeader); + + for (WORD i = 0; i < new_image.m_nt_headers->FileHeader.NumberOfSections; ++i) { + auto section_name = make_section_name(new_image.m_section_header_table[i].Name); + + if (new_image.m_section_header_name_lookup_table.find(section_name) == new_image.m_section_header_name_lookup_table.end()) { + new_image.m_section_header_name_lookup_table[section_name] = &new_image.m_section_header_table[i]; + } + + new_image.m_section_header_rva_lookup_table[new_image.m_section_header_table[i].VirtualAddress] = &new_image.m_section_header_table[i]; + new_image.m_section_header_fo_lookup_table[new_image.m_section_header_table[i].PointerToRawData] = &new_image.m_section_header_table[i]; + } + + if (parse_relocation && new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) { + auto relocation_table = + new_image.convert_rva_to_ptr(new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); + + while (relocation_table->VirtualAddress != 0) { + rva_t rva = relocation_table->VirtualAddress; + auto reloc_items = reinterpret_cast(relocation_table + 1); + auto reloc_items_count = (relocation_table->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); + + for (DWORD i = 0; i < reloc_items_count; ++i) { + auto reloc_type = reloc_items[i] >> 12; + + switch (reloc_type) { + case IMAGE_REL_BASED_ABSOLUTE: + break; + case IMAGE_REL_BASED_HIGH: + case IMAGE_REL_BASED_LOW: + case IMAGE_REL_BASED_HIGHADJ: + new_image.m_relocation_rva_lookup_table[rva + (reloc_items[i] & 0x0fff)] = 2; + break; + case IMAGE_REL_BASED_HIGHLOW: + new_image.m_relocation_rva_lookup_table[rva + (reloc_items[i] & 0x0fff)] = 4; + break; +#if defined(IMAGE_REL_BASED_DIR64) + case IMAGE_REL_BASED_DIR64: + new_image.m_relocation_rva_lookup_table[rva + (reloc_items[i] & 0x0fff)] = 8; + break; +#endif + default: + break; + } + } + + relocation_table = reinterpret_cast(&reloc_items[reloc_items_count]); + } + } + + if (new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) { + rva_t import_rva = new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + auto import_descriptors = new_image.convert_rva_to_ptr(import_rva); + for (size_t i = 0; import_descriptors[i].OriginalFirstThunk != 0; ++i) { + auto import_lookup_table = new_image.convert_rva_to_ptr(import_descriptors[i].OriginalFirstThunk); + rva_t import_address_table_rva = import_descriptors[i].FirstThunk; + + for (size_t j = 0; import_lookup_table[j].u1.Ordinal != 0; ++j) { + new_image.m_iat_rva_lookup_table[import_address_table_rva + j * sizeof(IMAGE_THUNK_DATA)] = std::make_pair(&import_descriptors[i], &import_lookup_table[j]); + } + } + } + + if (new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) { + rva_t resource_rva = new_image.m_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; + + auto res_type_directory = new_image.convert_rva_to_ptr(resource_rva); + auto res_type_name_entries = reinterpret_cast(res_type_directory + 1); + auto res_type_id_entries = res_type_name_entries + res_type_directory->NumberOfNamedEntries; + + for (WORD i = 0; i < res_type_directory->NumberOfIdEntries && new_image.m_vs_fixed_file_info == nullptr; ++i) { + if (res_type_id_entries[i].Id == reinterpret_cast(RT_VERSION) && res_type_id_entries[i].DataIsDirectory) { + auto res_name_directory = new_image.convert_rva_to_ptr(resource_rva + res_type_id_entries[i].OffsetToDirectory); + auto res_name_name_entries = reinterpret_cast(res_name_directory + 1); + auto res_name_id_entries = res_name_name_entries + res_name_directory->NumberOfNamedEntries; + + for (WORD j = 0; j < res_name_directory->NumberOfIdEntries && new_image.m_vs_fixed_file_info == nullptr; ++j) { + if (res_name_id_entries[j].Id == VS_VERSION_INFO && res_name_id_entries[j].DataIsDirectory) { + auto res_lang_directory = new_image.convert_rva_to_ptr(resource_rva + res_name_id_entries[j].OffsetToDirectory); + auto res_lang_name_entries = reinterpret_cast(res_lang_directory + 1); + auto res_lang_id_entries = res_lang_name_entries + res_lang_directory->NumberOfNamedEntries; + + for (WORD k = 0; k < res_lang_directory->NumberOfIdEntries && new_image.m_vs_fixed_file_info == nullptr; ++k) { + constexpr WORD neutral_lang_id = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); + constexpr WORD english_lang_id = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + + if ((res_lang_id_entries[k].Id == neutral_lang_id || res_lang_id_entries[k].Id == english_lang_id) && !res_lang_id_entries[k].DataIsDirectory) { + auto res_data_entry = new_image.convert_rva_to_ptr(resource_rva + res_lang_id_entries[k].OffsetToData); + + auto vs_version_info = new_image.convert_rva_to_ptr(res_data_entry->OffsetToData); + auto vs_version_info_key = reinterpret_cast(vs_version_info + 6); // vs_version_info->szKey + if (_wcsicmp(vs_version_info_key, L"VS_VERSION_INFO") == 0) { + auto p = reinterpret_cast(vs_version_info_key + _countof(L"VS_VERSION_INFO")); + while (new_image.convert_ptr_to_rva(p) % sizeof(DWORD)) { + ++p; + } + + auto vs_fixed_file_info = reinterpret_cast(p); + + if (vs_fixed_file_info->dwSignature == VS_FFI_SIGNATURE) { + new_image.m_vs_fixed_file_info = vs_fixed_file_info; + } + } + } + } + } + } + } + } + } + + return new_image; + } + + [[nodiscard]] + PIMAGE_DOS_HEADER image_interpreter::image_dos_header() const noexcept { + return m_dos_header; + } + + [[nodiscard]] + PIMAGE_NT_HEADERS image_interpreter::image_nt_headers() const noexcept { + return m_nt_headers; + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_table() const noexcept { + return m_section_header_table; + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header(size_t n) const { + if (n < m_nt_headers->FileHeader.NumberOfSections) { + return m_section_header_table + n; + } else { + throw exceptions::index_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Section index is out of range."); + } + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header(std::string_view section_name) const { + if (section_name.length() <= 8) { + std::array name{}; + + std::copy(section_name.begin(), section_name.end(), name.begin()); + + auto it = m_section_header_name_lookup_table.find(name); + if (it != m_section_header_name_lookup_table.end()) { + return it->second; + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), fmt::format(u8"Target section header is not found: section_name = {}", section_name)); + } + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target section header is not found: section_name is too long."); + } + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_from_rva(rva_t rva) const { + auto it = m_section_header_rva_lookup_table.upper_bound(rva); + if (it != m_section_header_rva_lookup_table.begin()) { + --it; + } + + rva_t section_rva_begin = it->second->VirtualAddress; + rva_t section_rva_end = section_rva_begin + it->second->Misc.VirtualSize; + + if (section_rva_begin <= rva && rva < section_rva_end) { + return it->second; + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target section header is not found.") + .push_hint(fmt::format("rva = 0x{:x}", rva)); + } + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_from_va(va_t va) const { + return image_section_header_from_rva(static_cast(va - m_nt_headers->OptionalHeader.ImageBase)); + } + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_interpreter::image_section_header_from_fo(fo_t file_offset) const { + auto it = m_section_header_fo_lookup_table.upper_bound(file_offset); + if (it != m_section_header_fo_lookup_table.begin()) { + --it; + } + + uintptr_t section_fo_begin = it->second->PointerToRawData; + uintptr_t section_fo_end = section_fo_begin + it->second->SizeOfRawData; + + if (section_fo_begin <= file_offset && file_offset < section_fo_end) { + return it->second; + } else { + throw exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Target section header is not found.") + .push_hint(fmt::format(u8"file_offset = 0x{:x}", file_offset)); + } + } + + [[nodiscard]] + image_interpreter::va_t image_interpreter::convert_rva_to_va(rva_t rva) const noexcept { + return rva + m_nt_headers->OptionalHeader.ImageBase; + } + + [[nodiscard]] + image_interpreter::fo_t image_interpreter::convert_rva_to_fo(rva_t rva) const { + auto section_header = image_section_header_from_rva(rva); + return section_header->PointerToRawData + (rva - static_cast(section_header->VirtualAddress)); + } + + [[nodiscard]] + image_interpreter::rva_t image_interpreter::convert_fo_to_rva(fo_t file_offset) const { + auto section_header = image_section_header_from_fo(file_offset); + return section_header->VirtualAddress + (file_offset - section_header->PointerToRawData); + } + + [[nodiscard]] + image_interpreter::va_t image_interpreter::convert_fo_to_va(fo_t file_offset) const { + return convert_fo_to_rva(file_offset) + m_nt_headers->OptionalHeader.ImageBase; + } + + [[nodiscard]] + image_interpreter::rva_t image_interpreter::convert_va_to_rva(va_t va) const noexcept { + return va - m_nt_headers->OptionalHeader.ImageBase; + } + + [[nodiscard]] + image_interpreter::fo_t image_interpreter::convert_va_to_fo(va_t va) const { + return image_section_header_from_va(va)->PointerToRawData; + } + + [[nodiscard]] + size_t image_interpreter::number_of_sections() const noexcept { + return m_nt_headers->FileHeader.NumberOfSections; + } + + PIMAGE_IMPORT_DESCRIPTOR image_interpreter::import_descriptor_from_rva(rva_t rva) { + auto it = m_iat_rva_lookup_table.find(rva); + return it != m_iat_rva_lookup_table.end() ? it->second.first : nullptr; + } + + PIMAGE_THUNK_DATA image_interpreter::import_lookup_entry_from_rva(rva_t rva) { + auto it = m_iat_rva_lookup_table.find(rva); + return it != m_iat_rva_lookup_table.end() ? it->second.second : nullptr; + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/image_interpreter.hpp b/Navicat-Cracker/image_interpreter.hpp new file mode 100644 index 0000000..7d437ae --- /dev/null +++ b/Navicat-Cracker/image_interpreter.hpp @@ -0,0 +1,202 @@ +#pragma once +#include +#include +#include +#include + +#include "exception.hpp" + +namespace nkg { + + class image_interpreter { + public: + using va_t = uintptr_t; + using rva_t = uintptr_t; + using fo_t = uintptr_t; + + private: + PIMAGE_DOS_HEADER m_dos_header; + PIMAGE_NT_HEADERS m_nt_headers; + PIMAGE_SECTION_HEADER m_section_header_table; + + std::map, PIMAGE_SECTION_HEADER> m_section_header_name_lookup_table; + std::map m_section_header_rva_lookup_table; + std::map m_section_header_fo_lookup_table; + + std::map m_relocation_rva_lookup_table; + + std::map> m_iat_rva_lookup_table; + + VS_FIXEDFILEINFO* m_vs_fixed_file_info; + + image_interpreter(); + + static std::array make_section_name(const BYTE (&name)[8]) { + std::array retval; + std::copy(std::begin(name), std::end(name), retval.begin()); + return retval; + } + + public: + class parse_error : public ::nkg::exception { + public: + parse_error(std::string_view file, int line, std::string_view message) noexcept : + ::nkg::exception(file, line, message) {} + }; + + [[nodiscard]] + static image_interpreter parse(void* image_base, bool parse_relocation); + + template + [[nodiscard]] + ptr_t image_base() const noexcept { + static_assert(std::is_pointer_v); + return reinterpret_cast(m_dos_header); + } + + [[nodiscard]] + PIMAGE_DOS_HEADER image_dos_header() const noexcept; + + [[nodiscard]] + PIMAGE_NT_HEADERS image_nt_headers() const noexcept; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_table() const noexcept; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header(size_t n) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header(std::string_view name) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_from_rva(rva_t rva) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_from_va(va_t va) const; + + [[nodiscard]] + PIMAGE_SECTION_HEADER image_section_header_from_fo(fo_t file_offset) const; + + [[nodiscard]] + va_t convert_rva_to_va(rva_t rva) const noexcept; + + [[nodiscard]] + fo_t convert_rva_to_fo(rva_t rva) const; + + template + [[nodiscard]] + ptr_t convert_rva_to_ptr(rva_t rva) const { + static_assert(std::is_pointer_v); + return convert_fo_to_ptr(convert_rva_to_fo(rva)); + } + + [[nodiscard]] + rva_t convert_fo_to_rva(fo_t file_offset) const; + + [[nodiscard]] + va_t convert_fo_to_va(fo_t file_offset) const; + + template + [[nodiscard]] + ptr_t convert_fo_to_ptr(fo_t file_offset) const noexcept { + static_assert(std::is_pointer_v); + return reinterpret_cast(image_base() + file_offset); + } + + [[nodiscard]] + rva_t convert_va_to_rva(va_t va) const noexcept; + + [[nodiscard]] + fo_t convert_va_to_fo(va_t va) const; + + template + [[nodiscard]] + ptr_t convert_va_to_ptr(va_t va) const noexcept { + return convert_rva_to_ptr(convert_va_to_rva(va)); + } + + template + [[nodiscard]] + fo_t convert_ptr_to_fo(ptr_t ptr) const noexcept { + static_assert(std::is_pointer_v); + return reinterpret_cast(ptr) - image_base(); + } + + template + [[nodiscard]] + rva_t convert_ptr_to_rva(ptr_t ptr) const { + return convert_fo_to_rva(convert_ptr_to_fo(ptr)); + } + + template + [[nodiscard]] + va_t convert_ptr_to_va(ptr_t ptr) const { + return convert_fo_to_va(convert_ptr_to_fo(ptr)); + } + + [[nodiscard]] + size_t number_of_sections() const noexcept; + + template + [[nodiscard]] + ptr_t image_section_view(size_t n, size_t offset = 0) const { + static_assert(std::is_pointer_v); + return reinterpret_cast(image_base() + image_section_header(n)->PointerToRawData + offset); + } + + template + [[nodiscard]] + ptr_t image_section_view(std::string_view section_name, size_t offset = 0) const { + static_assert(std::is_pointer_v); + return reinterpret_cast(image_base() + image_section_header(section_name)->PointerToRawData + offset); + } + + template + [[nodiscard]] + ptr_t search_section(size_t n, pred_func_t&& pred_func) const { + static_assert(std::is_pointer_v); + + auto section_header = image_section_header(n); + + auto begin = image_base() + section_header->PointerToRawData; + auto end = begin + section_header->Misc.VirtualSize; + + for (; begin < end; ++begin) { + if (pred_func(begin, end - begin)) { + return reinterpret_cast(const_cast(begin)); + } + } + + return nullptr; + } + + template + [[nodiscard]] + ptr_t search_section(std::string_view section_name, pred_func_t&& pred_func) const { + static_assert(std::is_pointer_v); + + auto section_header = image_section_header(section_name); + + auto begin = image_base() + section_header->PointerToRawData; + auto end = begin + section_header->Misc.VirtualSize; + + for (; begin < end; ++begin) { + if (pred_func(begin, end - begin)) { + return reinterpret_cast(const_cast(begin)); + } + } + + return nullptr; + } + + PIMAGE_IMPORT_DESCRIPTOR import_descriptor_from_rva(rva_t rva); + + PIMAGE_THUNK_DATA import_lookup_entry_from_rva(rva_t rva); + + auto& relocation_distribute() { + return m_relocation_rva_lookup_table; + } + }; + +} diff --git a/Navicat-Cracker/keystone_assembler.cpp b/Navicat-Cracker/keystone_assembler.cpp new file mode 100644 index 0000000..0b16c68 --- /dev/null +++ b/Navicat-Cracker/keystone_assembler.cpp @@ -0,0 +1,38 @@ +#include "keystone_assembler.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\keystone_assembler.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + keystone_assembler::keystone_assembler(ks_arch architecture, ks_mode mode) { + auto err = ks_open(architecture, mode, m_keystone_engine.unsafe_addressof()); + if (err != KS_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_open failed."); + } + } + + void keystone_assembler::option(ks_opt_type option_type, size_t option_value) { + auto err = ks_option(m_keystone_engine.get(), option_type, option_value); + if (err != KS_ERR_OK) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_option failed."); + } + } + + std::vector keystone_assembler::assemble(std::string_view asm_string, uint64_t asm_address) const { + resource_wrapper machine_code{ resource_traits::keystone::keystone_alloc{} }; + size_t machine_code_size = 0; + size_t stat_count = 0; + + if (ks_asm(m_keystone_engine.get(), asm_string.data(), asm_address, machine_code.unsafe_addressof(), &machine_code_size, &stat_count) < 0) { + auto err = ks_errno(m_keystone_engine.get()); + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_option failed."); + } + + return std::vector(machine_code.get(), machine_code.get() + machine_code_size); + } + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/keystone_assembler.hpp b/Navicat-Cracker/keystone_assembler.hpp new file mode 100644 index 0000000..4015ef6 --- /dev/null +++ b/Navicat-Cracker/keystone_assembler.hpp @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include + +#include "resource_wrapper.hpp" +#include "resource_traits/keystone/keystone_handle.hpp" + +#include "exception.hpp" + +namespace nkg { + + class keystone_assembler { + public: + class backend_error : public ::nkg::exception { + public: + using error_code_t = ks_err; + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, error_code_t keystone_err, std::string_view message) noexcept : + ::nkg::exception(file, line, message), m_error_code(keystone_err), m_error_string(ks_strerror(keystone_err)) {} + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + + private: + resource_wrapper m_keystone_engine; + + public: + keystone_assembler(ks_arch architecture, ks_mode mode); + + void option(ks_opt_type option_type, size_t option_value); + + std::vector assemble(std::string_view asm_string, uint64_t asm_address = 0) const; + }; + +} diff --git a/Navicat-Cracker/navicat_serial_generator.cpp b/Navicat-Cracker/navicat_serial_generator.cpp new file mode 100644 index 0000000..5e05afe --- /dev/null +++ b/Navicat-Cracker/navicat_serial_generator.cpp @@ -0,0 +1,194 @@ +#include "navicat_serial_generator.hpp" +#include + +#include +#include +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x +#include +#endif + +#include "resource_wrapper.hpp" +#include "resource_traits/openssl/evp_cipher_ctx.hpp" + +#include +#include "base32_rfc4648.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-keygen\\navicat_serial_generator.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + char navicat_serial_generator::_replace_confusing_chars(char c) noexcept { + if (c == 'I') { + return '8'; + } + else if (c == 'O') { + return '9'; + } + else { + return c; + } + }; + + navicat_serial_generator::navicat_serial_generator() noexcept : + m_data{ 0x68 , 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32 }, m_des_key{} {} + + void navicat_serial_generator::set_software_language(navicat_software_language lang) noexcept { + switch (lang) { + case navicat_software_language::English: + m_data[5] = 0xAC; // Must be 0xAC for English version. + m_data[6] = 0x88; // Must be 0x88 for English version. + break; + case navicat_software_language::SimplifiedChinese: + m_data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version. + m_data[6] = 0x32; // Must be 0x32 for Simplified Chinese version. + break; + case navicat_software_language::TraditionalChinese: + m_data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version. + m_data[6] = 0x99; // Must be 0x99 for Traditional Chinese version. + break; + case navicat_software_language::Japanese: + m_data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee + m_data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee + break; + case navicat_software_language::Polish: + m_data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee + m_data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee + break; + case navicat_software_language::Spanish: + m_data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee + m_data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee + break; + case navicat_software_language::French: + m_data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79 + m_data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79 + break; + case navicat_software_language::German: + m_data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee + m_data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee + break; + case navicat_software_language::Korean: + m_data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee + m_data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee + break; + case navicat_software_language::Russian: + m_data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee + m_data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee + break; + case navicat_software_language::Portuguese: + m_data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee + m_data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee + break; + default: + break; + } + } + + void navicat_serial_generator::set_software_language(uint8_t lang_sig0, uint8_t lang_sig1) noexcept { + m_data[5] = lang_sig0; + m_data[6] = lang_sig1; + } + + void navicat_serial_generator::set_software_type(navicat_software_type software_type) noexcept { + switch (software_type) { + case navicat_software_type::DataModeler: + m_data[7] = 0x84; + break; + case navicat_software_type::Premium: + m_data[7] = 0x65; + break; + case navicat_software_type::MySQL: + m_data[7] = 0x68; + break; + case navicat_software_type::PostgreSQL: + m_data[7] = 0x6C; + break; + case navicat_software_type::Oracle: + m_data[7] = 0x70; + break; + case navicat_software_type::SQLServer: + m_data[7] = 0x74; + break; + case navicat_software_type::SQLite: + m_data[7] = 0x78; + break; + case navicat_software_type::MariaDB: + m_data[7] = 0x7C; + break; + case navicat_software_type::MongoDB: + m_data[7] = 0x80; + break; + case navicat_software_type::ReportViewer: + m_data[7] = 0xb; + break; + default: + break; + } + } + + void navicat_serial_generator::set_software_type(uint8_t software_type_sig) noexcept { + m_data[7] = software_type_sig; + } + + void navicat_serial_generator::set_software_version(int ver) { + if (11 <= ver && ver < 16) { + static_assert(sizeof(m_des_key) == sizeof(s_des_key0)); + + m_data[8] = static_cast((ver << 4) | (m_data[8] & 0x0f)); + memcpy(m_des_key, s_des_key0, sizeof(s_des_key0)); + } + else if (16 <= ver && ver < 32) { + static_assert(sizeof(m_des_key) == sizeof(s_des_key1)); + + m_data[8] = static_cast(((ver - 16) << 4) | (m_data[8] & 0x0f)); + memcpy(m_des_key, s_des_key1, sizeof(s_des_key1)); + } + else { + throw version_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"Invalid navicat version."); + } + } + + void navicat_serial_generator::generate() { + RAND_bytes(m_data + 2, 3); + +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + if (!OSSL_PROVIDER_available(nullptr, "legacy")) { + if (OSSL_PROVIDER_load(nullptr, "legacy") == nullptr) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_PROVIDER_load failed."); + } + } +#endif + + resource_wrapper evp_cipher_context{ resource_traits::openssl::evp_cipher_ctx{}, EVP_CIPHER_CTX_new() }; + if (!evp_cipher_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_CIPHER_CTX_new failed."); + } + + if (EVP_EncryptInit(evp_cipher_context.get(), EVP_des_ecb(), m_des_key, nullptr) <= 0) { // return 1 for success and 0 for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_EncryptInit failed."); + } + + if (int _; EVP_EncryptUpdate(evp_cipher_context.get(), m_data + 2, &_, m_data + 2, 8) <= 0) { // return 1 for success and 0 for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_EncryptUpdate failed."); + } + + m_serial_number = base32_rfc4648::encode(m_data, sizeof(m_data)); + std::transform(m_serial_number.begin(), m_serial_number.end(), m_serial_number.begin(), _replace_confusing_chars); + + std::string_view sn = m_serial_number; + m_serial_number_formatted = fmt::format("{}-{}-{}-{}", sn.substr(0, 4), sn.substr(4, 4), sn.substr(8, 4), sn.substr(12, 4)); + } + + [[nodiscard]] + const std::string& navicat_serial_generator::serial_number() const noexcept { + return m_serial_number; + } + + [[nodiscard]] + const std::string& navicat_serial_generator::serial_number_formatted() const noexcept { + return m_serial_number_formatted; + } +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/Navicat-Cracker/navicat_serial_generator.hpp b/Navicat-Cracker/navicat_serial_generator.hpp new file mode 100644 index 0000000..0efe5e7 --- /dev/null +++ b/Navicat-Cracker/navicat_serial_generator.hpp @@ -0,0 +1,80 @@ +#pragma once +#include +#include +#include "exception.hpp" + +namespace nkg { + + enum class navicat_software_language { + English, + SimplifiedChinese, + TraditionalChinese, + Japanese, + Polish, + Spanish, + French, + German, + Korean, + Russian, + Portuguese + }; + + enum class navicat_software_type { + DataModeler, + Premium, + MySQL, + PostgreSQL, + Oracle, + SQLServer, + SQLite, + MariaDB, + MongoDB, + ReportViewer + }; + + class navicat_serial_generator { + public: + class version_error; + class backend_error; + + private: + static inline const uint8_t s_des_key0[8] = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 }; + static inline const uint8_t s_des_key1[8] = { 0xE9, 0x7F, 0xB0, 0x60, 0x77, 0x45, 0x90, 0xAE }; + + uint8_t m_data[10]; + uint8_t m_des_key[8]; + std::string m_serial_number; + std::string m_serial_number_formatted; + + static char _replace_confusing_chars(char c) noexcept; + + public: + navicat_serial_generator() noexcept; + + void set_software_language(navicat_software_language lang) noexcept; + void set_software_language(uint8_t lang_sig0, uint8_t lang_sig1) noexcept; + + void set_software_type(navicat_software_type software_type) noexcept; + void set_software_type(uint8_t software_type_sig) noexcept; + + void set_software_version(int Version); + + void generate(); + + [[nodiscard]] + const std::string& serial_number() const noexcept; + + [[nodiscard]] + const std::string& serial_number_formatted() const noexcept; + }; + + class navicat_serial_generator::version_error : public ::nkg::exception { + using ::nkg::exception::exception; + }; + + class navicat_serial_generator::backend_error : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} + diff --git a/Navicat-Cracker/patch_solution.hpp b/Navicat-Cracker/patch_solution.hpp new file mode 100644 index 0000000..24fded6 --- /dev/null +++ b/Navicat-Cracker/patch_solution.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "rsa_cipher.hpp" + +namespace nkg { + + class patch_solution { + public: + [[nodiscard]] + virtual bool find_patch() = 0; + + [[nodiscard]] + virtual bool check_rsa_privkey(const rsa_cipher& cipher) = 0; + + virtual void make_patch(const rsa_cipher& cipher) = 0; + + virtual ~patch_solution() = default; + }; + +} diff --git a/Navicat-Cracker/patch_solution_since.hpp b/Navicat-Cracker/patch_solution_since.hpp new file mode 100644 index 0000000..1e17cee --- /dev/null +++ b/Navicat-Cracker/patch_solution_since.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "patch_solution.hpp" + +namespace nkg { + + template + class patch_solution_since; + +} diff --git a/Navicat-Cracker/patch_solution_since_16.0.7.0.amd64.cpp b/Navicat-Cracker/patch_solution_since_16.0.7.0.amd64.cpp new file mode 100644 index 0000000..54a8d11 --- /dev/null +++ b/Navicat-Cracker/patch_solution_since_16.0.7.0.amd64.cpp @@ -0,0 +1,608 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "amd64_emulator.hpp" +#include "keystone_assembler.hpp" +#include "patch_solution_since_16.0.7.0.hpp" +#include +#include + +namespace nkg { + + patch_solution_since<16, 0, 7, 0>::patch_solution_since(image_interpreter& libcc_interpreter) : + m_libcc_interpreter(libcc_interpreter), + m_va_CSRegistrationInfoFetcher_WIN_vtable(0), + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey(0), + m_va_iat_entry_malloc(0) {} + + bool patch_solution_since<16, 0, 7, 0>::find_patch() { + auto CSRegistrationInfoFetcher_WIN_type_descriptor_name = + m_libcc_interpreter.search_section( + ".data", + [](const uint8_t* p, size_t s) { + if (s < sizeof(".?AVCSRegistrationInfoFetcher_WIN@@")) { + return false; + } + + return strcmp(reinterpret_cast(p), ".?AVCSRegistrationInfoFetcher_WIN@@") == 0; + } + ); + + if (CSRegistrationInfoFetcher_WIN_type_descriptor_name == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 0)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor = CSRegistrationInfoFetcher_WIN_type_descriptor_name - 0x10; + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_rva = m_libcc_interpreter.convert_ptr_to_rva(CSRegistrationInfoFetcher_WIN_rtti_type_descriptor); + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor = + m_libcc_interpreter.search_section( + ".rdata", + [this, CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_rva](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint32_t) != 0) { + return false; + } + + if (s < sizeof(uint32_t)) { + return false; + } + + if (*reinterpret_cast(p) != CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_rva) { + return false; + } + + if (s < sizeof(uint32_t) * 2) { + return false; + } + + auto maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_rva = reinterpret_cast(p)[1]; + + try { + return memcmp(m_libcc_interpreter.image_section_header_from_rva(maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_rva)->Name, ".rdata\x00\x00", 8) == 0; + } + catch (nkg::exception&) { + return false; + } + } + ); + + if (CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 1)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator = CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor - 0xC; + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator); + + auto CSRegistrationInfoFetcher_WIN_vtable_before = + m_libcc_interpreter.search_section( + ".rdata", + [CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint64_t) != 0) { + return false; + } + + if (s < sizeof(uint64_t)) { + return false; + } + + return *reinterpret_cast(p) == CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va; + } + ); + + if (CSRegistrationInfoFetcher_WIN_vtable_before == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Vftable for CSRegistrationInfoFetcher_WIN is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_vtable = + reinterpret_cast(CSRegistrationInfoFetcher_WIN_vtable_before + sizeof(image_interpreter::va_t)); + + m_va_CSRegistrationInfoFetcher_WIN_vtable = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_vtable); + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = CSRegistrationInfoFetcher_WIN_vtable[6]; + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_vtable = 0x%016llx\n", m_va_CSRegistrationInfoFetcher_WIN_vtable); + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = 0x%016llx\n", m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + amd64_emulator x64_emulator; + + x64_emulator.context_set("heap_base", uint64_t{ 0x00007fff00000000 }); + x64_emulator.context_set("heap_size", size_t{ 0x1000 * 32 }); + x64_emulator.context_set("heap_records", std::map{}); + + x64_emulator.context_set("stack_base", uint64_t{ 0x00007fffffff0000 }); + x64_emulator.context_set("stack_size", size_t{ 0x1000 * 32 }); + x64_emulator.context_set("stack_top", uint64_t{ x64_emulator.context_get("stack_base") - x64_emulator.context_get("stack_size") }); + + x64_emulator.context_set("dead_area_base", uint64_t{ 0xfffffffffffff000 }); + x64_emulator.context_set("dead_area_size", size_t{ 0x1000 }); + + x64_emulator.context_set("iat_base", uint64_t{ m_libcc_interpreter.convert_rva_to_va(m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) }); + x64_emulator.context_set("iat_size", size_t{ m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size }); + + x64_emulator.context_set("external_api_stub_area_base", uint64_t{ 0xffff800000000000 }); + x64_emulator.context_set("external_api_stub_area_size", size_t{ (x64_emulator.context_get("iat_size") / 8 + 0xfff) / 0x1000 * 0x1000 }); + + x64_emulator.context_set("external_api_impl", std::map{}); + x64_emulator.context_set("external_api_impl_area_base", uint64_t{ 0xffff900000000000 }); + x64_emulator.context_set("external_api_impl_area_size", size_t{ 0 }); + + x64_emulator.context_set("gs_base", uint64_t{ 0xffffa00000000000 }); + x64_emulator.context_set("gs_size", size_t{ 0x1000 }); + + x64_emulator.context_set("start_address", static_cast(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey)); + x64_emulator.context_set("dead_address", x64_emulator.context_get("dead_area_base")); + + // allocate heap + x64_emulator.mem_map(x64_emulator.context_get("heap_base"), x64_emulator.context_get("heap_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate stack + x64_emulator.mem_map(x64_emulator.context_get("stack_top"), x64_emulator.context_get("stack_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate dead area + x64_emulator.mem_map(x64_emulator.context_get("dead_area_base"), x64_emulator.context_get("dead_area_size"), UC_PROT_READ | UC_PROT_EXEC); + + // allocate and hook read access to IAT + { + auto iat_base = x64_emulator.context_get("iat_base"); + auto iat_size = x64_emulator.context_get("iat_size"); + auto external_api_stub_area_base = x64_emulator.context_get("external_api_stub_area_base"); + + auto iat_page_base = iat_base / 0x1000 * 0x1000; + auto iat_page_count = (iat_base - iat_page_base + iat_size + 0xfff) / 0x1000; + + x64_emulator.mem_map(iat_page_base, iat_page_count * 0x1000, UC_PROT_READ); + + x64_emulator.hook_add( + [this, &x64_emulator, iat_base, external_api_stub_area_base](uc_mem_type type, uint64_t address, size_t size, int64_t value) { + auto rva = m_libcc_interpreter.convert_va_to_rva(address); + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(rva); + + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "memcpy") == 0) { + uint64_t impl_address = x64_emulator.context_get&>("external_api_impl")["memcpy"]; + x64_emulator.mem_write(address, &impl_address, sizeof(impl_address)); + } + else if (strcmp(import_by_name_entry->Name, "memcmp") == 0) { + uint64_t impl_address = x64_emulator.context_get&>("external_api_impl")["memcmp"]; + x64_emulator.mem_write(address, &impl_address, sizeof(impl_address)); + } + else { + uint64_t stub_address = external_api_stub_area_base + (address - iat_base) / sizeof(IMAGE_THUNK_DATA); + x64_emulator.mem_write(address, &stub_address, sizeof(stub_address)); + } + } + else { + x64_emulator.emu_stop(); + } + }, + iat_base, + iat_base + iat_size - 1 + ); + } + + // allocate and setup external api stub area + { + auto external_api_stub_area_base = x64_emulator.context_get("external_api_stub_area_base"); + auto external_api_stub_area_size = x64_emulator.context_get("external_api_stub_area_size"); + + x64_emulator.mem_map(external_api_stub_area_base, external_api_stub_area_size, UC_PROT_READ | UC_PROT_EXEC); + x64_emulator.mem_write(external_api_stub_area_base, std::vector(external_api_stub_area_size, 0xc3)); // c3 -> ret + + x64_emulator.hook_add( + [this, &x64_emulator, external_api_stub_area_base](uint64_t address, size_t size) { + auto iat_base = x64_emulator.context_get("iat_base"); + auto from_va = iat_base + (address - external_api_stub_area_base) * sizeof(IMAGE_THUNK_DATA); + auto from_rva = m_libcc_interpreter.convert_va_to_rva(from_va); + + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(from_rva); + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "malloc") == 0) { + m_va_iat_entry_malloc = from_va; + + uint64_t alloc_size; + x64_emulator.reg_read(UC_X86_REG_RCX, &alloc_size); + + auto& heap_records = x64_emulator.context_get&>("heap_records"); + + auto predecessor_chunk = + std::adjacent_find( + heap_records.begin(), + heap_records.end(), + [alloc_size](const auto& chunk0, const auto& chunk1) { return chunk1.first - (chunk0.first + chunk0.second) >= alloc_size; } + ); + + uint64_t alloc_p; + if (predecessor_chunk != heap_records.end()) { + alloc_p = predecessor_chunk->first + predecessor_chunk->second; + } + else { + auto heap_base = x64_emulator.context_get("heap_base"); + auto heap_size = x64_emulator.context_get("heap_size"); + + auto free_space_base = heap_records.size() > 0 ? heap_records.rbegin()->first + heap_records.rbegin()->second : heap_base; + auto free_space_size = heap_base + heap_size - free_space_base; + + if (free_space_size < alloc_size) { + auto heap_expand_base = heap_base + heap_size; + auto heap_expand_size = (alloc_size - free_space_size + 0xfff) / 0x1000 * 0x1000; + x64_emulator.mem_map(heap_expand_base, heap_expand_size, UC_PROT_READ | UC_PROT_WRITE); + } + + alloc_p = free_space_base; + } + + heap_records[alloc_p] = alloc_size; + + x64_emulator.reg_write(UC_X86_REG_RAX, &alloc_p); + } + else if (strcmp(import_by_name_entry->Name, "free") == 0) { + uint64_t alloc_p; + x64_emulator.reg_read(UC_X86_REG_RCX, &alloc_p); + + auto& heap_records = x64_emulator.context_get&>("heap_records"); + + auto chunk = heap_records.find(alloc_p); + if (chunk != heap_records.end()) { + heap_records.erase(chunk); + } + else { + x64_emulator.emu_stop(); + } + } + else { + x64_emulator.emu_stop(); + } + } + else { + x64_emulator.emu_stop(); + } + }, + external_api_stub_area_base, + external_api_stub_area_base + external_api_stub_area_size - 1 + ); + } + + // allocate and setup external api impl area + { + keystone_assembler x64_assembler{ KS_ARCH_X86, KS_MODE_64 }; + + std::map> machine_code_list = + { + std::make_pair( + "memcpy", + x64_assembler.assemble( + "push rdi;" + "push rsi;" + "mov rdi, rcx;" + "mov rsi, rdx;" + "mov rcx, r8;" + "rep movs byte ptr [rdi], byte ptr [rsi];" + "pop rsi;" + "pop rdi;" + "ret;" + ) + ), + std::make_pair( + "memcmp", + x64_assembler.assemble( + " push rdi;" + " push rsi;" + " mov rsi, rcx;" + " mov rdi, rdx;" + " mov rcx, r8;" + " cmp rcx, rcx;" + " repe cmps byte ptr [rsi], byte ptr [rdi];" + " jz cmp_eq;" + "cmp_not_eq:" + " movsx eax, byte ptr [rsi - 1];" + " movsx ecx, byte ptr [rdi - 1];" + " sub eax, ecx;" + " jmp final;" + "cmp_eq:" + " xor eax, eax;" + "final:" + " pop rsi;" + " pop rdi;" + " ret;" + ) + ), + std::make_pair( + "memmove", + x64_assembler.assemble( + " push rdi;" + " push rsi;" + " cmp rdx, rcx;" + " jb reverse_copy;" + "copy:" + " mov rdi, rcx;" + " mov rsi, rdx;" + " mov rcx, r8;" + " rep movsb byte ptr[rdi], byte ptr[rsi];" + " jmp final;" + "reverse_copy:" + " std;" + " lea rdi, qword ptr[rcx + r8 - 1];" + " lea rsi, qword ptr[rdx + r8 - 1];" + " mov rcx, r8;" + " rep movsb byte ptr[rdi], byte ptr[rsi];" + " cld;" + "final:" + " pop rsi;" + " pop rdi;" + " ret;" + ) + ) + }; + + auto& external_api_impl = x64_emulator.context_get&>("external_api_impl"); + auto& external_api_impl_area_base = x64_emulator.context_get("external_api_impl_area_base"); + auto& external_api_impl_area_size = x64_emulator.context_get("external_api_impl_area_size"); + + auto p = external_api_impl_area_base; + for (const auto& name_code_pair : machine_code_list) { + external_api_impl[name_code_pair.first] = p; + p = (p + name_code_pair.second.size() + 0xf) / 0x10 * 0x10; + } + + external_api_impl_area_size = (p + 0xfff) / 0x1000 * 0x1000 - external_api_impl_area_base; + + x64_emulator.mem_map(external_api_impl_area_base, external_api_impl_area_size, UC_PROT_READ | UC_PROT_EXEC); + for (const auto& name_code_pair : machine_code_list) { + x64_emulator.mem_write(external_api_impl[name_code_pair.first], name_code_pair.second); + } + } + + // allocate and hook access to gs area + x64_emulator.mem_map(x64_emulator.context_get("gs_base"), x64_emulator.context_get("gs_size"), UC_PROT_READ | UC_PROT_WRITE); + x64_emulator.msr_write(0xC0000101, x64_emulator.context_get("gs_base")); // set gs base address + + x64_emulator.hook_add( + [this, &x64_emulator](uc_mem_type access, uint64_t address, size_t size, int64_t value) { + auto gs_base = x64_emulator.context_get("gs_base"); + switch (address - gs_base) { + case 0x10: // qword ptr gs:[0x10] -> Stack Limit / Ceiling of stack (low address) + { + uint64_t val = x64_emulator.context_get("stack_top"); + x64_emulator.mem_write(address, &val, size); + } + break; + default: + x64_emulator.emu_stop(); + break; + } + }, + x64_emulator.context_get("gs_base"), + x64_emulator.context_get("gs_base") + x64_emulator.context_get("gs_size") - 1 + ); + + // x64_emulator.hook_add([](uint64_t address, size_t size) { wprintf_s(L"code_trace, address = 0x%016zx\n", address); }); + + x64_emulator.hook_add( + [this, &x64_emulator](uc_mem_type access, uint64_t address, size_t size, int64_t value) -> bool { + try { + auto fault_section = m_libcc_interpreter.image_section_header_from_va(address); + + auto page_base = address / 0x1000 * 0x1000; + auto page_size = 0x1000; + uint32_t page_perms = UC_PROT_NONE; + + if (fault_section->Characteristics & IMAGE_SCN_MEM_READ) { + page_perms |= UC_PROT_READ; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_WRITE) { + page_perms |= UC_PROT_WRITE; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_EXECUTE) { + page_perms |= UC_PROT_EXEC; + } + + x64_emulator.mem_map(page_base, page_size, page_perms); + x64_emulator.mem_write(page_base, m_libcc_interpreter.convert_va_to_ptr(page_base), page_size); + + return true; + } + catch (::nkg::exception&) { + return false; + } + } + ); + + // set rbp, rsp + uint64_t init_rbp = x64_emulator.context_get("stack_base") - x64_emulator.context_get("stack_size") / 4; + uint64_t init_rsp = x64_emulator.context_get("stack_base") - x64_emulator.context_get("stack_size") / 2; + + x64_emulator.reg_write(UC_X86_REG_RBP, &init_rbp); + x64_emulator.reg_write(UC_X86_REG_RSP, &init_rsp); + + // set return address + auto retaddr = x64_emulator.context_get("dead_address"); + x64_emulator.mem_write(init_rsp, &retaddr, sizeof(retaddr)); + + // set argument registers + uint64_t init_rcx = 0; // `this` pointer of CSRegistrationInfoFetcher_WIN, but we don't need it for now. + uint64_t init_rdx = init_rsp + 0x40; // a pointer to stack memory which stores return value + x64_emulator.reg_write(UC_X86_REG_RCX, &init_rcx); + x64_emulator.reg_write(UC_X86_REG_RDX, &init_rdx); + + // + // start emulate + // + try { + x64_emulator.emu_start(x64_emulator.context_get("start_address"), x64_emulator.context_get("dead_address")); + } + catch (nkg::exception&) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Code emulation failed.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + catch (std::exception&) { + wprintf_s(L"STD EXCEPTION!"); + } + + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_iat_entry_malloc = 0x%016llx\n", m_va_iat_entry_malloc); + + // + // get result + // + // on AMD64 platform, `std::string` has follow memory layout: + // ------------------------------ + // | offset | size | + // ------------------------------ + // | +0 | 0x10 | `char[16]: a small string buffer` OR `char*: a large string buffer pointer` + // ------------------------------ + // | +0x10 | 0x8 | size_t: string length + // ------------------------------ + // | +0x18 | 0x8 | size_t: capacity + // ------------------------------ + // + uint64_t encoded_key_length; + x64_emulator.mem_read(init_rdx + 0x10, &encoded_key_length, sizeof(encoded_key_length)); + if (encoded_key_length != official_encoded_key.length()) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: unexpected encoded key length(%llu).\n", encoded_key_length); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + uint64_t encoded_key_ptr; + x64_emulator.mem_read(init_rdx, &encoded_key_ptr, sizeof(encoded_key_ptr)); + + auto encoded_key = x64_emulator.mem_read(encoded_key_ptr, encoded_key_length); + if (memcmp(encoded_key.data(), official_encoded_key.data(), encoded_key.size()) == 0) { + wprintf_s(L"[+] patch_solution_since<16, 0, 7, 0>: official encoded key is found.\n"); + return true; + } + else { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: official encoded key is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + } + + bool patch_solution_since<16, 0, 7, 0>::check_rsa_privkey(const rsa_cipher& cipher) { + return true; // no requirements + } + + void patch_solution_since<16, 0, 7, 0>::make_patch(const rsa_cipher& cipher) { + auto encoded_key = _build_encoded_key(cipher); + + auto CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = + m_libcc_interpreter.convert_va_to_ptr(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + std::vector patch_code_chunks; + patch_code_chunks.emplace_back("push rdi;"); + patch_code_chunks.emplace_back("push rsi;"); + patch_code_chunks.emplace_back("push rbx;"); + patch_code_chunks.emplace_back("push rbp;"); + patch_code_chunks.emplace_back("mov rbp, rsp;"); + patch_code_chunks.emplace_back("mov rbx, rdx;"); + patch_code_chunks.emplace_back("sub rsp, 0x20;"); + patch_code_chunks.emplace_back(fmt::format("mov rcx, {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back(fmt::format("call qword ptr [{:#016x}];", m_va_iat_entry_malloc)); + patch_code_chunks.emplace_back("add rsp, 0x20;"); + { + std::vector push_values((encoded_key.length() + 1 + 7) / 8, 0); + memcpy(push_values.data(), encoded_key.data(), encoded_key.length()); + + std::for_each( + push_values.crbegin(), + push_values.crend(), + [&patch_code_chunks](uint64_t x) { + patch_code_chunks.emplace_back(fmt::format("mov rdx, {:#016x};", x)); + patch_code_chunks.emplace_back("push rdx;"); + } + ); + } + patch_code_chunks.emplace_back("mov rdi, rax;"); + patch_code_chunks.emplace_back("mov rsi, rsp;"); + patch_code_chunks.emplace_back(fmt::format("mov rcx, {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("rep movs byte ptr [rdi], byte ptr [rsi];"); + patch_code_chunks.emplace_back("mov qword ptr [rbx], rax;"); + patch_code_chunks.emplace_back(fmt::format("mov qword ptr [rbx + 0x10], {:#x};", encoded_key.length())); + patch_code_chunks.emplace_back(fmt::format("mov qword ptr [rbx + 0x18], {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("mov rax, rbx;"); + patch_code_chunks.emplace_back("leave;"); + patch_code_chunks.emplace_back("pop rbx;"); + patch_code_chunks.emplace_back("pop rsi;"); + patch_code_chunks.emplace_back("pop rdi;"); + patch_code_chunks.emplace_back("ret;"); + + //auto patch_code = keystone_assembler{ KS_ARCH_X86, KS_MODE_64 } + // .assemble( + // fmt::format( + // " push rdi;" + // " push rsi;" + // " push rbx;" + // " mov rbx, rdx;" + // "allocate_string_buf:" + // " mov rcx, {encoded_key_length:#x} + 1;" + // " sub rsp, 0x20;" + // " call qword ptr [{m_va_iat_entry_malloc:#x}];" + // " add rsp, 0x20;" + // "write_our_own_key_to_string_buf:" + // " mov rdi, rax;" + // " lea rsi, qword ptr [end_of_code + rip];" + // " mov rcx, 0x188;" + // " rep movs byte ptr [rdi], byte ptr [rsi];" + // " mov byte ptr [rdi], 0;" + // "craft_std_string:" + // " mov qword ptr [rbx], rax;" + // " mov qword ptr [rbx + 0x10], {encoded_key_length:#x};" + // " mov qword ptr [rbx + 0x18], {encoded_key_length:#x} + 1;" + // "final:" + // " mov rax, rbx;" + // " pop rbx;" + // " pop rsi;" + // " pop rdi;" + // " ret;" + // "end_of_code:", + // fmt::arg("encoded_key_length", encoded_key.length()), + // fmt::arg("m_va_iat_entry_malloc", m_va_iat_entry_malloc) + // ), + // m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey + // ); + + std::vector assembled_patch_code; + { + keystone_assembler x86_assembler{ KS_ARCH_X86, KS_MODE_64 }; + + auto current_va = m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey; + auto next_reloc = m_libcc_interpreter.relocation_distribute().lower_bound(m_libcc_interpreter.convert_va_to_rva(current_va)); + for (const auto& patch_code_chunk : patch_code_chunks) { + auto assembled_patch_code_chunk = x86_assembler.assemble(patch_code_chunk, current_va); + + while (true) { + auto next_reloc_va = m_libcc_interpreter.convert_rva_to_va(next_reloc->first); + auto next_reloc_size = next_reloc->second; + + if (current_va + assembled_patch_code_chunk.size() + 2 <= next_reloc_va) { // 2 -> size of machine code "jmp rel8" + assembled_patch_code.insert(assembled_patch_code.end(), assembled_patch_code_chunk.begin(), assembled_patch_code_chunk.end()); + current_va += assembled_patch_code_chunk.size(); + break; + } + else if (current_va + 2 <= next_reloc_va) { + auto next_va = next_reloc_va + next_reloc_size; + auto assembled_jmp = x86_assembler.assemble(fmt::format("jmp {:#016x};", next_va), current_va); + auto assembled_padding = std::vector(next_va - (current_va + assembled_jmp.size()), 0xcc); // 0xcc -> int3 + assembled_patch_code.insert(assembled_patch_code.end(), assembled_jmp.begin(), assembled_jmp.end()); + assembled_patch_code.insert(assembled_patch_code.end(), assembled_padding.begin(), assembled_padding.end()); + current_va = next_va; + ++next_reloc; + } + else { + __assume(false); // impossible to reach here + } + } + } + } + + memcpy(CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey, assembled_patch_code.data(), assembled_patch_code.size()); + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: Patch has been done.\n"); + } + +} diff --git a/Navicat-Cracker/patch_solution_since_16.0.7.0.generic.cpp b/Navicat-Cracker/patch_solution_since_16.0.7.0.generic.cpp new file mode 100644 index 0000000..878c014 --- /dev/null +++ b/Navicat-Cracker/patch_solution_since_16.0.7.0.generic.cpp @@ -0,0 +1,16 @@ +#include "patch_solution_since_16.0.7.0.hpp" +#include + +namespace nkg { + + std::string patch_solution_since<16, 0, 7, 0>::_build_encoded_key(const rsa_cipher& cipher) { + auto encoded_key = cipher.export_public_key_string_pem(); + + encoded_key = std::regex_replace(encoded_key, std::regex("-----BEGIN PUBLIC KEY-----"), ""); + encoded_key = std::regex_replace(encoded_key, std::regex("-----END PUBLIC KEY-----"), ""); + encoded_key = std::regex_replace(encoded_key, std::regex("\n"), ""); + + return encoded_key; + } + +} diff --git a/Navicat-Cracker/patch_solution_since_16.0.7.0.hpp b/Navicat-Cracker/patch_solution_since_16.0.7.0.hpp new file mode 100644 index 0000000..7447d66 --- /dev/null +++ b/Navicat-Cracker/patch_solution_since_16.0.7.0.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "patch_solution_since.hpp" +#include "image_interpreter.hpp" +#include +#include +#include + +namespace nkg { + + template<> + class patch_solution_since<16, 0, 7, 0> final : public patch_solution { + private: + static inline std::string_view official_encoded_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889IqdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginva5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOFR0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmtYyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQawIDAQAB"; + + image_interpreter& m_libcc_interpreter; + image_interpreter::va_t m_va_CSRegistrationInfoFetcher_WIN_vtable; + image_interpreter::va_t m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey; + image_interpreter::va_t m_va_iat_entry_malloc; + + std::string _build_encoded_key(const rsa_cipher& cipher); + + public: + patch_solution_since(image_interpreter& libcc_interpreter); + + [[nodiscard]] + virtual bool find_patch() override; + + [[nodiscard]] + virtual bool check_rsa_privkey(const rsa_cipher& cipher) override; + + virtual void make_patch(const rsa_cipher& cipher) override; + + }; + +} diff --git a/Navicat-Cracker/patch_solution_since_16.0.7.0.i386.cpp b/Navicat-Cracker/patch_solution_since_16.0.7.0.i386.cpp new file mode 100644 index 0000000..7a2eea8 --- /dev/null +++ b/Navicat-Cracker/patch_solution_since_16.0.7.0.i386.cpp @@ -0,0 +1,629 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "i386_emulator.hpp" +#include "keystone_assembler.hpp" +#include "patch_solution_since_16.0.7.0.hpp" +#include +#include + +namespace nkg { + + patch_solution_since<16, 0, 7, 0>::patch_solution_since(image_interpreter& libcc_interpreter) : + m_libcc_interpreter(libcc_interpreter), + m_va_CSRegistrationInfoFetcher_WIN_vtable(0), + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey(0), + m_va_iat_entry_malloc(0) {} + + bool patch_solution_since<16, 0, 7, 0>::find_patch() { + auto CSRegistrationInfoFetcher_WIN_type_descriptor_name = + m_libcc_interpreter.search_section( + ".data", + [](const uint8_t* p, size_t s) { + if (s < sizeof(".?AVCSRegistrationInfoFetcher_WIN@@")) { + return false; + } + + return strcmp(reinterpret_cast(p), ".?AVCSRegistrationInfoFetcher_WIN@@") == 0; + } + ); + + if (CSRegistrationInfoFetcher_WIN_type_descriptor_name == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 0)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor = CSRegistrationInfoFetcher_WIN_type_descriptor_name - 0x8; + + auto CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_va = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_rtti_type_descriptor); + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor = + m_libcc_interpreter.search_section( + ".rdata", + [this, CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_va](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint32_t) != 0) { + return false; + } + + if (s < sizeof(uint32_t)) { + return false; + } + + if (*reinterpret_cast(p) != CSRegistrationInfoFetcher_WIN_rtti_type_descriptor_va) { + return false; + } + + if (s < sizeof(uint32_t) * 2) { + return false; + } + + auto maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_va = reinterpret_cast(p)[1]; + + try { + return memcmp(m_libcc_interpreter.image_section_header_from_va(maybe_CSRegistrationInfoFetcher_WIN_rtti_class_hierarchy_descriptor_va)->Name, ".rdata\x00\x00", 8) == 0; + } catch (nkg::exception&) { + return false; + } + } + ); + + if (CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: RTTI info for CSRegistrationInfoFetcher_WIN is not found. (failure label 1)\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator = CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_pTypeDescriptor - 0xC; + + auto CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator); + + auto CSRegistrationInfoFetcher_WIN_vtable_before = + m_libcc_interpreter.search_section( + ".rdata", + [CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va](const uint8_t* p, size_t s) { + if (reinterpret_cast(p) % sizeof(uint32_t) != 0) { + return false; + } + + if (s < sizeof(uint32_t)) { + return false; + } + + return *reinterpret_cast(p) == CSRegistrationInfoFetcher_WIN_rtti_complete_object_locator_va; + } + ); + + if (CSRegistrationInfoFetcher_WIN_vtable_before == nullptr) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Vftable for CSRegistrationInfoFetcher_WIN is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + auto CSRegistrationInfoFetcher_WIN_vtable = + reinterpret_cast(CSRegistrationInfoFetcher_WIN_vtable_before + sizeof(uint32_t)); + + m_va_CSRegistrationInfoFetcher_WIN_vtable = m_libcc_interpreter.convert_ptr_to_va(CSRegistrationInfoFetcher_WIN_vtable); + m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = CSRegistrationInfoFetcher_WIN_vtable[6]; + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_vtable = 0x%08x\n", m_va_CSRegistrationInfoFetcher_WIN_vtable); + wprintf(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = 0x%08x\n", m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + + i386_emulator x86_emulator; + + x86_emulator.context_set("heap_base", uint32_t{ 0x7f000000 }); + x86_emulator.context_set("heap_size", size_t{ 0x1000 * 32 }); + x86_emulator.context_set("heap_records", std::map{}); + + x86_emulator.context_set("stack_base", uint32_t{ 0x7fff0000 }); + x86_emulator.context_set("stack_size", size_t{ 0x1000 * 32 }); + x86_emulator.context_set("stack_top", uint32_t{ x86_emulator.context_get("stack_base") - x86_emulator.context_get("stack_size") }); + + x86_emulator.context_set("r0_to_r3_stub_area_base", uint32_t{ 0xffffe000 }); + x86_emulator.context_set("r0_to_r3_stub_area_size", size_t{ 0x1000 }); + + x86_emulator.context_set("dead_area_base", uint32_t{ 0xfffff000 }); + x86_emulator.context_set("dead_area_size", size_t{ 0x1000 }); + + x86_emulator.context_set("iat_base", uint32_t{ m_libcc_interpreter.convert_rva_to_va(m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) }); + x86_emulator.context_set("iat_size", size_t{ m_libcc_interpreter.image_nt_headers()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size }); + + x86_emulator.context_set("external_api_stub_area_base", uint32_t{ 0x80000000 }); + x86_emulator.context_set("external_api_stub_area_size", size_t{ (x86_emulator.context_get("iat_size") / 8 + 0xfff) / 0x1000 * 0x1000 }); + + x86_emulator.context_set("external_api_impl", std::map{}); + x86_emulator.context_set("external_api_impl_area_base", uint32_t{ 0x90000000 }); + x86_emulator.context_set("external_api_impl_area_size", size_t{ 0 }); + + x86_emulator.context_set("gdt_base", uint32_t{ 0xffff0000 }); + x86_emulator.context_set("gdt_size", size_t{ 0x1000 }); + + x86_emulator.context_set("fs_base", uint32_t{ 0xa0000000 }); + x86_emulator.context_set("fs_size", size_t{ 0x1000 }); + + x86_emulator.context_set("start_address", static_cast(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey)); + x86_emulator.context_set("dead_address", x86_emulator.context_get("dead_area_base")); + + // allocate heap + x86_emulator.mem_map(x86_emulator.context_get("heap_base"), x86_emulator.context_get("heap_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate stack + x86_emulator.mem_map(x86_emulator.context_get("stack_top"), x86_emulator.context_get("stack_size"), UC_PROT_READ | UC_PROT_WRITE); + + // allocate r0_to_r3_stub area + x86_emulator.mem_map(x86_emulator.context_get("r0_to_r3_stub_area_base"), x86_emulator.context_get("r0_to_r3_stub_area_size"), UC_PROT_READ | UC_PROT_EXEC); + x86_emulator.mem_write(x86_emulator.context_get("r0_to_r3_stub_area_base"), keystone_assembler{ KS_ARCH_X86, KS_MODE_32 }.assemble("iretd;")); + + // allocate dead area + x86_emulator.mem_map(x86_emulator.context_get("dead_area_base"), x86_emulator.context_get("dead_area_size"), UC_PROT_READ | UC_PROT_EXEC); + + // allocate and hook read access to IAT + { + auto iat_base = x86_emulator.context_get("iat_base"); + auto iat_size = x86_emulator.context_get("iat_size"); + auto external_api_stub_area_base = x86_emulator.context_get("external_api_stub_area_base"); + + auto iat_page_base = iat_base / 0x1000 * 0x1000; + auto iat_page_count = (iat_base - iat_page_base + iat_size + 0xfff) / 0x1000; + + x86_emulator.mem_map(iat_page_base, iat_page_count * 0x1000, UC_PROT_READ); + + x86_emulator.hook_add( + [this, &x86_emulator, iat_base, external_api_stub_area_base](uc_mem_type type, uint32_t address, size_t size, int32_t value) { + auto rva = m_libcc_interpreter.convert_va_to_rva(address); + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(rva); + + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "memcpy") == 0) { + uint32_t impl_address = x86_emulator.context_get&>("external_api_impl")["memcpy"]; + x86_emulator.mem_write(address, &impl_address, sizeof(impl_address)); + } else { + uint32_t stub_address = external_api_stub_area_base + (address - iat_base) / sizeof(IMAGE_THUNK_DATA); + x86_emulator.mem_write(address, &stub_address, sizeof(stub_address)); + } + } else { + x86_emulator.emu_stop(); + } + }, + iat_base, + iat_base + iat_size - 1 + ); + } + + // allocate and setup external api stub area + { + auto external_api_stub_area_base = x86_emulator.context_get("external_api_stub_area_base"); + auto external_api_stub_area_size = x86_emulator.context_get("external_api_stub_area_size"); + + x86_emulator.mem_map(external_api_stub_area_base, external_api_stub_area_size, UC_PROT_READ | UC_PROT_EXEC); + x86_emulator.mem_write(external_api_stub_area_base, std::vector(external_api_stub_area_size, 0xc3)); // c3 -> ret + + x86_emulator.hook_add( + [this, &x86_emulator, external_api_stub_area_base](uint32_t address, size_t size) { + auto iat_base = x86_emulator.context_get("iat_base"); + auto from_va = iat_base + (address - external_api_stub_area_base) * sizeof(IMAGE_THUNK_DATA); + auto from_rva = m_libcc_interpreter.convert_va_to_rva(from_va); + + auto import_lookup_entry = m_libcc_interpreter.import_lookup_entry_from_rva(from_rva); + if (import_lookup_entry && !IMAGE_SNAP_BY_ORDINAL(import_lookup_entry->u1.Ordinal)) { + auto import_by_name_entry = m_libcc_interpreter.convert_rva_to_ptr(import_lookup_entry->u1.AddressOfData); + if (strcmp(import_by_name_entry->Name, "malloc") == 0) { + m_va_iat_entry_malloc = from_va; + + uint32_t esp; + x86_emulator.reg_read(UC_X86_REG_ESP, &esp); + + uint32_t alloc_size; + x86_emulator.mem_read(esp + 4, &alloc_size, sizeof(alloc_size)); + + auto& heap_records = x86_emulator.context_get&>("heap_records"); + + auto predecessor_chunk = + std::adjacent_find( + heap_records.begin(), + heap_records.end(), + [alloc_size](const auto& chunk0, const auto& chunk1) { return chunk1.first - (chunk0.first + chunk0.second) >= alloc_size; } + ); + + uint32_t alloc_p; + if (predecessor_chunk != heap_records.end()) { + alloc_p = predecessor_chunk->first + predecessor_chunk->second; + } else { + auto heap_base = x86_emulator.context_get("heap_base"); + auto heap_size = x86_emulator.context_get("heap_size"); + + auto free_space_base = heap_records.size() > 0 ? heap_records.rbegin()->first + heap_records.rbegin()->second : heap_base; + auto free_space_size = heap_base + heap_size - free_space_base; + + if (free_space_size < alloc_size) { + auto heap_expand_base = heap_base + heap_size; + auto heap_expand_size = (alloc_size - free_space_size + 0xfff) / 0x1000 * 0x1000; + x86_emulator.mem_map(heap_expand_base, heap_expand_size, UC_PROT_READ | UC_PROT_WRITE); + } + + alloc_p = free_space_base; + } + + heap_records[alloc_p] = alloc_size; + + x86_emulator.reg_write(UC_X86_REG_EAX, &alloc_p); + } else if (strcmp(import_by_name_entry->Name, "free") == 0) { + uint32_t esp; + x86_emulator.reg_read(UC_X86_REG_ESP, &esp); + + uint32_t alloc_p; + x86_emulator.mem_read(esp + 4, &alloc_p, sizeof(alloc_p)); + + auto& heap_records = x86_emulator.context_get&>("heap_records"); + + auto chunk = heap_records.find(alloc_p); + if (chunk != heap_records.end()) { + heap_records.erase(chunk); + } else { + x86_emulator.emu_stop(); + } + } else { + x86_emulator.emu_stop(); + } + } else { + x86_emulator.emu_stop(); + } + }, + external_api_stub_area_base, + external_api_stub_area_base + external_api_stub_area_size - 1 + ); + } + + // allocate and setup external api impl area + { + keystone_assembler x86_assembler{ KS_ARCH_X86, KS_MODE_32 }; + + std::map> machine_code_list = + { + std::make_pair( + "memcpy", + x86_assembler.assemble( + "push edi;" + "push esi;" + "mov eax, dword ptr [esp + 0x8 + 0x4];" + "mov edi, eax;" + "mov esi, dword ptr [esp + 0x8 + 0x8];" + "mov ecx, dword ptr [esp + 0x8 + 0xc];" + "rep movs byte ptr [edi], byte ptr [esi];" + "pop esi;" + "pop edi;" + "ret;" + ) + ) + }; + + auto& external_api_impl = x86_emulator.context_get&>("external_api_impl"); + auto& external_api_impl_area_base = x86_emulator.context_get("external_api_impl_area_base"); + auto& external_api_impl_area_size = x86_emulator.context_get("external_api_impl_area_size"); + + auto p = external_api_impl_area_base; + for (const auto& name_code_pair : machine_code_list) { + external_api_impl[name_code_pair.first] = p; + p = (p + name_code_pair.second.size() + 0xf) / 0x10 * 0x10; + } + + external_api_impl_area_size = (p + 0xfff) / 0x1000 * 0x1000 - external_api_impl_area_base; + + x86_emulator.mem_map(external_api_impl_area_base, external_api_impl_area_size, UC_PROT_READ | UC_PROT_EXEC); + for (const auto& name_code_pair : machine_code_list) { + x86_emulator.mem_write(external_api_impl[name_code_pair.first], name_code_pair.second); + } + } + + // allocate and setup GDT, segment registers + { + auto gdt_base = x86_emulator.context_get("gdt_base"); + auto gdt_size = x86_emulator.context_get("gdt_size"); + x86_emulator.mem_map(gdt_base, gdt_size, UC_PROT_READ | UC_PROT_WRITE); + + x86_emulator.create_gdt_entry(gdt_base, 0, 0, 0, 0); // null segment descriptor + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (0 << 5) -> DPL is set to 0 + // 0x10 -> code/data segment + // 0x08 -> executable segment + // !(0x4) -> not conforming code segment + // 0x02 -> code segment is readable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 1 * 0x8, 0x00000000, 0xfffff, 0x80 | (0 << 5) | 0x10 | 0x08 | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // kernel code segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (0 << 5) -> DPL is set to 0 + // 0x10 -> code/data segment + // !(0x08) -> data segment + // !(0x4) -> segment grows up + // 0x02 -> data segment is writable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 2 * 0x8, 0x00000000, 0xfffff, 0x80 | (0 << 5) | 0x10 | !(0x08) | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // kernel data segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (3 << 5) -> DPL is set to 3 + // 0x10 -> code/data segment + // 0x08 -> executable segment + // !(0x4) -> not conforming code segment + // 0x02 -> code segment is readable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 3 * 0x8, 0x00000000, 0xfffff, 0x80 | (3 << 5) | 0x10 | 0x08 | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // user code segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (3 << 5) -> DPL is set to 3 + // 0x10 -> code/data segment + // !(0x08) -> data segment + // !(0x4) -> segment grows up + // 0x02 -> data segment is writable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // 0x08 -> 4k granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + x86_emulator.create_gdt_entry(gdt_base + 4 * 0x8, 0x00000000, 0xfffff, 0x80 | (3 << 5) | 0x10 | !(0x08) | !(0x04) | 0x02 | !(0x01), 0x08 | 0x04 | !(0x01)); // user data segment + // -------------------------------------------------------- access_byte + // 0x80 -> present bit + // (3 << 5) -> DPL is set to 3 + // 0x10 -> code/data segment + // !(0x08) -> data segment + // !(0x4) -> segment grows up + // 0x02 -> data segment is writable + // !(0x01) -> accessed bit, this bit is managed by CPU + // -------------------------------------------------------- flags + // !(0x08) -> 1-byte granularity + // 0x04 -> 32-bit protected mode segment + // !(0x01) -> AVL bit is not used + auto fs_base = x86_emulator.context_get("fs_base"); + auto fs_size = x86_emulator.context_get("fs_size"); + x86_emulator.create_gdt_entry(gdt_base + 7 * 0x8, fs_base, fs_size - 1, 0x80 | (3 << 5) | 0x10 | !(0x08) | !(0x04) | 0x02 | !(0x01), !(0x08) | 0x04 | !(0x01)); // user fs segment + + uc_x86_mmr gdtr = {}; + gdtr.base = gdt_base; + gdtr.limit = gdt_base + gdt_size - 1; + x86_emulator.reg_write(UC_X86_REG_GDTR, &gdtr); + + uint16_t cs, ds, es, fs, gs, ss; + cs = (1 << 3) | (0 << 2) | (0); // use kernel code segmet + ss = (2 << 3) | (0 << 2) | (0); // use kernel data segmet + ds = es = (4 << 3) | (0 << 2) | (3); // use user data segment + fs = (7 << 3) | (0 << 2) | (3); // use user fs segment + gs = 0; // not used + + uint32_t eflags; + x86_emulator.reg_read(UC_X86_REG_EFLAGS, &eflags); + x86_emulator.reg_write(UC_X86_REG_CS, &cs); + x86_emulator.reg_write(UC_X86_REG_SS, &ss); + x86_emulator.reg_write(UC_X86_REG_DS, &ds); + x86_emulator.reg_write(UC_X86_REG_ES, &es); + x86_emulator.reg_write(UC_X86_REG_FS, &fs); + x86_emulator.reg_write(UC_X86_REG_GS, &gs); + + } + + // allocate and hook access to fs area + { + auto fs_base = x86_emulator.context_get("fs_base"); + auto fs_size = x86_emulator.context_get("fs_size"); + x86_emulator.mem_map(fs_base, fs_size, UC_PROT_READ | UC_PROT_WRITE); + + x86_emulator.hook_add( + [this, &x86_emulator, fs_base](uc_mem_type access, uint32_t address, size_t size, int64_t value) { + switch (address - fs_base) { + case 0: + if (size == 4) { + // Current Structured Exception Handling (SEH) frame, leave it NULL + } else { + x86_emulator.emu_stop(); + } + break; + default: + x86_emulator.emu_stop(); + break; + } + }, + fs_base, + fs_base + fs_size - 1 + ); + } + + // x86_emulator.hook_add([](uint32_t address, uint32_t size) { wprintf_s(L"code_trace, address = 0x%08x\n", address); }); + + x86_emulator.hook_add( + [this, &x86_emulator](uc_mem_type access, uint32_t address, size_t size, int64_t value) -> bool { + try { + auto fault_section = m_libcc_interpreter.image_section_header_from_va(address); + + auto page_base = address / 0x1000 * 0x1000; + auto page_size = 0x1000; + uint32_t page_perms = UC_PROT_NONE; + + if (fault_section->Characteristics & IMAGE_SCN_MEM_READ) { + page_perms |= UC_PROT_READ; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_WRITE) { + page_perms |= UC_PROT_WRITE; + } + if (fault_section->Characteristics & IMAGE_SCN_MEM_EXECUTE) { + page_perms |= UC_PROT_EXEC; + } + + x86_emulator.mem_map(page_base, page_size, page_perms); + x86_emulator.mem_write(page_base, m_libcc_interpreter.convert_va_to_ptr(page_base), page_size); + + return true; + } catch (::nkg::exception&) { + return false; + } + } + ); + + // set ebp, esp + uint32_t init_ebp = x86_emulator.context_get("stack_base") - x86_emulator.context_get("stack_size") / 4; + uint32_t init_esp = x86_emulator.context_get("stack_base") - x86_emulator.context_get("stack_size") / 2; + + x86_emulator.reg_write(UC_X86_REG_EBP, &init_ebp); + x86_emulator.reg_write(UC_X86_REG_ESP, &init_esp); + + // setup iretd context + uint32_t ring3_eip = x86_emulator.context_get("start_address"); + uint32_t ring3_cs = (3 << 3) | (0 << 2) | (3); // use user code segment + uint32_t ring3_eflags; x86_emulator.reg_read(UC_X86_REG_EFLAGS, &ring3_eflags); + uint32_t ring3_esp = init_esp + 5 * 4; + uint32_t ring3_ss = (4 << 3) | (0 << 2) | (3); // use user data segment + x86_emulator.mem_write(init_esp, &ring3_eip, sizeof(ring3_eip)); + x86_emulator.mem_write(init_esp + 0x4, &ring3_cs, sizeof(ring3_cs)); + x86_emulator.mem_write(init_esp + 0x8, &ring3_eflags, sizeof(ring3_eflags)); + x86_emulator.mem_write(init_esp + 0xc, &ring3_esp, sizeof(ring3_esp)); + x86_emulator.mem_write(init_esp + 0x10, &ring3_ss, sizeof(ring3_ss)); + + // set ring3 retaddr + uint32_t ring3_retaddr = x86_emulator.context_get("dead_address"); + x86_emulator.mem_write(ring3_esp, &ring3_retaddr, sizeof(ring3_retaddr)); + + // set argument registers + uint32_t init_ecx = 0; // `this` pointer of CSRegistrationInfoFetcher_WIN, but we don't need it for now. + uint32_t retval_addr = ring3_esp + 0x40; // a pointer to stack memory which stores return value + x86_emulator.reg_write(UC_X86_REG_ECX, &init_ecx); + x86_emulator.mem_write(ring3_esp + 4, &retval_addr, sizeof(retval_addr)); // write to dword ptr [ring3_esp + 4] + + // + // start emulate + // + try { + x86_emulator.emu_start(x86_emulator.context_get("r0_to_r3_stub_area_base"), x86_emulator.context_get("dead_address")); + } catch (nkg::exception&) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Code emulation failed.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: m_va_iat_entry_malloc = 0x%08x\n", m_va_iat_entry_malloc); + + // + // get result + // + // on I386 platform, `std::string` has follow memory layout: + // ------------------------------ + // | offset | size | + // ------------------------------ + // | +0 | 0x10 | `char[16]: a small string buffer` OR `char*: a large string buffer pointer` + // ------------------------------ + // | +0x10 | 0x4 | size_t: string length + // ------------------------------ + // | +0x14 | 0x4 | size_t: capacity + // ------------------------------ + // + uint32_t encoded_key_length; + x86_emulator.mem_read(retval_addr + 0x10, &encoded_key_length, sizeof(encoded_key_length)); + if (encoded_key_length != official_encoded_key.length()) { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Unexpected encoded key length(%u).\n", encoded_key_length); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + + uint32_t encoded_key_ptr; + x86_emulator.mem_read(retval_addr, &encoded_key_ptr, sizeof(encoded_key_ptr)); + + auto encoded_key = x86_emulator.mem_read(encoded_key_ptr, encoded_key_length); + if (memcmp(encoded_key.data(), official_encoded_key.data(), encoded_key.size()) == 0) { + wprintf_s(L"[+] patch_solution_since<16, 0, 7, 0>: Official encoded key is found.\n"); + return true; + } else { + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: Official encoded key is not found.\n"); + wprintf_s(L"[-] patch_solution_since<16, 0, 7, 0>: This patch solution will be suppressed.\n"); + return false; + } + } + + bool patch_solution_since<16, 0, 7, 0>::check_rsa_privkey(const rsa_cipher& cipher) { + return true; // no requirements + } + + void patch_solution_since<16, 0, 7, 0>::make_patch(const rsa_cipher& cipher) { + auto encoded_key = _build_encoded_key(cipher); + + auto CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = + m_libcc_interpreter.convert_va_to_ptr(m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey); + + std::vector patch_code_chunks; + patch_code_chunks.emplace_back("push edi;"); + patch_code_chunks.emplace_back("push esi;"); + patch_code_chunks.emplace_back("push ebx;"); + patch_code_chunks.emplace_back("push ebp;"); + patch_code_chunks.emplace_back("mov ebp, esp;"); + patch_code_chunks.emplace_back("call label; label: pop ebx; sub ebx, label;"); // ebx <- relocation shift value + patch_code_chunks.emplace_back(fmt::format("mov eax, {:#08x};", m_va_iat_entry_malloc)); + patch_code_chunks.emplace_back("add eax, ebx;"); + patch_code_chunks.emplace_back("mov eax, dword ptr [eax];"); // eax <- address of `malloc` + patch_code_chunks.emplace_back(fmt::format("push {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("call eax;"); + patch_code_chunks.emplace_back("add esp, 0x4;"); + { + std::vector push_values((encoded_key.length() + 1 + 3) / 4, 0); + memcpy(push_values.data(), encoded_key.data(), encoded_key.length()); + std::for_each(push_values.crbegin(), push_values.crend(), [&patch_code_chunks](uint32_t x) { patch_code_chunks.emplace_back(fmt::format("push {:#08x};", x)); }); + } + patch_code_chunks.emplace_back("mov edi, eax;"); + patch_code_chunks.emplace_back("mov esi, esp;"); + patch_code_chunks.emplace_back(fmt::format("mov ecx, {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("rep movs byte ptr [edi], byte ptr [esi];"); + patch_code_chunks.emplace_back("mov edx, dword ptr [ebp + 0x14];"); + patch_code_chunks.emplace_back("mov dword ptr [edx], eax;"); + patch_code_chunks.emplace_back(fmt::format("mov dword ptr [edx + 0x10], {:#x};", encoded_key.length())); + patch_code_chunks.emplace_back(fmt::format("mov dword ptr [edx + 0x14], {:#x};", encoded_key.length() + 1)); + patch_code_chunks.emplace_back("mov eax, edx;"); + patch_code_chunks.emplace_back("leave;"); + patch_code_chunks.emplace_back("pop ebx;"); + patch_code_chunks.emplace_back("pop esi;"); + patch_code_chunks.emplace_back("pop edi;"); + patch_code_chunks.emplace_back("ret 4;"); + + std::vector assembled_patch_code; + { + keystone_assembler x86_assembler{ KS_ARCH_X86, KS_MODE_32 }; + + auto current_va = m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey; + auto next_reloc = m_libcc_interpreter.relocation_distribute().lower_bound(m_libcc_interpreter.convert_va_to_rva(current_va)); + for (const auto& patch_code_chunk : patch_code_chunks) { + auto assembled_patch_code_chunk = x86_assembler.assemble(patch_code_chunk, current_va); + + while (true) { + auto next_reloc_va = m_libcc_interpreter.convert_rva_to_va(next_reloc->first); + auto next_reloc_size = next_reloc->second; + + if (current_va + assembled_patch_code_chunk.size() + 2 <= next_reloc_va) { // 2 -> size of machine code "jmp rel8" + assembled_patch_code.insert(assembled_patch_code.end(), assembled_patch_code_chunk.begin(), assembled_patch_code_chunk.end()); + current_va += assembled_patch_code_chunk.size(); + break; + } else if (current_va + 2 <= next_reloc_va) { + auto next_va = next_reloc_va + next_reloc_size; + auto assembled_jmp = x86_assembler.assemble(fmt::format("jmp {:#08x};", next_va), current_va); + auto assembled_padding = std::vector(next_va - (current_va + assembled_jmp.size()), 0xcc); // 0xcc -> int3 + assembled_patch_code.insert(assembled_patch_code.end(), assembled_jmp.begin(), assembled_jmp.end()); + assembled_patch_code.insert(assembled_patch_code.end(), assembled_padding.begin(), assembled_padding.end()); + current_va = next_va; + ++next_reloc; + } else { + __assume(false); // impossible to reach here + } + } + } + } + + memcpy(CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey, assembled_patch_code.data(), assembled_patch_code.size()); + wprintf_s(L"[*] patch_solution_since<16, 0, 7, 0>: Patch has been done.\n"); + } + +} diff --git a/Navicat-Cracker/pch.cpp b/Navicat-Cracker/pch.cpp new file mode 100644 index 0000000..b6fb8f4 --- /dev/null +++ b/Navicat-Cracker/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: 与预编译标头对应的源文件 + +#include "pch.h" + +// 当使用预编译的头时,需要使用此源文件,编译才能成功。 diff --git a/Navicat-Cracker/pch.h b/Navicat-Cracker/pch.h new file mode 100644 index 0000000..9660927 --- /dev/null +++ b/Navicat-Cracker/pch.h @@ -0,0 +1,13 @@ +// pch.h: 这是预编译标头文件。 +// 下方列出的文件仅编译一次,提高了将来生成的生成性能。 +// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 +// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 +// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 + +#ifndef PCH_H +#define PCH_H + +// 添加要在此处预编译的标头 +#include "framework.h" + +#endif //PCH_H diff --git a/Navicat-Cracker/res/620.png b/Navicat-Cracker/res/620.png new file mode 100644 index 0000000000000000000000000000000000000000..90500bea8b68278269ff15b802639485988a10db GIT binary patch literal 95407 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± z+GjKo2S30yzx^$O)bb+1kcnCmc&@9Dp=HJl z6v%Mn)ZWv{1Tv`HAeb{BO$j_qg)Eu_Rzs zdr^_1tsVH^)`@>t8vEK8-11+qF^MkA14AgMliVmkDWJ71tz?Rm6s*PN2V&tbeu9=I zi=P+Iy{G7!-~7h?5VN2611#7`UrgTD_=liVi1bR)$(a!upiE&n^D=gfgL^$ zhk(^bAfgHhPPT|*JZ>ydIf5C1)-u713Z%p*5}5h=mtnyh{~t<|l+B7X27%b00P1VR(jJ~*D4pNY!XcIep&*}6XcEk z=2vhtd6S#3BCEa<5R;!d*!}@-EE%&?jpXic}!@bV@~dI60K(#ALZuq((4+ zK*ww=-{0j1JNJ*Mmlpz!U3!V@+*gH(Ch{Ms|`R`+;Om*#ayUu#0(N3fD=b~ZGY`C)WRU8D~@D|j+ z>=jmi`(`S0WO`&Up}AF{BuevKYkY*vIAe-DdxB9|0fJaYTYx`(ona3*FN1e~Ze*1d3a>o3Spp-vWhk#uq@Qz6Ft& zz61w-`y2c1JKLA^`X$TVU0pjdeda7QG&keCFMS?IoOF_vS@)o85gdVUzLH8JclSN8 zy1G$GrmDV6lo3+SjE_>Wh(e)&;$#x}bOxnd7MYO*Vn-cx>+OiaQV z=A6rt_h=WvjPbeh^O^)mo|ZOX-a^!^IPeMYEVu4{x58^1(wdsgG#rQhzq|1I<-d6AtfFnE}kK=INM@@DaygFki$6U-nXt z?E>GKi`E&P7#kc!a%_y6VHO2W8H!4C4HdamGC3a^il16o)3j*_M#5$}Z!(*JpU0f= z%2(sG|9B%#c*QeYvfH01e*b-L*PC8nP4GvmTfP8|GiFxv3=uqpUiu0I&o~24V%+5I zG0qdgF#k@VLWN7whVriP1gd@oxt7i0G#w)8Fgv=4Jz*77k3CdAY!O*ExBCLJ9I8nJz?H_ zShHut<~)x*&JvyJ?Q)Sz6D<9&NF;ryMqf!Lt3s-&$p|x1Wct1-9Gu<0!!2&zV65p% z*yvPB$c|1Tlg*pd0kNZwz_gW5Z`t>SMnC$*r`(Ib`Zdg&zYx*Jdc5f~pTu!5Kg0A@ zmZ02?kDH}3;%AiCu19grgT`^&j0ri!Q|Oj$7v-FT0_RdOoklUv&ukWv!w~oc%(;ezXC9Mcxwn4Irz{}g* zh>1MLxkA3{Fv4|2Ry z$t<%im0$=hvuBvdLtd5RTtF{??5w#+g~GV%#+&iy8*c-l))OpK>Kmi9?FaO%z*J^v zmn%P$$tx~G`o3GCTq7l=nzutJ$?Lw-nUF|Ur}o7dN;rB9u&53 zAmbS^3Es*?`jsNJ3z1^}SUoxy%td?0bZf_^P44>p?n5iV z)lsLO`fvYUM{m2`?K$^NhIt4~hMlZ%s4rzo3loKfALnS1Ckxt~tA3?6?YSbV6eiZv} zLj9sQ?6bbi?%3>lG6}=hjW47CBSE5oj{s#^q3)(sQ4$vCxm+Ghg2dGa!!xZD-UUmc z%+a7A)OlKlDUOby)ZGJzU|rd;J+=f2L1vnLn#-GF*52bzfW2q|2VfcDnKdi+zNTc? zHn&U#*-55N)S8y$Y_A{Qj&?My`g=N+&Fj{=Z#(=*G&Z*&R$q_Te)xlU#d%LG`HnNgP7{q@`t% z&Y=>ca#f~IC+C(DmRg!y{@|1P?3xrSn;(UfA&AQ7;cBT`{!tvGDljZkuBN{0Z^rn# zZM>G>_*Dg*GLLrICnO3?bC48O}F8YC{==Wqa`e&r&l5jKGau^?{i>i@_4v;J@D2yA+%&A+Rl6v>JK~S1=nx;8{KmG#` zqszJ!WCR1Jo&5$={PUn=Us&UN^!8ibUFZG>nI@UDtV}XKQSxuvovtC48i^;qgFD($F$G-7%{{K z_}h;sWA>vsydI774%;VvpL^s!*D~SkY!~OS$q!WIb4saX}FyOG(*laqQ!XeS+B)AzWDhkeRl#>NK9~&P<~b_CO=%My9*xW#!~{(0Ko+JyA=YZ z_BI4pt%5Bpt{gl?k-C3rbt7~Covy14=1Kybrecs5n4$ti0H@qy@{w|~1?1v!j6b{y ziLsPf&hv8)*yM|SO}8$2*hnFC;KE;pFkw_k9>2`2N$#GZpHX zX_bpv6uP%^z(n9_ZiIjSB6#P_f}PHjE99a2M0TMF|FrfOB#;`v@y~Ad;ajOqQoGc8 zsFpB7A(M5tM9o1ASd+oj^me?|GB_;q+_aL!!Ah+c<2PJk%&k+GtkFKAD}VYkz9%vY zIdJk_Di6tF#~+WM+;tny|Mi8|3k^t#v@{@)Q;`BdBp?S?E$0p0^&krAEWAcTk?N>Fvn%Tvct*b4=;(Ev};2b{BIcqBQw^T&12a^LsW6J4>OezbRZT<>tw9BY&*) z^csg=)p>)Klfxmz@4O3RSN;WgB}7b3phEuY>be4I1ZkC$`bx_^l(B^@@>l#G*&lre zse5m)@rUP-v>ZF~qi?wJFMkrLEB*(?%^Q*L?MAM<7x}>hE%;)js0aS?mej7dlA)n7iAfh^eRE9iMkT_?JEYz_T@r`QQmw<^h9*X2k0{vS00o#P+FNji~zn|AWe@I2i?*W?ch()20(p zH3Jg~GCMLn8R3+szK}-!A%|8^cmdJ)&6l}_U0aM`&>(WDDJXp0;-(^(mXf_SwV>S8 zgkoboD*h0A%tx?IOz$WRU(pd6L=QW@mO5b{(-lAag?rBpHzMW@nx(8F1zVY#*4w}M zd8|0>@E7d6X zIiSgFE^`xK`~*sO+@t|YNogUkQ)_M1*gxl z!m}5cM7<^v>Ay%$atxKp2~#OSWn)aT&Afu8IIcNf^*pkUTC!4cA0ZJM+8a?93qXa4 zD+EWQwhx)6FcP5V*p83L#> z#}n~=$tL41qvO1fqV43DzhH&+{y;xE|I_Z5-ti8ox>c&2N1B4Msjbzx#yooSty4$6 za4CHJ@o)(mOtDmBp{iQ%iUZ>q+`5y1DPPqhyLY0zeFrB80SE<-0SYQbQc$>c&V*HK z8Nns6s+7pU70IUPAo(6qIF&|6P#)-q6CX3d8^yt1l!gdKNaH*1aCHUUV>a-IAVmpKb3|z&2f@Rn+)OUo<2+~ z6>!LlUi6Ikx+)t?eckJ1kB{(SCs0lhPz?;i>F!3ke*o?{|DFoKQ6zH3r2-+VE9bBZ zMMSAr23A?!6#+Ji_P5|O zjpDejM(GK1Rr!gpsR?P`^Y%3lBT0ozK|R_}32NHA8^G*qG7FL(A}IcsWqTFTUETjQ zNW~a6nWa5C1W{VA^#sGPo9YmZ*@zK5_-4#R^BHHpU;sgK=LWYjK4i3Pazd1e=(V0+ z*tHXd9ovyxzZS){>rmd>3wP@%+#Qp!<5gzqDN##R-VSQ^Ge7lZOgr=SH6XQ*sBh;^ z_kE|F>i+DDUw}>RC{9qk{P4qY!AIVU@4oeo_`ft-l3I z(kY`IJJ}59!z7%YJK#=^^E<)S#FzGq-f(l_n2T zj(|S3YXrr~Ed1#tLXvZ`pU8naWFrvpBcOuE9JhV~YcG%SOiY@B&l>ZJX5F93`1{G1 zSId=JeKN94%1@@6%7o)t4(C2EWq-vnNjuAhB!Zp>R3fctJFXS;4w#4T4UK4=I|H%l z9jH5a0fwSsSVy-Z_R2;o1RS><*JTA|NHLh&Yo8CUG3?REa^{1{}*60{-2z{1-4%Wm=8br5S(((+2*&W1*Qa? zJVfB8BRKKBMC;yIJ^Ya-L^Q`UNkm?IR`uW)2vx?0s8P!ogxa;1E+_z$8bT2krm{K* zDB>KTBb-o4GG7rjdKGK5mEd+ct#s$Adln&_hRfPKf>6W2cCMiJx{55^=d16?DAs zxhqV(Y^-m&s?UckNgke~l0GGYE(#{sAwcZG_8cdpWu=;4_d2_sRoWcEih#%3MCRV4Yh-js_zs5m0za7 zv_2Fj$81`<|sA)+c8Pzp}a1IRL0brqH+ai zB8AM&w^UDl0aDYO&Z%0aIJULiXF$W0!+;4w;lBWxV?$HS)HpPth?|_W%PHl^i4#c0 z37{s(lnIn32rd-qS}3Eqs~b*Vw-HJPtYoT@uu59E+s6tDyDp?mLD+l`=ipu>`9>M- zSnq+N~66GlrLEK}2l>DUxoZuK%Pkx}b@<-182tXfwpxV&AL`u{;_4Nfo zlb2uOI&1Dn#TPQ=TV!eUldpTn#yB2}hL6if%3}X}k}3EmC-|9whhtmsQ~?>v9-c2( z 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 Wu`o+VH0BBb0000~&oaYoD26m$lb@ulu>z+WVY$ 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 K>At7^{Qf^TcqMZH literal 0 HcmV?d00001 diff --git a/Navicat-Cracker/res/NavicatCracker.rc2 b/Navicat-Cracker/res/NavicatCracker.rc2 new file mode 100644 index 0000000000000000000000000000000000000000..633e0a3d9815154ae18b2532e6f331e0c8c23f09 GIT binary patch literal 686 zcmd5(y9&ZU5S+qFNNZsgunC9>_y=MvBzO^@ScxVEBt9T&S}g=CQUAb3@B_t0e9T3H zt#-2P@bc0Y+HN-s6TIu9+u literal 0 HcmV?d00001 diff --git a/Navicat-Cracker/resource.h b/Navicat-Cracker/resource.h new file mode 100644 index 0000000..30be997 --- /dev/null +++ b/Navicat-Cracker/resource.h @@ -0,0 +1,46 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 供 NavicatCracker.rc 使用 +// +#define IDM_ABOUTBOX 0x0010 +#define IDD_ABOUTBOX 100 +#define IDS_ABOUTBOX 101 +#define IDD_NavicatCracker_DIALOG 102 +#define IDB_PNG1 134 +#define IDI_ICON1 135 +#define IDR_MAINFRAME 135 +#define IDC_InstallPath 1000 +#define IDC_PatchBTN 1001 +#define IDC_VersionBox 1002 +#define IDC_ProductionBox 1003 +#define IDC_LanguageBox 1004 +#define IDC_Key 1005 +#define IDC_GenerateBTN 1006 +#define IDC_CopyBTN 1007 +#define IDC_UserName 1008 +#define IDC_Organ 1009 +#define IDC_RequestCode 1011 +#define IDC_ActivationCode 1012 +#define IDC_GenActBTN 1013 +#define IDC_CheckKey 1015 +#define IDC_KeyFile 1016 +#define IDC_OpenKeyBTN 1017 +#define IDC_OpenPath 1018 +#define IDC_ADVANCE 1019 +#define IDC_ProdHex 1020 +#define IDC_LangHex1 1021 +#define IDC_LangHex2 1022 +#define IDC_About 1024 +#define IDC_hosts 1025 +#define IDC_Logo 1026 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 136 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1029 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Navicat-Cracker/targetver.h b/Navicat-Cracker/targetver.h new file mode 100644 index 0000000..79934a3 --- /dev/null +++ b/Navicat-Cracker/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 + +//如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并 +// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 + +#include diff --git a/README.md b/README.md index b4b0a31..77bede2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,38 @@ -# NavicatCrack +![screenshot](doc/screenshot.png) +------------------ +# navicat-keygen + +[中文版README](README.zh-CN.md) + +This repository will tell you how Navicat offline activation works. + +Previous previous code is archived in [`windows-archived`](https://notabug.org/doublesine/navicat-keygen/src/windows-archived) branch for the reason that previous previous code contains 3rd binary libraries and it gets quite big :-( + +Previous code is archived in [`windows-archived2`](https://notabug.org/doublesine/navicat-keygen/src/windows-archived2) branch for the reason that Navicat has come to version 16.x.x which I think should be a milestone and I decide to obsolete previous code and rewrite new one. + +When you git-clone this repo, please add `--single-branch` flag so that archived branches won't be cloned to your computer, which saves your time and disk. + +```console +$ git clone -b windows --single-branch https://notabug.org/doublesine/navicat-keygen.git +``` + +## 1. How does it work? + +see [here](doc/how-does-it-work.md). (WATING TO BE UPDATED) + +## 2. How to build? + +see [here](doc/how-to-build.md). + +## 3. How to use? + +see [here](doc/how-to-use.md). + +## 4. Contributor + +* Deltafox79 + +* dragonflylee + +* zenuo diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..089f386 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,34 @@ +# navicat-keygen for windows + +这份repo将会告诉你Navicat是怎么完成离线激活的。 + +第一次归档的代码位于 [`windows-archived`](https://notabug.org/doublesine/navicat-keygen/src/windows-archived) 分支。归档原因:包含第三方二进制库,项目过大。 + +第二次归档的代码位于 [`windows-archived2`](https://notabug.org/doublesine/navicat-keygen/src/windows-archived2) 分支。归档原因:Navicat进入16.x.x版本,本项目打算进行重构。 + +当你clone该仓库的时候,请使用 `--single-branch` 选项,以此避免clone到已被归档的分支、以及节省你的时间和磁盘空间。 + +```console +$ git clone -b windows --single-branch https://notabug.org/doublesine/navicat-keygen.git +``` + +## 1. 注册机是怎么工作的? + +见[这里](doc/how-does-it-work.zh-CN.md)。 + +## 2. 如何编译? + +见[这里](doc/how-to-build.zh-CN.md)。 + +## 3. 如何使用这个注册机? + +见[这里](doc/how-to-use.zh-CN.md)。 + +## 4. 贡献者 + +* Deltafox79 + +* dragonflylee + +* zenuo + diff --git a/common/common.vcxitems b/common/common.vcxitems new file mode 100644 index 0000000..d36b4dd --- /dev/null +++ b/common/common.vcxitems @@ -0,0 +1,59 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + {6d81a756-475a-4093-919e-3e9217f662ca} + + + + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + \ No newline at end of file diff --git a/common/common.vcxitems.user b/common/common.vcxitems.user new file mode 100644 index 0000000..966b4ff --- /dev/null +++ b/common/common.vcxitems.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/common/cp_converter.hpp b/common/cp_converter.hpp new file mode 100644 index 0000000..0a38f3b --- /dev/null +++ b/common/cp_converter.hpp @@ -0,0 +1,79 @@ +#pragma once +#include +#include +#include "exceptions/win32_exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\common\\cp_converter.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + template + struct cp_converter { + static std::string convert(std::string_view from_string) { + if constexpr (from_cp == to_cp) { + return from_string; + } else { + if (from_cp == CP_ACP && GetACP() == to_cp) { + return from_string; + } else { + return cp_converter<-1, to_cp>::convert(cp_converter::convert(from_string)); + } + } + } + }; + + template + struct cp_converter { + static std::wstring convert(std::string_view from_string) { + int len; + + len = MultiByteToWideChar(from_cp, 0, from_string.data(), -1, NULL, 0); + if (len <= 0) { + throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"MultiByteToWideChar failed."); + } + + std::wstring to_string(len, 0); + + len = MultiByteToWideChar(from_cp, 0, from_string.data(), -1, to_string.data(), len); + if (len <= 0) { + throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"MultiByteToWideChar failed."); + } + + while (to_string.length() > 0 && to_string.back() == 0) { + to_string.pop_back(); + } + + return to_string; + } + }; + + template + struct cp_converter<-1, to_cp> { + static std::string convert(std::wstring_view from_string) { + int len; + + len = WideCharToMultiByte(to_cp, 0, from_string.data(), -1, NULL, 0, NULL, NULL); + if (len <= 0) { + throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"WideCharToMultiByte failed."); + } + + std::string to_string(len, 0); + + len = WideCharToMultiByte(to_cp, 0, from_string.data(), -1, to_string.data(), len, NULL, NULL); + if (len <= 0) { + throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"WideCharToMultiByte failed."); + } + + while (to_string.length() > 0 && to_string.back() == 0) { + to_string.pop_back(); + } + + return to_string; + } + }; + +} + +#undef NKG_CURRENT_SOURCE_LINE +#undef NKG_CURRENT_SOURCE_FILE diff --git a/common/exception.hpp b/common/exception.hpp new file mode 100644 index 0000000..385447a --- /dev/null +++ b/common/exception.hpp @@ -0,0 +1,86 @@ +#pragma once +#include +#include +#include + +namespace nkg { + + class exception : public std::exception { + private: + int m_source_line; + std::string m_source_file; + std::string m_custom_message; + std::vector m_hints; + + public: + [[noreturn]] + static void trap_then_terminate() { +#if _MSC_VER + __debugbreak(); +#elif defined(__GNUC__) || defined(__GNUG__) || defined(__clang__) + __builtin_trap(); + +#else +#error "exception.hpp: unknown compiler is detected." +#endif + std::terminate(); + } + + exception(std::string_view file, int line, std::string_view message) noexcept : + std::exception(), // don't pass `char*` to `std::exception`, because it is not documented in c++ standard. + m_source_line(line), + m_source_file(file), + m_custom_message(message) {} + + [[nodiscard]] + int source_line() const noexcept { + return m_source_line; + } + + [[nodiscard]] + const std::string& source_file() const noexcept { + return m_source_file; + } + + [[nodiscard]] + const std::string& custom_message() const noexcept { + return m_custom_message; + } + + exception& push_hint(std::string_view hint) noexcept { + m_hints.emplace_back(hint); + return *this; + } + + exception& pop_hint() noexcept { + m_hints.pop_back(); + return *this; + } + + const std::vector& hints() const noexcept { + return m_hints; + } + + virtual const char* what() const noexcept override { + return m_custom_message.c_str(); + } + + [[nodiscard]] + virtual bool error_code_exists() const noexcept { + return false; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept { + trap_then_terminate(); + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept { + trap_then_terminate(); + } + + virtual ~exception() = default; + }; + +} \ No newline at end of file diff --git a/common/exceptions/index_exception.hpp b/common/exceptions/index_exception.hpp new file mode 100644 index 0000000..568aa30 --- /dev/null +++ b/common/exceptions/index_exception.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "../exception.hpp" + +namespace nkg::exceptions { + + class index_exception : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} diff --git a/common/exceptions/key_exception.hpp b/common/exceptions/key_exception.hpp new file mode 100644 index 0000000..933f8e1 --- /dev/null +++ b/common/exceptions/key_exception.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "../exception.hpp" + +namespace nkg::exceptions { + + class key_exception : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} diff --git a/common/exceptions/not_implemented_exception.hpp b/common/exceptions/not_implemented_exception.hpp new file mode 100644 index 0000000..66990d3 --- /dev/null +++ b/common/exceptions/not_implemented_exception.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "../exception.hpp" + +namespace nkg::exceptions { + + class not_implemented_exception : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} diff --git a/common/exceptions/openssl_exception.cpp b/common/exceptions/openssl_exception.cpp new file mode 100644 index 0000000..d2c879a --- /dev/null +++ b/common/exceptions/openssl_exception.cpp @@ -0,0 +1,20 @@ +#include "openssl_exception.hpp" +#include + +#pragma comment(lib, "libcrypto") +#pragma comment(lib, "crypt32") // required by libcrypto.lib +#pragma comment(lib, "ws2_32") // required by libcrypto.lib + +namespace nkg::exceptions { + + openssl_exception::openssl_exception(std::string_view file, int line, error_code_t openssl_error_code, std::string_view message) noexcept : + ::nkg::exception(file, line, message) + { + static std::once_flag onceflag_load_crypto_strings; + std::call_once(onceflag_load_crypto_strings, []() { ERR_load_crypto_strings(); }); + + m_error_code = openssl_error_code; + m_error_string = ERR_reason_error_string(m_error_code); + } + +} diff --git a/common/exceptions/openssl_exception.hpp b/common/exceptions/openssl_exception.hpp new file mode 100644 index 0000000..e34f158 --- /dev/null +++ b/common/exceptions/openssl_exception.hpp @@ -0,0 +1,34 @@ +#pragma once +#include "../exception.hpp" +#include + +namespace nkg::exceptions { + + class openssl_exception final : public ::nkg::exception { + public: + using error_code_t = decltype(ERR_get_error()); + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + openssl_exception(std::string_view file, int line, error_code_t openssl_error_code, std::string_view message) noexcept; + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + +} diff --git a/common/exceptions/operation_canceled_exception.hpp b/common/exceptions/operation_canceled_exception.hpp new file mode 100644 index 0000000..b395175 --- /dev/null +++ b/common/exceptions/operation_canceled_exception.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "../exception.hpp" + +namespace nkg::exceptions { + + class operation_canceled_exception : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} diff --git a/common/exceptions/overflow_exception.hpp b/common/exceptions/overflow_exception.hpp new file mode 100644 index 0000000..216e860 --- /dev/null +++ b/common/exceptions/overflow_exception.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "../exception.hpp" + +namespace nkg::exceptions { + + class overflow_exception : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} diff --git a/common/exceptions/win32_exception.cpp b/common/exceptions/win32_exception.cpp new file mode 100644 index 0000000..76643f5 --- /dev/null +++ b/common/exceptions/win32_exception.cpp @@ -0,0 +1,30 @@ +#include "win32_exception.hpp" +#include "../resource_wrapper.hpp" +#include "../resource_traits/win32/local_alloc.hpp" +#include "../cp_converter.hpp" + +namespace nkg::exceptions { + + win32_exception::win32_exception(std::string_view file, int line, error_code_t win32_error_code, std::string_view message) noexcept : + ::nkg::exception(file, line, message) + { + m_error_code = win32_error_code; + + ::nkg::resource_wrapper error_string{ ::nkg::resource_traits::win32::local_alloc{} }; + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, + win32_error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + error_string.template unsafe_addressof(), + 0, + NULL + ); + if (error_string.is_valid()) { + m_error_string = ::nkg::cp_converter<-1, CP_UTF8>::convert(error_string.template as()); + } else { + std::terminate(); + } + } + +} diff --git a/common/exceptions/win32_exception.hpp b/common/exceptions/win32_exception.hpp new file mode 100644 index 0000000..98ec4b1 --- /dev/null +++ b/common/exceptions/win32_exception.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "../exception.hpp" +#include + +namespace nkg::exceptions { + + class win32_exception final : public ::nkg::exception { + public: + using error_code_t = decltype(GetLastError()); + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + + win32_exception(std::string_view file, int line, error_code_t win32_error_code, std::string_view message) noexcept; + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return true; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + return m_error_code; + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + return m_error_string; + } + }; + +} diff --git a/common/resource_traits/cxx_dynamic_array_traits.hpp b/common/resource_traits/cxx_dynamic_array_traits.hpp new file mode 100644 index 0000000..15132ed --- /dev/null +++ b/common/resource_traits/cxx_dynamic_array_traits.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace nkg::resource_traits { + + template + struct cxx_dynamic_array_traits { + using handle_t = element_t*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + delete[] handle; + } + }; + +} diff --git a/common/resource_traits/cxx_object_traits.hpp b/common/resource_traits/cxx_object_traits.hpp new file mode 100644 index 0000000..d0ddee1 --- /dev/null +++ b/common/resource_traits/cxx_object_traits.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace nkg::resource_traits { + + template + struct cxx_object_traits { + using handle_t = object_t*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + delete handle; + } + }; + +} diff --git a/common/resource_traits/keystone/keystone_handle.hpp b/common/resource_traits/keystone/keystone_handle.hpp new file mode 100644 index 0000000..9c88276 --- /dev/null +++ b/common/resource_traits/keystone/keystone_handle.hpp @@ -0,0 +1,35 @@ +#pragma once +#include + +namespace nkg::resource_traits::keystone { + + struct keystone_handle { + using handle_t = ks_engine*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + ks_close(handle); + } + }; + + struct keystone_alloc { + using handle_t = unsigned char*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + ks_free(handle); + } + }; +} diff --git a/common/resource_traits/openssl/bignum.hpp b/common/resource_traits/openssl/bignum.hpp new file mode 100644 index 0000000..17584b8 --- /dev/null +++ b/common/resource_traits/openssl/bignum.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct bignum { + using handle_t = BIGNUM*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + BN_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/bio.hpp b/common/resource_traits/openssl/bio.hpp new file mode 100644 index 0000000..fa4e387 --- /dev/null +++ b/common/resource_traits/openssl/bio.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct bio { + using handle_t = BIO*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + BIO_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/bio_chain.hpp b/common/resource_traits/openssl/bio_chain.hpp new file mode 100644 index 0000000..cf321a5 --- /dev/null +++ b/common/resource_traits/openssl/bio_chain.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct bio_chain { + using handle_t = BIO*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + BIO_free_all(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/decoder_ctx.hpp b/common/resource_traits/openssl/decoder_ctx.hpp new file mode 100644 index 0000000..7bd7dd7 --- /dev/null +++ b/common/resource_traits/openssl/decoder_ctx.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct decoder_ctx { + using handle_t = OSSL_DECODER_CTX*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + OSSL_DECODER_CTX_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/encoder_ctx.hpp b/common/resource_traits/openssl/encoder_ctx.hpp new file mode 100644 index 0000000..2d484dd --- /dev/null +++ b/common/resource_traits/openssl/encoder_ctx.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct encoder_ctx { + using handle_t = OSSL_ENCODER_CTX*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + OSSL_ENCODER_CTX_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/evp_cipher_ctx.hpp b/common/resource_traits/openssl/evp_cipher_ctx.hpp new file mode 100644 index 0000000..b38c8c9 --- /dev/null +++ b/common/resource_traits/openssl/evp_cipher_ctx.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct evp_cipher_ctx { + using handle_t = EVP_CIPHER_CTX*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + EVP_CIPHER_CTX_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/evp_pkey.hpp b/common/resource_traits/openssl/evp_pkey.hpp new file mode 100644 index 0000000..52d70e3 --- /dev/null +++ b/common/resource_traits/openssl/evp_pkey.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct evp_pkey { + using handle_t = EVP_PKEY*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + EVP_PKEY_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/evp_pkey_ctx.hpp b/common/resource_traits/openssl/evp_pkey_ctx.hpp new file mode 100644 index 0000000..96c9f0d --- /dev/null +++ b/common/resource_traits/openssl/evp_pkey_ctx.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct evp_pkey_ctx { + using handle_t = EVP_PKEY_CTX*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + EVP_PKEY_CTX_free(handle); + } + }; + +} diff --git a/common/resource_traits/openssl/rsa.hpp b/common/resource_traits/openssl/rsa.hpp new file mode 100644 index 0000000..3b9f49a --- /dev/null +++ b/common/resource_traits/openssl/rsa.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::openssl { + + struct rsa { + using handle_t = RSA*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) noexcept { + RSA_free(handle); + } + }; + +} diff --git a/common/resource_traits/unicorn/unicorn_handle.hpp b/common/resource_traits/unicorn/unicorn_handle.hpp new file mode 100644 index 0000000..67fc254 --- /dev/null +++ b/common/resource_traits/unicorn/unicorn_handle.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::unicorn { + + struct unicorn_handle { + using handle_t = uc_engine*; + + static constexpr handle_t invalid_value = nullptr; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + uc_close(handle); + } + }; + +} diff --git a/common/resource_traits/win32/file_handle.hpp b/common/resource_traits/win32/file_handle.hpp new file mode 100644 index 0000000..0f1aafc --- /dev/null +++ b/common/resource_traits/win32/file_handle.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::win32 { + + struct file_handle { + using handle_t = HANDLE; + + static inline const handle_t invalid_value = INVALID_HANDLE_VALUE; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + CloseHandle(handle); + } + }; + +} diff --git a/common/resource_traits/win32/generic_handle.hpp b/common/resource_traits/win32/generic_handle.hpp new file mode 100644 index 0000000..dc0dd85 --- /dev/null +++ b/common/resource_traits/win32/generic_handle.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::win32 { + + struct generic_handle { + using handle_t = HANDLE; + + static constexpr handle_t invalid_value = NULL; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + CloseHandle(handle); + } + }; + +} diff --git a/common/resource_traits/win32/local_alloc.hpp b/common/resource_traits/win32/local_alloc.hpp new file mode 100644 index 0000000..f593736 --- /dev/null +++ b/common/resource_traits/win32/local_alloc.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::win32 { + + struct local_alloc { + using handle_t = HLOCAL; + + static constexpr handle_t invalid_value = NULL; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t handle) { + LocalFree(handle); + } + }; + +} diff --git a/common/resource_traits/win32/map_view_ptr.hpp b/common/resource_traits/win32/map_view_ptr.hpp new file mode 100644 index 0000000..a8b848d --- /dev/null +++ b/common/resource_traits/win32/map_view_ptr.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace nkg::resource_traits::win32 { + + struct map_view_ptr { + using handle_t = PVOID; + + static constexpr handle_t invalid_value = NULL; + + [[nodiscard]] + static bool is_valid(const handle_t& handle) noexcept { + return handle != invalid_value; + } + + static void release(const handle_t& handle) { + UnmapViewOfFile(handle); + } + }; + +} diff --git a/common/resource_wrapper.hpp b/common/resource_wrapper.hpp new file mode 100644 index 0000000..9181c67 --- /dev/null +++ b/common/resource_wrapper.hpp @@ -0,0 +1,245 @@ +#pragma once +#include +#include + +namespace nkg { + + template + class resource_wrapper { + public: + using handle_t = typename resource_traits_t::handle_t; + static_assert(std::is_trivial_v && std::is_standard_layout_v, "`resource_wrapper` requires a handle with POD type."); + + private: + handle_t m_handle; + releaser_t m_releaser; + + public: + template + resource_wrapper(releaser_arg_t&& releaser) noexcept : + m_handle(resource_traits_t::invalid_value), + m_releaser(std::forward(releaser)) {} + + template + resource_wrapper(const handle_t& handle, releaser_arg_t&& releaser) noexcept : + m_handle(handle), + m_releaser(std::forward(releaser)) {} + + template + resource_wrapper(resource_traits_t, releaser_arg_t&& releaser) noexcept : + m_handle(resource_traits_t::invalid_value), + m_releaser(std::forward(releaser)) {} + + template + resource_wrapper(resource_traits_t, const handle_t& handle, releaser_arg_t&& releaser) noexcept : + m_handle(handle), + m_releaser(std::forward(releaser)) {} + + // + // `resource_wrapper` does not allow copy-construct + // + resource_wrapper(const resource_wrapper& other) = delete; + + // + // `resource_wrapper` allows move-construct. + // + resource_wrapper(resource_wrapper&& other) noexcept : + m_handle(other.m_handle), + m_releaser(std::move(other.m_releaser)) + { + other.m_handle = resource_traits_t::invalid_value; + } + + // + // `resource_wrapper` does not allow to copy. + // + resource_wrapper& operator=(const resource_wrapper& other) = delete; + + // + // `resource_wrapper` allows to move. + // + resource_wrapper& operator=(resource_wrapper&& other) noexcept { + if (this != std::addressof(other)) { + m_handle = other.m_handle; + m_releaser = std::move(other.m_releaser); + other.m_handle = resource_traits_t::invalid_value; + } + return *this; + } + + template, ptr_t> = nullptr> + [[nodiscard]] + ptr_t operator->() const noexcept { + return m_handle; + } + + template + [[nodiscard]] + as_t as() const noexcept { + return reinterpret_cast(m_handle); + } + + [[nodiscard]] + bool is_valid() const noexcept { + return resource_traits_t::is_valid(m_handle); + } + + [[nodiscard]] + const handle_t& get() const noexcept { + return m_handle; + } + + template + [[nodiscard]] + as_t* unsafe_addressof() noexcept { + return reinterpret_cast(std::addressof(m_handle)); + } + + void set(const handle_t& handle) { + if (is_valid()) { + m_releaser(m_handle); + } + m_handle = handle; + } + + void discard() noexcept { + m_handle = resource_traits_t::invalid_value; + } + + [[nodiscard]] + handle_t transfer() noexcept { + handle_t t = m_handle; + m_handle = resource_traits_t::invalid_value; + return t; + } + + void release() { + if (is_valid()) { + m_releaser(m_handle); + m_handle = resource_traits_t::invalid_value; + } + } + + ~resource_wrapper() { + release(); + } + }; + + template + class resource_wrapper { + public: + using handle_t = typename resource_traits_t::handle_t; + static_assert(std::is_trivial_v&& std::is_standard_layout_v, "`resource_wrapper` requires a handle with POD type."); + + private: + handle_t m_handle; + + public: + resource_wrapper() noexcept : + m_handle(resource_traits_t::invalid_value) {} + + resource_wrapper(const handle_t& handle) noexcept : + m_handle(handle) {} + + resource_wrapper(resource_traits_t) noexcept : + m_handle(resource_traits_t::invalid_value) {} + + resource_wrapper(resource_traits_t, const handle_t& handle) noexcept : + m_handle(handle) {} + + resource_wrapper(const resource_wrapper& other) = delete; + + resource_wrapper(resource_wrapper&& other) noexcept : + m_handle(other.m_handle) + { + other.m_handle = resource_traits_t::invalid_value; + } + + resource_wrapper& operator=(const resource_wrapper& other) = delete; + + resource_wrapper& operator=(resource_wrapper&& other) noexcept { + if (this != std::addressof(other)) { + m_handle = other.m_handle; + other.m_handle = resource_traits_t::invalid_value; + } + return *this; + } + + template, ptr_t> = nullptr> + [[nodiscard]] + ptr_t operator->() const noexcept { + return m_handle; + } + + template + [[nodiscard]] + as_t as() const noexcept { + return reinterpret_cast(m_handle); + } + + [[nodiscard]] + bool is_valid() const noexcept { + return resource_traits_t::is_valid(m_handle); + } + + [[nodiscard]] + const handle_t& get() const noexcept { + return m_handle; + } + + template + [[nodiscard]] + as_t* unsafe_addressof() noexcept { + return reinterpret_cast(std::addressof(m_handle)); + } + + void set(const handle_t& handle) { + if (is_valid()) { + resource_traits_t::release(m_handle); + } + m_handle = handle; + } + + void discard() noexcept { + m_handle = resource_traits_t::invalid_value; + } + + [[nodiscard]] + handle_t transfer() noexcept { + handle_t t = m_handle; + m_handle = resource_traits_t::invalid_value; + return t; + } + + void release() { + if (is_valid()) { + resource_traits_t::release(m_handle); + m_handle = resource_traits_t::invalid_value; + } + } + + ~resource_wrapper() { + release(); + } + }; + + template + resource_wrapper(resource_traits_t) -> + resource_wrapper; + + template + resource_wrapper(resource_traits_t, arg_t&&) -> + resource_wrapper< + resource_traits_t, + std::conditional_t< + std::is_same_v>, typename resource_traits_t::handle_t> == false, + std::remove_reference_t, + void + > + >; + + template + resource_wrapper(resource_traits_t, const handle_t&, releaser_t&&) -> + resource_wrapper>; + +} diff --git a/common/rsa_cipher.cpp b/common/rsa_cipher.cpp new file mode 100644 index 0000000..f6aba0b --- /dev/null +++ b/common/rsa_cipher.cpp @@ -0,0 +1,625 @@ +#include "rsa_cipher.hpp" +#include + +#include +#include + +#include "resource_traits/openssl/bio.hpp" +#include "resource_traits/openssl/bignum.hpp" + +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x +#include +#include +#include "resource_traits/openssl/encoder_ctx.hpp" +#include "resource_traits/openssl/decoder_ctx.hpp" +#endif + +#include "cp_converter.hpp" + +#include "exceptions/overflow_exception.hpp" + +#pragma comment(lib, "libcrypto") +#pragma comment(lib, "crypt32") // required by libcrypto.lib +#pragma comment(lib, "ws2_32") // required by libcrypto.lib + +#define NKG_CURRENT_SOURCE_FILE() u8".\\common\\rsa_cipher.cpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + RSA* rsa_cipher::_read_private_key_from_bio(BIO* p_bio) { + resource_wrapper new_rsa + { resource_traits::openssl::rsa{}, PEM_read_bio_RSAPrivateKey(p_bio, nullptr, nullptr, nullptr) }; + + if (new_rsa.is_valid()) { + return new_rsa.transfer(); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"PEM_read_bio_RSAPrivateKey failed.") + .push_hint(u8"Are you sure that you DO provide a valid RSA private key file?"); + } + } + + RSA* rsa_cipher::_read_public_key_pem_from_bio(BIO* p_bio) { + resource_wrapper new_rsa + { resource_traits::openssl::rsa{}, PEM_read_bio_RSA_PUBKEY(p_bio, nullptr, nullptr, nullptr) }; + + if (new_rsa.is_valid()) { + return new_rsa.transfer(); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"PEM_read_bio_RSA_PUBKEY failed.") + .push_hint(u8"Are you sure that you DO provide a valid RSA public key file with PEM format?"); + } + } + + RSA* rsa_cipher::_read_public_key_pkcs1_from_bio(BIO* p_bio) { + resource_wrapper new_rsa + { resource_traits::openssl::rsa{}, PEM_read_bio_RSAPublicKey(p_bio, nullptr, nullptr, nullptr) }; + + if (new_rsa.is_valid()) { + return new_rsa.transfer(); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"PEM_read_bio_RSAPublicKey failed.") + .push_hint(u8"Are you sure that you DO provide a valid RSA public key file with PKCS1 format?"); + } + } + + void rsa_cipher::_write_private_key_to_bio(RSA* p_rsa, BIO* p_bio) { + auto r = PEM_write_bio_RSAPrivateKey(p_bio, p_rsa, nullptr, nullptr, 0, nullptr, nullptr); + if (r == 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"PEM_write_bio_RSAPrivateKey failed."); + }; + } + + void rsa_cipher::_write_public_key_pem_to_bio(RSA* p_rsa, BIO* p_bio) { + auto r = PEM_write_bio_RSA_PUBKEY(p_bio, p_rsa); + if (r == 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"PEM_write_bio_RSA_PUBKEY failed."); + } + } + + void rsa_cipher::_write_public_key_pkcs1_to_bio(RSA* p_rsa, BIO* p_bio) { + auto r = PEM_write_bio_RSAPublicKey(p_bio, p_rsa); + if (r == 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"PEM_write_bio_RSAPublicKey failed."); + } + } +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + [[nodiscard]] + EVP_PKEY* rsa_cipher::_read_private_key_from_bio(BIO* p_bio) { + resource_wrapper new_rsa{ resource_traits::openssl::evp_pkey{} }; + + resource_wrapper decoder_context + { resource_traits::openssl::decoder_ctx{}, OSSL_DECODER_CTX_new_for_pkey(new_rsa.unsafe_addressof(), "PEM", "pkcs1", "RSA", OSSL_KEYMGMT_SELECT_PRIVATE_KEY, nullptr, nullptr) }; + + if (!decoder_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_DECODER_CTX_new_for_pkey failed."); + } + + if (!OSSL_DECODER_from_bio(decoder_context.get(), p_bio)) { // 1 on success, 0 on failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_DECODER_from_bio failed."); + } + + return new_rsa.transfer(); +} + + [[nodiscard]] + EVP_PKEY* rsa_cipher::_read_public_key_pem_from_bio(BIO* p_bio) { + resource_wrapper new_rsa{ resource_traits::openssl::evp_pkey{} }; + + resource_wrapper decoder_context + { resource_traits::openssl::decoder_ctx{}, OSSL_DECODER_CTX_new_for_pkey(new_rsa.unsafe_addressof(), "PEM", "SubjectPublicKeyInfo", "RSA", OSSL_KEYMGMT_SELECT_PUBLIC_KEY, nullptr, nullptr) }; + + if (!decoder_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_DECODER_CTX_new_for_pkey failed."); + } + + if (!OSSL_DECODER_from_bio(decoder_context.get(), p_bio)) { // 1 on success, 0 on failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_DECODER_from_bio failed."); + } + + return new_rsa.transfer(); + } + + [[nodiscard]] + EVP_PKEY* rsa_cipher::_read_public_key_pkcs1_from_bio(BIO* p_bio) { + resource_wrapper new_rsa{ resource_traits::openssl::evp_pkey{} }; + + resource_wrapper decoder_context + { resource_traits::openssl::decoder_ctx{}, OSSL_DECODER_CTX_new_for_pkey(new_rsa.unsafe_addressof(), "PEM", "pkcs1", "RSA", OSSL_KEYMGMT_SELECT_PUBLIC_KEY, nullptr, nullptr) }; + + if (!decoder_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_DECODER_CTX_new_for_pkey failed."); + } + + if (!OSSL_DECODER_from_bio(decoder_context.get(), p_bio)) { // 1 on success, 0 on failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_DECODER_from_bio failed."); + } + + return new_rsa.transfer(); + } + + void rsa_cipher::_write_private_key_to_bio(EVP_PKEY* p_rsa, BIO* p_bio) { + resource_wrapper encoder_context + { resource_traits::openssl::encoder_ctx{}, OSSL_ENCODER_CTX_new_for_pkey(p_rsa, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, "PEM", "pkcs1", nullptr) }; + + if (!encoder_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_ENCODER_CTX_new_for_pkey failed."); + } + + if (!OSSL_ENCODER_to_bio(encoder_context.get(), p_bio)) { // 1 on success, 0 on failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_ENCODER_to_bio failed."); + } + } + + void rsa_cipher::_write_public_key_pem_to_bio(EVP_PKEY* p_rsa, BIO* p_bio) { + resource_wrapper encoder_context + { resource_traits::openssl::encoder_ctx{}, OSSL_ENCODER_CTX_new_for_pkey(p_rsa, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, "PEM", "SubjectPublicKeyInfo", nullptr) }; + + if (!encoder_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_ENCODER_CTX_new_for_pkey failed."); + } + + if (!OSSL_ENCODER_to_bio(encoder_context.get(), p_bio)) { // 1 on success, 0 on failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_ENCODER_to_bio failed."); + } + } + + void rsa_cipher::_write_public_key_pkcs1_to_bio(EVP_PKEY* p_rsa, BIO* p_bio) { + resource_wrapper encoder_context + { resource_traits::openssl::encoder_ctx{}, OSSL_ENCODER_CTX_new_for_pkey(p_rsa, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, "PEM", "pkcs1", nullptr) }; + + if (!encoder_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_ENCODER_CTX_new_for_pkey failed."); + } + + if (!OSSL_ENCODER_to_bio(encoder_context.get(), p_bio)) { // 1 on success, 0 on failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"OSSL_ENCODER_to_bio failed."); + } + } +#else +#error "rsa_cipher.cpp: Unexpected OpenSSL version." +#endif + + rsa_cipher::rsa_cipher() = default; + + [[nodiscard]] + size_t rsa_cipher::bits() const { + if (m_rsa.get()) { +#if (OPENSSL_VERSION_NUMBER & 0xfff00000) == 0x10000000 // openssl 1.0.x + return BN_num_bits(m_rsa->n); +#elif (OPENSSL_VERSION_NUMBER & 0xfff00000) == 0x10100000 // openssl 1.1.x + return RSA_bits(m_rsa.get()); +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // openssl 3.x.x + return EVP_PKEY_get_bits(m_rsa.get()); +#else +#error "rsa_cipher.cpp: uexpected OpenSSL version" +#endif + } else { + throw no_key_assigned_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"RSA key has not been assigned yet."); + } + } + + void rsa_cipher::generate_key(int bits, unsigned int e) { + resource_wrapper bn_e{ resource_traits::openssl::bignum{}, BN_new() }; + + if (bn_e.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"BN_new failed."); + } + + if (BN_set_word(bn_e.get(), e) == 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BN_set_word failed."); + } + +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + resource_wrapper new_rsa{ resource_traits::openssl::rsa{}, RSA_new() }; + if (!new_rsa.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"RSA_new failed."); + } + + if (RSA_generate_key_ex(new_rsa.get(), bits, bn_e.get(), nullptr) == 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"RSA_generate_key_ex failed."); + } + + m_rsa = std::move(new_rsa); +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + resource_wrapper evp_pkey_context{ resource_traits::openssl::evp_pkey_ctx{}, EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr) }; + if (!evp_pkey_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_new_id failed."); + } + + if (EVP_PKEY_keygen_init(evp_pkey_context.get()) <= 0) { // 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_keygen_init failed."); + } + + if (EVP_PKEY_CTX_set_rsa_keygen_bits(evp_pkey_context.get(), bits) <= 0) { // return a positive value for success and 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_set_rsa_keygen_bits failed."); + } + + if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(evp_pkey_context.get(), bn_e.get()) <= 0) { // return a positive value for success and 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_set1_rsa_keygen_pubexp failed."); + } + + resource_wrapper new_rsa{ resource_traits::openssl::evp_pkey{} }; + + if (EVP_PKEY_keygen(evp_pkey_context.get(), new_rsa.unsafe_addressof()) <= 0) { // 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_keygen failed."); + } + + m_rsa = std::move(new_rsa); +#else +#error "rsa_cipher.cpp: Unexpected OpenSSL version." +#endif + } + + void rsa_cipher::export_private_key_file(std::wstring_view file_path) const { + resource_wrapper bio_file + { resource_traits::openssl::bio{}, BIO_new_file(cp_converter<-1, CP_UTF8>::convert(file_path).c_str(), "w")}; + + if (bio_file.is_valid()) { + _write_private_key_to_bio(m_rsa.get(), bio_file.get()); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new_file failed."); + } + } + + void rsa_cipher::export_private_key_file(const std::filesystem::path& file_path) const { + export_private_key_file(static_cast(file_path.native())); + } + + void rsa_cipher::export_public_key_file_pem(std::wstring_view file_path) const { + resource_wrapper bio_file + { resource_traits::openssl::bio{}, BIO_new_file(cp_converter<-1, CP_UTF8>::convert(file_path).c_str(), "w")}; + + if (bio_file.is_valid()) { + _write_public_key_pem_to_bio(m_rsa.get(), bio_file.get()); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new_file failed."); + } + } + + void rsa_cipher::export_public_key_file_pem(const std::filesystem::path& file_path) const { + export_public_key_file_pem(static_cast(file_path.native())); + } + + void rsa_cipher::export_public_key_file_pkcs1(std::wstring_view file_path) const { + resource_wrapper bio_file + { resource_traits::openssl::bio{}, BIO_new_file(cp_converter<-1, CP_UTF8>::convert(file_path).c_str(), "w")}; + + if (bio_file.is_valid()) { + _write_public_key_pkcs1_to_bio(m_rsa.get(), bio_file.get()); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new_file failed."); + } + } + + void rsa_cipher::export_public_key_file_pkcs1(const std::filesystem::path& file_path) const { + export_public_key_file_pkcs1(static_cast(file_path.native())); + } + + void rsa_cipher::import_private_key_file(std::wstring_view file_path) { + resource_wrapper bio_file + { resource_traits::openssl::bio{}, BIO_new_file(cp_converter<-1, CP_UTF8>::convert(file_path).c_str(), "r") }; + + if (bio_file.is_valid()) { + m_rsa.set(_read_private_key_from_bio(bio_file.get())); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new_file failed."); + } + } + + void rsa_cipher::import_private_key_file(const std::filesystem::path& file_path) { + import_private_key_file(static_cast(file_path.native())); + } + + void rsa_cipher::import_public_key_file_pem(std::wstring_view file_path) { + resource_wrapper bio_file + { resource_traits::openssl::bio{}, BIO_new_file(cp_converter<-1, CP_UTF8>::convert(file_path).c_str(), "r") }; + + if (bio_file.is_valid()) { + m_rsa.set(_read_public_key_pem_from_bio(bio_file.get())); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new_file failed."); + } + } + + void rsa_cipher::import_public_key_file_pem(const std::filesystem::path& file_path) { + import_public_key_file_pem(static_cast(file_path.native())); + } + + void rsa_cipher::import_public_key_file_pkcs1(std::wstring_view file_path) { + resource_wrapper bio_file + { resource_traits::openssl::bio{}, BIO_new_file(cp_converter<-1, CP_UTF8>::convert(file_path).c_str(), "r") }; + + if (bio_file.is_valid()) { + m_rsa.set(_read_public_key_pkcs1_from_bio(bio_file.get())); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new_file failed."); + } + } + + void rsa_cipher::import_public_key_file_pkcs1(const std::filesystem::path& file_path) { + import_public_key_file_pkcs1(static_cast(file_path.native())); + } + + [[nodiscard]] + std::string rsa_cipher::export_private_key_string() const { + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + + if (bio_memory.is_valid()) { + _write_private_key_to_bio(m_rsa.get(), bio_memory.get()); + + const char* pch = nullptr; + long lch = BIO_get_mem_data(bio_memory.get(), &pch); + + return std::string(pch, lch); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + } + + [[nodiscard]] + std::string rsa_cipher::export_public_key_string_pem() const { + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + + if (bio_memory.is_valid()) { + _write_public_key_pem_to_bio(m_rsa.get(), bio_memory.get()); + + const char* pch = nullptr; + long lch = BIO_get_mem_data(bio_memory.get(), &pch); + + return std::string(pch, lch); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + } + + [[nodiscard]] + std::string rsa_cipher::export_public_key_string_pkcs1() const { + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + + if (bio_memory.is_valid()) { + _write_public_key_pkcs1_to_bio(m_rsa.get(), bio_memory.get()); + + const char* pch = nullptr; + long lch = BIO_get_mem_data(bio_memory.get(), &pch); + + return std::string(pch, lch); + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + } + + void rsa_cipher::import_private_key_string(std::string_view key_string) { + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + if (BIO_puts(bio_memory.get(), key_string.data()) <= 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_puts failed."); + } + + m_rsa.set(_read_private_key_from_bio(bio_memory.get())); + } + + void rsa_cipher::import_public_key_string_pem(std::string_view key_string) { + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + if (BIO_puts(bio_memory.get(), key_string.data()) <= 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_puts failed."); + } + + m_rsa.set(_read_public_key_pem_from_bio(bio_memory.get())); + } + + void rsa_cipher::import_public_key_string_pkcs1(std::string_view key_string) { + resource_wrapper bio_memory{ resource_traits::openssl::bio{}, BIO_new(BIO_s_mem()) }; + + if (bio_memory.is_valid() == false) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_new failed."); + } + + if (BIO_puts(bio_memory.get(), key_string.data()) <= 0) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"BIO_puts failed."); + } + + m_rsa.set(_read_public_key_pkcs1_from_bio(bio_memory.get())); + } + + size_t rsa_cipher::public_encrypt(const void* plaintext, size_t plaintext_size, void* ciphertext, int padding) const { +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + if (plaintext_size <= INT_MAX) { + int bytes_written = + RSA_public_encrypt(static_cast(plaintext_size), reinterpret_cast(plaintext), reinterpret_cast(ciphertext), m_rsa.get(), padding); + + if (bytes_written != -1) { + return bytes_written; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"RSA_public_encrypt failed."); + } + } else { + throw exceptions::overflow_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"plaintext_size > INT_MAX"); + } +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + resource_wrapper evp_pkey_context{ resource_traits::openssl::evp_pkey_ctx{}, EVP_PKEY_CTX_new(m_rsa.get(), nullptr) }; + if (!evp_pkey_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_new failed."); + } + + if (EVP_PKEY_encrypt_init(evp_pkey_context.get()) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_encrypt_init failed."); + } + + if (EVP_PKEY_CTX_set_rsa_padding(evp_pkey_context.get(), padding) <= 0) { // return a positive value for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_set_rsa_padding failed."); + } + + size_t ciphertext_size = 0; + if (EVP_PKEY_encrypt(evp_pkey_context.get(), nullptr, &ciphertext_size, reinterpret_cast(plaintext), plaintext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_encrypt failed."); + } + + if (EVP_PKEY_encrypt(evp_pkey_context.get(), reinterpret_cast(ciphertext), &ciphertext_size, reinterpret_cast(plaintext), plaintext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_encrypt failed."); + } + + return ciphertext_size; +#else +#error "rsa_cipher.cpp: Unexpected OpenSSL version." +#endif + } + + size_t rsa_cipher::private_encrypt(const void* plaintext, size_t plaintext_size, void* ciphertext, int padding) const { +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + if (plaintext_size <= INT_MAX) { + int bytes_written = + RSA_private_encrypt(static_cast(plaintext_size), reinterpret_cast(plaintext), reinterpret_cast(ciphertext), m_rsa.get(), padding); + + if (bytes_written != -1) { + return bytes_written; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"RSA_public_encrypt failed."); + } + } else { + throw exceptions::overflow_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"plaintext_size > INT_MAX"); + } +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + resource_wrapper evp_pkey_context{ resource_traits::openssl::evp_pkey_ctx{}, EVP_PKEY_CTX_new(m_rsa.get(), nullptr) }; + if (!evp_pkey_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_new failed."); + } + + if (EVP_PKEY_sign_init(evp_pkey_context.get()) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_sign_init failed."); + } + + if (EVP_PKEY_CTX_set_rsa_padding(evp_pkey_context.get(), padding) <= 0) { // return a positive value for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_set_rsa_padding failed."); + } + + size_t ciphertext_size = 0; + if (EVP_PKEY_sign(evp_pkey_context.get(), nullptr, &ciphertext_size, reinterpret_cast(plaintext), plaintext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_sign failed."); + } + + if (EVP_PKEY_sign(evp_pkey_context.get(), reinterpret_cast(ciphertext), &ciphertext_size, reinterpret_cast(plaintext), plaintext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_sign failed."); + } + + return ciphertext_size; +#else +#error "rsa_cipher.cpp: Unexpected OpenSSL version." +#endif + } + + size_t rsa_cipher::public_decrypt(const void* ciphertext, size_t ciphertext_size, void* plaintext, int padding) const { +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + if (ciphertext_size <= INT_MAX) { + int bytes_written = + RSA_public_decrypt(static_cast(ciphertext_size), reinterpret_cast(ciphertext), reinterpret_cast(plaintext), m_rsa.get(), padding); + + if (bytes_written != -1) { + return bytes_written; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"RSA_public_decrypt failed.") + .push_hint(u8"Are your sure you DO provide a correct public key?"); + } + } else { + throw exceptions::overflow_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"ciphertext_size > INT_MAX"); + } +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + resource_wrapper evp_pkey_context{ resource_traits::openssl::evp_pkey_ctx{}, EVP_PKEY_CTX_new(m_rsa.get(), nullptr) }; + if (!evp_pkey_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_new failed."); + } + + if (EVP_PKEY_verify_recover_init(evp_pkey_context.get())) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_verify_recover_init failed."); + } + + if (EVP_PKEY_CTX_set_rsa_padding(evp_pkey_context.get(), padding) <= 0) { // return a positive value for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_set_rsa_padding failed."); + } + + size_t plaintext_size = 0; + if (EVP_PKEY_verify_recover(evp_pkey_context.get(), nullptr, &plaintext_size, reinterpret_cast(ciphertext), ciphertext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_verify_recover failed.") + .push_hint(u8"Are your sure you DO provide a correct public key?"); + } + + if (EVP_PKEY_verify_recover(evp_pkey_context.get(), reinterpret_cast(plaintext), &plaintext_size, reinterpret_cast(ciphertext), ciphertext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_verify_recover failed."); + } + + return plaintext_size; +#else +#error "rsa_cipher.cpp: Unexpected OpenSSL version." +#endif + } + + size_t rsa_cipher::private_decrypt(const void* ciphertext, size_t ciphertext_size, void* plaintext, int padding) const { +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + if (ciphertext_size <= INT_MAX) { + int bytes_written = + RSA_private_decrypt(static_cast(ciphertext_size), reinterpret_cast(ciphertext), reinterpret_cast(plaintext), m_rsa.get(), padding); + + if (bytes_written != -1) { + return bytes_written; + } else { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), ERR_get_error(), u8"RSA_public_decrypt failed.") + .push_hint(u8"Are your sure you DO provide a correct private key?"); + } + } else { + throw exceptions::overflow_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"ciphertext_size > INT_MAX"); + } +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + resource_wrapper evp_pkey_context{ resource_traits::openssl::evp_pkey_ctx{}, EVP_PKEY_CTX_new(m_rsa.get(), nullptr) }; + if (!evp_pkey_context.is_valid()) { + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_new failed."); + } + + if (EVP_PKEY_decrypt_init(evp_pkey_context.get()) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_decrypt_init failed."); + } + + if (EVP_PKEY_CTX_set_rsa_padding(evp_pkey_context.get(), padding) <= 0) { // return a positive value for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_CTX_set_rsa_padding failed."); + } + + size_t plaintext_size = 0; + if (EVP_PKEY_decrypt(evp_pkey_context.get(), nullptr, &plaintext_size, reinterpret_cast(ciphertext), ciphertext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_decrypt failed.") + .push_hint(u8"Are your sure you DO provide a correct private key?"); + } + + if (EVP_PKEY_decrypt(evp_pkey_context.get(), reinterpret_cast(plaintext), &plaintext_size, reinterpret_cast(ciphertext), ciphertext_size) <= 0) { // return 1 for success, 0 or a negative value for failure + throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), u8"EVP_PKEY_decrypt failed."); + } + + return plaintext_size; +#else +#error "rsa_cipher.cpp: Unexpected OpenSSL version." +#endif + } + + rsa_cipher::backend_error::backend_error(std::string_view file, int line, std::string_view message) noexcept: + ::nkg::exception::exception(file, line, message), m_error_code(0) {} + + rsa_cipher::backend_error::backend_error(std::string_view file, int line, error_code_t openssl_errno, std::string_view message) noexcept: + ::nkg::exception::exception(file, line, message), m_error_code(openssl_errno) + { + static std::once_flag onceflag_load_crypto_strings; + std::call_once(onceflag_load_crypto_strings, []() { ERR_load_crypto_strings(); }); + + m_error_string = ERR_reason_error_string(m_error_code); + } +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/common/rsa_cipher.hpp b/common/rsa_cipher.hpp new file mode 100644 index 0000000..2188248 --- /dev/null +++ b/common/rsa_cipher.hpp @@ -0,0 +1,161 @@ +#pragma once +#include +#include + +#include +#include + +#include "resource_wrapper.hpp" +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 +#include "resource_traits/openssl/rsa.hpp" +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x +#include "resource_traits/openssl/evp_pkey_ctx.hpp" +#include "resource_traits/openssl/evp_pkey.hpp" +#else +#error "rsa_cipher.hpp: Unexpected OpenSSL version." +#endif + +#include "exception.hpp" + +#define NKG_CURRENT_SOURCE_FILE() u8".\\common\\rsa_cipher.hpp" +#define NKG_CURRENT_SOURCE_LINE() __LINE__ + +namespace nkg { + + class rsa_cipher { + public: + class backend_error; + class no_key_assigned_error; + + private: +#if (OPENSSL_VERSION_NUMBER & 0xf0000000) < 0x30000000 // for openssl < 3.0.0 + resource_wrapper m_rsa; + + [[nodiscard]] + static RSA* _read_private_key_from_bio(BIO* p_bio); + + [[nodiscard]] + static RSA* _read_public_key_pem_from_bio(BIO* p_bio); + + [[nodiscard]] + static RSA* _read_public_key_pkcs1_from_bio(BIO* p_bio); + + static void _write_private_key_to_bio(RSA* p_rsa, BIO* p_bio); + + static void _write_public_key_pem_to_bio(RSA* p_rsa, BIO* p_bio); + + static void _write_public_key_pkcs1_to_bio(RSA* p_rsa, BIO* p_bio); +#elif (OPENSSL_VERSION_NUMBER & 0xf0000000) == 0x30000000 // for openssl 3.x.x + resource_wrapper m_rsa; + + [[nodiscard]] + static EVP_PKEY* _read_private_key_from_bio(BIO* p_bio); + + [[nodiscard]] + static EVP_PKEY* _read_public_key_pem_from_bio(BIO* p_bio); + + [[nodiscard]] + static EVP_PKEY* _read_public_key_pkcs1_from_bio(BIO* p_bio); + + static void _write_private_key_to_bio(EVP_PKEY* p_rsa, BIO* p_bio); + + static void _write_public_key_pem_to_bio(EVP_PKEY* p_rsa, BIO* p_bio); + + static void _write_public_key_pkcs1_to_bio(EVP_PKEY* p_rsa, BIO* p_bio); +#else +#error "rsa_cipher.hpp: Unexpected OpenSSL version." +#endif + + public: + rsa_cipher(); + + [[nodiscard]] + size_t bits() const; + + void generate_key(int bits, unsigned int e = RSA_F4); + + void export_private_key_file(std::wstring_view file_path) const; + + void export_private_key_file(const std::filesystem::path& file_path) const; + + void export_public_key_file_pem(std::wstring_view file_path) const; + + void export_public_key_file_pem(const std::filesystem::path& file_path) const; + + void export_public_key_file_pkcs1(std::wstring_view file_path) const; + + void export_public_key_file_pkcs1(const std::filesystem::path& file_path) const; + + void import_private_key_file(std::wstring_view file_path); + + void import_private_key_file(const std::filesystem::path& file_path); + + void import_public_key_file_pem(std::wstring_view file_path); + + void import_public_key_file_pem(const std::filesystem::path& file_path); + + void import_public_key_file_pkcs1(std::wstring_view file_path); + + void import_public_key_file_pkcs1(const std::filesystem::path& file_path); + + [[nodiscard]] + std::string export_private_key_string() const; + + [[nodiscard]] + std::string export_public_key_string_pem() const; + + [[nodiscard]] + std::string export_public_key_string_pkcs1() const; + + void import_private_key_string(std::string_view key_string); + + void import_public_key_string_pem(std::string_view key_string); + + void import_public_key_string_pkcs1(std::string_view key_string); + + size_t public_encrypt(const void* plaintext, size_t plaintext_size, void* ciphertext, int padding) const; + + size_t private_encrypt(const void* plaintext, size_t plaintext_size, void* ciphertext, int padding) const; + + size_t public_decrypt(const void* ciphertext, size_t ciphertext_size, void* plaintext, int padding) const; + + size_t private_decrypt(const void* ciphertext, size_t ciphertext_size, void* plaintext, int padding) const; + }; + + class rsa_cipher::backend_error : public ::nkg::exception { + public: + using error_code_t = decltype(ERR_get_error()); + + private: + error_code_t m_error_code; + std::string m_error_string; + + public: + backend_error(std::string_view file, int line, std::string_view message) noexcept; + + backend_error(std::string_view file, int line, error_code_t openssl_errno, std::string_view message) noexcept; + + [[nodiscard]] + virtual bool error_code_exists() const noexcept override { + return m_error_code != 0; + } + + [[nodiscard]] + virtual intptr_t error_code() const noexcept override { + if (error_code_exists()) { return m_error_code; } else { trap_then_terminate(); } + } + + [[nodiscard]] + virtual const std::string& error_string() const noexcept override { + if (error_code_exists()) { return m_error_string; } else { trap_then_terminate(); } + } + }; + + class rsa_cipher::no_key_assigned_error : public ::nkg::exception { + using ::nkg::exception::exception; + }; + +} + +#undef NKG_CURRENT_SOURCE_FILE +#undef NKG_CURRENT_SOURCE_LINE diff --git a/doc/how-does-it-work.md b/doc/how-does-it-work.md new file mode 100644 index 0000000..48f2ed2 --- /dev/null +++ b/doc/how-does-it-work.md @@ -0,0 +1,284 @@ +# Navicat Keygen - How does it work? + +[中文版](how-does-it-work.zh-CN.md) + +## 1. Keyword Explanation. + +* __Navicat Activation Public Key__ + + It is a __RSA-2048__ public key that Navicat used to encrypt or decrypt offline activation information. + + It is stored in __navicat.exe__ as a kind of resource called __RCData__. The resource name is `"ACTIVATIONPUBKEY"`. You can see it by a software called [___Resource Hacker___](http://www.angusj.com/resourcehacker/). The public key is + + ``` + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I + qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv + a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF + R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2 + WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt + YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ + awIDAQAB + -----END PUBLIC KEY----- + ``` + + If you have the corresponding private key, you can tell me. I would be very appreciated for your generous. + + __NOTICE:__ + + Start from __Navicat Premium 12.0.25__, Navicat do not load this public key from resource in `navicat.exe`. Instead, the public key is stored in `libcc.dll` and has been encrypted. To avoid being replaced easily, the public key is split into 5 parts: + + The following content is discovered from `libcc.dll` of __Navicat Premium x64 12.0.25 Simplified Chinese version__. The SHA256 value of `libcc.dll` is `607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0`. + + I __DO NOT__ guarantee that offset values are absolutely correct in other versions. But __char strings__ and __immediate values__ are highly possible to be found. + + 1. At file offset `+0x01A12090` in `libcc.dll`, stored as __char string__: + + ``` + "D75125B70767B94145B47C1CB3C0755E + 7CCB8825C5DCE0C58ACF944E08280140 + 9A02472FAFFD1CD77864BB821AE36766 + FEEDE6A24F12662954168BFA314BD950 + 32B9D82445355ED7BC0B880887D650F5" + ``` + + 2. At file offset `+0x0059D799` in `libcc.dll`, stored as __immediate value__ in a instruction: + + ``` + 0xFE 0xEA 0xBC 0x01 + ``` + + In decimal: `29158142` + + 3. At file offset `+0x01A11DA0` in `libcc.dll`, stored as __char string__: + + ``` + "E1CED09B9C2186BF71A70C0FE2F1E0AE + F3BD6B75277AAB20DFAF3D110F75912B + FB63AC50EC4C48689D1502715243A79F + 39FF2DE2BF15CE438FF885745ED54573 + 850E8A9F40EE2FF505EB7476F95ADB78 + 3B28CA374FAC4632892AB82FB3BF4715 + FCFE6E82D03731FC3762B6AAC3DF1C3B + C646FE9CD3C62663A97EE72DB932A301 + 312B4A7633100C8CC357262C39A2B3A6 + 4B224F5276D5EDBDF0804DC3AC4B8351 + 62BB1969EAEBADC43D2511D6E0239287 + 81B167A48273B953378D3D2080CC0677 + 7E8A2364F0234B81064C5C739A8DA28D + C5889072BF37685CBC94C2D31D0179AD + 86D8E3AA8090D4F0B281BE37E0143746 + E6049CCC06899401264FA471C016A96C + 79815B55BBC26B43052609D9D175FBCD + E455392F10E51EC162F51CF732E6BB39 + 1F56BBFD8D957DF3D4C55B71CEFD54B1 + 9C16D458757373E698D7E693A8FC3981 + 5A8BF03BA05EA8C8778D38F9873D62B4 + 460F41ACF997C30E7C3AF025FA171B5F + 5AD4D6B15E95C27F6B35AD61875E5505 + 449B4E" + ``` + + 4. At file offset `+0x0059D77F` in `libcc.dll`, stored as __immediate value__ in a instruction: + + ``` + 0x59 0x08 0x01 0x00 + ``` + + In decimal: `67673` + + 5. At file offset `+ 0x1A11D8C` in `libcc.dll`, stored as __char string__: + + ``` + "92933" + ``` + + Then output encrypted public key with format `"%s%d%s%d%s"`. The order is the same as it lists: + + ``` + D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933 + ``` + + This encrypted public key can be decrypted by my another repo: [how-does-navicat-encrypt-password](https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password), while the key used is `b'23970790'`. + + Example: + + ```cmd + E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git + ... + E:\GitHub>cd how-does-navicat-encrypt-password\python3 + E:\GitHub\how-does-navicat-encrypt-password\python3>python + Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32 + Type "help", "copyright", "credits" or "license" for more information. + >>> from NavicatCrypto import * + >>> cipher = Navicat11Crypto(b'23970790') + >>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933')) + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I + qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv + a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF + R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2 + WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt + YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ + awIDAQAB + -----END PUBLIC KEY----- + ``` + + __NOTICE:__ + + Start from __Navicat Premium 12.1.11__, Navicat do not load the public key through the method I talked before. Of course, the public key is still stored in `libcc.dll`. When Navicat starts, it encrypts the public key by an 8-bytes-long XOR key and stores the ciphertext in static area. When verifing __Activation Code__, Navicat will regenerate the 8-bytes-long XOR key and decrypts the ciphertext in static area to get the public key. + + In `libcc.dll`, x64 version, you can find some instructions that looks like: + + ```asm + xor eax, 'M' + mov byte_xxxxxx, al + ... + xor eax, 'I' + mov byte_xxxxxx, al + ... + xor eax, 'I' + mov byte_xxxxxx, al + ... + xor eax, 'B' + mov byte_xxxxxx, al + ... + xor eax, 'I' + mov byte_xxxxxx, al + ... + xor eax, 'j' + mov byte_xxxxxx, al + ... + ... + ``` + +* __Request Code__ + + It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of __Offline Activation Request Information__ encrypted by __Navicat Activation Public Key__. + +* __Offline Activation Request Information__ + + It is just a JSON-style ASCII string which contains 3 items. They are `"K"`, `"DI"` and `"P"` respectively, which represent __snKey__, __DeviceIdentifier__ (related with your machine), __Platform__ (OS Type). + + Like + + ``` + {"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"} + ``` + +* __Activation Code__ + + It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of the __Offline Activation Response Information__ encrypted by __Navicat Activation Private Key__. So far, we don't know the official activation private key and we have to replace it in `navicat.exe` and `libcc.dll`. + +* __Offline Activation Response Information__ + + Just like __Offline Activation Request Information__, it is also a JSON-style ASCII string. But it contains 5 items. They are `"K"`, `"N"`, `"O"`, `"T"` and `"DI"` respectively. + + `"K"` and `"DI"` has the same meaning that is mentioned in __Offline Activation Request Information__ and must be the same with the corresponding items in __Offline Activation Request Information__. + + `"N"`, `"O"`, `"T"` represent __Name__, __Organization__, __Timestamp__ respectively. __Name__ and __Organization__ are UTF-8 strings and the type of __Timestamp__ can be string or integer. (Thanks for discoveries from @Wizr, issue #10) + + `"T"` can be omitted. + +* __snKey__ + + It is a 4-block-long string, while every block is 4-chars-long. + + __snKey__ is generated by 10-bytes-long data. In order to explain it easily, I use __uint8_t data[10]__ to represent the 10-bytes-long data. + + 1. __data[0]__ and __data[1]__ must be `0x68` and `0x2A` respectively. + + These two bytes are Naivcat signature number. + + 2. __data[2]__, __data[3]__ and __data[4]__ can be any byte. Just set them whatever you want. + + 3. __data[5]__ and __data[6]__ are product language signatures. + + | Language | data[5] | data[6] | Discoverer | + |------------|:---------:|:---------:|-----------------| + | English | 0xAC | 0x88 | | + | 简体中文 | 0xCE | 0x32 | | + | 繁體中文 | 0xAA | 0x99 | | + | 日本語 | 0xAD | 0x82 | @dragonflylee | + | Polski | 0xBB | 0x55 | @dragonflylee | + | Español | 0xAE | 0x10 | @dragonflylee | + | Français | 0xFA | 0x20 | @Deltafox79 | + | Deutsch | 0xB1 | 0x60 | @dragonflylee | + | 한국어 | 0xB5 | 0x60 | @dragonflylee | + | Русский | 0xEE | 0x16 | @dragonflylee | + | Português | 0xCD | 0x49 | @dragonflylee | + + 4. __data[7]__ is Navicat product ID. (Thanks @dragonflylee and @Deltafox79) + + |Product Name |Enterprise|Standard|Educational|Essentials| + |----------------------|:--------:|:------:|:---------:|:--------:| + |Navicat Report Viewer |0x0B | | | | + |Navicat Data Modeler 3| |0x84 |0x85 | | + |Navicat Premium |0x65 | |0x66 |0x67 | + |Navicat MySQL |0x68 |0x69 |0x6A |0x6B | + |Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F | + |Navicat Oracle |0x70 |0x71 |0x72 |0x73 | + |Navicat SQL Server |0x74 |0x75 |0x76 |0x77 | + |Navicat SQLite |0x78 |0x79 |0x7A |0x7B | + |Navicat MariaDB |0x7C |0x7D |0x7E |0x7F | + |Navicat MongoDB |0x80 |0x81 |0x82 | | + + 5. High 4 bits of __data[8]__ represents __major version number__. + + Low 4 bits is unknown, but we can use it to delay activation deadline. Possible values are `0000` or `0001`. + + __Example:__ + + For __Navicat 12 x64__: High 4 bits must be `1100`, which is the binary of number `12`. + For __Navicat 11 x64__: High 4 bits must be `1011`, which is the binary of number `11`. + + 6. __data[9]__ is unknown, but you can set it by `0xFD`, `0xFC` or `0xFB` if you want to use __not-for-resale license__. + + According to symbol information in __Navicat 12 for Mac x64__ version: + + * `0xFB` is __Not-For-Resale-30-days__ license. + * `0xFC` is __Not-For-Resale-90-days__ license. + * `0xFD` is __Not-For-Resale-365-days__ license. + * `0xFE` is __Not-For-Resale__ license. + * `0xFF` is __Site__ license. + + After `uint8_t data[10]` is ready, Navicat uses __DES__ with __ECB mode__ to encrypt the last 8 bytes of `uint8_t data[10]` which are from __data[2]__ to __data[9]__. + + The DES key is: + + ```cpp + unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 }; + ``` + + Then use Base32 to encode `uint8_t data[10]` whose encode table is + + ```cpp + char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + ``` + + After encoding, you will get a 16-char-long string starting with `"NAV"`. + + Finally, divide the 16-char-long string to four 4-chars-long blocks and join them with `"-"` then you will get __snKey__. + +## 2. Activation Process + +1. Check whether __snKey__ that user inputs is valid. + +2. After user clicks `Activate`, Navicat will start online activation first. If fails, user can choose offline activation. + +3. Navicat will use the __snKey__ that user inputs and some information collected from user's machine to generate __Offline Activation Request Information__. Then Navicat will encrypt it by __Navicat Activation Public Key__ and return a Base64-encoded string as __Request Code__. + +4. In legal way, the __Request Code__ should be sent to Navicat official activation server by a Internet-accessible computer. And Navicat official activation server will return a legal __Activation Code__. + + But now, we use keygen to play the official activation server's role. + + 1. According to the __Request Code__, get `"DI"` value and `"K"` value. + + 2. Fill __Offline Activation Response Information__ with `"K"` value, name, organization name, `"DI"` value and, if need, `"T"` value. + + 3. Encrypt __Offline Activation Response Information__ by __Navicat Activation Private Key__ and you will get 256-byte-long data. + + 4. Encode the 256-byte-long data by Base64. The result is __Activation Code__. + + 5. After user input __Activation Code__, offline activation is done successfully. + diff --git a/doc/how-does-it-work.zh-CN.md b/doc/how-does-it-work.zh-CN.md new file mode 100644 index 0000000..1d0a677 --- /dev/null +++ b/doc/how-does-it-work.zh-CN.md @@ -0,0 +1,282 @@ +# Navicat Keygen - 注册机是怎么工作的? + +## 1. 关键词解释. + +* __Navicat激活公钥__ + + 这是一个2048位的RSA公钥,Navicat使用这个公钥来完成相关激活信息的加密和解密。 + + 这个公钥被作为 __RCData__ 类型的资源储存在 __navicat.exe__ 当中。资源名为`"ACTIVATIONPUBKEY"`。你可以使用一个叫[Resource Hacker](http://www.angusj.com/resourcehacker/)的软件来查看它。这个公钥的具体内容为: + + ``` + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I + qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv + a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF + R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2 + WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt + YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ + awIDAQAB + -----END PUBLIC KEY----- + ``` + + 如果您有相应的私钥并乐意公开的话欢迎联系我,我将非常感谢您的慷慨。 + + __注意:__ + + 从 __Navicat Premium 12.0.25__ 开始,Navicat不再从`navicat.exe`的资源中加载私钥。事实上,公钥转为从`libcc.dll`中加载,并且已经被加密。与此同时,为了防止被轻松地替换,加密的公钥被分到5个地方储存: + + 以下内容是从 __Navicat Premium x64 12.0.25 简体中文版__ 的`libcc.dll`中发现的,`libcc.dll`的SHA256值为`607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0`。我不保证在Navicat的其他版本中相关偏移量和下述的相同,但相关的 __字符串__ 以及 __立即数__ 是很可能找得到的。 + + 1. 在`libcc.dll`中,文件偏移量`+0x01A12090`的地方,储存了加密公钥的第一部分,以 __字符串__ 的形式储存: + + ``` + "D75125B70767B94145B47C1CB3C0755E + 7CCB8825C5DCE0C58ACF944E08280140 + 9A02472FAFFD1CD77864BB821AE36766 + FEEDE6A24F12662954168BFA314BD950 + 32B9D82445355ED7BC0B880887D650F5" + ``` + + 2. 在`libcc.dll`中,文件偏移量`+0x0059D799`的地方,储存了加密公钥的第二部分,以 __立即数__ 的形式储存在一条指令中: + + ``` + 0xFE 0xEA 0xBC 0x01 + ``` + + 相应的十进制值为: `29158142` + + 3. 在`libcc.dll`中,文件偏移量`+0x01A11DA0`的地方,储存了加密公钥的第三部分,以 __字符串__ 的形式储存: + + ``` + "E1CED09B9C2186BF71A70C0FE2F1E0AE + F3BD6B75277AAB20DFAF3D110F75912B + FB63AC50EC4C48689D1502715243A79F + 39FF2DE2BF15CE438FF885745ED54573 + 850E8A9F40EE2FF505EB7476F95ADB78 + 3B28CA374FAC4632892AB82FB3BF4715 + FCFE6E82D03731FC3762B6AAC3DF1C3B + C646FE9CD3C62663A97EE72DB932A301 + 312B4A7633100C8CC357262C39A2B3A6 + 4B224F5276D5EDBDF0804DC3AC4B8351 + 62BB1969EAEBADC43D2511D6E0239287 + 81B167A48273B953378D3D2080CC0677 + 7E8A2364F0234B81064C5C739A8DA28D + C5889072BF37685CBC94C2D31D0179AD + 86D8E3AA8090D4F0B281BE37E0143746 + E6049CCC06899401264FA471C016A96C + 79815B55BBC26B43052609D9D175FBCD + E455392F10E51EC162F51CF732E6BB39 + 1F56BBFD8D957DF3D4C55B71CEFD54B1 + 9C16D458757373E698D7E693A8FC3981 + 5A8BF03BA05EA8C8778D38F9873D62B4 + 460F41ACF997C30E7C3AF025FA171B5F + 5AD4D6B15E95C27F6B35AD61875E5505 + 449B4E" + ``` + + 4. 在`libcc.dll`中,文件偏移量`+0x0059D77F`的地方,储存了加密公钥的第四部分,以 __立即数__ 的形式储存在一条指令中: + + ``` + 0x59 0x08 0x01 0x00 + ``` + + 相应的十进制值为: `67673` + + 5. 在`libcc.dll`中,文件偏移量`+0x01A11D8C`的地方,储存了加密公钥的第五部分,以 __字符串__ 的形式储存: + + ``` + "92933" + ``` + + 这五部分按照`"%s%d%s%d%s"`的形式输出则为加密的公钥,顺序和上述的顺序相同,具体的输出为: + + ``` + + D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933 + + ``` + + 这个加密的公钥可以用我的另外一个repo([how-does-navicat-encrypt-password](https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password))解密,其中密钥为`b'23970790'`。 + + 例如: + + ```cmd + E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git + ... + E:\GitHub>cd how-does-navicat-encrypt-password\python3 + E:\GitHub\how-does-navicat-encrypt-password\python3>python + Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32 + Type "help", "copyright", "credits" or "license" for more information. + >>> from NavicatCrypto import * + >>> cipher = Navicat11Crypto(b'23970790') + >>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933')) + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I + qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv + a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF + R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2 + WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt + YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ + awIDAQAB + -----END PUBLIC KEY----- + ``` + + __注意:__ + + 从 __Navicat Premium 12.1.11__ 开始,Navicat不再用上面说的方法加载密钥。当然密钥还是储存在`libcc.dll`文件中。当Navicat启动时,它会用8字节长的XOR密钥来加密公钥,并储存到一个静态数据区中。当验证 __激活码__ 时,Navicat会重新生成一样的8字节XOR密钥,并解密在静态储存区中的密文,从而获取公钥。 + + 在`libcc.dll`,x64版本中,你会看到如下的几条指令: + + ```asm + xor eax, 'M' + mov byte_xxxxxx, al + ... + xor eax, 'I' + mov byte_xxxxxx, al + ... + xor eax, 'I' + mov byte_xxxxxx, al + ... + xor eax, 'B' + mov byte_xxxxxx, al + ... + xor eax, 'I' + mov byte_xxxxxx, al + ... + xor eax, 'j' + mov byte_xxxxxx, al + ... + ... + ``` + +* __请求码__ + + 这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 __离线激活信息__ 用 __Navicat激活公钥__ 加密的密文。 + +* __离线激活请求信息__ + + 这是一个JSON风格的字符串。它包含了3个Key:`"K"`、`"DI"`和`"P"`,分别代表 __序列号__、__设备识别码__(与你的电脑硬件信息相关)和 __平台__ (其实就是操作系统类型)。 + + 例如: + + ``` + {"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"} + ``` + +* __激活码__ + + 这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 __离线激活回复信息__ 用 __Navicat激活私钥__ 加密的密文。目前我们不知道官方的 __Navicat激活私钥__,所以我们得替换掉软件里的公钥。 + +* __离线激活回复信息__ + + 和 __离线激活请求信息__ 一样,它也是一个JSON风格的字符串。但是它包含5个Key,分别为`"K"`、`"N"`、`"O"`、`"T"` 和 `"DI"`. + + `"K"` 和 `"DI"` 的意义与 __离线激活请求信息__ 中的相同,且Value必须与 __离线激活请求信息__ 中的相同。 + + `"N"`、`"O"`、`"T"` 分别代表 __注册名__、__组织__、__授权时间__。 + + __注册名__ 和 __组织__ 的值类型为UTF-8编码的字符串。__授权时间__ 的值类型可以为字符串或整数(感谢@Wizr在issue #10中的报告)。 + + `"T"` 可以被省略。 + +* __序列号__ + + 这是一个被分为了4个部分的字符串,其中每个部分都是4个字符长。 + + __序列号__ 是通过10个字节的数据来生成的。为了表达方便,我用 __uint8_t data[10]__ 来表示这10个字节。 + + 1. __data[0]__ 和 __data[1]__ 必须分别为 `0x68` 和 `0x2A`。 + + 这两个字节为Navicat的标志数。 + + 2. __data[2]__、__data[3]__ 和 __data[4]__ 可以是任意字节,你想设成什么都行。 + + 3. __data[5]__ 和 __data[6]__ 是Navicat的语言标志,值如下: + + | 语言类型 | data[5] | data[6] | 发现者 | + |------------|:---------:|:---------:|-----------------| + | English | 0xAC | 0x88 | | + | 简体中文 | 0xCE | 0x32 | | + | 繁體中文 | 0xAA | 0x99 | | + | 日本語 | 0xAD | 0x82 | @dragonflylee | + | Polski | 0xBB | 0x55 | @dragonflylee | + | Español | 0xAE | 0x10 | @dragonflylee | + | Français | 0xFA | 0x20 | @Deltafox79 | + | Deutsch | 0xB1 | 0x60 | @dragonflylee | + | 한국어 | 0xB5 | 0x60 | @dragonflylee | + | Русский | 0xEE | 0x16 | @dragonflylee | + | Português | 0xCD | 0x49 | @dragonflylee | + + 4. __data[7]__ 是Navicat产品ID。(感谢 @dragonflylee 和 @Deltafox79提供的数据) + + |产品名 |Enterprise|Standard|Educational|Essentials| + |----------------------|:--------:|:------:|:---------:|:--------:| + |Navicat Report Viewer |0x0B | | | | + |Navicat Data Modeler 3| |0x84 |0x85 | | + |Navicat Premium |0x65 | |0x66 |0x67 | + |Navicat MySQL |0x68 |0x69 |0x6A |0x6B | + |Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F | + |Navicat Oracle |0x70 |0x71 |0x72 |0x73 | + |Navicat SQL Server |0x74 |0x75 |0x76 |0x77 | + |Navicat SQLite |0x78 |0x79 |0x7A |0x7B | + |Navicat MariaDB |0x7C |0x7D |0x7E |0x7F | + |Navicat MongoDB |0x80 |0x81 |0x82 | | + + 5. __data[8]__ 的高4位代表 __版本号__。低4位未知,但可以用来延长激活期限,可取的值有`0000`和`0001`。 + + 例如: + + 对于 __Navicat 12__: 高4位必须是`1100`,为`12`的二进制形式。 + 对于 __Navicat 11__: 高4位必须是`1011`,为`11`的二进制形式。 + + 6. __data[9]__ 目前暂未知,但如果你想要 __not-for-resale license__ 的话可以设成`0xFD`、`0xFC`或`0xFB`。 + + 根据 __Navicat 12 for Mac x64__ 版本残留的符号信息可知: + + * `0xFB`是 __Not-For-Resale-30-days__ license. + * `0xFC`是 __Not-For-Resale-90-days__ license. + * `0xFD`是 __Not-For-Resale-365-days__ license. + * `0xFE`是 __Not-For-Resale__ license. + * `0xFF`是 __Site__ license. + + 之后Navicat使用 __ECB__ 模式的 __DES__ 算法来加密 __data[10]__ 的后8字节,也就是 __data[2]__ 到 __data[9]__ 的部分。 + + 相应的DES密钥为: + + ```cpp + unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 }; + ``` + + 之后使用Base32编码 __data[10]__,其中编码表改为: + + ```cpp + char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + ``` + + 编码之后你应该会得到一个16字节长的字符串,并且以"NAV"打头。 + + 将16字节的字符串分成4个4字节的小块,然后用`"-"`连接就可以得到 __序列号__。 + +## 2. 激活过程 + + 1. 检查用户输入的 __序列号__ 是否合法。 + + 2. 在用户点击了`激活`按钮之后,Navicat会先尝试在线激活。如果失败,用户可以选择离线激活。 + + 3. Navicat会使用用户输入的 __序列号__ 以及从用户电脑收集来的信息生成 __离线激活请求信息__,然后用 __Navicat激活公钥__ 加密,并将密文用Base64编码,最后得到 __请求码__。 + + 4. 正常流程下,__请求码__ 应该通过可联网的电脑发送给Navicat的官方激活服务器。之后Navicat的官方激活服务器会返回一个合法的 __激活码__。 + + 但现在我们使用注册机来扮演官方激活服务器的角色,只是Navicat软件里的激活公钥得换成自己的公钥: + + 1. 根据 __请求码__, 获得`"DI"`值和`"K"`值。 + + 2. 用`"K"`值、用户名、组织名和`"DI"`值填写 __离线激活回复信息__。 + + 3. 用自己的2048位RSA私钥加密 __离线激活回复信息__,你将会得到256字节的密文。 + + 4. 用Base64编码这256字节的密文,就可以得到 __激活码__。 + + 5. 在Navicat软件中填入 __激活码__ 即可完成离线激活。 + diff --git a/doc/how-to-build.md b/doc/how-to-build.md new file mode 100644 index 0000000..fe9dfdb --- /dev/null +++ b/doc/how-to-build.md @@ -0,0 +1,60 @@ +# navicat-keygen for windows - How to build? + +[中文版](how-to-build.zh-CN.md) + +## 1. Prerequisites + +1. Please make sure that you have __Visual Studio 2022__ or the higher. Because this is a VS2022 project. + +2. Please make sure you have installed `vcpkg` and the following libraries: + + * `fmt:x64-windows-static` + * `fmt:x86-windows-static` + * `openssl:x64-windows-static` + * `openssl:x86-windows-static` + * `rapidjson:x64-windows-static` + * `rapidjson:x86-windows-static` + * `keystone:x64-windows-static` + * `keystone:x86-windows-static` + * `unicorn:x64-windows-static` + * `unicorn:x86-windows-static` + + is installed. + + You can install them by: + + ```console + $ vcpkg install fmt:x64-windows-static + $ vcpkg install fmt:x86-windows-static + $ vcpkg install openssl:x64-windows-static + $ vcpkg install openssl:x86-windows-static + $ vcpkg install rapidjson:x64-windows-static + $ vcpkg install rapidjson:x86-windows-static + $ vcpkg install keystone:x64-windows-static + $ vcpkg install keystone:x86-windows-static + $ vcpkg install unicorn:x64-windows-static + $ vcpkg install unicorn:x86-windows-static + ``` + +3. Your `vcpkg` has been integrated into your __Visual Studio__, which means you have run + + ```console + $ vcpkg integrate install + ``` + + successfully. + +## 2. Build + +1. Open this project in __Visual Studio__. + +2. Select `Release` configuration. + +3. Select `Win32` to build keygen/patcher for 32-bits Navicat. + + Or select `x64` to build keygen/patcher for 64-bits Navicat. + +4. Select __Build > Build Solution__. + +You will see executable files in `bin/` directory. + diff --git a/doc/how-to-build.zh-CN.md b/doc/how-to-build.zh-CN.md new file mode 100644 index 0000000..2d99357 --- /dev/null +++ b/doc/how-to-build.zh-CN.md @@ -0,0 +1,54 @@ +# navicat-keygen for windows - 如何编译? + +## 1. 前提条件 + +1. 请确保你有 __Visual Studio 2022__ 或者更高版本。因为这是一个VS2022项目。 + +2. 请确保你安装了 `vcpkg` 以及下面几个库: + + * `fmt:x64-windows-static` + * `fmt:x86-windows-static` + * `openssl:x64-windows-static` + * `openssl:x86-windows-static` + * `rapidjson:x64-windows-static` + * `rapidjson:x86-windows-static` + * `keystone:x64-windows-static` + * `keystone:x86-windows-static` + * `unicorn:x64-windows-static` + * `unicorn:x86-windows-static` + + 你可以通过下面的命令来安装它们: + + ```console + $ vcpkg install fmt:x64-windows-static + $ vcpkg install fmt:x86-windows-static + $ vcpkg install openssl:x64-windows-static + $ vcpkg install openssl:x86-windows-static + $ vcpkg install rapidjson:x64-windows-static + $ vcpkg install rapidjson:x86-windows-static + $ vcpkg install keystone:x64-windows-static + $ vcpkg install keystone:x86-windows-static + $ vcpkg install unicorn:x64-windows-static + $ vcpkg install unicorn:x86-windows-static + ``` + +3. 你的 `vcpkg` 已经和你的 __Visual Studio__ 集成了,即你曾成功运行了: + + ```console + $ vcpkg integrate install + ``` + +## 2. 编译 + +1. 在 __Visual Studio__ 打开这个项目。 + +2. 选择 `Release` 配置。 + +3. 选择 `Win32` 来生成供32位Navicat使用的keygen/patcher。 + + 或者选择 `x64` 来生成供64位Navicat使用的keygen/patcher。 + +4. 选择 __生成 > 生成解决方案__。 + +生成完成后,你会在 `bin/` 文件夹下看到编译后的keygen/patcher。 + diff --git a/doc/how-to-use.md b/doc/how-to-use.md new file mode 100644 index 0000000..0166d9e --- /dev/null +++ b/doc/how-to-use.md @@ -0,0 +1,196 @@ +# navicat-keygen for windows - How to use? + +[中文版](how-to-use.windows.zh-CN.md) + +1. Use `navicat-patcher.exe` to replace __Navicat Activation Public Key__ that is stored in `libcc.dll`. + + ``` + navicat-patcher.exe [-dry-run] [RSA-2048 PEM File Path] + ``` + + * `[-dry-run]` Run patcher without applying any patches. + + __This parameter is optional.__ + + * ``: The full path to Navicat installation folder. + + __This parameter must be specified.__ + + * `[RSA-2048 PEM File Path]`: The full path or relative path to a RSA-2048 private key file. + + __This parameter is optional.__ If not specified, `navicat-patcher.exe` will generate a new RSA-2048 private key file `RegPrivateKey.pem` at current directory. + + __Example: (in cmd.exe)__ + + ``` + navicat-patcher.exe "C:\Program Files\PremiumSoft\Navicat Premium 16" + ``` + + It has been tested on __Navicat Premium 16.0.7 English version__. The following is an example of output. + + ``` + *************************************************** + * navicat-patcher by @DoubleLabyrinth * + * version: 16.0.7.0 * + *************************************************** + + [+] Try to open libcc.dll ... OK! + + [*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_vtable = 0x00000001837759f0 + [*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = 0x0000000181fa52d0 + [*] patch_solution_since<16, 0, 7, 0>: m_va_iat_entry_malloc = 0x0000000183439bd0 + [+] patch_solution_since<16, 0, 7, 0>: official encoded key is found. + + [*] Generating new RSA private key, it may take a long time... + [*] Your RSA private key: + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEAvxaFFjTE6hi80nhjgfFMM3yPer122OIWIbbumFIuAOcCF6D3 + PnRHBdP9IqB99K6Nv6vKK3Jf0Y+dc5ETrg0l0AHYq+dTFTiWusHuRMx6xFjWzO96 + 7mFmJq6P28dUucKnr6yG1TQeZaq+mHh2DNEnNEYgV7cLVT1unUmMOL/PBh/eCcaJ + 8hQNTQafQQknzCnAKC89v33y+rKInJNy9B+zSB0BGCz+eS8MKf6zc78JMSOnF2uj + NK+QEwaYw8lAbJve1F+rCQS0mbm0QvHhZYZrblVHI5l/8LkX5qBtKw7duUhXHxmO + fQieF23bBk9HDp5uQUGsdbKX6ZWitn/h926xyQIDAQABAoIBAQCHXxDRdni5zuSV + xivYdnUhVHDg5zA23ZQINmw5BJ8KjJzy2FnPqNhXzKJb0Y7ptG8/BhinRtOSxkcp + A/IJL89F2MkCn1JAimJd091UZ/fg+X7SmCVikyWm6auIa2IeZ0QcNAEhMVcHdzqn + EU+wLMu1QKjQ+x/QN0ERtHTeDyQ+lUNB+bvAjx3LHN9Zh8weVBHHtwDoyyZDdJPw + NWgpgcW+uYzlT66uh7LPPaRsEZgAkPIkhzZnwmugXdhlWxtYHKTEfe5gCqubQICc + I/x1yBP1EZFm6qBQD4/49775ZbXwxgaWvBXG+Aah9x8JYtVUS4MgrAiC4a8NQqFp + nwKVjUIBAoGBAOWsj9GGb2KYbfLzJNRrSxhs4TUBfpHteKSm2pL92NAbIOjssNhL + hLY3gBFX2RnYmoGD6YT84JNykuAictgAd5GwvLIbaVF9l7MQn8APRbe2CzQ+/494 + 9hpn33MZOBNd3I+a5+2qoFbXI04loyYDJkkeOqbwZzJjs7k9HmZMNwY5AoGBANT9 + tRFWFDvA0pPgGoHhzlsAUAmrbSfCPkhrRXpE9fgl3VnV+NRtjCf9NhJt0uaIokZ5 + oSf+jClcwU8N4EvGxMBaCHTqBzgc4dLPWpMAhPoMjjv1Oyug2iBcuTasHVP+Jdgq + CaNzpXOuq4upaaNrq+QMsI6O9wA/zWhWPmnYQYgRAoGAUk56471noU+65zvXUQB6 + UvCB7Hrynt0ZRPg+kDrEPh/atV5NKdY2Yw6UqKJwvOBwzkU1pGDzIiQHGqd9vIa+ + Usmhdbp5DakSeitU9IEEnQdyEHEbKJFSsLfUzeyVuesDJbt/rh5dg4Fpt5GpW+/5 + Am8A2d6BPP+Z4qJSiJp7hZECgYEAy64TCZEXqEytE1yr/KjDfaK+54BX0j2e8gIj + XtmznqoXE2Hboslfzp4Gp3j+xhbDmEGYK3bw8l0RP1g1tkFOxeNTUvq6DJ8SFVbV + dt54S+bV3eCVxRL9hRUmyXGuWjQgXKdWsEhXYFkZE2Xe77h3mI3KCYoOCt74v146 + MV3szQECgYEAozTO7Wuum+VMKIY35hmHMjUiYmLl3EXWwMBT2VSsk8Siu0XoH0yd + KoxsLDUBMS8sWKCZhFwU+Fx8UZjfo+xE3H4UTyVsw5EDpB9gSud928gNADwxTKor + 3s4jnUzb4XRQ0qN2jXzdNuqXNV1ozeqajbM2oSZqbSnWSs5g6DpIs1Q= + -----END RSA PRIVATE KEY----- + + [*] patch_solution_since<16, 0, 7, 0>: Patch has been done. + [*] New RSA-2048 private key has been saved to + C:\Users\DoubleSine\source\repos\navicat-keygen\bin\x64-Release\RegPrivateKey.pem + + + ******************************************************* + * PATCH HAS BEEN DONE SUCCESSFULLY! * + * HAVE FUN AND ENJOY~ * + ******************************************************* + ``` + +2. Then use `navicat-keygen.exe` to generate __snKey__ and __Activation Code__ + + ``` + navicat-keygen.exe <-bin|-text> [-adv] + ``` + + * `<-bin|-text>`: Must be `-bin` or `-text`. + + If `-bin` is specified, `navicat-keygen.exe` will finally generate `license_file`. It is used for Navicat old activation method only. + + If `-text` is specified, `navicat-keygen.exe` will finally generate a Base64-style string which is __Activation Code__. It is used for Navicat new activation method. + + __This parameter must be specified.__ + + * `[-adv]`: Enable advanced mode. + + __This parameter is optional.__ If specified, `navicat-keygen.exe` will ask you input Navicat product ID number, language signature numbers. It is for future use generally. + + * ``: The full path or relative path to an RSA-2048 private key file. The private key must be in PEM format. + + __This parameter must be specified.__ + + __Example: (in cmd.exe)__ + + ```console + navicat-keygen.exe -text .\RegPrivateKey.pem + ``` + + You will be asked to select Navicat product, language and input major version number. After that an randomly generated __snKey__ will be given. + + ``` + *************************************************** + * navicat-keygen by @DoubleLabyrinth * + * version: 16.0.7.0 * + *************************************************** + + [*] Select Navicat product: + 0. DataModeler + 1. Premium + 2. MySQL + 3. PostgreSQL + 4. Oracle + 5. SQLServer + 6. SQLite + 7. MariaDB + 8. MongoDB + 9. ReportViewer + + (Input index)> 1 + + [*] Select product language: + 0. English + 1. Simplified Chinese + 2. Traditional Chinese + 3. Japanese + 4. Polish + 5. Spanish + 6. French + 7. German + 8. Korean + 9. Russian + 10. Portuguese + + (Input index)> 0 + + [*] Input major version number: + (range: 11 ~ 16, default: 16)> 16 + + [*] Serial number: + NAVL-GFKA-T5SR-ZFTK + + [*] Your name: + ``` + + You can use this __snKey__ to activate your Navicat preliminarily. + + Then you will be asked to input `Your name` and `Your organization`. Just set them whatever you want, but not too long. + + ``` + [*] Your name: Double Sine + [*] Your organization: PremiumSoft CyberTech Ltd. + + [*] Input request code (in Base64), input empty line to end: + ``` + + After that, you will be asked to input the request code. Now __DO NOT CLOSE KEYGEN__. + +3. __Disconnect your network__ and open Navicat. Find and click `Registration`. Fill `Registration Key` by __snKey__ that the keygen gave and click `Activate`. + +4. Generally online activation will failed and Navicat will ask you do `Manual Activation`, just choose it. + +5. Copy your request code and paste it in the keygen. Input empty line to tell the keygen that your input ends. + + ``` + [*] Your name: Double Sine + [*] Your organization: PremiumSoft CyberTech Ltd. + + [*] Input request code (in Base64), input empty line to end: + CpgnfbIJGmAcxCuo/pAb8EeoS0audZn2NNemg6c3NPK/dWgb343IZQrFwoBZY6lpxE4Fq1BoNmCM75P03XpiXQ+hErcvFWk6iQPDCk/d4msf/AoprIqAMpXFoFLkeP0G93UIIEeBsUej8SrxdDgQDM585iPok5fUW+fTDCD1VICr7DBdL3c/69IxeIgiOQSuImdIQiM3/EOfDiFbAJL9vHW5LxFT8jj+8RPXehwPTBphpInmGdzxVZUZJwAGlXt7orrRbzafdeBjz6MnTajTcJP3SS2dBCiR33UScnyxYGEXdzv7+QLScTmCvI7gqg3Z8DMhroKMoHmy1AvC16FKVw== + + [*] Request Info: + {"K":"NAVLGFKAT5SRZFTK", "DI":"7D48FCBD093C778879A1", "P":"WIN"} + + [*] Response Info: + {"K":"NAVLGFKAT5SRZFTK","DI":"7D48FCBD093C778879A1","N":"Double Sine","O":"PremiumSoft CyberTech Ltd.","T":1644387294} + + [*] Activation Code: + vwLGmQIWg/DtzHMcaKCDHAjTcBNbTo2VmNllphUSUMgGjgvL6v82ue+GqXB6M/qn48Rj4D4Joqqisr6UwMSclNmQxOQz4RftEpLtG6KBjDo4LM71qn9R/jWoZV5EoHPQkX5gzhO/D7GammrRGn2MV+zI6dJ4c4SBFNnNyjAeEqNzinrQwjB7lUVTlpHEe/SMrdCsGliPZQ/X+5ASbEsq3D8PZsjysJv98MIJrZvdTdznrRe8JzYP+8sbIPQMIX1UDmdyDpbpSl45N92OhO4htz1kFjUEfnrwY0GMOhdYHv/PfMI7RiQzkRyY7pLvX7muJ4dkA+CmMmwew3gy3MWjig== + ``` + +6. Finally, you will get __Activation Code__ which looks like a Base64 string. Just copy it and paste it in Navicat `Manual Activation` window, then click `Activate`. If nothing wrong, activation should be done successfully. + diff --git a/doc/how-to-use.zh-CN.md b/doc/how-to-use.zh-CN.md new file mode 100644 index 0000000..a2c1c12 --- /dev/null +++ b/doc/how-to-use.zh-CN.md @@ -0,0 +1,194 @@ +# navicat-keygen for windows - 如何使用这个注册机? + +1. 使用`navicat-patcher.exe`替换掉`navicat.exe`和`libcc.dll`里的Navicat激活公钥。 + + ``` + navicat-patcher.exe [-dry-run] [RSA-2048 PEM File Path] + ``` + + * `[-dry-run]`: 运行patcher但不对Navicat程序做任何修改。 + + __这个参数是可选的。__ + + * ``: Navicat的完整安装路径。 + + __这个参数必须指定。__ + + * `[RSA-2048 PEM File Path]`: RSA-2048私钥文件的完整路径或相对路径。 + + __这个参数是可选的。__ 如果未指定,`navicat-patcher.exe`将会在当前目录生成一个新的RSA-2048私钥文件。 + + __例如:(在cmd.exe中)__ + + ``` + navicat-patcher.exe "C:\Program Files\PremiumSoft\Navicat Premium 16" + ``` + + __Navicat Premium 16.0.7 英文版__ 已通过测试。下面将是一份样例输出: + + ``` + *************************************************** + * navicat-patcher by @DoubleLabyrinth * + * version: 16.0.7.0 * + *************************************************** + + [+] Try to open libcc.dll ... OK! + + [*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_vtable = 0x00000001837759f0 + [*] patch_solution_since<16, 0, 7, 0>: m_va_CSRegistrationInfoFetcher_WIN_GenerateRegistrationKey = 0x0000000181fa52d0 + [*] patch_solution_since<16, 0, 7, 0>: m_va_iat_entry_malloc = 0x0000000183439bd0 + [+] patch_solution_since<16, 0, 7, 0>: official encoded key is found. + + [*] Generating new RSA private key, it may take a long time... + [*] Your RSA private key: + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEAvxaFFjTE6hi80nhjgfFMM3yPer122OIWIbbumFIuAOcCF6D3 + PnRHBdP9IqB99K6Nv6vKK3Jf0Y+dc5ETrg0l0AHYq+dTFTiWusHuRMx6xFjWzO96 + 7mFmJq6P28dUucKnr6yG1TQeZaq+mHh2DNEnNEYgV7cLVT1unUmMOL/PBh/eCcaJ + 8hQNTQafQQknzCnAKC89v33y+rKInJNy9B+zSB0BGCz+eS8MKf6zc78JMSOnF2uj + NK+QEwaYw8lAbJve1F+rCQS0mbm0QvHhZYZrblVHI5l/8LkX5qBtKw7duUhXHxmO + fQieF23bBk9HDp5uQUGsdbKX6ZWitn/h926xyQIDAQABAoIBAQCHXxDRdni5zuSV + xivYdnUhVHDg5zA23ZQINmw5BJ8KjJzy2FnPqNhXzKJb0Y7ptG8/BhinRtOSxkcp + A/IJL89F2MkCn1JAimJd091UZ/fg+X7SmCVikyWm6auIa2IeZ0QcNAEhMVcHdzqn + EU+wLMu1QKjQ+x/QN0ERtHTeDyQ+lUNB+bvAjx3LHN9Zh8weVBHHtwDoyyZDdJPw + NWgpgcW+uYzlT66uh7LPPaRsEZgAkPIkhzZnwmugXdhlWxtYHKTEfe5gCqubQICc + I/x1yBP1EZFm6qBQD4/49775ZbXwxgaWvBXG+Aah9x8JYtVUS4MgrAiC4a8NQqFp + nwKVjUIBAoGBAOWsj9GGb2KYbfLzJNRrSxhs4TUBfpHteKSm2pL92NAbIOjssNhL + hLY3gBFX2RnYmoGD6YT84JNykuAictgAd5GwvLIbaVF9l7MQn8APRbe2CzQ+/494 + 9hpn33MZOBNd3I+a5+2qoFbXI04loyYDJkkeOqbwZzJjs7k9HmZMNwY5AoGBANT9 + tRFWFDvA0pPgGoHhzlsAUAmrbSfCPkhrRXpE9fgl3VnV+NRtjCf9NhJt0uaIokZ5 + oSf+jClcwU8N4EvGxMBaCHTqBzgc4dLPWpMAhPoMjjv1Oyug2iBcuTasHVP+Jdgq + CaNzpXOuq4upaaNrq+QMsI6O9wA/zWhWPmnYQYgRAoGAUk56471noU+65zvXUQB6 + UvCB7Hrynt0ZRPg+kDrEPh/atV5NKdY2Yw6UqKJwvOBwzkU1pGDzIiQHGqd9vIa+ + Usmhdbp5DakSeitU9IEEnQdyEHEbKJFSsLfUzeyVuesDJbt/rh5dg4Fpt5GpW+/5 + Am8A2d6BPP+Z4qJSiJp7hZECgYEAy64TCZEXqEytE1yr/KjDfaK+54BX0j2e8gIj + XtmznqoXE2Hboslfzp4Gp3j+xhbDmEGYK3bw8l0RP1g1tkFOxeNTUvq6DJ8SFVbV + dt54S+bV3eCVxRL9hRUmyXGuWjQgXKdWsEhXYFkZE2Xe77h3mI3KCYoOCt74v146 + MV3szQECgYEAozTO7Wuum+VMKIY35hmHMjUiYmLl3EXWwMBT2VSsk8Siu0XoH0yd + KoxsLDUBMS8sWKCZhFwU+Fx8UZjfo+xE3H4UTyVsw5EDpB9gSud928gNADwxTKor + 3s4jnUzb4XRQ0qN2jXzdNuqXNV1ozeqajbM2oSZqbSnWSs5g6DpIs1Q= + -----END RSA PRIVATE KEY----- + + [*] patch_solution_since<16, 0, 7, 0>: Patch has been done. + [*] New RSA-2048 private key has been saved to + C:\Users\DoubleSine\source\repos\navicat-keygen\bin\x64-Release\RegPrivateKey.pem + + + ******************************************************* + * PATCH HAS BEEN DONE SUCCESSFULLY! * + * HAVE FUN AND ENJOY~ * + ******************************************************* + ``` + +2. 接下来使用`navicat-keygen.exe`来生成序列号和激活码 + + ``` + navicat-keygen.exe <-bin|-text> [-adv] + ``` + + * `<-bin|-text>`: 必须是`-bin`或`-text`。 + + 如果指定了`-bin`,`navicat-keygen.exe`最终将生成`license_file`文件。这个选项是给Navicat旧激活方式使用的。 + + 如果指定了`-text`,`navicat-keygen.exe`最终将生成Base64样式的激活码。这个选项是给Navicat新激活方式使用的。 + + __这个参数必须指定。__ + + * `[-adv]`: 开启高级模式。 + + __这个参数是可选的。__ 如果指定了这个参数,`navicat-keygen.exe`将会要求你手工填写产品ID号、语言标识号。这个选项一般是给以后用的。 + + * ``: RSA-2048私钥文件的完整路径或相对路径。私钥必须是PEM格式的。 + + __这个参数必须指定。__ + + __例如:(在cmd.exe中)__ + + ```console + navicat-keygen.exe -text .\RegPrivateKey.pem + ``` + + 你会被要求选择Navicat产品类别、语言以及输入主版本号。之后会随机生成一个序列号。 + + ``` + *************************************************** + * navicat-keygen by @DoubleLabyrinth * + * version: 16.0.7.0 * + *************************************************** + + [*] Select Navicat product: + 0. DataModeler + 1. Premium + 2. MySQL + 3. PostgreSQL + 4. Oracle + 5. SQLServer + 6. SQLite + 7. MariaDB + 8. MongoDB + 9. ReportViewer + + (Input index)> 1 + + [*] Select product language: + 0. English + 1. Simplified Chinese + 2. Traditional Chinese + 3. Japanese + 4. Polish + 5. Spanish + 6. French + 7. German + 8. Korean + 9. Russian + 10. Portuguese + + (Input index)> 0 + + [*] Input major version number: + (range: 11 ~ 16, default: 16)> 16 + + [*] Serial number: + NAVL-GFKA-T5SR-ZFTK + + [*] Your name: + ``` + + 你可以使用这个序列号暂时激活Navicat。 + + 接下来你会被要求输入`用户名`和`组织名`;请随便填写,但不要太长。 + + ``` + [*] Your name: Double Sine + [*] Your organization: PremiumSoft CyberTech Ltd. + + [*] Input request code (in Base64), input empty line to end: + ``` + + 之后你会被要求填入请求码。注意 __不要关闭命令行__. + +3. __断开网络__ 并打开Navicat。找到`注册`窗口,并填入keygen给你的序列号。然后点击`激活`按钮。 + +4. 一般来说在线激活肯定会失败,这时候Navicat会询问你是否`手动激活`,直接选吧。 + +5. 在`手动激活`窗口你会得到一个请求码,复制它并把它粘贴到keygen里。最后别忘了连按至少两下回车结束输入。 + + ``` + [*] Your name: Double Sine + [*] Your organization: PremiumSoft CyberTech Ltd. + + [*] Input request code (in Base64), input empty line to end: + CpgnfbIJGmAcxCuo/pAb8EeoS0audZn2NNemg6c3NPK/dWgb343IZQrFwoBZY6lpxE4Fq1BoNmCM75P03XpiXQ+hErcvFWk6iQPDCk/d4msf/AoprIqAMpXFoFLkeP0G93UIIEeBsUej8SrxdDgQDM585iPok5fUW+fTDCD1VICr7DBdL3c/69IxeIgiOQSuImdIQiM3/EOfDiFbAJL9vHW5LxFT8jj+8RPXehwPTBphpInmGdzxVZUZJwAGlXt7orrRbzafdeBjz6MnTajTcJP3SS2dBCiR33UScnyxYGEXdzv7+QLScTmCvI7gqg3Z8DMhroKMoHmy1AvC16FKVw== + + [*] Request Info: + {"K":"NAVLGFKAT5SRZFTK", "DI":"7D48FCBD093C778879A1", "P":"WIN"} + + [*] Response Info: + {"K":"NAVLGFKAT5SRZFTK","DI":"7D48FCBD093C778879A1","N":"Double Sine","O":"PremiumSoft CyberTech Ltd.","T":1644387294} + + [*] Activation Code: + vwLGmQIWg/DtzHMcaKCDHAjTcBNbTo2VmNllphUSUMgGjgvL6v82ue+GqXB6M/qn48Rj4D4Joqqisr6UwMSclNmQxOQz4RftEpLtG6KBjDo4LM71qn9R/jWoZV5EoHPQkX5gzhO/D7GammrRGn2MV+zI6dJ4c4SBFNnNyjAeEqNzinrQwjB7lUVTlpHEe/SMrdCsGliPZQ/X+5ASbEsq3D8PZsjysJv98MIJrZvdTdznrRe8JzYP+8sbIPQMIX1UDmdyDpbpSl45N92OhO4htz1kFjUEfnrwY0GMOhdYHv/PfMI7RiQzkRyY7pLvX7muJ4dkA+CmMmwew3gy3MWjig== + ``` + +6. 如果不出意外,你会得到一个看似用Base64编码的激活码。直接复制它,并把它粘贴到Navicat的`手动激活`窗口,最后点`激活`按钮。如果没什么意外的话应该能成功激活。 + diff --git a/doc/screenshot.png b/doc/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..67203db3d41354c65e723f1f7b92a2bc0c483d7e GIT binary patch literal 341881 zcmYIQ1yqw^+qMt|X#pt%=@dq@fk+8#pmZZS1`LprMkFL8q(_VpMmG#;MY=|e?(XjX zr{DLT|2>E8oWb7bdG7amulsuL`+5m}rz}rIKud7z)-581w=$}?Zr$s-b?dJ1gFCoS z(wAQu;@%$GztwTPb&I(9@6YX6PGY)Sx1Qfpkdab%9p9|Sb5++mKb2Iux!OU`n7r72 zc#l1XW2n&1xwZuEdk5}IRTH~q#-jWM?_~Dr7p2`<-+P3#!u+L(2Oo{+g&YoQg#aV+ zVSkkAIl^0RQ^6P})b&gUe>Ku%x8C484&Z zajktg^p#TOuzW+BP|xD9k|Jn&S?(Fob*8cVN!}Isp4f0riodR_q01XnIfVCz82KE>yln3f%3xI(Q z35#$?QBDCa5L*bF32gl+HxkBV<97E1%;*ZDh*&u<0Yys->L5Gpk}&Bn&W~1Zq>AzW zbKYCCdwXD#6ll#Fa8Py>z<>uF3>gHRX$-1k76~LwH-B7=fY~c4)gjTKa*_!E0^PBI z&<2L$4FY^pm+#h7{r4=NA$M$82U_jF|CK)|d>YCANafyc58_Pg9w zC{*B;*m;J|5;?M?@^NJTHaTRf5VEQUP03M%LUzH7hd2<*2ws3@S8JdHBgm`?mSX5J zxiXAjV=yEuF=M8Fg}{B8R-M040{qiMSp3Bcc9!MN6mbQ99a{wj9VscYWyFr*`h~5{ zj@IAXi6JxN!K1GpjE?3-mpUAwqy6;CiXm%Fw-E_n1$3p6SF={8uF_-&K?E{d?s&sX zr;=Tb(8-BIyZxwpHGe>iZOI^lB7-$;|7Y48%4 z78ErSSVwF!LqV3vH4`j=JrDNBkRS*H*b0LR7Cv>uY+CyT^UkBwCDG_@omGhPf|44*m?)^&*|IUgZEbl|1>{Oc`698AV z`P%r_GpfOv)zL!^PGkFej6{RixoM0cu9+uALwfne?%SwHSNo?wN&zOGcN=O-m7m!a zr`0RNj4T$)AyHz*F#rE1#=|7%zy#tJ1 zkBd`4^#bs5XcTp(IssFAW1JR~#JcvuZv?k45VHugLysqU9gmgu7`xv?tQ~o=0&_yF z88_Eli-;U!TF}xne5!qSlrbrofq1aYDu!^1?WMZOB`o1XkYq+!pw1wPsL+O)_C50) zFb%e~WJ7ie>CODqE2;32)~uIBDU=}AR)jHJ8h6K?De}3USeA4i5wrr!4xPvg}`@7X`Pam@tc$yAFNcnDnS{(h$1`m zLjL~>7!`jgjA#}a11BiFb%%a%W9oT>*db&Vc;+dgmXrTWnDFmBk+(KB<}}={`H^cj zSO5b%GPlbraUOAhsAA=yyW#2)dh8@!gf%bz$_B4I5j=#uC+b~+(MCAly8^C}P=M5K z#Qq4KfuigEIg|{awp%8MH4B1g7oHL==#?(x6GQ}#U2MvIb7#qS+LoTJm55eKc2!y{ zgYFOa&|?;J%3d!xGWnlTouorpmyotr<1G=F)YkhAoR?&3K82s{{*&G!zCvBRrn#08 z%~9q4Q1U7vz7_y{4GHU+LlDcUC0->UVZ5`5JHJ=HPC+x#W(iRPn-{l02P3&nXWg&r z^;8cK=WTD09r{jkH_7Msodw1rKa9;)$sK3ABxzBb!49ISvzrpf8rCGe00?`^1?f+Q z;PJ_3O|gyzuBZQeliULs*Dv)v1ba4J`pcq<37>}{B&$G%ZLRF`jRfS+Bk0|3#4r~%8V zBcKv(I|!f4xwcO{Hw(pS?iQ?CnrgoQW7bLhJbf<#@(NR_&c-v(z9%4BXQ~Vr7&M9NILp9Gd^p4P7Y4VU8e=w#E)sX$P+xPAFw8zU&q`O^sRxjY zX8$QAsn*mW4=OJF`G&Qf*i0}HTv%z|IXU;}kJw_Kk*n2{`pp8Q8L z?XJ37kQkBW@x~9b_EYz8e2Qdk0Zak!_kji(PQb!Ati8oJ8GE3@$S}=sMgbQzdti!; zREbTt2zF!Hsb60nK~LOKyI7s6FR%5HXM>++_ENe|vRN8|`!9cFd#<)WoJIWlVUcLi z9dy)O&-(A4yLAfy8tl4v9G@#Dz~{j6%fE2oUVs7^rwk8N{ck`DLaCR)9VI3BtN~hf zkc!GdaqHp8)nbRo-NKFsb2$(29dv6kOWU~n-|zNCBiGhUkWjHwP`P9kRP1nL=W}S5 zAJ5Y~=sp-F*pE|AvxxctP14sOX5;Fn^r_??XLSEvMPd9); z6g1d5ivSuAEudlc%0C<};bB<lk-f|cGNewutg9~Xna8Pj+ zz&FHXGnif+d(EdO!N7Lo@&itr@|rVw!1EQdLmkq8$}8z__>T&3XZiJG3t{MqTr&=b zioK6ZmIV#=zxm5p-+qO~^eOwf9h-t)IeR_l3{^`6BF9E*KApHPQ}0OsznJ}a4A#nn z)+GK#y*o-4-9dSb{bnhtr1it=19B|&uv=o;ZTZCL4-PK>J)YWOoZ3KxJ&YJ9GY?ek z8gdNYwDtjIzn_cZ&bD&t2Y5VmXW1Z!^f&wX5d6R1#U)S!$T3*Y0~&%$g>I;qg8+yM ztjsY<9nZYc5@nw#={p?9oAp=Y9&d+0k5QPUt3!j;%Kr^}82}ti+(sl=>2Cb#j$yGA zQN6CTX)3HQJ!HwY8sE=nX*6^2u<$WO!eoi^px38kdVSXa1=%gvO z45O2;IwPJ0ITj}#7CW~4-89h+zW*Q5g(bvY@Gdysb`R`zxS_Bjpdh%_tqw_&xPuEI zZgON%;B&0b_nFL(sAMgfsmTJlpECn_L%N-65Nm1Er2B5a7>M2ra?puYd`WuV{_>RQ zH-~p)k?c=j(lEuWVW8EJd_^9y7i%ASXc!H|a#-nEbH*|}xa{9bU)B^9{`5{+Wc+)Q zdfz{-yW8xSLuVaZXz}fw6yl+jRC6K!km_IT;P-&hDuO!bj#n!Awgjf=j@(2SVBXnl zU^H@|V*XKzRfzZb@(jx(J~~^j!($SR-OB2#@m4y*Oh?mLUAU4PqD(rUXL_CbXSV*I z$oz|d>VVF0Vsm3OSOs0jCYhbnn_-(1RlIMIF#7HJ`UR|XWv!V-E3X26R=dI_qKOTE z&Rxy=DF6^85~E+dl%r=0E02Q#ma5A(Gu$iDKQzBv8^e#ptvjZu8L2|=x-6sjx8>D* z#K9a?yfsrn_Am}ZJ%`T`-aAU>4?mWc#@jNj#0ggpYimkF4E7NVbuul>^I=~qEDH7? zimK-R&VOGA`1PqCC%5xo^dt8b6;q|e@|Hv`r)qyN_ty)~=&V-B6`5Q!7c{sX{<^OB zaM>9rBWrN(LJ@5Y7wA^obTpkgLNSjX66nN_e|fTwh&GDk?c#7zVLVHsUxo!X zinu1C49D4On^xngi>E~Bs*T#_ekxK9i;~#s|7lxR%i{1~sC$_h*EzXJ7jIfT-OE-q zc!Wo&M+xJ^C@L(o3TD$ryKP-LmNO}-I!{rpv5juC>NtEIlV?A|qBT}njUvK=!;~Up zh4UwB7c&15Pv1h$P5^#j>o6?X*Jn6@%^}EjUY|oOSxzjkY~C)q85;A$bO-&-d|-@E zk$Z=fPu@_L=7m+Fl0*Ls*QEaRrVqI7En*o_!Jr}z~{&6+;lHiJS=w#0(4n247xf4k-LsQw+DJ6W#_FWF}Q}1I6>bzYgQ>5dS#7HxL zFmYh@%69c(UVB>y&>R`r?zqz(4h_d4NDW`SE}fGI!}iw(diPwzeE7Gj3UqUP{(fug z>(ZGTx{$@74+^`(r&i%kk!T$>=cxFHE#xc7wWfomZ`_BKExHY&C%bRhhrfCI`Zi3P zl$zDQf$0$Sx5m7s4ty45R_-&%r7$b8>0}klmp*{^(V3x;L0gUMh)N9+>~g#JSU+jF zAU_Oc6Vd3pTzwITHgmjWEPbVcQCTwELYZO-dapO1^1ZWwc?5C-A+i#j5*bm90 zH8-uL;=?+^RhRGQir6<6)mn9);0Lwb_UIBYbIj(U3|&cXG*N(W4ECmoJgt^^M_=OP zTkK?eI=Aqiud2wPIqYCE7~=c00=B{1L!_OmZ)o85N$YL_deinP>`;EO}W?c<%a|KhRa3+;(VA_ou2M!foF2@2*D7-2SrJq zciXil_w}98*%?cAkRkndU9$GXPO_Yz>|Ou#M8olUrH1MWi;|@ zj*tE^VOlm!!Hl^6QV6NHvr=m|(~$#OWfM5HjJBWw4*0>1}TSLSKGiB7ZnXK23gChE@96X}6?S{u&mGOj!%N`jDO* zOh9%~AmYOA^33WJA){$=`ee)y>>UNy)H606*LtZ?XBqdlbu1fi_nsVnI<2Fa*L>b{ zBclSAX^Dp4a{(L;TNOPBd`6zwa+GGC(x?0PW|18QbgdZ^Vduqo1Icytc6aA%P2R&x zr*dM;a$fnAI`#AM3yx}f+GeGW`kc*W?rUTY#a?f zW~-FNQob*5o=+?M#4%CX>=70lTd3P*737W*F!ND0zN;I95?UKKV7}HPA9#;Uw0Cy= zK)Q~2tJiCB6WQ)TRIPV;rL|?W6v|;Xnlg?)K9)Q4CEY=^ePmv?QkeY;>?gxvQ2XaVATd)guC^C z2jIfMcSUSm6I{fiI)1Eh@x`2gz~q9hk{tB9g*gN^`6d-l{u3s#fxEs=Zmd8&_U*-# zc|#^NFvEz|=<%~>?1py1*fxBR@FV*sK<-LCH}%ETO9B2`vYB{vp@2}gJeLmH%xJ)M zZhn;0@|f;GNs=vZq`%>dYkc2|WrnGrCTN*Wkm*>W;D*a|0Xz!6e=xyjE!)Qu@?h5> zIxy8(8dTZ2s$;U#A{^t&Or~Mr#(mDcsd)4+p|5`IBP#&Du*Gqr@+C% z1Zd4W9Qol&L09l(T;67tKHMpKC0PXvu~G#_D+$6&KIEYU8?BC4RA9Of^H7$ZRc|(K z<%U*W;BRuJJNaYHqkj2OF0RRo5is_>-{GiMG@xm7A6V#6sU?yO={ ztvK<$v0uK1r#59Z=n;nLc(v+>He4=y$1<i6|K2D;Whv2kUC3hp5Tb<*WSO+*VP?nyOsXEk^J63(Lc_sh>lSY3U)onbR=H$a>t;(q8=6EVXSDN{Wt zY&B_4szFJa8A*5$%@dx>(h}oVG$Ic_q`rXvxq0*+G+5?tHDP@)PaFt|zgG~{3D2nw z>q&ycBN>dy*!GNmZkc&{J3CHXmA!G3kn7#ref_a7TwL@_eNlFF(NkTz-=-1i4*3@``RKW{2o`R7xCH)8LD@u%{>AU|h!W>ds5zQ8iS$n}ws=aqjMr zF`Ww;V)1H%DowZ6``LE|i4xPTPQh9erE&Jk7M9%5mQgO}P8vI9sf#=PFm5Z21!Qhs zZ_t#W^k(_I<>7TT`Hi!@@cke^#_e`91gxVfBTlL1b}d0E&AoGXtGo#O(E500A*v!#f)jVN6DxN+Bu$}s1}KEk9izP%D>+u5$ z^MSTKZO70}WV%BRRd$LH}zzGC`! zTep$}X>j)1+{k|UF02q-r}a$lGlZQIpP>lrWW}Leq$6kiF{k)Rs&H4HULVr`hxQ0> zbF^dLyutM}ALHX>W{?ldW#`ROHJm`n3WT-LxCvI*etFNJm>gD6Z{{@T&uX0$;M9yHg^W)h*n*kgF6**E_b? zEmjU3pnTBPNsPdZZ&2MPN#2b*qt6+$~n7 zP9O`fe;ApZ?JSHVnu_(`N&l3vS`0ZM;{ zZ70jT8?bcFMwFEr8@2_n8$U}Bp3Jbr`(1J!|Lxv)BXdG$%E^Y>%vW>hs5_1}su&^+ zp1tDCtB}pI?U)Ku_;UXMympzh`0ZN^Ak^zkxTbXl(MQLu(CGeB^*@!>1LidF2i8HW z^}DM*_o7af$bM%+X=ykfxS`5}k-@ml6?DC6+-zcz#FM1=v?w`OeABL3t6C%4Jn0x^ zki#A`@OZzwLGEu&l~ZcyF@)wMW!JKLbJl5QsJTuA?lpO*<4`)&nUOm;KQn5UG}laH z+iNVnuvCV_e-5##sZ{4jJQv#bWLcHmKe<`r%aT{0fl~q>zb56*!-o%I6z^U!z3^~I z(y$8CoQNrTSHo7S^W%N`9}~}9odTBM3DCU7d}eQJ4C|_3a25iP@In9%pl{vxbeuo-lqXyCEt`@GZ)qDkkz ziOA6pg(8dA*d&A8SX{g;96M=mMBm3+!Z$+aBMRhh7*C5uoc4AJeALA(3df!$sg1-m zS*qNC%xN<<&|_NkKZ|puAxB`PUU4fKxK0f8@9Uc+X?>;--f%w5 zqp50`+-k?4n6Y*r!~579p~TJbriI8t#To`k66kI zf=Um(?%#2BXI{nhKx-~&PhiH<S_*(r5-FmoBfo`Y_QCZs~1h0k>fIj%s$^b#3N>J1bOzsSi!*zc|uKLg^Kk zt7*8ezjN@$K3dDGZQ&zJdOOT3RsYg{%>7c~bnVM{(gAbLnyYKuJ`wL`UnGp&Q^;J_ zEX@oim$a5*=;mhpVYHvg<4k_|a8oPOoB}5 z-Mr&-4dxt&5NTd)6f##+tCcJ6E!ETT+Nbr@;(w+ABdN-q9Bpj9B8~8d#+i(+&ifV~ z=L-PYex8co^7Ni>d1hqyz)HGh6flhLHuv#Ef^-TtN+l;`F1#Z&IZSY(lVZg7-A{KL zgb`^&B+*vgC-P|EmCLeOLA0V~*EkvcYUy36(dksC2KkP8%@VAqm|Mb*%33-r@5R+> zT#3%WYb-$eE_z_)%LgR;F|jd=;mX&y?PGNn2Zlf2b0EDlqg{H4`{Fxb>=&I#bvV}3@ffNh7`W(w$v!I zEi@NKXOyi`^X$Cl0lrGjFaZIoo=y=>e8g|=Pub3f~GsRhCZOn({8H{QU-esuS>Pp<;P2&SuvFNrnil>+Nk*Khsb1#!V4or>^p$$%&9Ob zrFkSfkth=ukR*r#06xX0h5Mo*C8;kO1Dqaj zBY5I?L=uYB^Eb$a&plKkep>%bWvyf;b3QsdTcvq8MH8=Qm|wsXo1Gl`Ef45M>O2J8s?klq@}LM2rG@QDQE8nM~k!jG%=6fS7E8T2px~_oyo7pe{G7(ZvjSo z6xR9TLAzNWntPY9dil6XKd8T~=-A_6J9@OWgXJB2> z-d#50wrl&4l~zH^qj`3g#j$zA5I5A!K1e=T9Lz9PkBvygG`p;pb7+}Q0@f;ru&q2Y zn4vnaD#}MYb!vMb2W9YxcSDKY zsJSm|ALDX=B{Fe8C(MJ#oJxaZ!#dQ?j)>HQSLHX$g|0s6A3r@MUZ3Z_2B?_kzRi?I zH+`k&$|W4R=)v_7&nE+0$2~^0&fijRiPnH*_;+Z9g5J$cY(EPkx{v4ldHruD#O*AY zW)Z{!m}d3CI8-7~2U0H6-{N2Lfxi%Es_-z)V^0_mz%?vzE!E#bI!ICHrh5%9>QPy$ zF1RMqYjvo_*EUM6l@vWX|0xmZ@8O(@>eyxw?Kck=G2$tT=Q{K=-SyK2XdWSKRIC&> zAn6X3LD%FnCLK>g%z4^f)3y1>Hd35tnv!ds6;v`BB~l!5=Rsa^HiWVFHaTqCiYH|H z(eWwCYhm2kO$BtKj`VBo6PwgO^R;C!i%fRGT~?vnzuUwu=k_U;EKKqnKOkvJ_&tS6 zP5KA)u(G1x!#gMDaNtmtwBe{LKpb=bz*5ar0C_x%BIW|+x_V8my>(QjFB@3!2RVbe zXa)?w$A-;(e=~t9;2src(6iH|Y4n+zN1U2nex`&{e8M|}cfy{N>lPltx*lN6Qmp-; z^Hrbp+50_EEi3i>E_T?d@ntFw$WSgTqa9ZDA~_ApuS>4S`suEVXrA{#cAkAcNp(<6 zOa0@c?q88pdu8iO;$XM(-{}Xd{`cw1atjW;O>5`s zE_y?MrZ+lAm=}gvt`ENa(lVeC97t!(4^$gWKy$z2x3=5#eP@@NHRs6WJ15-nvg>C_ zH&kpH5#w%!)AtVr4!c{vnuQsN{x_v@AZgU}b+xtGLK9#9UcP$4O_LP30+oK0jG_GH8eKH){8ET3|;=r+m* z_pA>GF6WJEIIaZVS8875Zy!HCw-Aiu0@89F>rlnc6xf3GTax8yN?tr{jK%Yr600pl zC)PCQ5bkTgFPgQ74DnjvFEj6_$QKdEbUDLc5UXe?!NoFjzX`a+m`}iudA8EFZX+Ewf zKh*wD6xFS<(KT4lh~g$HqX}(ppVm~o+zi`eL!dO)a}y^vHkY_Nl5QiuY06>?EipE0eT)WIW&fH2yCr?<^m^!R z79pnRz=Jof-&d%3Wk@!OZ(EUi{8tMf6$qy=)j_gPf+h|gR(PlJ;!G2RI(S^JoPoSx5 z>L`H>YD9Md5IDn3R$?o#yf_kCW}_ysRQnMKt>M=)9PD*NlEL-hG%r%$TF+G;bU3T$ z+r+dOc4RTnlR7UUswL91IcW?C*Vx3K%$J|;dlBx_jh}zxR5;~`3#w5@#w905Y3QrW zNDic{qhUmU_E9LgWE5)Ign)+v&y6| zKImyoBselRRD^xZR?=|pjBO?u0QMJaf2^E~dKbojja@RCQh7e!S`b=lR!e{_pJ19hrhL2~|C2vk<=+-MeVdzeHr9OKErWT&3N_^@M-RH$? z-Ur87=}tUg5;Dj!20u5@F+P0R%Qa_~$I>Fikn_6?A|40l$0-06!HXvvJq@T_i)Z~Y zrKau~ri{9kiiJ|zLRqT0mF?2k1NI|fT~|+!#wB>R9VMNkZvbyrt`?-;ex9UTLs9L^j1W8r-4Q#qSO)1WU`e$)UebVAbKU#9 ztJegg*%O7X#aEC2EfV(v>|6ypK5vB9?7OlU2*Satka(W;tgvk(Us6?wAAH|Tu+)B5 z6QU}DlgCPg#zSV~7CyawW4Pw533BYg|IV`ez|RfEx`r@JfX=Hy4J?&zyNRsx_BR6u ziH^Vqii5Fn156qeBzjy0W5(fz`w5vzVcgfedsr%xZEgdbQ=7rSlu@V5QPf>8Vr~t= zt#5f2M#e+Uf9_3GG<{h@NUB^mJpJELvt;*=x_{&Rfx@mVrH><7=MdPe&p4NxP9992 zM0rTSKmSFJi9*hg!X(6;)q^hH4Q27jXUj+`P z9D<35oN#_pEz{rm;bl;_WM@?(pU>k=q7Emcnr3xZ09f|HJP867^SSI{|9;+>0 zZHz{}{{JTbdyDp4yz5crr_6~@YjVqN19Qv6>DeLrf(%dc6avE-v=UJ9Vp>isMB<%y z#jn(q=bS3dCs2hFRUKfPb%!KuGwN=O&{j1?(*3y#L6f9Rd))(hA4YeI-xZL4l?4`Z z=(cvm>n+ZVQaz97In2kGd~br^F~*D@k=I_c|BDmy5r)3|7%Z(gI20|JwPw+lo#IRJFN!FCJp&;pB-1!aoO_e6Y*8etG2e0K5fueF(2sAmw$n6E6;m6{% z2SAFyEB^d-0pW);0OEXb%CPyowH!4FzSk@D!LUc-4Wy(>Bmh4(ahjIBJXF}6M5;0n z-I0}ui|xxVBSJ(9%7znI`Dcl4{J;bGUGOdi8=2x`Ha?B_PFXqgn$`TdHNP*k=W~cw zRLm%iRAaK1mi?grYJh#F$PT2~hWSsK=ywo5sQWwBMC~W)(H2RzF2~xV`*<4cTe&n! zB;pr5f#OtL6BR%5P!igCx#f^VD_WbuR$r^6D;jig07Ja}cv(|mP{UP#O>|bu)rEGj z_x1M?0LfC!MW%ZCZRFX5(KqjneZK(w?#bO_mgplNTnva0<>22IHXp7`(VRR1rR=o? zh8h)y*XZb$Z&^7Q8uwGoBHmgfxIpDOI!Zno2HEZH@36UK^VR4hL%IE_0Zo68XNk)f z+_WaOHB>~VFEi_bSIVApA493+9!`BhmA-Wmt}0`&hRSGYJ@1MdaeCgzgA1|`Glsqy zx8ixBUt>X5n!(}$$Vov*x5>mpM6yC*i4Z9aV0tA>RP;YwP(qyo()ar_4!(<*>n!E7o2Z|cJFnz zT2Eo^1rP!vlxEgh$%B#CBOP_D{XqoV-5&KbfTC#AC6K0x)#<60oM+{wOGK=8LIZTb zn%7f^m#1-+@1Xk!4W6EAC(opHf+xQZ*sRsZrNyWEY(P>gS(_@wDZgOZ%GTGr%TZj& zMl_Czw=7e}7vqu*W!%ad38#N8>RqdA>Z-$h(WA(8F4T~ME=3FNGkjl7X-{-9AMV*; zUpk^0JP)Dwa@5FN!*Z%dKTxG~b{5Xo4h_U$Y}K^3Zcf*-r-?b=%?Cc$^R z7iNyBKnFX2#$>5t*mlRZ55a}|rx&a79p24tfT#gYNYZQmV`-1Wp@yCC{`yyL!&w)) zDNxN3gG(@z`$s<@%@H^$)zqwm`q)M!QqB2V?K|yX@5DJ%VM1ecIJi)-x)N8kfTxKsHMtBCXycrz88r zDMOz>UG|q(%7BdA$@9FRURLNjDg4h6Ec{%{-N$2HqJ{2zT#_jgW<5r7Qx=Q@F>I9IifL_AtBt z#iQO1^Q2+)`Kr7>-(2%uXXXBwhmy`aKhZhQSwVafF9h}8V*$u9+EhLA6hkk7_u6OV zes|Mlccy;~m)m=i(Kp844yO|d7CbeGm%ME2?2_!N?Wz=N<{?dY+`PRTGD`4)hF2QFX=dZw{OH_OEy62?bB!5j((a!61CbhnIZz~ zG~c!QmcBh{^rhDnT-N;P?c#9nTqk};WhOlF%$xW7k-u~YyL_u&Fp|dkdF9*OH<8Qv zH}gl}%*uiXUC}s)O!yn__VZ6zNF_s07}1j>L7IcF=`Mn278Dsgy8epWX;+!njP@w)Qm((Sow;UvzfHRdLv24^|lC!Y;^QJWFP+-h1hJl$Qw{s8$px zNLvo{EwykAU0IK^QxK7GrjHopTUlrIp$4orFy7xPs|2rV0x3MmqU& zgUKRuG|@mcJ?f+M&z&`xj7*teI7nL6dY8r8Y9xba3MsZn^Zh84_Za2Q0;O1+wK04N zpANWx4+p4IkmIYOL_--x$5+S!dKn0;rl!0+5g9Hpg#B9U_i{>zZ|?9F)g6A(UlqG% z_~nmNtk(V2?2?LPaN1zFmxd_BUhKX9U_WW5y%;G@``kaM*x+SL{`TuCx-c>0vr&C5 zcd8Ck1j&tY&i2ho>QiG2+nO1G(zblB>&{N|gMQOrHzRkEIx#+=O-}rMQv55Y=k>F< zCz_BakECrlr*!%3BG0g)MvW6ByhFB=*WLKm=#UK` zF=Gq5K}Ue|o~c=d8A%MA``iQxd{=YpWGBceTKDJ&LL6`Y4?wQ2wFsxQJ}iM3}f z9lqFyedYb>CnaYO@s^*xyn#OZ237s`+^!>ZQMmg$e&ZYw%Q5zB_|aFl`xnv&V}Us> zyrD8i2G+J1VtXpLd#&*^c9zz4fT4yFkI?z;A<9Cx_X0M(Tl-WHkMl(+-nX{`p3b>) zeSlJe{0Y4zjs@yEe{U%XNvVzm*anYh==Rl7;ZmY9{0Lc9B3Zpc7pcrYceaNR3qMQ9 zt0VmsVz9SO4{MM(wp%R?4=*y+FH^J}n5`BK3zKbYP4kv;jVnmejN*`NN4UrIN}X-l zU=~{+V>V^fxxKEz*`LhE3^!6K!*;Qe9+5MoLU2mY$4DJ1lcJR zLx1;g!2x%vgovG1%m}j?UKZGV6U!zdOK{N*r8>jole6300F)m*))C#WEvx%hD+;3- zV_(xz$VK1rSfVJkJd9AP8gjeAN=vhrzLUd>_X!L!}1Y) zuz5_rq;+lIr0YB$XZkfRyeV*e*&S8Q93^+y?NNUGOy|t5ThM4CQuFk=(q;`**X5hR z9+*(?XlJK;)Q8DN-G@uQoGbU2046zlfF^N36p#yel|HzlymDjfeC_bVaiFsIrrE{& zWBNfojra{8wC(MT1}`|}Y_LucyXmnWC@jmUwWm>i*4BP8hQE#&ugPz$PV*v3YCNl0 z7|ei5%)AF1HjWymym}^>k=`(&d9(R~y#6PT^W@W|EVIuT7F-4O+7Jcb@Lb~&9gYKz{KAv8s_JD#RNQPsfHG} zr62{9F#v`}y*fdYiO$qM$!wKIfR~y~^Zhk@+;b_rg3(17b?V+D0rlgaGn(_R58vH+ zFlK^erPM{s+#S^aL+7uq1KhTpnBiB_fLZ?Xts1L!zdu6kbL>y*j#n)m-brLla2p6Z z&)Jqh@NMQ8J>sm!$7<7zmF~3&?b(;Tz-cC#KAUJ9_Qv(-D3sktb;*7^DfeSbXB@+) z2||>J+dG*%G^Q0ak{8CY-?&&7sHMX5mX68!`O5>N8wO{Q4(9+EQdF|iQOas%bFp_VIHh4P0jgX(edcVl0;Lwa zp_w{UZtoSoGg5ze@#O`Dm$E^~kCS0Pqe}zqr^_|{1Fgfki%q`+Fn1nh&J^qUVeMo7^lv};R& z2h)m9Gk2Ngi>8=lDn@d+<87zEJ@jZ}!pP{FPe^-uWerOFrXRE3Ol@dri0ZHdg+9Ge zqG)Mo@Z~I`B`<&Lq4B=IK5Bk4X``Vj{JPMqM$^~>mrb4bh3u-|QpBfrNfhL3) zf?6E@vLq`+kR1(sAYbn|zAKgu68{Fv<_5_`d!O=p9BQiTt7_|W0E-}Rd)qs*3ccN- zt!cO?M7HZWUIth!t5r!-@N4fNJ{4VzBNh+_qH>r$U!402{_{D&IWXIt*`)=*&AF%9 zcgsd%^u5h^`TY2^a9qjVoLQBD>t?etl|1-9Sa=BcH>I4&u_M#XGx81OVzcN8Cm?D9V(eagE1x0rJqL;odP03V>5_|wWgsvLTz zj?0(SjP`R*s0Y~;&_}ZozMgZL7h2Dq=r)d9%OD|+s^taS#PsO3ko&SC25fUSO7~<% zf}d+d18f+AUacp`lt}-OBoo+r3_07QK3?VK<~-@^&++>ju_Ni^wDbF=2QmG4y`;m) zw4eA1{b(uFr`cBESax&#(@P12#LT{rc3|-htCZgH&crLbA&rCOo@wq}Ve?lh2}Zd$ z?O_1P<0hWyORwvOyEk43b{0KJm77lvc&}}~LUxls?lvujvNFcmHvD+y#st?1#$~)N z#cq%wnq)XHT5D^1^I&+UCsEk?zrWcGfx28h@o1271Ob?GDZ2dWFAy3coa8&Z}>8E%G`#cr6%`-$Zp&Q0)os+5?2yj4ID5BBad#t#Wm-8NHJYaRl~6W8e1N&B6+m8CdNI7 zsBhgIJ31<7yhwdnWt>0omV}D|76rwbFR#v4I@?z{sZUPBo2g0}K2-)s#{IN=KT=8E zCFb;1qyB=yrhjxtm_hei)E%{T6F(4=qxjP2Y|$}wb$s}n5#QL>)!dB*rX`_q4W-&u zEPwY&8029@TZ)ZMR6)i8> z9Bf;@{!3%=#(u9bX5Gk^^2EFMYoqf-ADrNx*CWpCPR|-=;Ysej%eK~Y+bm%@&dKAD zUsPnt@fMk@)X${>e_Xwy=K1!GLM3ECR0j(hmkX^)+)su}OAqY)#oqoEgrf#06+%?D5$jy707 za|}xsoFRVxe?)y{RGUq-H5E#WODV;zxRc@pN^y#7af$_ZcX#*T?!{e;TOhc*ySsjA z?|tt#KUga(Jb7m3%*?TU_K2E2^<@mO4FMFY&n0mswIgL%+=?5_HuQDZvOt0EcLKz= zyc6Ae$SaNYK@wSq-*>5+?7f5pDGDVgI9)EOzrS)X_N3e1M+uc^X~w^SOwqs#YuI@P z!y7*oAd^k+dzw%3xC>{$;Nz#gko-_w{1UcnrX?r0jN1vYq#@D|KIiNNFm2;tUrCn4 z^l{?x^b#>(SWZ16`GI-|q^Qqej>h9LNt+}3iF*GDN7PF<330mMGEZoW?K|g#ujltP z`kR-8!mp_@6WgdUQIH#HI5s}R^Ud`W)jV}>p&oYNeMs5b<+Gmd^dE94;Ha5a{#s;$wwJJq$1dlSoHTrcz(l;<;Bs-s za~2(YB%FPN7GLnRsG|Q6gR?JcVRUir{=`;;I>iV{!E{_uPCHd!`==E-lhYZVs=QhA zpM0Sfqx%wNn7jq$(lnmMCOjW?kfuU3&6gQa{-%LWeO$JgdGm@=fCs{m^etH_2>a65A9E~)VegT$`#=5@{$!~m zsVuV0EpIzjnNQ8Bo7XX=samb}eTUcy36=;dn!Rk^7qt2!;W?mwUCT8pz>?w2o-acC zbu{S@WGh7>P5!zjT1{ZK=_&d=d$-|L^oEmH!SNxWGz?-^_Q3JpHGj`$sHI%oV~Wk$ zmTcy`KmrV}8TQ^etb4XKO4^&32fzTNlaZ6{e@nPzLX#^3Q*O};`+Pb&v_fk_;~;T9uCq&d$XscybtG8ho4jPh;zCQMOhPyq*%4ML4055Ww zUY?G+&xln+1BTU~i$`s$$x`@Z^y_6th`gN*qa}ud^K%-HpP%lPYeh^yh8H(#&CQmv z6PT;(**5<{keY22S(=xOScV#cyp>Gqa;K2y@h;P&dgtmoaTo@SiNBYju{TKdFErce6WfnthNrhkXT!`rN=M|*jTT!uYo(>F41kn~Q z;ClETMmd6T%cqZLCOX}8-WW^>A}ycMNn1d|TAf9$u93YgXv(XwQ_pm;AdHAGxR~9A z*Ta4#%J_qnN!QR|O|@wDdI`^0x55Sd;z0?qLE3|bF|-nO+Rc!V{OSCFd{i^-{W=r> zmQr#5ql%)M%xZu`e(k$`xbgB17xP!@AB-Cf!fC5076!*z zO@q6X*pxof9#2iGEVkP6un5X61Y}?;Y2J?=iH`3p@)l&*(gVuNd@s@vg_Tm&{vsTB zvyh2laHITW-?LImcGra8$-efgQcdPf&W%w5hy@*7nzL&L^zW<#LO*z0iqByu+HwP8 zOVXt^>h^XwrQepNSzKBPccs5ivy$(ei{MD@ub2tUq1hfl9J^U@8+NF8Tt81LnPJk1 z2#siUVcb5SLrNSG>PzP)wmo0$i3KqUrG-auW4W(i-c2@h0XJZRJ<0}QPVAqD3^Hm3 zhql=rxk2KqaVp>Ny7N))ANph6W)bqcAKw<)_DQEpNkCam4?S*Af3d+|7Crw?^>H0b z9KCMwsoUAxO;T{u%kCi*4HX>Xw*SO%Y%~cD)YjE<^Seosc|O}-AogIRF;bTdc>KWI zOT=`xgw`JI*LSA2P3{n;SVpxXoRi7JT-l9q_CGmOBF6wU4;WPl)A@H;rndF6n5)}2 z^&1SoxrCh}x$wnr;s+>2s|LMB!uM;Fyk12p5{9oNDwD{n!CLkZX=?f<$q9V1ij=Qy zm09d|>d%JJ*E7;4FbAE7V6FpGddzQ3JGnMQPX+xN(z1@Iu*tq##*`Uq;PS zu8Xm|t1Jvt?M{Eb1w!63FXB(^{_GR%}D6I8vzZ7**@U?oZZ*nVd$`Uokn_z0=~ z=U8z^GTz-a3ti+f1Ow>Tsoa1Lu7S_HCO=sn;Q$)E!J{RVY|KY?)*$~BQZab@yZ~~` zhEqQPQTEx2+rvz>WHD%;LcubLfzwYbTeI<1V8bf`!vE_>Bu)ku(Dp5tx5F+{Kq)17 zmO!MKa)Le31@-g3z&o1Mk2?hG#~ndg+uavJPEjn1oOT)G@mnK79YVX9#lHQ_Fa!tZ z*=MhSQ2Z_~;D90(E|GrJ$leH!P*7OYx4fXYN3knMI^78WY^LNF1#s7zd0}gI=?QH#mDYN)){ld>A2Fplp%FUZE zFhOzHTdU9nlV$Snwr{Y4CA)WIzr(sf`x%OlhKA)k!C#cX^V2egpflJ%k?~zq6I$;3 z0s)>%7y^fmH^?gApGT%)tkeIK4pG-!wpPOrY0uEB_$=r#V~mM z5UdRjO8oe7veYbEirL-B`B&TiYiRz70T}6AkHR*uk1ogqVA)i~;k9l8wMBOOMyXDA zgqSt)cjN=&-4{QdlJU}iBJ1^Bbb5Ox=vL6Lj3QGr+1x@T>Kr_6*>|Kxtv&Hwr8^$ojhOB=d**FRU5&HB`}eZ{faqHMApJ zmA$&n?ofFH=as&b_lsP1%FTGzN+~kLfHN6VVO<33?Zi znA18Bh;~<&%<5&*K-GHTOKd9g+Lx}-_Z(Nm$oqNXgyqq5=hnIdfj0s+D zX!io<1|(bc6XN1BV;XVbycjE-FSffpUyXM8*`oZxL21K-gS+HqLL)vKKgD65nv}|P zmrI-?_?0Bcvk9-MYukYHsp}mo`|S2NCf3=J;6CQBy!I^LZkSY%cYJ%fmOvH1jH5FFtC-{Q+#EmbG3~NB7lvntSWc8yDOm_wNH8 zV+9n|RaM8!tv@uP#5KafadEJ6-pFVEs(;v%f3n(rUEXpVv)dQUFAKaF8~Em+XK)#7 zh^u0_9}5;17Dn{fJy~uYrTSmV!of9l{$OhTlKl18y7mMhc*`@W))NsC@%-YV1Mm-1 z^Y$dY+II<-duR|ArhfY8uTY(#i90w>D|fg@BbS4w>L-KJX^h_|{5lhIG4$~8aB!$Ih83RBM>4hoiZ-{CTzV)k zi;lM(c4hv14z9fYl64=v@pf{Ap-k@MLJ;4#7m9VcQ%KW%r{Bba3Iyc?xLSXr(oa6G zD1E@$+VIye(tR*17*Yr_nKvE8@?>bcR^7YuR9d{NTfc5s8;r~>ub&Z_DR5ti+gT_w z_S5>0;O~$262OxHAoA_#(&Db)$q+_ca(u=}hWOH^IERuBj*q7}1gj~zJ9pN^G(h94 zoRhCvfA4#kpYH}N{*e}%iet;;GDXHC6rSLz{f)M7M-z)`2~5p(^W&M!(H8t~I7G~r zIx`?d7sL8tjaF@~q}a3^>hj-$88oJYbY}>Lu7;XQ-&f%#88SS`cYn%zoB@Rm7lUn` zYlUK}C8J|wJRJ7#7hrz#_5*<03D@qY>AXPE1{mHcD3j3iF z4fa$lPq4+}`WCN*-PGZ3mp?$xJuJBiJ$&E2>ec^fgjB@EJpyD?& zfL>D?+D1CF%(+#Qn4&Llc*fswmsq^f}@_Q9oe)ZVR zlYlnv%X&>5U9|glAFhp>hAQMmK*odq++Hlw$_u_>j9|}$v?bw**TB~JCF?lg<)mx$ z>A`2^{$(t%i~kl}o`;8|JVO~SKh>8LITb!&E{vpZ>uEAf6o{8k`+^`fAerVuNh;h< zI>qA@7inQ1=>xj{_J5>AP6WKM=JB7zC2#u@g(VHA*!SH)P70J8h+HD=K|Fl( ziU4t29ZPvr-Q&C?G(?DT{8oM((9TIi7e!S{9L)FlHRvXlZS!`jAhJU_o?&G^hOLeP zlq&J8EwyKs%YsVtjMaGK3Nm*psB6TME4lDE>c81g;&U6M-SbfF%8@kaS;@ntx%0~p z-whP+A5L;*Hv4lfCJigMkMIm}i&c7C`P+y7J)LmVAtum|rr9y3|2ws@A_JFQn7;E@WN9nX~{z`31B{N3%8AQwlHGGzOq6mp=48 z9+ARR(JIh(V@JAyK%wjDst)%Gmjjv3xO+(;z9(}H`_?L>m*!nl%cHoQbmu1oJA@I; zG!P$fUjr60FrL7lB{H zq|@A5|2IUUI#|khf^|S>j&F@_EOI3rN4fc{>Ty<%90D5gis$a`vajeh0cVY?=Vnbhh@y@H=Y(qcYW9Q#LB-X)6^dN991jlB%H;+p2dS_-Q2Nclj`) z>znq}@wKju0w|a??Gma&sntTb8PUeNnfO~yE+t9$Y!8EKi=oK2{o4nPbPg;`U6187tg31gov_Yh9fU+48m1ildOUdHK^S6 zB-rDs2y1o9`tmmc@O-HMJHW`?tE&>#q!_kbk=hKvmHX*Bde-H+_meZR5QS3LiQL48T}#vR7HwT6rQQhQ49^g!=Xwl z)Sv$Rr!O<9AlIZWhBG_E&o{)DL6ngxI+dV^$CG|y9!~;hdsu2Kh6A^VmVuFx{DdpJ zl(D?xu#GZ~P&wffPQ0vRPAMZDBV)O;%`(42k)kdKdlrnUEjKr}p`jr&6OQ5Fc&WMb z26|`)?JMgl{CU{?^Md899c;sn@5!VdR=TmE{u84 zenZr>3a%j=rOFQ`gR#ZUg!}vtdKAVbrnd@SszM!ADQ}@oe$-4n2Y2P80AipuaTYCL z(2Y}mlZ5(hNu3$?$^+rxrE9@Txp=B&2&hUSYV%TYk`4ubyfhYglfWXJ(29^eoV)`j zn6Mf?l^iUfx%xl-?yZADeBNdvwKSfzd5A5a1BHUTHwKs&N?8f+K+T zeA}Cip;S<Lny^A8%MwtdscD^ce4*7v-E?3G^LY<(hgF*4*sd~8Z&RXby zX394e-s-^e_fv^Od$GHrhVc*ELrkF_x5v#0Sq?I}Ad{5w1^H)U*PU0>LgVjNr!HnT zE=Lt)gyFm2z`uG$GcN2Rsu-eK=~$VWj)L8sx=#8Do$gabrjCHi2?M%3$(L^=q~3mI zJ0G4?-hTJ;LYbU6ac}EeFms?BvSe8B z;Rw>4V0f$i-vCd$T(`|!Pa$YGl5zFniVhuj=Rp*?4*nSXNHbfJ`?&L=QD(#DyDqCQ`2>+4 z#gaRo>-Yhg+yA#M`4F%vu=UI0xtu8f8H%TbqyM}eZNKz|9OFU|cM`rY=zo?WN$lTu zkJ2F)hq&a&`jh_mM25qV;oom=*X?F#i)dv8x0Cj-szCW5O+MG_Oivppk%jb{$%_K$ zA<)Heg{53@$KoMyOW1=v9hcDl{&dXT6aF{z-B1mG`88b3;oe-S-uq(XY_0vr8 zK@^>QUExG@Qz*Bdh&XL5Pv_mUu$_(U&-+ljvbl3KF{tY!>y;`V3#~6YQ6lE&ggY{& zBv1$gpEJ|p;F4_Q#7>s_-wwO^2F#^tA+p~|{_XFrk6l5UkwTuIOa2^{tD%TMRKZ1e zoqlG7_HnhTtq_L(<#^(nvGu|8wr_PygX84?kY&f|0m%H}aHJwv#~qyGJ^vr(WA6w?cypGlyGEiHDTA(9A9a{`Pnk ziENU~`6w3HkDtSV1)E z42c-K#x=iiARu;!eK)Z<#`==0@NcMrnj39)KfkOgYW z1LtK2Z3OLe-@t70VB=qISRmXj=N1L>b@haiVQyg2kXWwU4+0y(6AUGd+Ml$+1zD ziBuNX9I8u8*xY+rO0n|fvGD8}P?hA?%KbZzS`piW_w>`#{IJZ6KgvOCl8dI2>*Fl+{y*u=Bau5H_m za4sC}%!pfyY-+6?BBNg&FEj|rkGN5J3s;B6nAmV7{>ixs{oodNmi*@y)cWop`q#*iTR}qHK z1z;h>@lsNed?qxjPmE#KeeHgPD^)dPLq*hYxq=vid)1@^qj6%ABlLTJ26_FWS_q7& ze5RWZoqTzV0P+5LSqQrU=g ze_`^FaY>Nz=cBHjOH)D4S4U|1dA^#_7TI(bAu#rK{aIP{7=zqS6W|>39~Quj>bezF zg_}o#Tz6Vuj4PS&XNcB>r4hy-D4G^+!mU|h@hMy=yPBI=um`J1>9BlUy_m62FUani zW755(j08KLbqt_8A)aetiQF6_tyeMo8h?pUlw!SE9~6?6E#n37*|2 zq|G5BzjgkE!?#s|9H_uP#*%Hn&adPv=w$z?g4S35-!a_g#Ch&I2kNELO<+PQs}zyC zfwAM#fghcd_GSxMRH5=tJs+5`&N~6OCz#(`E@jVB@%_T@|7`h>S3-5G(hF+RB;WDz zhNDL(J$?P~u$oEhf){&DA?g4ORFpI#U}xRP$;i0-%1HHv62QrNBrqH3Oj&Z<^!%+d zo(226%WwK~HbS{@SQvA^DwUortw&6gT}}6ggVM_7VJM?9^4KY<@EqvSymC}D9Bo=n)cYqodCf!bhhyVPRb zH9tkCk-(U`!?`dr5BaIBE-36#6<4ZfrJ4aYW;-r?+=UlMw%bU0{KoL2n~+HzefpCz zslPQuKGfHCo+1Zz2bI#-FK+`j;U4VH)S)wq5N&n14RNKj!VAFaQ zkff;DmA}*4fIm98RKWF>y?MQ;s4#>BLkR13KW5H;jrdtnQlM*7ox&dp{DTDt^Y8M# zq;0wOpP4>=jLq2GT%eR;E67gYGb&Y@*l?)^ifun+l!0UH_B!oPqFM@N=+d1mdp{eq zT{Lb3^tog>aM?~y8f2VDc0f*)DFTfBU8e(5O=c{g<@i6v4z0vTGHqNIsrIPUB1rRv z{VwZ0jQzyoA*(zWm_7iRqW~@*TdNA^)>fiU#rr1IpqXCG{Nc`a~U%i!}} z*nFpqoGe(_{Gwa{a8;#0!D|6MQEvoJ?#CpV^6@3QJ(VvZHna%8!l>oO$HOH|OiGSU zOHuhoGI3AxGDI7C1$^;=7+pd3TYO^?pe>qYNiK|N+64u@2FZ`qZ!zNK*36NkKN7Qi z|E_EkR9G_-aO#5tLOnFqo3RP^?*F{N;CknZ`ar32`8)?$-$6ZGOOBXJ8fc81a(*y) zXL{I5H0#~mmZFbfavSZU4xXLV$w{}of*Z;B{Mou1!OqpMdt|Y=?Wi&l-v0S}MDoer zS3|$E=^Rn^12h4B)J>%s#SI|#LuCEWCYvo*)1p_b29cGCKXw;p23KRQ_84pD^7Sb^^(=jpdsZcPe%d z2sLj{q-Wg0lQG=QO1P%&O(@yXAF*pS5Zwe*-QlJWNNNJDD}vsam+Ie!)>8$!l5(q2gL>d8|Du*FKXqHM>2^TKHjKub(O@i$`6(zk3=R6PQ6O zL92EWz$#6SZV}Vq&!oONH{>yX8(pcfTIF)It%?6J+M9JhnfL3*o~W_bBXH^_w&OB- zE9Y8j&ZUvRaTf*);Z~)@5F=I0?xJI{>Y>SDw6SlqedI5ZnNZhu*GTT!%}TlnBMqn| zy|~&C`2Ax0lX6H9?Fn>{Z@+@AF4r%K*mI;~A6lVdMg-Cegc>@7sSKAsqxU=N=X;r$9c2w=gTdi?th;?lMW+>6-NMV^|kd11jiuufMl(rYh_v z>GF0z2D6#HV>#a2=<_CW$;J$IBjQ7K21`k3kY=q1=lC&TVyP1hG^!VZXkki;4HCwN z$!a=sqNS5Z=7Su?kp@IC=;*jbWS>PlRYDj>l%PzL-pON;>k_((IZ5En>t3^hhfiHY zySuw{)?ofC_tBEmd7PT8wXhO8>Qyk+Jm#4hmU;SZaZxEJwl(wEiv#S&jP;AYVO9l| z;Bf7kGD9Po1x2Bl6(z$7EagZ6^yXO!!;!M!AQ(a^o-R=>ggmHbxGJ7H1-hent?U>t zC8NRN5f#vU@(%pVq>i=o0!&eA;!`k4ZI5LVKyq#C-n>^cWQC7(w*zfIiqOh zwT%_-5`8$Si6-J*9w(1c{FupM;$Y@{Hsq^}Nv7*E6uBHcz(hx-PtntB74-fmskfwt zD-W4SRKq6y_i`EMkC&2t&3qzH7?oQcs;Mh+xfjX4`iq@5rxe&ULzKx&!B+8jUy90d zhD1fBUJHm&n;h)#&k=ShR)Xg|2P3`$BY#zx7TY-fKw))P>o8Qou!IrS3rMU zV6Z5;iJ{6O!eGuK%JGNvf&882Sr$?EuRdX8T6U)n-?a|ejVs}Q>Dw6YHcBPLB9Q7f z{gC0Mf`t}_iFjS4-c_64F%Jo7{{hhHqA}S!)CkndDK0DzI6rU0Nj^$MfaGl-( zoUs+HFTnlOPh2A-wxEb3rXxH8n<3jQPO`Sun)a7H|8-x(Wu`aKw{0P?TMs0)C}XL> zMmZx`KWZv>kn0A9hX)1*Mn*;k2L~Y#$ZE{LkV-3Jxw`;9UQHuxlh<4c)MA;31qqRX zwm*U)DpC}}!rdK4|jS1085a%V-E&LFfc1tFX3_(XU%JXJq7 zlx-6v@JJc@^r~*Zy~Qot@Gjbyx)GZtVX?ZreH9ecQu#YA?RU{&kbv&IvcqnEa11r8 zhMe^Gm-3*lIu{N14SHfWNdfhGqy$&MXZLNeO@C%3*)CNmBz(J6wwv}`4vWoo-lh6W zjm$k$-1H6dEXz<0%0eDp{($)~z4%Ql!BE;(e?G;r@;4!Ki;rWrjuNP>uF5{`zxXku zH3)C@yStOcbEW;Gw3t zk+dhntS3_L3jy2|;qwV}Hh083$yK@^h6VbDs;am$tbGK%0^j~NH*)VDUAZ(NrP#zN zA$7WuhBoTduUIarSe+s3?mMw%s3kG*f-}3>YBpvMv+EzAnv)ZW|QCI3n*u-c;rr za%$1Ze%?anWuH~+rQkIi6RJkYo02@f$H%_AfiCyS76l)4zr*7vi^g(q?Fzzfp_){_ zvX-dsbKACB$Xt{b+yyWiqaDA2ZX!b?QW$7!kALZ!X#CM-(a&8PGyVNz@9iA}CXPC| zca!h}8yKq;jgR4GU*h5^Wa0ag(-%p+%xybA1GR1mYn?MXwjAijW-2U=*f89Zg_iba zMB&s1=guf%jnGeTmfekwjiaNZt*x!Sy+#l;J^lW- zK~_YL2oE0_0MYVi2x`WVg0w{j&&KRA0t?Z3wgXh5MTN<%XFv>D;EPmRBa?Ev*kNtU z`xLxN6JD~`#fPSsIs5bMag!Le9oFw=o6|jgmT}dn1FgkWt(4)nm$M`0WkYsC2!lM$ zL?{i0Z2Eo!$!X0EW}2BK#ft~&1H;#?6}yqh8Ps%CL8ZCWtPR5e)yZAWK_e>9hO1xg z2d{6NQo@rP$P1VzeRse`lb3{8qS+!HWs+9702et$XXBvo!b`@8qY66KW2X!*Tiw`g zqcrk9JK;VPT+;}VcXV@y9@lP-HNA*f#?5^OHC81zrM7;^>52Wj6A`-)=its=0FMj*iNzs07v>7}-X!ukCKVM@By668w&$P8t!GL>&^Q{hU3~Mb@B- z-kdnQ%VWN6XI#(=htbNq$_Ra(6n+Bgbuan(UKJ(wdhhL8nBO(!45sa&1d8x2*ww3yN&L( zLQs`zd=g#6Ms%e^35u{kqd*gR%D}OE(j3p1s9#v3nHkLb0=g6~T}aYJ$R9b_aCyWo zcq@}9s!PP$cbPrn+H&6QgGEvF6Zr>5pit+vVzW*BJ<>>$7@l!DRl@z!{Ka}~;dj@G z%LzhymF=IEoC%;Uf<>R);#`%SF^Deg;%}K3{t#%0jx(8r_BZ!!V)b9{F9Tx-XXmnW z>}v8pCcbQ0(B~Zs(w0x?*rH-xw}>t4`dxT zvzuOu3ibZT5wmWC%U(|%4$i?4+C$C?u@$y1h!^1sNF3cWU}4-aK-(Pq;8}t^-5jo^ zYgm^uxobd!%>FmxrmmB~1U4`*Fyav=iypnk^X>2gegAiw@}z^))6-K@hGdN8sXt2d z*|sq_ZU6Q8$aY4!DUO?}@fL`5xcQROcfgge2O{|hIMllgm7}b|)&dKgq6;n-F*pF# zBWgAwgSjeW!CZnF)kth@!Y8ZRw(QH#$Kz$bz0^?65*GccgQdh4d#`k7^+-8Be}k$y z_f>FbtO;4fS>Y;+wF(CzV!`M*M@S^|qQg4VD`~SaVm@ovPrg$JiqR)vWW3C(>%laJ zSkYmbOj{S5$wcYGJ=7W(MfoKc^k+-+;U|v7eh9C-gyXjtx%HSB%p3&N$>)P>mjMC5 z8zdx)<_E(uCj=FMI8z-R8m2mCjP;Pq?E8`nF!od_(;KYnj1BN6ZHK!Pu`kA>K@`G! z#t?|8*)fvINjf=j+N0szSdu1>w9(Iu&rMp`$QwvIE}GS%zh87$T&8c6exZD)}DP zf-L(03i9%!bu|3^8HwXUN(ypXudLre-6BC%B}GXUNb2-oWJ#K;R!J4d1(H4W|^)Z0H#a0EprHP#LT zfLsJC*?nh_!F@h2RS}Z0lFvWU?#3>#Xm@W%HMs?&&H_GF?Xp!mc*ZI8mePKxjIFtD z*X5qR52zoTOv8=aM6m&k0J*trFK-9PsZPSsY!j+b=*o4KKl(Y3B%VZyF(6ZCswk<% zQxHtz1%-W`UB}Us9Xa$>pb}oZY=-o?Mpjaj@x9#kTx)vV#7K;yl@-%VBc1=ugZSMZLF>(WJ zx6A_M<)2_^ma%XU-4%zib46k^k0L2PFX|@UH*VJ4`uXhyDhesK21`;>=tr9!V1?XA z#wn*6myrjMkbm-vSIUByAWA`v2FCRjzVl-GKJzs{Q$L&GqyKk-6!V%&5%n_&1V+gI zpIBpKVqjurVnPe-I-5@4+61H-dV?HJz-E-&x$K~+k?8p$sNdSIxvsL*u=6g9B_8Ou zpzz5Z@!-ccU=CTrS{S>87vfwqnJ{_Y;#&wZ^k-n3O-c6nslM!xK5eyJD!AOB+DM4I zc{rQo7Z*k#`6??&Ln2QOYeu}}>bybKp$Dnt)d{$bQ&*KWZQ)L4g=G5dLjoC@?|sgG zB}1&%6i9K~wVzBEP}@h+PdtJn{{vT2tz$z|Bxe*WR@HV;(P3?iyoucYDaI0lj>|4A zto(70DX-MRnYLs#VDFY@f8D0pCsI{B8zGY2#x+W%!>lAhoGFBJiynFxfjq_o7S_Ao z7oVt(fUxXggytn;Sy(a)LCyYrIWSM`s@y`B77*cLJU%{)7m-i(cW0~jPrN>MR#FnW zS&br3pqg;%Lndmajh}9$uYLsgkOUK|x;s@bl&^Rw1eyxHI}r>l%5ZM!(}|fRR=Avg zi%B* zh}+zXcD}woxqxhQytJ6_^{%|tW@{I?I+{w^W(;gKFaB-n#?TUB3CtMC*CX3Nr2W|m zNW;FR=T+fTofK*ZpdpsPUqt-kOU#kDH-ndV5O#1v4Ij>?TtbE9RxS{6T0i-`O3LwViTVYp|*Ls~o~=1^5KIDb)bXNvlX5fb3bL+6lB4C^b23aGnV zra;XqQn11ZB+1_^f&)fPUU_OP_UadM;ajTe z_ZZvaS=ANMbsN`yIS+lu;k*t9na5|YyRSw$e7s<77aJND87cGQhoCxjOymX^}e z(#_4y8>j7&*C|+hJ#vOrkM&P=fV!7!$SvqX!(E2d!r8k6-x$|+E~yb!%fmfsmbVMy zc{Be6sULks>rl{+guI*PBI}Yv`&S8^3ElN~C&M=sOer#h z;d6p=;sovYa(JG^0o~8_TTANq21=KNu~gW1DWc^4n;W-~vh=z0{L29Upo&U+!Aal` zm|^LWf#!LjpX4LhdFxrd<5&zEiHDVu#;r>*87I|WM;Z{`qibtxJ25eVg^B5M4HUesr7-*4kIzCunM=Oe<&Dx#S+-5=D^aem zGD$y{wV(jJ{ye-2Ua8i1(46z({}Q%R^fv}S*m!yw!++(K*h^1KONJS2gtK{aZD_%oa}6uQ^_;nuXy8WlfdJw1u~wAgw*z3teU{6D(c+< zO0)CxqnT$B2kU?#X@0y#NiBvpjw*Z>Eaq4ySU?k^eu5(N#12$2s@*Me$S^z9i3C2$ z8l|PJxX7s5p(Rnh?T*|9YyLjR`VzYXj*gCQ$@8+Yv4Np7kq{9lx3Dolt_Z&_04b`G zVO$#q_1mr6^eYzuHZdD%y6P2+i40d~7am(;xwH2LJNY>;Y%S_)D)BXMmBv0a+o)b$ zU7?h(uybIP5w`v)w4`ofm+^T(7iO^l^M68!N>;o)JJl9!SSkBp2A3fhHTy*HvkEtwR0*ssL<(dUPn5Y)lt z(Qc#hA&{z>|3}b*$nXO5!J@f7$fKRGaSM0oQ|iTmGKAA+obroL`oIzsGiSALw9PxK zY*7dFlxvKN-+}gJ0y;tTYIW)bTWOzfbe3PG9bnvBzgFwvX|umIO|0HmYxiojCm5o& z>P&n3ZEF2%Mzj!=T_6f-(&J8x|5mJ^vuaVlOn158T0rka37gOZu#d%^aSY8a7&e=u z>_}IVN_j;=7iOYa2XM7t^P9rH{g%C=-x^*RT%b&)&%LgdIF1`kNG`~4smYs7j%wyH z9OUtzscXS%LX{ojpYkjGkpepH9hBfnjmT*=_O|zGThOP30(itJ`2z=Re|WTq+<+c* z|4tu%y80(|+jb-x^z5`kx zu}Cb?@$+A+gm(49*7hWQ~%$q!qHnVvg5E>`ilP z(VSC9rwS_BQ}fM4x!wg6wn&QsJNY7106U*O>d=8}4nmyQQ^W-e~v8UVT(|@rVs>N-j>mzuYU1 z_1Gq0w+orS+?!xyi0Hj7ua_m5Kl%b)QQ3NVlYU2tnv6{g_CcaLe^3(EK!jy(JuJXs;*V^43D)7BOURYGoE23B@O@R}!2v(o3pv$f1iGZ$vnItrD`79W1>lGE+fQVJ(1pfYm}4TxLF!{uTM0tyZ8nnB2h%U zf1kKNSc{&5#rdma;bH1k*^yaNc?j)(6vgLL$jJ=guFF7f;IJkizFeW_K<+GE;qT>( zr*C|>Vqn3gzPwnid|0p|H}?w#MV6G4qN3u@pFhRK#AFWOjv&NMbfkbsDc5SW z>48F_Gcz~mTSGWZS}j&U1ipjN;p{JaESA>QY!L(*WT6XPx3fy>jd0l+H@msDd)Ny7qNq?VQ`Sv$eudpA#kPfN`ig zk9uMu+FR)3iQLbhvx2O#OyEa-Lt){b3yt{+v;EjGOvU#re-R8zU*&-{3N0@a*)P7r zFYRi|$|8TG9S`p5;Fm9lQ2fZH=(L|%2w^LCVUJ>>hBsYk>Y4G0m}d1w(<})|P0}Sv zb!a0W3I5ErsYR~x_KvXGRp3yKc>IS2n3ERdRxdfS(_Kmpu872%9CAD&cjfs_dg+}$ zcL75q@b%{oVR1I=lPs8iVwJ1Dh@8G!ifEd(RsHMVIhBc@0B3SbK(ut!Bp1z2lsqaPe|g@*=LJ99MkmZn?kbEZG&GAs(DXPw75NlkX{VJU(7B=Exd?<0Ci4MWBx&-0 zJeF=;&_(~01N+~Uu5IHTI?D=@Z#Pux{SI(aiL|TscLKbR3E#r(rutRz|5{DTg)-SZ zWA%J90GL7)T~JNy8)l!;d+jSw+&x>mCo-szcpK_x9ca{cp=4UUJHR%?jkb8RwKtaUYb-cw_U1sm?^1d zacK|4Izl^pH_RtS`}S|S#%(9;CS^5;3iX&V?@&4!CwhK|ey0M@{)X2s z15|O-DgQSN=X2r$GZaIbn;+`T7b1xHkGHmJVef4lifdB^J(`67dK$zv!)Yz1m@fn+ zKvkHwTqwu1&JJ7+4UMf#&YpzUU4gOj7*4^WoJE0puK_=g%Ei|b=d~Q2LO(J#Ftmt_ zJg4)cz%VrJC*XfGi>}=Rz{W=Jt8?3~JxMIlcx*gX2@xgSSnmntDJ>wf!*6epDCV=xGiMx_*DY-jjFkavM!)M#m#kax&_qzu9Sqw?+s%#Kh0@YhTK>!x!FTOjJbwB3PA8oWT)FzlzO zCLJy9;L=iStVy=3%g`l}?q^RY>?b$$n`+mN%%@rJhjWDEfrpihqz}icOpg{G3hBWP z0rNlr>dmrsbs8XE6Lk$G2>Vp>`P)3|on(!hj!s}lHNngw?{BPg*fq@m8+ZM7smd37 z0Ir5XRO9JXwry0a^u?jSHxKq%5d-CWOSa2S+I}V4t}tYAw3y!=^8$EyTpzBFU}A&K zUqomq7Q_TL4f(mbb}Hz5{jU7Gk+#D8#J%;d+gcI&&z6qIG8S_&uJUcF&=wq(Q{y{` zG=SmGXSVWv(aHZ&4Um4X_w5>}it}X8F zS_l@rKud9_xVyVcX({gR?(Xg`f#6nLg1h_6IrqNz#>oGSWbZZCH|P9B-J~I4Z06o6@{QAu}BvWGYwuASgRq zUrbC4JSd{WsU#tIK}7;)A#nMX4zjrheGqW=Tge(+9Cz1_n6g+ue;~h?t@?seKVJ2X zpMdcwWowI6uh~p|qx%V}qwDb>1Xx3>Im{+;jyAaAcnFZpuAjB~oh13v-Jx4H z58NN5YB$*&HuRhfhT|*U9)-6r)tlelx*v=~0NRZ;u8KB%Qk#aUFF5Aq3@8@n|NP+v z>rV~-^Hu-Djo%#iprg-TUIrwyYU2?RJ*A*pr9jEY&Gs8zPJ3hUY|VCSb#-;H;N6|G zv-MGc`^gfe>Zovbm0jpiSg~BkLzQ5?ZG!c)QLS#a$&3`hlelvH?LzV&3P$^1$NK-g zg|IMF&0O1c#M^yDdctMVzP%gE60EjV2KxA0TTd_|G3G1U&@CE>RtJwoWAo(X5<1sTl61&jzQeLr7~kz0 zEN2ny5IP=hp1gB4r_6?45C5Sz`~FZNY!$w8w4Ivg?*?$2W6nQh?-0->{!TMDmiS=| z3jcZN2;ICp*O zX&vB)d@O!8r+aPYd1idNq2A~UJU%#k3MszDggyFL%?r0-iH7NyNN|~k7Am(Xa4&nt zFPg-&<_XCFI#=nmI$drL8V^T#dU!zbtz$0wR<9g8*_=qH_WP!nZOF)pTXE*On6t9 zA7<8L(M{g+xrj`AAV5ZocWGkd^aaF@+|-d(oR%qwod`PUp0(L|9(b2MnRv$<;ama6@e^(D&)4)_C~N@$%wA zv{}IkS_Te#0s8nSF`I(S*I2aGuKC+gEbUMBzrUo~A|*qqZh15VSDlJ1H)#2jS2N{< z+3U`+YjoAZdUxO3zx<;fuZ8U6a`&prmBuEk^P)0pyOZPn<2n`Mv9L5G&)e3~$Zr}J z6WxHLQd*%7Z84@gQf9-K;~LHG=&tugeO*ijW}1g{5r>_JP_dI@e_lly8>%fOT@w*> zmgTk*ofFTaGX8*7H<^mL*D2tUVEYi-w+9k}N5RZz|`iF>4l9PO`#NQ+F z`aDxc?V0CGGn=uUX4oAhH61VS-+cQbM|4XqtdG^~wzY9qjlHK@=9=cIcMA_U*2>NK zpCTh8@k8(L*=%a_Q=*^BKU3?{jjjr~1!_rr^0|MA`__i^o6LZMf9`&hlK)nP?w%(R zk7t{snn7Ykjs3-jwJzNC5anMTcT@wdTjJe!m-bXy)HP`#T8NGH3R&=2rwkFs0U>*Q%b%8r(tZk&c)@Ei+#={ste=bJa zR#=Ne!)8;=ooXTu`6aK>EvsqHb)nAj|K<1#UK`WY*9h|#axfOLZA-#nU40}^Mod^WueySm+;xSz3DStv@d{sMlLlVczF7H@ej{rXtxx#W% z-#@g@?{RGj_)`_{!QEI~Rzi&hxq)+v>ncPw1vOK)cQ%cFA$sotTCY!FBA`?65(jZH zqt3gtjomzzM2g z-U+cJSS!zGh2wU6?Jj9-j4b5;zNF^yN{X3_G8$l8Z@z~|SAmu97> zKYq1jK%?~s$H{zu?Js70Pu15cN=?S!4{ynH{-C9B802i_^b#TE%~WUK+Ed?YrLMVc zBomNG$jVUf@2M%vl#P#jU4c3x{KFjQ;t^-x3I6gbF*ZyyHO(+Krs&z_>Dd*0pH0^) z<^EeF-0F2*w{k6cZ124|tXr*sZXFU?D%h6P=S;1YNn*LM$bY1JTE1i@8 z<{sxk!MmvA1ZSXcpa2p4VwdJ{0TRwL2Mc0Bd0dv40S0|dfDcoN|IvMeUk*UHxjAec zZIDOtyL^~CQvEx%^ObTvZr;iKpwX^7-tl|Y#B-@9$RPA|a3upl^OIco-f8*B6UybQ z>cvJ25h#e_M`E)xu5NRgQFGiu4W4DV^3r>#a|h+OWp6Gek*Gm#FVCCRg>2;}xVi=O z>~T;1R!ct;{X#f@A5eX~K@7_|D!K2@jzqvrj~rB|BTixO{b_hx+v<-t%1|lSuWEjDM|< z(6qtxtJ>*lub_L$)l`#{WW1BP$_ngw*xucosT;1doW;=59%Oc$mAgb;tMINZ;TvFN z+*}z_p13@k2#zZRGE60v%<>SZWiHPtiUk(Ebjx!`Ho3M68g;>F6S@#YNc zkFku)$Ty7jx<@X6aw4tWR|CRBt@&!}lI4?RRs3Dyeo)3DXYrg^Ip{n7yvz|Nu{x9(uM2)g|(uOdIHU9Eg+yq^MhHSxP9ILx}L92yYo7PW}3%i28dWE-s z8bLJS!#bbXjE=_<4uIdA+Q+Y|&y;CDM8c=@@k+{sT3lLZFCR`wjM##7elZX2gkN1b zrfS032$$#PwmxpSvz{*yq{|;}Y;5{d&Bpj)%*3N|&QOyJt^&=YIDaoZVlx#6{rQGJ zHp(AGYJEAYpl7XqS?>D{WIr};1CoKJM5XfB$==aOWz_L~RqJp_GpSuDP@Wj2CE_e( zikmCEbJYav?F(A7AXUiSn6ClBZ99V)t%_b=tgpLCN6zLN&1~~R7*Pk~ zkG}*Fca`Q#nvDH0rVHOGiegqxqA2@;BlrG?Q@71#MPf`k7!JI)>{lFirdNdcqUmTT zepq{2h{%(Wt*h;4DfL(?uGY-H`0X!OA$>=mS;vrB_t0JkTVH=Cf^a;P2S>e@Q(pd$ zIV&|IBO^02l1Bk59l$|>x2l{^G#yXzE7v4WTA9eQ% z-EUCO4}{f9@ixU^bhM$5;{voUYn&8I9Da%Z@Zu%wC2l6IYsPu(>9E(TvUk>A;%~>| ztgF^$Xt})dw_#$O$*r=;PFo#fBsr~;b1)L;y2s$w_DyCY96wDt1D%ma3&(jL3!649 zR5`TNDYueo(v8V22+nYbPnDZ7XnT)NS@n37tJw19R=r}%+V!#Y7GCq#dm>%B-N&r2Gv=4>&9zzPq<$+l5nJ9A91&@VJ&>#b%P zOz%vl-DyTN1GX5M0`3g4XHXnc(RO{e6La*_YqyHKkXx$wImq|Y0UQ+%HdDw7OiUJ4 zi_c+^SKKL~Q&{IH0b4|L| z&Qut0-qcaWmhZq|+F@nqDTgfF;4eD z)|9p7(|^Ud9uVHI;z0OB5VViPNY_n|*GkR|^P&^jhJOWxVl|`hPK=LQ<0n>R{A_dK zA;L)pCL}sD+#!6^iVrK6iRXS}Xh@Y$F&A~=p#UDnpA_M1m&8OC=Y8c&m2OZPjyp?qy5$ zNttPLhnw(DC{S$KM8aVeI~O>A<-fidU5U-TR@?Ah8Q_c?Utw{*W9nkp z&G@9gDDVrH9<5~8q^wtFGKQwyFZ+mW>ePdAY8}PqgxJ`v^Ye0_qWsF3ee(qe!Fugc zA4!4Xlao|ZsHO(fahT8LxOskwmwa)Khj$v)C~JUY-A@d#Ca&4=>ZjtS{z0gaF)QJx zJ<(Nj)VJo~)&jLZr~&^G=|e9Z>^Xerrvvns)u)$}wvLLS6ErAEynx{85wL4(jjEf0 zg1@YS_b+~5I~GEOKao0$9B(P1R@!H|O~XA3du{nx-{64359eJeM(i5b>J(cGOZ3+) zjPIJUl^@%Qi+$+ZjN+pyJazLgRA;!yB{+0cRt(p2Uv z+z4DB3vwxp0vMAWiyZ67%&8r;R7rp2aR9Fu!+9&$1A3ftsxHBI;~ZKy&R>UQYUw9;^MY4m7S$7kCr_VMqG zY12TX{G(f&C&C!~k@8MD;`0gz@WObubdmx z9Vw%bKEeMT*zM`cVABExYg=+3ceGZDb~O(aRyH`UZ-<*_gc478Q>*poKN)3x-~GAp z>;FB>k6cPJ#3-momn5S$1I9-+skcB&*H%mJRzln^;etrEhrjg>cSR4HLo|rkag}7# zqLBtUvUAC_B~qUf2E!7D_X$V$G)p&6xRKn-;H*va237M)VW(YCdUb>sH=|`;LrGkv zA|QdVwv2gICbdlxp;@Y_p*E%Y7&~!@&$Z;oQTWGQm;y`PJU|k!hHM1rHd_DKezCGJ z5L0XLK4-Qg_4NrD8kr670ntSs?)p$Nw$B*NB=(cZbJh`MBziohzVH|Y-<~WXVhZUb z9b@9ulDxG~Dtr{L(tmHju0lf|%_xeK zuCJ~nmMd^!M*~i`Qd|?GTta)&*p<@W#*jG82st*i`^pmlqNXst^$U0&LDxRSXF&qm ze@t&xZ#zS6IWbwTD6hYGmN8OO&(c4FQnikBh2k?U=l_^=Dn*)UeV!12Q^W zxo$m~aRb{J(PgZ+P2Z}@YN8MSP1$?I6jEOzA_8gF;I#?-?{rPyaEc{$Nik+VA$=t! zekLYeFF8vw8BZlSRU>*lf2~DKXG>?(BGDd5y{O2lt=%Z9klCSEZ;^%dRjy3bP$!^6 zBVgtsgHYv)CE?08p*ATD9xu!T)pPF4r5VbjnUm%$eG#Ly34`2-di=<2JmrCu3KuN{ ze;jQPXW=zEf%%$7@_jwqsj%a+RcPpeJ=5#cG8$>u?7+*}v~fyc zAX!v&2fhUrr^iByqs&{3p!(1Bd46ON+Wfl|&Am$YdvAzOY9TN)hgotuQ1M1RcXqGe}8i@ zG)#BBA@L_p?KVVS(4hV4jHRR!CMZ{?s@o>(?9`e>rS`LQ^~WEpN(I-Z5(meUrJ53_ zMIuOSCd)ZCH?Pl8mWUNaKfjs?|I6wQV$~{C-NAa0D)jRoZx&-PfpwW1bY&wAX%Fj$ z63CkO^ui7p$Fp<0d>3^NtB0N+5nhDtkle+eD4;-mLhWnO>ooq3`4X5j;oVpXf!byP z>8q6S+-RlxplaG0kggTDcvn>9yv%#k&ePExEdAr{uKtRUvv3VS zJeqZN(6ovy*d8@8kTt)R5nNDJ`!`6?#r?n2_8vg@O^BwI6!hZr^|BE+G7(?BZVTCL zOUAUyMw}N!HTouKCfK3d;rXqr((p_+Qb#4RkG0K{XABJRTE#y?AGrHLgbD>X^#Vg_LGlL@=$$6Xt3g(>P3*qDU zB7)H}gKlPbgrx_}?Vr&=Pfk`UQc4d{K|Y!A*wy0JFmJ2h)$&48GIkORO^ZjDU){C!9WAt7dkTYAWgo0Q_}D|eUvM%~mrIfCor*SJKwV?zX@^MT=4KkV z6shM-@&K#};Yq-Ax=@*wU1@acGvG;#y{7FE-EH3f0J19-8nI|`{nXT2c)hd;3F6e+ zNnhl4kxomdqgQLqd?;#P;ZL&lOg!XFfI7?09;Zzwzt1i3B%$1bw6qEUNBMbo(KUm+ z0{H6U?rAuSP5+k*fcW1COTp`KGtO~Fxzsyr?1T1?(AwCcV;>w z+OCHZh0WfN)29QtQJPO>tq4~Q{~!fIZG?64BiapDjda+$MMe|2jEG#Nyc1WTA_yoY z#hfKFl`)b#sXtX=v{@B2mz_pIoyun^HilE`f=dWO8>Au~HDbNoCd8Hj;V>^~*T1g} zJbC||D12>PR9M&mYP+9$*h)~iSb6{LJ2@d8GE@KP=k}y)6Pj>C^es_M1t;mp5AD#G zve8D)H9wK%sAR6kQ+HLc%M<002s$Sj1Lw8>A2k2Rc}0_wtsH%|r`zlG*7h~D>v|1# zay6mWKLRb>Ym+Q13s(Se4HHLbhq2tKP9>*+>yuaT*p9$5axD4fN2A(e9@||zCKn>HeXAJ|h`(m(WkKa}UGZq~D+iCH zA*|a9IUhIS_KnnE{xAt~?z~$5X&e60-iV{Ku`nb{3hb?LIHagQucGugb3fjg8ea-5 z=!Jb)&LlmGpaVAz$^3Hjx*1mQ7!cl3?HF8rlK-(tAD|FZ>FwJF1CWQ%Hy5J6ygHN6 z><^)!F(3bDczgk3msYWp7MK0eAC4GF`Qa9`dIA1vVg1TX_ch%2(IRp2ZHzj-L?AiI z&WU09L_)_PmBSWg$jvNjxID#>6(DE9Tl-1UiC3fLyp8t2P*PS2ru2j}9= zlj1yLf^kc!tN86g8tnI&ABmYURl=dr$= z|7V@oiP=bnD!hiyw32i)9KRgmpP~sxu zRLy4<3K{Qjc$1>y?SzbG9(ntrb=MF6OWM;sFy<;wdeD6U0V?v7YK{7rFWE(mdmMn2 zyaL>uS5KkX+LaZVbfc;7JToQ-ifexFD&Iem7Km7-JbnCDMEP1pA{_WO)@@l~ZNy=% zj4dsQfwPoiTFz`{&9Hw|mLI?|N5|sEBI2D#Cs+^=C~nWTKboP6!hm;Co5ffXYY_`= z%u&;dH?^}bDiScEdw>-vUx4~QwW1b~QLcQlJ=W%-Ts80H zG0$DuP&d@;wsswCJtX}C1s{pOkeI7CN#d+=+d|GQdZ|4uF3Eqtf>8s6?o*?dI)w1}u%+U=YRd0HmgFs|rc zBcyMhb!$(sbtq`jh{2nrsOIinvD${D=f!era{6a|i&}P>6Lds1Gb@!JT(LGQ4NK1C zrC>=7bC011{TxV<9i2*wPEPod65<63++|cI)QYe5;^g~SO4Tn#1Aspwnk~aVUMg;? zmABt1;ChYbT@{2@1ry(kMEk`r&3M znR|-gE+>NKQoaj9wE4{W8*TDSQ_sNN7E~gskyzInwVVRNZ=HpGf6j<8o+petmMY^b zQI~jPk!~s7trs55qWzH8uKTzN*fz-O&xVTL`Gj8wcvu7^CaPQ6~(5H{itRbKtTB* zloR?Leh?OFDu1<=wQO0anVWO#V@7oSnq|o?UR(|(JZnO&Q_jZ}ROwPWS%D#M&p_z> z*~RQS_TQG&C>T?2-vfd&2Y4UVo+LcupX*y==VMQPwn>m8w)?BMQLqZkUY-ZQk8fL9 zF1CoreRJXU)V&ty@{}>q7WY{_`BX!r$&JUfmcz0M!!wkpR|&8o-#z83S9dZX zXzmOZTDzEf_E`z6QlWQ*`!!why%-ht6%^BLW77}Fi3&N3z0j04lqze^ z7GB?)qL{sXp3ikv3+9<4ajv{v50*BY*!$xe-QDVAW^BnJDK=wt z9G_2w)qjkwx9~k!9sX(BCn`tD^HHLZd>Bw(?JQW2z562UJBRgz=i`X8$ zmTy1M`|hRk&;kB>n3a8Vk9(|o;S*YKxZMC>%662)`R|dvuGLmFTc|v@9Yn0doUxt$ zYlyQ}7jONC)imCS*ac-2Cz$edo6@!sN840(cRPxDO7R}U)Dpnot24i&?U?;{^$CT0 zIVMRsJZALVL){i0k0p#ZY>R;Exz(GpR+m6eub+c<_+xFFgUqa>b+aO1CPC<1woyr&PcxrMeB)mT6_MhJQZZmT~MQ$TuCmFAHF{(AAw@n)|-J9KIj! z?5q5YU8lTR_pVlk`wY(*76y;H1mpcpXPha_w$^xXD6Ea?TTD~~+>DgM52Vt-l!13y zQ3<4@qciWS@kfw3C<5SqCUh^~vXS8oRMWOtZwf%ZFf6ohsgyMF&Uib^@4sF*~y#OY4(k1t!LJE?ccC1Ov|lq|F%bB|EJwL z(fH~y%IppDb4%9sN!RpA+EdctdT75qAxPh&=CvEB&`IU%%w{1BCN4 z+V#rojPh39eT*p#TPjnQL)pjyRt!;ghhb2o_+y%Tm2=M8t?fP6U;%$jHER&<@LWpD z_I;%d>UEzv%Sp<4;0Dp^N$z6o<_wutu*kuWjsvx#5)3U)?m4E$c_#F^XW(^XJb%kC zz+7An)9)@bVOH+6TDuR<;yU+3aF8lB7!$Ym1h!xEe$;n*Y$x0)iVZ~x_jLrDvhvH- z6ef7P(|+r6f-R{n)})ly+?38hPe~?5b5w47|HWnTHTWq_C=dAaJnD^}uKd#i+ z->&li2JQ%V^|z)Wia{VaFDu_7+3wKQ)m;^ZzMBs6Y8Ya)W$Ha8yyV0@9?@El9F6HB zhpN}@r8UL)FTL-Oo4TV6BOPJuMh|mDks3fq-_p(92!|q}B!kzi1}Anhypw%u1dtHt zWBh_S(UCZ1?)thDU;UUr*NBhIs`v+>N)!2HY7Sh&MS(F3*HEf)8)-ZTA@s8Yiq<$v zJARm_r4UXOgb4|GzCgK$02k)5LD#_q^lqFOwsiIiy_KQ81D<*PHedYAEbu?h-2J)} zHI^tr=Mac{WGUd8>ok3x392xy<{82VquT!C!aU0l*4si2ce9UdIQY@*E3DEetJVZ{ zWVuZYu!;=T%1m6brk^(>Csj?LW~BU;K_IJ-x1NZ#oXB5oZHs1Xt-RPIu`rnZbdVs7 zvejKdP7=2gBO2a zprmk;m%Z9A=v}j)oV^6^xjNkZVRAPSA9*Yc#`b+45$#^eP@z}TX$a-2tzdF*TFx%Y z^{Fi|JK9$z5$Ds?@5Sn0lSiH|;a-n4OwOjmR~iFtw1N6ggduL5zmM=~>loVKcdnwP zcwijfHr}^lPL00+nM{n7Zd!m1NbFuZ1OQ`J^7Xs>xqhgV!fso4R0KBar=2fUq_!OU zitMXkaN<=v-|R>a3>Mj^FL8i&(a8kNRQu3&hC<qR3P<0Bba|b3vsX{|EORV{yl;2^HqyjtxHH}Mn4W3yF3%5 zetl7b3Bn1?n?9n&tu5U>>jHa!rSTQ?EbNe2uVfz2)?=MEx8X*~6_?E*|}Qldsv zA{-&SBdM(19cB10S4Mt^;%D{V9s1SRXL{Q@B5S^v1Un$Vl}p=(6ZG9oW`|>l;eMMD z^~5xc_>%^fIzl6Vi7_wD6cf+FJJ-9>#p?d^g3v@rS4+>c-q`B+kQb|^(y7v$YnEAI z{hVGf(VX{D5>x32pGxP7M(3n-;j(6>&{V>wvxsOXx?zu*?U&NQr;_S(6hN9Xa3)J)dR zq$_d@E=Oi~|7G~^(Ap0L55NIjjzGE5Uqfw9O)jJx)4o>v?r&fr-pT7T{k`N>L}2|k z2TYZ}?QRL%ajR=U2YqHt(l1?p%q|DAN3UL9HF3%pSNomv^%X3=iR-Mm;DnuarSZO% z{8cS65^dO%7#WD#=~9x3iIvEfe+S*`?4v&&Oo=6I0EtGMO$5DUe3fqcNYl!VgT0rk z=+C~6v;1X$aoUKaP!k$)4DsP;m;#;ZmFilnu{~K8-(P@_ANL#}%pzWeHsu$Eop8KX zt(c9VU|5?%;az2W1BFT?V&hzn$9xxN+&nNH4gTgc4J--~Wjut~5C!EkZ~AkzqQ`=_ zU%U%0U*zJyMaDOcSlbIbw&fdr`eKID zfJ@ojuEAcp`F7ZiCiSA6-3m?MrR$qSTYS?A)cgD2^W$l_*H-tEdtMY8V)gq-K{W3G4gKkmbUPpKm^p2b(_f)F8dvco@-p4R3 z=x_=7L0vfM5It!ca2wl&k5BhAdo4*s{lGYS=Gnq# zrOJMhigop)vRb1wVuQJQYT4XBrhcJYeqT_?y4iz)wowbUWfvlFGCE;XQVyA#zNPkD z|I^F}tf2Cbq4#0c-aovK**I5cdRusUa6FTlsH@(|Ezx$)GU32PaLZmakoKF9!kOFJ zWHH%#fPOOpF>yrH-D$*4ucU`dP&;`>c6S={DD^AzBAG{@ zNi@fXUvP*I(YqiHJfisb20Pk}vH7Ez($D7S=0V=$18ZU*V3led&P7mk9%1~bd)K7s zn!I)>W01Yv<*`KVxshEme0*p zUMK@jKQGIf6w8Pmd_KSWdD-0jlJF`KqnOo!bO~g23zEMh$l^Zt`Nt_stfXzG#`|2M zvS+~VJ={$ZekvTvr0@CT{LK|yr5iJP$Pz6TW0~tcsXGD=Rrw<-s~ojA{3k~vmP<{RHhV>iI%0wul(DG{oRs(`lSDKNpyeb{FSzvzQ4q| zVzNt`W6IV~59d1R+~aYStK)KU4Ek{_PUK!S$>YpNdZ6uXr?92`)5-Cr@$b3)O)JgI%PT*D%D8xfWdOK7iKAcLe) z12Ze*FFtUVr&D`~G>*|{F<6KQgm+xh-GO{t-~V4k3eyi4B|8Voyq_4MBtUQ_AAB`66Q-C(%8}C+|5AM+VSD@ zOdE#%xo}hP?X})yq0YMf-<+&tW{;LA4zEWQ{@7oqmE{H-9aD|Aq(F|}d>e?o8^p~$ zn4kAn$V`@xj2DiKr?E_;L+;uw?Gh?V8y5ySW;f`+e_P)1f46+=$1GnJ9CqPT4#AJ! ziR&ww{EkDcn^w%q-IGX$J0SQryD{qmj6+7GbiQCSK=6jxJUk6MnI*)- z(+rF|M*xQTuC=EsRVCW$E$xv%djn~$*eG%*0Uyeok>N$anccZ9GNM*x(99Ty_H;wo z)J?|&N8rWd=&duOpI;P{J!^5(VKTdoa8+)t;B}S*vaIkM3V-A@&eQwOSLoQcTUL#TtIX@V6 z*lkkud*+GhIO~g;Pa?7H-{E*G-1En_yPl>Me%9L>Ewx^xK_t-r%dT7RHd{*XdB`lx zM$B#;`Yp8VQ)J?vEE(g5`uctFc&6RxMXS95;d_5;HByrg(Lk;!4uqw2$r$V?mi@!#t6_IE0CzeuC*HkI9OYkg3vEoL267p6B|^)};( z2>9&xF(BOjf(-9hh9_^f_rBosg66_}JdC+=eG)d-9|ylA3rX9EKM1!a0{jCNj?PB5 zZ$aAQcnRd1@5fE7r1$dc(xJ>6I5R%{cgYSS9$y)}GR0ey)FVU98gsQebDipQsYuE~ zxK-(h$~Rf(KTOi_5q|2Bz5K8c_(fm_*4-xs-m?FZ;#um6^w2&zp+xu;O_)l#y29owFpzVK*=Taf29{#dUpC{J;hq}h#JyP%kRY?f%p zF!Z)T%v&>8jKsmwZ=k?nCX8V$$OLB6vVA7yndc)hv%5&o#qa%l4>fkU3rO!$JuFJB z!r2ReB}0%UDAB)Y{|M-&rgY<)gFWsz08p;?Wby0CP!5@aHImUh;%{wT19w}P8V+k%FD-Q_0!?`_Y)cID zoRc?DbW>gyq-*P_*<_;F2b>H?yN?KB`gLhtWVk5=k($pIVx z@|FoX>-3zOOB$2jaOc>`u;)Fz6lHELsPuvwtGc$B)h7ubPVifgT_x>o=I-`!&6C^2 zxm|3j-8*ycCI8}0OV{J`iO+MR>0(#M4A|3xB*$09FkF!eKO%GvnF8p8g-xRc6T(Vp zfyjDvT1Se{o|1+>Zfa(#FTjqLjjmTFYECxHcQcJgd$@CJq`9(h6rZ=l+=f~RtV$05 zNt&$<--_I!W0csMDNT1VSPS_+FYQ2gz=mnvP`aU|!O(0#80wTePmqRHxwtMKX{A{x z;<=ZHzj@%FT>A?D@B%IIv;NM~4_z1nSr2b|InWj7nm98y*Be^egMpQUILzl1FY zg299qt*TRX_Ih(sR!h?l+Gp;Cs9!^StbIQhXY4J-f_Ryd;hopCZe#w0snU}@+4uH>%y=`IX3p6n0+3D^M}{8S`zh^_m!EJu~pka!f|#s zG?BeS)fT4QCkrF-7O6j>5bK>~QpIlxy=WD^E*ZVD8Cy0Lp-#n(2)*+7=OqdkTy*dn zA2LF(1Gcwy;8<^cJrX{l9}iLnwkSw6!CgdXzokIYU{7!d{omCUC$h3v)NRA7G%MhJ z^>6K7!pXh(RheQBd<7@Ay*l{*9q9!Esp9mt|kv1dz4MN${C7ustsH=5F3Z>qaZqlc6O%xaU8Bbk%C+qBNC<7B=6i$r3wdtvDm9$Lj9J6G&gwh9k*C3 z%J)kwWkPB{W4RcuSG1EPVOB~@B89W%c-Xw zO}^y%X^@7c`Lmd(5fgrW@!1_nho`u$Q3gsL412Kq0Lf>S}TLUreP%^+G`#jmVgj z=g+TZ>00%3d)+(EJKYdm+85!}H<*{6^+sqRP>RJ1Wc zk1wA&J!1g$)-4!tJ(#pUe+dQ`X?~>$Q}R~W+vrGb?s|7#-^0(mb?g~L@p8W3@VnX^pt?Bn)tJ`i z*ouLA$tk!g9oGMoZo@V?QckI;!}=cZQG&8m?Muar@Mp`KAkj*sf$?>0iZLaiyS`v|J-Z8niPO@@ zDYJhY4VG2uRl-b5HtaG`14WAFl7oSc)ELKr=w)S&(=xCG64&F&j`d zH9Rr%UQ(a}$^P@Ng)gF#)GOn7kqlp7439_7lW4|Ulil{liQY=}4DQGNTXHJbW5;5v zzkgPdFTNk`^yQjN@V=~Zv-O{T`}b*Z+sgDC2fySU{-1|XdCE_F5gCT(b0LcolkIMw z*vXtOcc9*=_~+kl{qW4Y{Aw-)Hf3X^(#k#6zz>DpzoRmv?Jmf5w$|EvI-Rq;uUV=$ zRTb9Xs#wQMu3s(Q?o8}uIx@)^Co@`BNcQ)8EXsS{nx4&+O%C1YS0{kaHxo?va6Dx9 z{99*wepJV0?e6vYn)$It#4hUXy)M5190(#txd6wZFg_LTibA4wb;Nz6U-y81Z=xL^ z*%1NtOKmHOObbdZ3?cwW$a*xwhwUAXlRlY~YssZ#Cr@`aC%?{7U!UUrGt)LjZnxcyMeyIn)8+ixYWjNozh^#`AQVLoL}*h{bAB1YiW37GS609Ml)MhN06NO z5b?Uk%8ARa5n$68&}VaFsLp@7&_;^kg@kErQp3s*!Vs0~6Z6**W3ZFL@ztdg;?Amd zr{3S-O8LY+q?|||r+vC|~PWua?nJ*S-tz}xhzE`Jl@_R9G6~Eoz z+CBfpqZ^0IsWVmYrh=T6B4%E=%h&_RFeizrB`zqi4b5p~r5Tb`JVh(zQ7o%B{rQXd z*ye2G>ql{4eMxaSgN<_r0a=&_lF%q|1&rI`*K596(A1~xbL!!&Q9HCJB$KW}GDPfb zw0a5-WIn}<8@*9pkQkM4Cw71+%<16N(h0}pOA>*e2C4A;9jxw5Fh7xqd&dHF3Sz`5UawoHwbu}I?W^A9$q7>(Lob&({ z#8@Bx7vOJ6C#4;yBhLr?KWTh_vOA3?vDQO?Ey0&zF{9E)hS8c-wHgxLJJl!7u{1c{ z*i!bsa|6h3qcBgly4YWQNnreh=9$%owILLN%B4A+E_Hrx=ImbeD{zbT^Q<}009-lJ zbHB5--qlj-SF>lJGker*9L7cIcXdSkOyEfB?907wEAmLBbEy}$q!UED6e;_h7dfv5 zf$oGlaV?4PFR$iTx;DEBM3IfEoUrdz;JI~10J;oN!H1#_-X#BFVvJ2)KKOPgzr;A7 zNkRzq^*fwQDn@E+NeE5C@n?oyeOID);gOk`e%=<{l~057a_4exSe_%j@hWf6TA_+C zL*@2o2beO{d);BFu(kY>i8qVt{@pCf2{k~e4|y>R;<_Am*<=zN=)H*cb1SNn#|VL1 zwJt>`Jj=QO<+LC~U{dDd8m)FB!=4}l4t$9&)rZr5Dm{F%I~M>B=Z6NZ@KSSDN)@AW zcx6ik$DTmOYi5tmk1lh(d7U|?z7ohzx?GY+N8!Y5Ppa%A_7yk%RWG~HBx5DN1)>wAJ`0bw$Iqo0rrjx^sK~B{)jx)!jX==DS`vWbg=xe z`|cs>ThWPUsfiOU>*4mWlwZkAX0QKvyg>W6RK{*FRX3cYTyWEwnj^>TGLHu{{(Jng zZBV@-LOuVDKb#`AEf=bFQDCj&;L4#v#?6;IEemaK9~+owsKpo?lf|e+)2-oV58Z$t z3mfz8g6Y-eYs2cRF8v+n6-J#M6-Lc*`GzIzqmlMg^=Rp>egxWJtOcxQS9z>{jLJ|9~?%b0@+%>DjkFyeKfWbz5w zoVTKWjPvKyv;8fp1SYmJq&et7m|lrG8RA(8P|n&HlA`457IT{l*{jP6lvPI(*7jTZ zz`4vr#bXyD;m!Cp0g=U9Sx@R$AEL@5=BpX)n)|9rzDdWwEMqCVI}CXYb)ueJSeGwa zF~=RV2P-9^@fknQMkm*s8Exo#Qe{IM@SAkW^V-_d`aQQqmUsC|?*Xr7^ph6~@>gm6 zm!#%*%9AT!Dbzh_dOuBO81Vb=X^Aed+@^Eb@tMaxw!9cXbF3@{)M+e)+NeIqXpn!~ zln^C(@HDjxcAzouN^cq0GrUJ+86D=EZFGQ|=Nk8gqNY8qhaE<%r@$(ZB1VGP@-fE` zuZpfITrzHfWgY{ROBP5pH7+B~ePG{!k)KYyj@{Zqa^ke~w?k*y&P<~c<- zE9Zyv`hl19Q>@znHMOZDlG|X;kNrrS!`{RlU3-9ESxK%oC$H_f=O;lFU^ zq{*J9$+l~W5)@*o=bi!nsln^Fgnmfrvy;RN8hcH#j=o*zDeJO%i%hQzStjlm-2Ddgm1W2J%0}M zVwa^UfN2xVQ@;F|5=kP^ecH4qKk0p~PXm#q&$j%>Zx&BO1$-2)F4vmVGI|r*Ts>9_ za6Z)(Y%>9SCX$X!P@L#?HPRA4iU9)3J*Ka^CXZ`IPEybGop^-qqYKt0`J z=CI&tu&-{0vZL^>MIoa{{UsxXT8nEWWWB~)h4;8$~jIe$pq zZuM{xupJD#a3MRwulKPJdiL`GF68`NXu^lI#Vq6icZ|B1$#kMyY`c+(g{>GLjvD+c z4jP|2PA<$7;LhSkW;*RKGf=Z!bTFbtGJf+kUGy7?6l$GQ|zTSLjEp(ni#8-yW2)5Oamr2{2Rw8y`JKZ13OlMc9J*%fAq1U`n2Yt!TClX$! z43>T`8Tim&iL6`a$1ESFe%NMfM<~JmXe1nELXECJcqOO{m-N&t5d+eQD8fTMxf+Y9 zWf3Ux(wzO=SG0Kieh+f{Nl4(rSIl5CQ#BIyLuu@UtQjDDRtu= zHcHc*Az#Spo5ObWNSUX3*a8_`t)a<{=B#6$=IRC_h=Q}s8 zwQ64LUbQ@qMxw@^A|aAES4WT3?f@eqo;kBqG2`pla@S03V%}JXYJ8l$FCv;aNa8;& zKz(aJ6(T4mW(fG~4UMgyxX^A#H82ZnT)1RZ3E{#+eKKZ5xz4W%GriCrS?Q>IKhRxz zbgHB&Nn4&mW3S0g=KU_6r%mwr=Dt7B9qx911FFB(o1bNf>SQKZWTwo{B~sxhlxZ!; zv8W}o*A!aoO6uZ>IWv!};gL)>p^=}-f)cFPq+GaxHF?0A=wvOr#S9xZO@gKj!bVL( zqzoGuO~4PHflc_?twIxpMkTMb<>`7qx|43Fc-JF}y;+??;dKcvEenC`tG7c&5XS|Q z1o-+u_X2tc3Bj&wPJy5t?>ISjdm5wG4p=hMWGrKuTb9DNQ}pANX7N`JtxQ%t{HMm2 zSiuEGE&@y(9xKZofp6TrGT{=1VGM|vqMTTEO&n(tuir;rhFH)Fftyq@#b9QE9Wr()(wn{YoXG#zYcsmp>MA@ne^kOXp7^xnSfof&cA#$Qoa?9Vttv<(K1b{d zt_Eme=AKy=_|1P#BD+D{mPakX!qmUb@W=GB?$|y3QMBJZJFDAONtZ^wIqgmVxV;G% zyH2PKP!g6N4b77(2J`YZt&>d?srP-=mKVuf!`|>_?APOQgG6lvc(rjXe!M+P_?R?} z3vaHgSVoqxOc+^kAQI*K>^89(iy+>eaQm+=a|(5|FkMPmQ~{iMBHJTm^q2n3Cj?DY z1~*$dDmhQ@PP)(B^D7G(AcA$A3Lz!39x>-|gmN;BU^I^^X(T=9D?jy;ykq0^O4x2W zhe$QJARv%IGJ}ii#^5{PV(^|*^wGs$DxhI6-;~6x*G?6Y+2l>6D~cVw#^tkT(*Az8u!mw-R_nh$q~}MIaGrGCuupI`tRK#{pC|8QS3 zyn|WZ8IG9!<)G-dq6yS`P9_B z@@f=J@;1+m0wWwK85buX@6nt(yvm?-#hu({klc5drnH5wZVq_8Jye4y?d2Gq|${A$<~DH_suttcR~$fjVU0yG;i*(f30_hKz2 z&rj&Z%pzY8)#wJVC*LY~k#`?|u?>fBK3rOvhdY@gLQ**h7AD~Ufgy#Mh~ZR-5?1Jv z7Gu5Ht=!p-zmcy^Wg~uRXX?Mk?B?}2OCa3!a z`|#x4AF#Ka4Po>Ab~WOz;QPR1bv{#R!ut^=IpUj7Z%^iBiQbhfBG2dC=+}@co|VGg z^)ibif|PjN1CaZdfyeFB{)!?{2pt+j1%*11cfnnX%)5q-b{P1~4hOtbtFO z(V;V)uDum0zB6}H;?{f7QT4c;1Jj)bFEFyJT0M$H^}q(OD7OQHzjMS7VG$3RXgSE? z?@MpISJe-B=d-w^Pvn_y58(RU*cq5*3h^!EM)E!wmC3)uWwKoR4@J0Y#WPPic-kqs zC?Tz~oJq&ELIoLtbJGs(?3)m82VsT{)qCcq!f^VhepxAj)4|@5Z_ZjLQc4`WT&6rq z>xyp8$xjsf;y}0CQ25PvP3-A^iB;3y!hQ+)hygP8<7GzO4c#b_95gJ|J1BVLoJvoK zaG#=*^I}`AzqE;w&b_`~@ytroFkrPzbk}3dH&WTWhw0J8S1ot)4 zlm}@B?h)fo8~$$7`20mGV5S?Otc1v|xio(C;;PuFT*{WB9A$+iInT@C6I|oPBtR)( zB)s(xZ8!s(awtt&7G8h4hK=&iYQ44VV3~9xt%U%5bw0W{?*x`2A?28?%A!6pz*gV1 zdppq%{zZ9Gnd17X!JyDeX=69&*2{!=v%q+r(t~Qh zXVaqSuFfpImqFkz;I*2Bpo~}4#R;!P>v7wr)jWjEcmvF=I~n0Dp;+h_5oCO5Xxh|& zO{pWvTK(@!&^p^p|G>H06A-!!cdHiUp8^S{Iz!uDcXe_KHL^R4$B6A5xpgR?pJqQy zJ?<7c6^*V#C+C6BqCP8n1**Os-OTiv$tCgJ6U z!iOo1t=@<4hv_Y)t|Z#ACH=7s`}qsk33` z5i|1+?8Yr2kSOp>TJ}*2DS7$r*LByDnkD11wc}#QP^0|t@ zA$MDB7<7Z7AsU$0lO31}aO#&}=U~7$*24NMSiJ5*(d+>xVrgcoOBSEZG@ry;=g&;k7!9oZ+h!-C?L5L&xk*jI>|Fn~k&#fhHT>ONYRXdPetXxT6vL1Vyxah8$VV}w zNf`7=Jkm!^$U{w^p=EMQ8&^*_25A`~eXkDyH^n_Q>7yD9wTr1{bn^_k8cSM_j(8dm zH9J%eb55fHyv;NBTb|7DDZx^c(uS8B=k&FYhMFQCeom(5lEn#I`8n$ezQIy8d6kBQ z^E`{*b?Q z*vC6lPxm8>?K`oOa}78VkK6(lk1XvCK@fA4#KQ^?Ty`ps2gmq%KsRESqJsT`1_CFh z^3+~@Va&>lc}bnrqpHhSsCu{e(-fQ4e_yOr!c0UYXtmmm?P&6JMIp4K{>9WknyiU} ziJ#@hhMo8vTA-od86>R?UVnz4@_tTQ6S?tgR{VY{BE~a zSD@V|6F`MY;+AF^e9Yd^mYj!x<)O@!ChIfZS=)w2bQWh3{@4`+D8s2Y9cXX5`_u3j z%M7&iB-Ki*dUm|JuTu&Bs$TB+qp0h#;2fP)ax-$;j7}0q1#JI^&O$?DbV!wGdV+^9 z^w`M8dch$u@xz`O=Ey(PlIU9VzzX5(Di0H&09UXFbi&pGhs11e4^+Trvsl|eM~R4x zq_0`X2J_Ep?U+HN6jRZ`#qmfKx?%}U*A1?{EGF)rjX?Ar;)BmDC+cG7pAfd|G?emL zmpi#x*1hI4d#VGv(aAm;B|H~i|cg9xn z-a4}=3tJvIy?llxc%dDL-9hLU8N4*T-I543EkdhJ-`wc#81qHWYG(1;_QmYE-)!@-EXB9mQOx!2dj8TJJJx&|cHqb@<*Bc0 zKzynr`wah)4RFe`N4)W!U%Z#nkrH1=&LbtmwBZSGH8RIC_00vA{HX=~IOWsQw zfZ$)j3ZH}AB(>6kl*a~H#)6o~hhEKc-xPzep^j-(765*RbttNhAryv4e!V5J6~EQS z3WI(X9`SS>rARyD9miq?JPBHYE-F{Ju$@IMSUE40H>p%Cm@b}BFK1GAH7kdD zXf3SZbS)@TEvr_s&QvomK$$m82|YIjDMY5Kh?nAf<_XxIYVW=Mky54p>^-VR??~?< zFxuoEZ}W=3U*BY?H#5v$=k8fxE>)T@3(4pc3St_YZMDbl4CS910K2pZyJ5FuU830T zddJ4Ee5_F?>#5hpcue{L`n=+I?6qX4%6pYdwZg3sKSKRP&N{SC&n?^IHAr|~z$HhO zh$z8^kHpm9?G;`fYT=4S;F2eH)J?vLgJj^34aP>T?HwlF{fhci`t1@xHnfO;*5B_F z$JE`cPDTq?+^RKyApw*u?w9>2U$xh z#(Lv5Z@w&3!rY-cW!!p=NfEW-z*7kxeE}@6IgSLha#pZcS>w5#$DRU)PthQy^BD)? z*BTfoB)jVX2nltPN3rXggn`NDskkPCiA?TZ+U{GDet)}4k%oJ_&=DMHM^<@M0=m5x ztGD2CNA_vO319j3Bf^lV3mx9d!nU%eqO7{Qtg52M&fMD4cA(B{EoZCiyE2{LQ&H5r(wf`u5R zvN~z#5b`&&2*TP0HgQe+uCXwi62~{Tu;hz;MW5;ObXG|v_p#(`Dw$?EQmZ{+Z>Vy3 zufy$HpnABcK`FvwsO`0h&rfK=Y!%QdaCc&c^ut$tw{6`Gis^N^b$t$miLt zi(HsK1!#QJ0m7Esyar5IpS^T*sQ$Phz~jWd#o6csfy;{<{o{NkuFnK({c9cF6f{L% zm-*F$TniHNQeo&+gGAVtu+Qw4wF{+z<;fLgsbv=I=2QbN7zXVu>$wqC|AtJZA5A+> z7d9^WbQU1lL6*6O)Nd=Gfk3P-bslzXiU|!kTtnBkEqpeKey~WRzdwv6g!Vm`%P=wj zOz}$%^5m-hqXuL2s%$$@;>0>?OD3v}dTRuW_$($CWu!)HBONCo{7%?&J(twSLu8L~ zs~;*3HNz6O#7ROcB_RD|lTNZa<(FJX`aWqF_pzs8|Au|vRMuBaR(7+x+qs;ZRc9zt zt@t{AL8Z%@tg>!-MVGQ#m9lEUG)GMX2j#bet5dE^L9}ny)rA=Trj+m|vr3brO*Avz zqa#ui0^Osf&!eZ)Bsq_HW~ium93(do9bX`{(UQbuUh%BD=^>{XG;R#Grz|@idrx0F z0p21QPL_aSC)&nq%R{ym3Ju6l}5mPK`=tIBlS z#IHmCTRkFl^8V?Z9bJKOUZ>LcR3pAr`TCkH6CJL}_M~;EbBLZ|fc({gOFs08D|q`p zjoPAb=3F+MeK9}n3VKs7%Fe{p3Tk;O;bLEsp^->~KeOR+9mAo6E#P>geYC?5Q^p9< z?kzjx8}x7;PwR-8LpN!jfw2e2AI#SpuMYk{a^wEiC~!JqfaU`J(eg-BF_N7 zg7GJ9IaIA1R0DWu>a#afBRnJBtR>a5+H_Tny3Quvc$Q6ui3wU!ll-s9j06YC3B_(9KKvzgYEqp>$aZE^*UU6C@mcp zN{_T5u$*yhD@_l+W!BQ7M4!d++NXfEYoDW|5v3HJgK9fsa`oITffJFNo@ z9dws)J3r(Wc^*6YJ$ZG3cIo489&14n{vcmhsN|=ve<=QanEwkee@hdml@G z2;4JZeU?6Ktn3xlsU$b3NlW0+_7h{F2kJ7TBoiR%p@QoHZc=e_tT6y88bUpfh=&_! zYh^wUiC!mWj$nr~@>d1KYf{@;pdnn8r=DdrOdw5-FCrx`kD} zx(1imB?I~(G!d~tq(`^pvoqDfkmLLST=nWJdp@*Xp4jy8kTLcex;Z;yL@na~XaU}r z{cnFD|8a(WKD4X!Qqw@Gb~>kS9h|xjW>KTB2|8wH3CtH}v~Z|32~5MbeD3GAVm`Z&-8#y_l}q<fQ`0}TU8ubRQe+@Wx$djdG8kCE zU)-j~jac07xT zT!WCYmYsMa+!j=>shv0}rxJysr-Dsj@mY3)9{j47{w&cXxN3B@=c8(diz(jW+L?*w z*&;X4=B;4|MD8Q`T64VBZ5o?~j#;M-#fF*l@FP>1DpDb_iFW}MF_TlL{%u_DzKSoV zE2!y}RBn{!Ls&nSOD$4UGe&EuKN8n*N0{>vHpY@M_oE-`ht)Ct zNtU8p#4EL|3YRKKHmxWS>}cWoy+VX}8WV#!NQ*R36G>_OD+YWPby+y^Q^)83YtitP6=(1~~zXSq)V@Uea!^V$XTB!(WpRUHB(n9IlwU zNAd8LdtL{Nb%W}DLQxDB4mf01Dr#GOSFjvyqdiY*P?jT0+Y%(;Y6^dhXGBcb~MgA7OR3q?9YfYOaN%&ZRULIoR&1 z{AM6);n&@g8FR&_c+f;k;pc*5PQd4}138Y^(=6V(o>U4Z%aL%v}=R%@uN9g zMoTmK$1kwMzDna=@yymw2Ru#JRUibE-~)E0L(ZQZ7Vx=?>Xj=tpPefQUA5CagX!pQ z>2v)3iT_dI{cn%rcf0>Ev51v`@lz8AcrUyyrwBvxU|G$ttk*Il4Q1&#oy1TNkbt=> zdYDGIDV5t2#0@eItlG?I*cYsVNXtTyN%8dp+3HZWfohPDMwD;UTc#sP)X%~E8mQ5r zT5(F7&3t(qp4hwJ?Cy@8!}Xl(;(K|h#pZKFV=^g)`6y-5v<#F|kH)3^Ts7C?1L?Fk zws4Ag5REDWS(R;Fn#_#qh^ZoC0}&a+t~%7htbW?xcQOUUaKf6Gl)+5>*Z^A)QMYW; zI`1cx)!dxi2VS($`*kGmd8uv% zlcFV)J}r_4a4*chh<0J{V;S#~FimkT9w;I4xft;<&czZ`=g)Wg2r|=6lR0}#~3xrmb>EmH# zb-_ahFDqdE_2zedlVItHT9$orLvZ$FwV(;E;pks?9J`yiDA`1|Xq)SQDP7_9F3?;? zTz{J=x9dqvC-%EX2*8ZAbF?+Y=#(a2E^UL@Ex)_{4)+7;Txlp zqxRpqWL^9=uVIC@%D5pfm#?O3|LG|UaT<91AX~^hGZ1!RgiST~&O3?n`J=oXb%MhNKj~v?!pQg2Y(?rYHbI; zlc@9>1;`4Kmlh(2>O10Y^2}i4#$D7pUrh5?P+6Bz){0iy83qz!SyJM==v%cY2(Og( zZYcZXhp_%8j!tq`n2{$co=WTfXCSs`o$OqC8ZheNL_zb1+Co1gv&ZsE%f3Lwz_hK{ zH#|eGEkdlRo?6NXOH&WYz--09EO0J6dg%?Vpk$@|!)|X;e!>%c6zX3htX=-qT3F_J z_+!&ZYg%rl%ZzCTr4pOIaE6tux@DhruDv*E8oqx<$|e8P$)A#D&K4n*V;AfX3F!m%gPvj+{$!%r+TuMSG!7E=|K}^C*#mwY*;A5|V|MyzkxToG?f7AAZ}F^vuVqQWf;h7JI0bD>8jtJD*b z3I7AKBmp*qj5aFD9deadmiOy?b;NUertO+bo zx7``EXxgStqEqfh%4QV2O?vXIkMB-Uf6s!LMh6t=1DRD{PP4$D|N0Ysz5M#OKR>aY zt#KI(Vn8eJaQa`a@7Vy-T^4m8;cQB@Cub)SKSRvI-&l$7;b2L2MLsgT$AVdEvqfnU$lylcV-4{}Oiu6O(#lx@5SvuAi^+`wd%G@*umh z_+{mH5;7UY(hMup-z4M*{mfb2{P%=PK-GXy*Q6A>X#t{J zVE=~9t}a&XU!Dct93i!ld6H&2wSgyC@lMXhn}z(+Pw+ly$)~yHS+e&mHH&gy8Rqh* znb%A4NwbCpsiXy|w{_oyrrTd(#2s6I&zV z_5!f;Qzh^bS3bmXT+I3xzh0176p%w?+SDnR>AB5I3Gn7z)h#}mY4L&Bj>WNwn-WtO z5L`<9#@%FB`AKg-E(FpHk?B+7eS`e^VZVK!AG_ZhCXZrPH@XR@FcRh3PX8maI|}m} zvuUcKmdX*JqV9A!^uF5lS?8$MB|vX`fsp)j;IMKXJkZYv~4!6(f|0;Z`7tn-UPR@D6gRQdOEp!jPwwHGASyejku}f zaFD2Y?Gh-FXh#4H2jNPIsTTRfx~gWj-oNsZN_X<0F{MQuhZMwUST5cL9;4op62r8D82yMzM7@C1X3EJ)G%L-`Sf z7~lU)^ki~P6JOz)n&i?(MghQnjr$%HRepJT77=+4ttjc{V$ipUQkYwt!iMGO3aS85 z3nIOJaSeo3LLyGYFjF3HaY;=varLE63Y^^iC8R6RSUW3wHtTzqt7pb*mS#{50nI#V zzj!O-h_K+?l%guofEvWOrjw`USPJ1??zA`r&?2%k$M<_rgh!|nHwzXH!1CMjGbV(2 z>MJZ?pDe9;_T=*Olrjr7^RvYhT$h!!-?B}Ar*ceBqo;nKi$!7_qmy7K;LE9VhD9Y2rEA)>NP5Li}Zy3tl#VV3(()2+1hrANc4$M*mum$c=THyopVJmSM*pHL?D~ z3PJm@4$B5fV$Y|zTwj87r`l{=!NjfoWz8Bn92UJl?%G~3{(iqK>Qkm8U;P^(+ znrMG?n3B+an-iB~?#M7UVuH_0lRYX(=J|0M1u1u0&wHAe#oA8uE}d&_|6BRP5*10$#T^!RDZE7>BpaJYgk*TN z0<5SZz;R5nBYTBS!#p~LTx!r0aFlh*)hh^+O^h|uQl_N0BDK*$u(5^PoDZAlQms>aTQKxRYhDS{-RFU6m7%mP;IAmr^ndxXw=liVJJam;IYMIm zl7h#U7uCYkQs-%H(~=GPtNfX$YB#!;nCMj$IOkz*ZYnwNl73sQdKEdx%*@PQgPaCl z*R%GxIv;_TzU?j)yp$S9+2>*9ph`?>T!?~dYCYBM%DwznWSqBL zojQM6pe-(+ZPxPra&PaLj?d87s`=CSu(hELjm1<11NFajyrGGNLrZk)*!_dV6x8hM zV#bzW8dE+50OuB0N9jRV(jxln|I4&rcOpfFWCw+Bb2cuG7^ z|Asn+F+W~C+Wz*!Z3QR7!*opRZr>LCJHcN1NH##-M4O(r)5B89(GZYB4V91GNy)_I zpg`&Tu`rm@U1!$`GG*+mS?r;Hj?sZ?7AMsEm&@FLm@h*LE3bWEX21J=)`WT212+vo zW}R$TMiidl98&59Lc$&Y+XitDtvsJfG~2gAqmFlXYep?ldKdlspFOa(3kJXGz>r=w zkB8WXpGk{`X4F>?cVq>qdU`f{kL!>8f=!;}O{!0qL|1T#goV{V=~qhLU+<@B1LR47 z35tz~+?xJA4CT=d-D8fdu+aK5IwN&1B;LrY^dZFcNJ` z{dz_13PK(eeP*X!r^~o@e5|t61S6hb+lEiu@m`7E4&T-oCL8rMtpwDR{qib77>WW2 z{md)UEhs^-H?6q6U{?}tZBq;l!JCk(n$&HWlN;Wpqf# ztSZuMNIj=4IVq=|SCv`;Pj7knv&C1T2(*UPBIX+kTb=}O zd0qdKxbBJ|6s1+K%?(?@q;XZ}S+df?6fJavBOxIa`Z*^dgck5Q1+`w@aemeQzWKS` zIqh+j&Xo>G_b4&;^;oy0336fouVT^}EaU3#xz#5Z?3cOTH0<;`i41J3wR`N!7m9ir5bH=G<{4MO2aiS{tk2V# zgE=)`IF1X>*)S;-y;HK4wHL*rNCvGruPU~`KPgeC+c-4aB`th1KChlSg*-PJG)T`+ zgmjqu_AQbryvccDd2LO2Vr?csTSUAmy50#$$z0riJ52bq0=R%d55huOR@Jk!9%f!! za(OtQ%qTz_m@ZtF%JE%_RC5jRI{y8Awb<8@3InY9yVZuDo zyXS6122SFR=Kj;$w&i09P=@5x!uSbb38DRyJ)q$E%xN1_Wmpk_I z&nK{ws8{IZGDFjt8eJ21wR`x)jIJ0~71`IuW@LAYK-OX;&~k0Yei~jW&HCkPUX%yI zwBMOICX1(uqGX3!x%Q`h@xt{F zA>Jf3CliniU6%|!foxi1O4$$((|l@3 zAF5YvQ(iu!g9nnVERu=8l`EM|sMP$I4w zCV%%49zG^2K>`82JPd3IMmuqyo)efsA{@u>$D%7b%p&cl$c|(AMh@6pg?gmZbK8IK z>);$Fnp|bZiv#TtDooWmvHBk``lN zx{V5rQdDs{?2`~eCZjWHTW>x{u*wNtl$3tY+~iyr9qs4S(zdzz!uNh-)zFbb` zEJ^phfb<4F%bzhX_-`7!uF|Bw6I)Nye>zXO&ugOEeOL<-g-50SnkdIo`0La><8P=P zPmTYSHMKXXYxY7^)#j|-+SQ5R-2`yZRqOf^JeEy@l4nW$5);fDgvb`TVVfM;UgR5+ zbEwPs;zI>g{!uBZdcdod&HSsLQ!W+$yPJXJ=_m_>5KVqZmjWc53PWZfwJs$!IkudN zZur1{hQ*_XUB~Ypd)4_>qK||wxwJ?F)Vv3kVnf)w^Pcsua&GHkS`K*lkufCzxqMyv zA6u&5rtq28@b6Qq#`Ob9*E(drH%SRkIeauCuC__}+MVTw2{7Jy%|Jt)MNv3TbLmHA zmZ-+RS|BI9cXdA^1Dwkqsjb`t73D|eBn$2;8V6#jX4YIhuD@^LKH&|(`I=~<8{ zrxpfDG6#=siGoKm7>|13ucIGu&)na7Vo1=)ZIgsA%i8`kI?Q0r-EBU*hy;fQipiRv zj-l929*T~?)6NFr{O%PT!WC>2q0MriC)D%nbd6%>n`-e8a{8O)W}fhCzT-32?vZfp zTqjdZBY7qZOGr+;x6|hkvAW@8irwwl6gw14Z~CdVG@Fp?VM5f|Yn|V3pWpBNN*Mgp zgy+9;TZL%`qwO{Bn?2l~7NcC)A(Db`dB-Ct5J3_AVJzz(lH>MO?G2IW2Wy6h$fY!z z{+;8(GwhL(d);^i?(u^3IonOg1)+f*33k0!cTS$-=&IZQBL-=S9QfOj!kbOJ7Jp$! zBP~9MLWb>T@ubEJk;pHajxnWqf^Ld2PSxc;4tri&tBsRRFz!@c{3fM~@)+DlS$`U1 z-r?!)t3DWWr~9qSE4X%AKVc~*oFS^QWGZ3WyQjejKmnhEX2ujWU{mH~+Qy)nnU#fG zOl#5ORT0wKhxW5#!mD^WF`HsrLcpJ;#LBwds=`zEsZ9BoMH*p-B07NUK1i0~+8`h# z*ded?v7S#>m8q<;8FPGZac~sBX2Yqu^0hHBEm%V&swZ?^>o!Ic&FWWKbMa+?|KRQJ zaN#LqnvBq4$=9%5*!x4CP@8hU0}Z?gy{oZzl45&9E%FRU53hIea525FPidnn|Dd+f z1&>@pSnDrQs@S=fsqO(JG{w90N0e_t!kAbjlpFtARNx1Ei{EJ;_x=Y4DqHSK08mBpAO2FRCA+yRX5CeJiZ?#s3tg z-u#i2W8Z}jxG}Vu$@fyeqhgUf{|){eTbEM>x2pa)qbEgQ)`$jQm^c_zj@fgU+RQ5- zifmfQA}nb{`V@T=PH`~Nb4b{j3iXPcP&?2Cr7Ns*z0_3r;4WlH$;6J6gApPfIZ!gZ z_mi{^-k^2mmvtHn`zSi`&VP?igV0=tAC(#?d99TO2=I6%sW)wCrv?u2?m)0#;c;21 zP-?PS{9chk^Bfy~hC|~UwW9*U<;D=i>);{g%}byhBX$+Xa~c@9v~F>?jC_dl3!9wt z6TX0o?>{w9$_j03njKpcwUgoX2UDZoO zJnxFq>ry(C)ILqAXVeU=D!RXwsnN=lHK~)=fGTjDX{uIK%Opu>k4b0InD}%_8I>xU z1Z=Yk*$10eX{j*{HGl*DF6dl0u*lbQAc>1h+f>>iCH*dkEcwoRnZdltobtl*>S~r| z+u2x1q)m;kf+TUm;e)e54hFUWP4~i6ImG77O^(q>!U7vaVKIzM&Mplb=1g(d3Py*d zVROFH1$ku9(XX$d`Deu^rS6uT-&{=Bv{a`cIyQ4bIp=g<$mDpqtXHXV0sGvNer{f~ zyrym9uT@d_m8DYnl-Hd8Hq7z$$@cf7yYazqFpujtUXb&IR#`= z2sco>VL-czW)v;8(?9MYQu;=;4VPpxd3`czEeZpFf>n#qMIkRHDsn{ZrWEa`ZS5}E z`LO8PQq)!BFGt6})AbU-_M|O3nli8YvJek2p7bJYP+X*Ad{0KQWo@SaxSUOG#=3cx zqFuq#k;TlZ)dtgcu2Z+dviCl{T_U~PryK>;upE+2)rMuc$fz8txaYiTuzpul7|mrn z%YH`#goGsh3Y<|t*Fbm0J8TDDC?g?cbPY^KIhf^_k=rv^GV6-^kl!up4%zh=+tp>l z*ZDE7=sVTwDPQF84yC}cTi-%T`OX%u$AxZ&4egN74C{$CEcfP6Sfd7JbDGqdtSZlm zX!9#MNRF$!9BgD|0u$|RDLPHImwNBqQ{{&*U6)9Y#?y`e-thhIh6 z`R-tBpF&Q%)jqGLMt(G1=(V_=5PuM3q~CzCi>*caZo3;$6SEN5*Z6z83t-o^GG><4 z9vP8A$H3`+vtUGBLt>fYKmzTlKva#C%tVv#o4kI3vtM7px-r0DK6x2)wE4z(I*Q$S zn3VOiDbeteaBsBph5R?$U5-10M7w#HXlJ;(lNdS5tgUw7{3 zRmt_>WI{7sw7g7|LndU9;1NX|t?@INmpixPi`J=`ckud%u@SO(XNeF8hZ;?QiY#wo z;DFhagV->M*O6Ax){Fg!7?Q)j&1Dd}K|pEHo>~#(|Iq@FV8I3Ns~V3pvqd6tHEX74 zbzXTvYc(H2jPa-p?aX?mdGCd2iWa+oSob-a4I>chzsoj1DzIW`#1+&`at)!)VBmm2cE_H z|6{ahqO*fk7MFyElia?Gl{o`7j|FRot!zEul}k4Z1=prQY;^3+7SE*bm|e<{VS|VF z0|$3?pF_a5wJL1t^0X;pGYku*d5PZ&PON-q-6$5G&cL9D37egDlFzcn+9^BY@9n&! z7p}0)LWNy)&^PsKxlyo5>h~!u8XHW)5fb9$=dYyUCm=>-)3%1=X9i<-{7BhrdpwbRr66-c~k)62^>JL|{%4{5&7 zrh1QE6>{`osrwJXn$EuQBSfAK%(8oV?whh;k+$S(a{V2RXo%%&TXehQ<&vd@Um~n@ z)Urhx@$(|pk2=mA{vP(}+}?R)m*M;79EMbcuo2vin z=gb)w%R%5m?SggvthM8k&2!5@jci`limZTNn8O#`xfI%Q-y*p4xt>5~>3?tLMoLO6 zf51Yw5)=*U@Ar~-ZzF(pPRAjV(_nO-)z;-HPcUxJmjQyAoyR4mR>5+aXxuiM69lU# zT=ySCesJ;GM7%~v5L6a9Ws3AaQMJ~*DNH#uCUj-`J?D(I;;EW{C-&{+3VsIS&KQA) zy`SWUWWN!(2}Op$4%=n3uK0{nwlBEA>+gjQ4}T|N3>*PFKW_V{X}Npqe%_&1*BorM z{&i(0S1;X_Re>`t=VZaG?2;>~k_)9Gu*jb?E!^0(jFP<@D1q7CI|_PbS87rvO*Zu@ z!XupYByCc~CR`iy8K`Qi{J6-L;7F(ub&KPpTB_h#B;K1~8(XNVIPq$E$XXluxczf{ zH1zep>>g`-3naed>G_)pSy&Bj%;Ksd6Ew5|BMlwKe)*`Wjij}Kw5I*Ae!=!{Ny=P{ z)11=EJu^%7@o6!-2>U#!D@^0QOteggX-h|tTms+5xsi%_vX*56qGvT&vDKrtiRfbY zuk5QpPzEn+!uuKg^{UQRB2Oo*+FMP|VG@B^4xh+&cSZui1|c6Yt70$@)o42EL2%t- zZr0~R^#w)Z8f2H2k50S+_=#xQ=9mJjnN>z4Gz)p~yCL8AqTrM~Zl_f$46z;|rC%@I z_NHFeaHrO&UFWi1Te?aL&p)jZyHcFLO`lps{=~;euZDu-&wTom+x9Wg=Vqp+z7FU+ zHa2@5Ichr}!7SjnK9Ez59Bdx|7I5S4ZzUg$w?nUWDJiKqiGx+A<1d|3s)Gr?5Ze)0 z_`}6Ulz5+^K=mvXP;_eEl{2>x6ppq0NhW%!mCy_BC$LyUpCykwdZa7 z3m;le%#!96F$$=t_W}1wcW*{D*97c#a_*#OW!~$pBp24!y4_Y`i@giy;&b zx2^O1nn5W9`y-{?H6$raTDZ(_y;i&3bMS9cG(4*r};T=q)1nB2ba>@DWYiUM9 z>M5RSLVY}*v(w=YEKbR9h5aWcPSTxHr&P*mKUpbIn=&sbY6_u)FssMEggd%;xI~Fz z5XDcLRhPXF)qHvF&6Ny=%uI$jGp8)7j++)7@u+XSnw2&1Iv19_tE*Lt^EHvx$`w>f zRpKjD6iS!>nJZ^5?^Z-VH4SB0Bm>6|HBUCQ_gi(Xwlw*wfCK|0^A*_$xyrtsGOg)mTW{ z0xa$=#xJvvAUMhImN!8%_`aVHvcwB4jP2$_xgTQqhGhG8kBH|m4VB~_L(uo8={eUUn5ebqDl~f|%K{r&u@mDMbe`(C3z4~8dz2kS>-y1F* zt6^hXjm=3KTa6mqwv(pOH?}9Xor!Iyv2EMQncrFKym;3056p{M`*ZJWU%DBE4tmQH zO&AHfTitWJjB9TZE#IYzObvWS60FLhM2hJ<#$}-my(;S1|4iUO51Om0%Ln87%TRG| z)@*E4E|G_uZ>R$b&;q=wX0KwJz)jH>@ZcrDky7lumJk0U=FxzEj0pgEZcKVRCMuz^&pn~I$PNgwd+*tkdY9sP7EVSL z>=sadG|b(-`Kj{}@CALnSfyhynvPjK68kMto~rPJ0^r~2d)7t+*6H?G91maaj>x5$ zkC!ed&*I~kYNSG8Q5=F&b3qJV=L9uW`BE z$?Ss6;G$iN&+NSTt(%s=J)}lLTDbVg16%f}o^_z7utUlvfLT51n;6RoN$lGjsn5i1 z&30`qQ}k8QtMLru^J;aCs~It=S=a9>${(rEX#jrFfDU;~n#}7YfN1w6CB1cB5y99E zhwR8g9BLJXt~=JpdrVkOukS*NWLXjUTpmm5q2cf6A%5wx*mfD|x11_;M$X+lwS1F) z#<9rXUWka{;rrtGyWbNC!i39yLgl%L|&u)O4Y4xe!aOUwP1 z7XG^+g-W8Z12OWDj(o}`*Tl5TO(C@-xVOCS;9#cd!Z~{;IlJ{INYuIiV{PiW$7Ung zjd$4lWszS7lWsq3xXPM!0J^6Fd@>6|j6I33az%_#R(rwP&3 zS|qF-#B*S$f{>%dfb>QnnDeQrCP)_u3-;lmusA+#)Uh+U>W*==k_UjP{O`EdYD=M3V)J*WBJ z+39z4DR{cyP=1!SzVDetxIr4m0LVm0O$2C@g8RtFUo=ok$2WOHA@#T8@ihS?M?&}S z$4H=dX=4+l`y$^Q_8wxu&+a2;J9T;7!%S@FLt*myU5;Qk2E@q3n^Crwfsyb~1&Bs` zIAu&+!eFI{9?6NTskP^@(CGO^t}H63o__Ur9~SzuV=In?;xV9p8rU$V;6Sevf z&46&-nwY^g^T8i*dyuG5(Jl1rLA05iRY^L(RM>ShO zL2|4Tc|*>+*+zR`o7Mz#XHV;g$=3nJ;p}^tA75h!R}wWFm4i-wJM8F6(y{el53V78 z0>dn~+2V-8rbr>us<#11wKN7AuHZBrnP{Y3>R{Gp(*~BDJzb%`cK;YnC(qnl1kgG1 zh3vnXPEs!()O!QHaiO+IA79O{n~e|JZ!H#R;N=xnV$N-V18UWMCRF;vXlOlM3Z`|1JO5 zs%WbODN1DTJ;hgmEzMYRZ(CVx!u3U-s&zp2-z#J2=97L~4p@(!elAa<+Y4eM1nx~6 z!~zRa?wI+GE&Lmlo6}W`|B--v+G_Y^Et#2NKwB?oHFQCgQ4Ei)%l8AXh&c-mxj9)E zW|8N}!r%RP|KPH3K}kU*Cqk z{!*?8R+%S&dgD%fHiZCUmEGT-otxPm5$3j@pWMX>0A5}}ej(X0sS%ncM4>$)$3*uI z`brxL@WVkegRuSE?e+LC@+tZM`lzM06AMK8sU;w{2TF#FG5hG?Z@-R92j5UF5u@~C zj1!4zl_2lGbGvDP<*WU9{EDavS#DcVO^sCBX;>-~77BB6iu#$=*E4wG2G9Y6? zS=+_MnLyURx%=|nm#np=7~*N2w61{_F4<`^c`kAtfLCFlXnU7&WFY%LHDWs?brk9}8+UT7cFuk6 zZD+HLYboxwn)NE}3uJ<*q_c;ExV%$3h6P0kxs+2FLWO!j{;*2ysj;*hN3mDBvLB<* zhizG)BEX3G82!j1@KN}cm*lB-<;=26Qpc*S?>xlCyo8?4{`%4Dm+t#pcHKkM(PEX- zoMiA+oE8~iQf}ABC+$DB!lNr9YASN}cLa7}s}yu1fA|c;8vzE4SwtmG!dZ~JG{k#u zAikWX{C{{N&;-zeh^}e2cJ0*6pT8f6zWF=}zTXV5T1>N!Xym%c!`D|=o?pJ)(Sq#O zvNPI-gvkc~(I{@wEzS%m>5t05G_OwtOAVmz3c#;&ZIz!sMd`R+Zz3&%zi`j?VH6~u06l%-#vu3%Q z=>6O^IX|=Tbi?l6mPc~REpW;$vo5W3zCJL~AGMmgw5yD+NY`RWOOM27z^Pv}t&Kf5 z5^4)L>gk;e&yHPO%^uZ#yxqUOU4IENhr?#}e)jw(A3K3!hJ=E8z&f{*_;m6zX|DzTgh`Co;-UqIEpu5 zo#J7_1pkB9-BAt+&K|gJFm=^wGS^89^f5&{n!$P8VFLEIp7#;|;q$UUyN!swfwc24 zAkqv-1XGYZe!p^_*iyhQ#!nTWJyLe_E;RU$NMKn-74)5l%NLMi8p!v}{~A172P1Dc z+C78=ZlD|wudmPYc9tAAqb}D1wwHJ@*)7>i{r)DLUh!fw{a?h&oS-fx6Zs~*7wvjA z7mr%?RT{kOXcCNU2tmgtQ}k7d2$yDG@9d>^4Ie)G+l0x^`7b~JqCq05srh-j-lNR{ z!LZaw5q_Y4IvQPn4Ll00j z`wzu8F@KWOcqevOeTpNgTA7(aRP6psV8we^ogxZQ;Ju(nRMpd){!%{u-l_skbK(T` zwm5F|m!rlt$y=tkLBJs3zv*|cD1BRo;`BAG4_I*M{y5K|F$u<%`!)9L8s+3qFIDHq z##QMZ`1j6O#-#<ctlFgx9h*OinM{?l}R1#!k+BQXv2&Nin#N&ioGi>G@l z4$2~n)kuE}0j+mief_zLu^^izCS_$fbh95&v+>zIeUF>vaI5fd*&`nM6!~4d!oa5o zDhbb~HT+!0CjQCBo8od_O5R0rShM2Ldhte`V^@BHJ-vxh?ocY74|`~?C`ck3aCWOK zzlsxVZ+{5Aw$^Kv6br$@JaAXV1}hxLSM_4(7jA7?_w>v|oSNW%7sQR>ghLBCH1|9S zpC>AKPTJ?q>*i6=ypBU|R$d;kEH5RmoPbM*`=__}^?ccQbW|*h{_4F}UCJf%{Ur1o zx3}lO7z0#al%|^Op9=92`q$~S1J1xyC=INZ)`(7Mxe=_F&B7OQ;4P&pZLVz3W-j8p zAuS{mWD$O^q2UA!=G{hQYErhK`oo+OFV^X_9>fHR^Ty=a2rb%{a=X{@V{h|n?`mq? zFylb_6NIC)gYI$tzhidIp|o<>bh-kCBpp|5n}vOw?TCdjq$Yx~g&()k+;GS9|7kcJ zN$NBZ=w%_bj4_xUNGeD`NYe#*U4-7nh2AOC$VzkYu8I&6p9agINV3HCnisj&7>I5( z{%yA7vRRTm%x0?mSi=vyTOR(lECIiKgz6$2^CaB*F^VdN?Y(N<3S!}C;5eQQyk|9F zy@*6K9tfF9EWkTKyq7>+cf*fW{q+RzgX@`&%Yp)X5tsT=gmBfyWYk$g6t}rbCwx)O zTfptp&ut)f|GmIm=S2hlL2^!O;5@1O3del2Q?}DHNux2=-M71-+wLc=-SP3x3t+8Z* zNe3^by3!-8^n7LUJ0by`5Mu@TeK60@;=8ECNK zo9Nc3ICqSakYgWD-U~VYP?Wh?%Ca0@e)26j+s6z&!M!LEz?vJDq#vFr%wh?|_YQBM z609&YEcI(j2!2yo%y?~<`+mQJI&gxdA+*0!_j1ZuuY2xVYBVG~WODFK(LB-f-R3Cw>m0@)swMSmQb#BDA}Qb>i82&m?CX%+C>#p3vXK2Zw7{ zc7z9I<3UYz1ef!B6w3dM6I&4Z2PXxipB0q#MB;kC5E{{IItkoZ*S+90WQDYd=?+?4 zJg7GoGJDT!4p0j-c^@M3OLHCRe?s~Q<`{;zP92F9z?qYJImr7L!62X?3#N>*8h8~5 ziF+@9_PE|U{iH>=kc9&jJwO{Z+WyKkbs`#vy8~{%W#>ap5q)Y5!%lJa3?WXvd)fZc z^>a@zg0YRszNJd5oNgX241WhvE-RGR%FIbfpg8jzbW1WP`Pg(37i4iKqLvZ_quxDT zvE(7}-4PyQkSF$zn+4#8MoI+X*FI}Xo)x*agXM3GZVO28EA>7bfW~b1r5gHM(y+7aiUk%`qn4wY1rCEk)Wct%CEDu|H$i(b5u%7h26Qako zBpR|;JJqrbRlm2r5?wDwGK<+fi@6x=JFc(s1GRIljCQQ)hM5+wm{rEG&06#Pa^TQ# z;8ZT3Q@5R0wdMLHl2PuVZE0kC-{av#atPzVkN~o~^0mnT!OlZi!11XTbXb=41{cL2 z+;p{9-7g(mo04&+SXoh(l}j-6?P00sl8v_Bzjb`GmNjfL_ov0zVH#NQ1dXEY_gNKa68xP{xAU#59+m zp@E`TfGL5#50VIw@GP$RDhdi?ySUimb&dNIm{8Nah`iW^=lOs+kj_Ht2x-l&Im=xm zZZ&;buPla7?~eDQ@q}Tq=fLJcji6G^V3a|vKbhfRKSQr_^{9ObpHTCR48lUAtd!Gg zwCQvTlXJygPm9%VG1Z1$#onFE{+rXqf3CyD!O9v`zZO{v9P}pFo3fic7`EjPcZe(d z1Q$mE=M7=YxG|3QU(c}c^AWV??^S-|s%hiDz&KRIq)NX}w;hF ztu*>ok`I;piNn<0_-F9;AY5S3tBOve8{2z!2TY8iCdR2X7|?w9uPb zuE<&0`eO(yhFeu6vsXYNSs?0wZ?fCWfk>1aQ<3Bn&=uCmoZLc}1jLwaph>ASqZjZ% zY3FUWNEI+qg|j)cUVM~)tbPFcfp_B_I877%(Y2__-q~c{0d%nae!Dezm3~iy`zkj2 zBI@;z=WrwI))H~QQsTW+Q<*(J{%vQcN7!cL34=6Fs7PMod5g2h^&yxT<-b z^q&A?0ue{=a2>wUcl_078V;3ix;m{5Li@oQRFLx!g~)do5C(qjviu!1vXA2-zpq9P zl9>QL=$p&-7j|5eD|k$&XB3NriMq9=Ye@ zElq(PrBQzWB`1|i2w6L#x2gvu?AB|>26ct|Z(hvV%+q)XSZFeM;Z5v6mz?Mc?Pn63 zq&hsPhx86irs!VmI>ik}G8P%u%FyV<{gDIzmrRfrt5(6b0`-#yDghQYcPqeXo4%wX zKmSvk3FVB!)@u^C{k!g{p|IMc{$x|ZNP36Omr2pEMIWK%i3wzKltg5&&)yMkUD6-q zn7;c{LGVw^%qp1BK)$gbZpjI0MWu{rkCJ^?+%9<6v%bG!S918Qu1n5+E{l0~c<2SYj@|fj`xORAe^(*% zC)dVye~n0!r-p59NyXs1xp(dDDUt_@BN>MsE=d?We6*7Qa}i;WA$y)jy5aOG`#lQg z^dcy$KJz|AF9Yn{dER)FqZ6Haze?6;Cl{4MGfo@bjemvHj3p{c@Uh7OwEtGFWu~$X z{F@&R!3zniz)EgNrISY2qjHUO$o!*u8-8@VYz_i5bTR{zT7X4cpIlyXDqxYwLPkbs zmi~&>IiiPx7H$v|iAaci6)TH9KG>Y1mQ`Cyc&KMt%sl2J>5803k1ZS`Jv|&D%V+ea zQw1CkLOJXd~|~a%&a&o$U^D>(Vb?n3>JJYXJcI#6)Wuxd|@tc(?rMJu0)PBS5syq z?$K|c#pQS2;9G|XgpVfirho{JCZk0hjU1Q5(L`EEi_6VULZwSc@CwLW`G&&H_xFt; zF?5Sd=H)vn-i8QPUTz^FQ3p@v>->Y*T7taRTlbOUm%HcXku!`#S^%YqsL$b762K)X z(t-Tv=Yq)xSBQXvvXE%b?B>6YzE%G~vnoQl!`PTuR8-{XF0LpvRTY#bF0N?2A@Q#H z8x?m=1?+l<{UzqyoA|Djk_A6ZLcD|T(z=$Vbwspo9=>YHujfbI(s-l6g~--3|0itMKT`DT8`Ol>dRN)B#m*e4nn z%eebv?gZgF6h$9wtK&(~zv(rPBR*8#ih*4PQALH_lin-ZnwD)P) z9x3U;whrq$qQ~STCM?=9<$Fp4JWF!6fQBplD4~%CP{8^5IobLZp=Hl&J>H-@dRQuy z21`i3#j6ra0OkOtU}>}4>+Z3i;C484pzgEzXd8oF$jM%Z^_*wV1Ufi$?6%%wT7Q0r zS9z%Je~7f>aNL8fyVmV5L*9$=PG@$!hqkd>;|wh-iLSCd9RmRt#LKH4D{Z@294Ct4 ziDWlj|GtluqI&I6*Md{$i9@SL=e-P}i)pZi`-?v10dBxvV5c4Z**4;2>ynd`F*!!Bt4xp!v1R8yPO3 z5L*10C{9aci~`%0g^8oW%29VafczY>1Z>SCAV5{^g5S5Irm$wB@xQR#8EC%7bG5N^ zTPTonV;OToLHRI+I$EK0PU9I}OW8LQdtfc#&wOl27fC7o{Z)-8?CUJ8q|Hn14N1M; zzBC?VZL@A;Bk#;f+4dWXbFd|iONYYxKCe7&(z~44oWK(vb4Ka0_VUK<7}4g|mZg*ohHRxu2IrRuHs;cA$l1n;NprTKeJ4d{XI2xR+M zUyH51sc7&FIeUKRas2fcaIzQ0KQ0tc9~?u*T4hn(wWCSA_1-wo&atey?&DM>-G)N3 zt^b45o8;CjGDjJtacd3NsL4|fQ?};*3tBlN2TTaO+qP32VJ7~S8Q=A;Pkp=`$-i9d z6RiKXJE7{cBJtLfq|%t%W3VnEQ`Wn zM{U^U9x$31Q=44tV-{!32$GbkuFrK09w&p zo6JO&rab2?@(wMuP21eR4Lp|*byqj_MbCT>!EJLUha3q|umAee8I02_67ef`(~^2`n9d$YKzP5I=?yrXK#g-;UrnuK zI68hI^yWzLR_&v!^WUf2x}+m@&S&vb!87xMF**A28pBvw!ImpkSfy?8pMMZdhl5ZdKmKe$5=PbjHwb$z&M3Z1Gt4BN5#YZ@u2EZu=6RJl7sMc z1isnGg~M^B>^Zq^*(_dfysu4zc6X_G#{|bPD68%hwdKX#5|dY3Nq+`w1`f#*EMtWH z_=T>$4u!C_au^u|N=>DmikA~VzE6-b#K=lsF|}GWu3EA#2z31?>67lxRND*78z;Kq zy$gL@h7o0U69r~!sV(3$%Aeg>UaH)_;IkF4cCM$BS^0dQuWPV3-x>I9yGPOydeWKQ zo54V!&SW_6Yd*{%hw+ECl!uWtz^rNVh_F=cGn2y&pro&Hcro?`4SdPhGyKHcqZlVo zJKsn74r@O3+QoC#Unz8fQ6Cq_5km35Zv|{*o_hC?!~LFqa+bPtq3VBhd6lVyb{;&D zT<71Y?4g~D30SY7rL6PO<2UPPmwhyrUF_RbFYC05=OmTNNF{dbf~Nil5^xsr@I|NQ zLq53DHOX5stX?p#Tr?_OvCo%q0$qM{ErM_RCo1^5`~H?Pz^Xx0w^+o+Q_SI#!dgFv zfA;IGnb`t3LTu~FHDWBU>+tdMv7I5<;@mXqL4moGgf0`ISeF4Kk)!?X$A9ws;Z2#0 zm#h-HhHb&ha|DlBRU=ps>AgQrCDxjS!F3-+<+t5O;>gPXy$_9j>J0k9gXR{QiWy@r z6_AQ0-$aoQkEF94md;Gpz?(vm>nY!~9${77V%dzj0*4`&( zA}<)W+gh?>6!P>hZjAQl6feF_WMWwVVX{fyKixqBx4&^=oi!#Cx~gT!&#zXw5?(wI ztjovsRv!--8cY6qDn6LMsPOSHeXui7*lMbFxH2EgTkq;$^H$pbpkQw(NdLOV0W}8e z_;WJZJzi9Pu5+iZoBY6M-)obZh2t=u#Oals(4CK~pN88l8>wPNJqB9D%LB zwLNVDBV9c6(ce!bVsDKYqYU?}3a%y!?Z^KVzi~faZ1hxlKH5F3YwE|W)#Wkx7->op znS+Y~nDDaDXVXa{b&`W4ufa}c_m@?-m)|B)Ndj&M%KXlT5o~JbjsNUH3lbUSpiIj~ zJUX5X0!M_Ll&68kC5PIkJM@>!^O!6L@Jgog*}lfvky=Hi_F3_UK}EuY{4gi(0e*bU z4#xHmBKl2tH6mV?N&gS7TN!q72p*d z*t^+`iry4-8k05su4X2_4f8GTpR#iKz)M(J_MC-}eC7c&U{2!K>UTI7;CZE2O*aD>1k26z8$G{dc;)3~C+JGw)(Dnhg>!?-HcnOL+_M6+R5x?ohaVewbR>@50;O<4GKZ%J^% z9HkG$0dsVTdGSnr>Ws7I+>?FrUl$c$n7MWFlKYNMybNo&9O3<~_M!G0$|vEa=U7=U zrAy=_0K^^eF611bv!cVEZiDkwC2hzUT~sXPUJ|lh|L;bC$9CKiAHa`CSik$7iXt?$s8;?NZB4tt)dxTwBF+Ye*&* z^JaE`+*nU;oN_}vX9_-E6GX{qMsHEUlgC1@p}#Z|<5D zd2ma}pR`X}&ocN_Y1U+Xc$*YWR{6tZ#_F#HjNAwRS zeP4wDTULFbIH^g4>@VK8x(D3Iz8aw$MmpIp<)|G$bS>mo}j&A|Lw(}KJvXukqI{>}y zc1`@%Gl(EwEJ8L?%wt5}hW-UStJ1|7W&0%!%OwrbjAM7t_QsWTP{v6!0i`yw8v*)i zR0i6Y#`NLMi~%KafZ!oKGds$&>KithlVlHp!Jp(R_@bS?TB<&9y6GGVsP*REUCFZk7V)` z1YMC~a^gh#Jjz&O%QKN9Xo7!Tpd$noe99ig8S`Mt5!mBQ1$)Q>=?GW1s&J7l)*j_Fgw>aycADx zE))9*A2pkr+_&Bk?`BJTCoXihZw~?d@Q@8%CGb3U*B6FKkDeauGd;ka0NQ~wEZ_hO z9WFCbjJ54+lODA@*&bFBh4~a>noz%2L@<~=L+6_OVwN*U^C~U#F1;PyRsy}&WE+7E zDfimGIGOl@aSr4VogqtQ9@tB~G9fz(z0>~zy z%v$xAz7wPV)=ss%7bH9f-=f{T%==Ma?dOKLH1wQPUqZNr|D^?eTsnA)_F}Dc` zkBM>XxVTTDqWhYHJ3<}3evW?IpG|>2sV_^4E?|zoe(G{8G%Ecpg;leJO|uAUzOY7d z$X-80KY4xM`jz@G@qfZa7w`Wy#6hO;*l^lwB1{aWT5}DgL~* z6%WO{viB{WA1ocryeNu8$<~>rv{w~@YmW;FrkJn#-?Rnmd#ZHZp40YamjRwAoKqX) zAE1czrD?Vr;BmWS%hd$r&_#kjwbM7qj=lrzS3ZOIu}{&wF9G; z*ZNd;_QVr8<5HQx&YkSePxsDEjm~UyWj_@qm+~;g$?;$uvtC8#Qe@C(Q79d%JN<3_ zw8}g^D|>ex@9p23OE%3VITaFY9U_*s-=H)+ZhRZg)3W)pUYjO0@{##P7~o2jveiP6 z*n~;pvK10MFx-Qi+-nU(36Dz`ePz9+w^rx7qQpg9FP$F`kv}gIy48=C*Q2JAt}pwxv%kkSE38({=8e=s7(XUV zVF{~6c!iaiR3xhupyrFnRp_fWK;~`Onrv7*Y#7@uTH4RsTK%f2k{Q|JVpH=OtO)sG zJ$s8(o$#wUAz@n9!T+TueKCc`=S_Ri%dM@=ZS_AKJFdp;o9#71?%t>QT)ujPAZP*#4s17QOv&>Q+!+2JhcV`J zQsY0=<^0#B^FNn8&a+kep@Y2%7x-h^yE1rZ?>lxM=UhX%*FlpG``s(l!765pY@wdz z)PBK?Y2L0#ulzrL9e=z`Y02ajXN9I(`;`R@5SD`sK9iOfN6suS9Bd4QzR+@4vfrBu zdABZEJ!A_t9XeRJs1YF44R9cqu;Ty?tg&u~hTyyi^vEGk@Kny5mfH6+%Z1bb`09Hb z%)pfm5I~NA>W(smO2g6Ht&Qovq!5)ka~k@-&LZ>UK0{4Z+|MUq3?z~h!V0gNCgcjo z_$SA8&Ka2PdX@-Vh6mN%E;cx`lSSS{;Ee=wFE=esr<{Ik9sjivB~s8rFhd;eT@|%f zPc+R`OUK&SnsDsrQPyvi`f||zUE6~`$CZsC=K94d0!!fo#sH z9!5<;Ev|XVJ|S(+BR~D|(F0^VkR{Che*EhB(#eBXa~BcIh6X(aBhZb6PHFK*AUW&r zIK8>;J)&hQ?vJ}t7>;V9HgTsU@dh06 zhPlfej!vez&Nzg|;njZYv43!Ix!lU+F}!%O25D-)S+5R8rx>Ri zbfOqwgbJij0-654iE=Y%c~cX5d-tCj?62Gv9SRA8U_XK9R`sYVw$)wE!k5#>kkJ1w zy8<@DA3dqKK&*{=xhCp0qM_4(ujA60-Si;fom2}hQY-Z^1pCdUE=egfA=%yw6;$lZ zV9EV;+l`>BKzCEjM@~hf9wDR@Tk2qK$}qbo^;`okr1e1x5vi{l|38h7P*I|vpnTFz zrp(+Yo1_~XjaxzosCmrLx&&paQ})$+B0+;QcaHD!>T z0jXsJVfD&4P59OGB~^S*WkPl}QubNA=6`r~iv&YGGUST;SzHHQ`Vi^Td|GvXdTnvL z;NuWWt*AlLkCe7XGpkL>?rDS)T9je#3R~SbZ6BNGSqyVLEDC@wz&O?PbhrO#-W2-v zFC=^3vCjUVb>E5>tn!7nOXcJq%nl`QA`_n%R{jzvCji_Mz^Xdtr0P;v8vgU0#dBO# z)6LZ-wl8j9JD#EgBSk9q>?x9rm(}wFePO+=w;wY#fPgf3usuJFG3qTY6c8HvA-x}$ z^-$Z;AJ=*Dr)u&~kX=nHz1!91(%qKJND>w$Ca7o}xM=|A4vWr<1a}vwS%`jpwG8)o zP!Tj$J-t|IrKx=SZyix4^{lA6$_|F+qpSVBY-Y<}f% z!$3$2dtkYr4rYXbT?HxU{tSfT!yLP^V;11&^|#FQv`F_<3h@l6dLF^K*{SLi%YL4~dU$tEv5+{?_E+?f+vgGM4^PA?2;`=v4l*~I^{Pj1UcLM*1i0qJ36CmyRaChKf zF?{Y#VmK3$y`+mD;P#YZEA+FEB?qoSklSIy0>#()p=pCrqte9YiNA z8Amdrbh|&yd(%f;_Djt1|9JsCMYxHSTu>K-Ei6Q1=kcP{Y!@`Tz8f_Wnssi?9?15- zy2yx>^g$_x!JhXTPKOk9$#MdA_JW1c#cWE+gL!v=^4E$qRGKb-1v0kn!k+3$>%<<8 zt)8st#~Z_yN&eK}&m<1F{$@R8pb355v_Fy#P&!+zYPG+-%o!!@$AQ>~*3e?nh3cW# z@l@?UY1#MdR?<9Nv2Gy8Je5~0F+(X>T5TB`gpX|^-MmPxeG-!w&&vZ+VR^!+ zJS%P2>CPf%W4U^npHC78THBex=@^2JKR`YZ4ad;65RdXpA8*~QGEs|(L6?_y6^o62 zw^lW`t46^S>AcXZw#$0w(OB6tnsAGkBRm^JTH(5Iur1L&O$&wsO_EC4a@dLS8cM^OhG@H^W2D`0x{!&tY|PLqLAL_K;k=nsEz8bb z_6>2ocX_$rP?6N%@#?zEi^ODi6tt0&v2j=qz}wJ=2X}P1$m&y-I2COF?0j||A6QVG z^Qe~JYUlqr9+Kb6*{e9I+qoGAJs&kI0s%6@=(1ZtQI@IQi?W@|nmv-SeIh2~%e7vi z#R+EFf)H=W4YqYQWL$OiY&Q?DeKCavtfcNR+h!2%3a0^?AkO z&SQ5lQjZF%^fN_g!bkFeZF!5W;~asz`;)m6p|AJ-(Zs5%s^QoiUib6m_yQ?3QX${# znLO1JMMM~=5mDt_zi+TeSafk5c_TkK!d^pkZeh(v`);XJ%o19DXw`EmEvxm^Oyev% zpxds1clDU3P;sz}m9kaOv-()4QI4+Z&bK|mrt--R$yg0&9SWNlk)C4%T3CFarRQg9 z{9n}^@7j)Ei*BSmEQUf0gY(j7H_Ph$>8)&2hCe5(tjDGn!$$d7K4vcZW7mas4?8UD z-oi+II;=>)d7d;oM-PuJEMr%&Ms9g%H+QtwrpeHJ@epIBPYaO98vyv6tlypk%WsH7 z_E7M5Z#|6^|07$8B;BDy7`pbW^3>OWLX*?Fso#FlzV>4@>*U-}I9Wu{pi8(c3lK5z ziL8HBG?{O;oahl6_IuP=i>m7S&k;ZxE_8X~NJ+@`+fXiobx7v~oy{=;1!!6!Z`>VT$P`zlIJJ-nd$a`CKIrL9GEqDf9~n6pKvV> zaQM>r4F7m%iMh!nd~T%&4k){);SO(wAK0Najt*$gWig$^m}Aj$d|wPajx@X4B+v5u z{CIyi^da27Uu)Clw9QK=nh1DUJ)L3wcfI{(D*!v4jbU>d3IJGfsdv=WAa=dE`<9Zn zS$_yS7l#?_PiG;>-cCR1-xGg&@||VHeRjVYtqu_ zWYXwxNAn!WSgQ^anuy~E_VMy;%lqdtZ7pd-08c`oLXPan8M<%;N##Nb6aFre`<$}Z z{>Lz8jq8gY%X@0SuqZ%kw)tnKOyeKlxn=#gGR-CplkRH8uqI}{-)I)alC_HzxjR%* zkh4>9p-qLbBZs4=1Mu~86rQc&edSO_cPV9=nxgc8EX0(o8KgcC&PNQQA!cm_8=Y?@jT-1lzUd%$0+3N27x(K^1 ze*)4p&-Q;SIo}D7k;<>>Licl0bM-7a9zgy4Wa?llYSim06l82?Oa*~t9c^p&dlZfI z>T*2+ER-pPm?KCJrZ4TaeniXqG4c*l#i_*ob1C@SeG0LO=gaI8zxVr=h!GgQH4({&m5}bj--Q6vCa2p`F zySu~A+gIQ2zS{e5YJT0SbB}eOZj#_?whx_^3GI(rj|LirY*;dn`aCm(PM`PxQeH1zF zd@|?JUco=k!n*V2VLsmAc6jV}C^_I~;3qhwU0K?XspAQ;4tfu*-cCmUcX%?RR370m zomw{KT0R}s6z0;&O^qUGtNJlzf+LYea>?=z0vv1UYtDiYUbzP$?@0i(?JPa_J)xC5 zr7FT5Sn^iQ;d#`960Wn1e&%P=rs*$4r`(!&L!RX5YJ-gD6d-!9`<1f};g_vv5$nZg zhO!W=lduz_r%Dw!t-4vqBd75A)DFMKS-&IpO!14r?K*WKgcCon1G~PHEpNw!uyQIt>nlF!#yVgbkxn?F@@}sT=Tb%6-MYv(Xl2!?o)U9N7shz_e zYrqJ!LcSquAqa#hD?cQY9+PbGuh0K}1$NL5TJiAfc+f+v5$omVCl>U+MT5yzUK+lp z@cDY6yUWW!o9LW|yqtlsz|F+dk+;SNh~I}@1 z7dKF=PQ;^8%BNFnwNt#YNLDj@Y)WpcSlnq_ly}CjK5D{HLq3;?+4^!&>K#`yU$VA8V5X9|Iu|c zUT4wZGAcU^<2Uc6-%iG|7M*iGDbs(Ql;yd!-j~5?WR}rNuU9;gAv-xlB~j0^h9~OI zQ3Au?PANrNI#S{e%`O@A#;=AA#UAdWD%qGU(S$v;d0o(cGK7L1Q9LS!0y>Q?9`xjB z*x}XTLG0$`em_qXLeHs9A-W%!Z#f2s9iavP-Yco3@9tH*A5 z^mVXqIrL@FGTSeCm$n*NNS}z5G9cxTAR~Mhc8W2ND41PID~aQhKV?h=mqb@2LURpz z8U=B(_{AU#gCp?*64Y!Y{@v_=JP{{v6*(uR?74|7274?3eMdZe0!kB_+3Z z%yhSE$M@5|WetUGPwWroO`LE|p~? zhqgSbo<;rw$-!?)U0HLgQIPx8Zg;%4<|yyIYuIQwy@>aPGjkH(e!uhaoneIl^iF@t z;&Gs}^AzA9yT|9r>Y#e9XMgOX(!kUu>{x9Zv{{v0wm) zW%ZD%fM7jC;;ALY)AOvN*yEh*3BSwcniYN5ag?aliNyS#WaFOW=S^A9L?F`0dcd}w z6sn6M)nh%93f~GnwZeH%BB4EclCxgp04{ZS;@wYxw&4Ah zn3h1Pb3ZIn<%K4WTjt&#>!KWMA#F4RHO&qKw+e5+=#v%FwkVvD zP!PF$b`Jxsk1zoj9NkPl3F?f*uNxk$F3!TD55wh(w1LbD@jbY0CbdK?gpv6@L0Z%B zRPFF`D>9_esmcAdHW6uVI54ew2;BXv?_uT^UK%U_?9@iPJU_Y4jL zg~ki!QKscJq4#I9NpO|t{iUINX^Feo%t+u!3zJTd|F>g7og~83t$otub#~UbHGA*pkdjNO_$Mfz(&*zd*(J_U3w*S>jk$nW3)Sq!Nfeg?)@!HM$`U zpYxXh)-%3@)J_a%{rrk?U}i%oYTN55id#JyLtpGsa9&6HG~4Hl0%)c_S1S73GWb^@ z^>$ggRZXID&vmF{2I`r_-==uEftcZ-89-_Al zMGKJ8*`^+K!1XFsP>1;I`C%!j1FbGK76!s#1jiXAJ3ooi|*e*OlSmn5I{?f zzQZ+qHyh(m3&46t4c&&#iJ(1bTn~(g%7^-v2ZoADj|~sJo2RMsr*QlpfB9we*L@x` zy4PB?zd*>$3E9ZOIZ-EnU=7B*e>%(zU{wW%aU>oW-^u;fr13uvC}M%j4>k2+s>6T+g- z5zyD=brgnnd=}_*m~;n9%Ak}kbOgq6{darj3*UN-j*ti-z6ZprGWZ47x z{L4g>H(QtjCpf#b?A~frTL8;tHdZ#FJ2$vvF6_VVh3?o zXy=<3RXBRf1Hzh;a&Z*)A{@<&3EZu@Yp3Y7}WxkXjTNyr?WskaYNHymP1Wqo~&Ml)U_(v9R4 zDEKLQ3DNPF=R6#T;Mrr<#pCIPBXD3#MX8IG1xA!iuFBiRj;!92M}ytEu>1a2e|R9r zf!~5LF1ZRngY!N_?Ad<+=vGykw$YRAgVD7u$DqCJ;@;;}Td1{4SF!f`KDaxut8fAI zxf1o=f0%8)EZWqd?x36M<dDN_8O*e2jBXQhf^aUEDWK~ zhuKv4pw=7+b{}WGvYrGLKmpJulp?X*YwBBe=Nf`7+3qVpTf0$ZkQfc#aqYLBI2RB< zPT+LHWbzRuEv@4>=fJFC$+@!^Yxi58n~S2UqvL>c=*t_&7~E=9j@1-Tb!dc3i>ZhZ z{>sX6JC$`oj|}3ICk1iQcxz9KW*v>ZkH31T8Y+Gm&63lB`-RR z9K0TNyPlVo;Ip(Z{0V#vHiBI8i!3yIinlDMmt2!K6NUoUJZV|kcXf@kSw+%0eaYDb znj;3~*!fcPWfvJ(oT@1YR+Fa=hlU-vOs78-Shnk*TfeQV3HzBofMahO`t>f{iakul zF4qJdH4b={)XzLEU(jme)56EbXnI}iQEvHJ^q@9oN{Wlki)jG*-5}5RPr5(;d^0mQ z?i6A|wLsMbe`=n->ME)xW4!s;^o{3{t2BH2j>pKYR}0(b;3#GBFWw+7W?1m;z6IjC zO}4t#biUKXdFeJ^OH@8k;^ydPZ)zi*zdw}FkpF~ghE;+t>xVXq4ki|!Wwf(QwyE({ zDFQOk|HUx>2F-Kb_vYcJnO%dtF&21m231NY6)&?mJsZ+X|Fs_wf4*Z@@;RDayy&T~ z65G!u7b^Kq3N-su-H86%viATcmyIRZKH_jD^a20Kol?$gLbmiSGf(Bs9&&8>A#0EK z09nLs=84*ao?a#Ud{oT+9rhQ7Z2kWL+vV(^0o}NIfBqgbV7*v+qxJ?#aNX?*Yh2EG z`?cFmXdh>~{@8&M`A;2&s3u9C2wh)_9SB~zr-?7>JRRISDsWz-E!668J3gq^qO0C0 zoTaX|QGJV@xca9IZ<%`MotgeAd2;6SlvL}%Kms43-SLv3x+tcgKr*hS0(y(FxF)of z)0v~HGsp!aJiMj{Cu`$ zsk>E0965Fbe3U7rSyUPBgm%20{is8ovBye1WhbAO<7*;{kzC$5a6)G&{tVdZVcdKY znS3cTp>@PL)C)r?0u3d@VPB#acicsFFBTGj6PQQ2zj~k2^0u zTN<$vr0(4@9}-W}yMXz3?EO=1^|!SGzat(kEF zv+vmf&u#2;Sf4a1VSm~+wQN5MB>J2liD=qMw~|xDkZrM`pl_OnH^?ONdRmT;<4YIf z%?xKB+KD@G5;So1EoJ`xZW|dW-#I6l+wgX=DeI5LkN9!jGo660n*xqs zn;27P8XaG+NG^+fQl+xZl>If#sFPlc*_};sg*hehQYTX6(Z0M*)B(2*U*YCR(Vs6Xw^BlPAt zP#~?yASb8W%jx*FH!`WiOmv2HiQTc%avP#6!r8o`+%l}$u=1-z#h?QR#umUyR;+~R=KSBEs@K1icni?dCo2<*-dexpW$_t*6#0rs?WP^=E zbNMnkx=zyr<0>6k+^q0fgi{PsSpI1m)>SihO9ZRWtr`PS10Ye;KRA9)M)WAPwaRLrU6Y9diE3i> z@UqfB7k!`Pa2YRkpL+wM=?1Yx?`reBme_r=AZ>5wXBH(F&ZhAo{e%7*TEl}OHf2gW z%xqHw1onlfT`PH~y4=k#f>12to;SU}bF4>_m`%AX0Qd=OzbgiWGU6d`qDn+iE)6D|+6N3D3eC^> z)XJYFBrdC{-7$-H31OMm0Ivd4j%tJ9Cb5DaS|~$!F}Hnamz0u&V6B|U;jBdl4`)Gg zmZZ2Y?hIG&B-2Xof<~B9g}s3Y2KsHwjkf!lHw`V!()Rl4-L6La=P5_ti-3!@^r!oZ zrO6jiRf=Fnj_XO8+ex`Ag(@U_uYI1EZyg8v!jFonsDUDn)60&3M-Kf4-shIdv(T!0 z`Kk|1ae`Mk=LH&7pEsrZy`m_ekpc=}tzqh`D3&0aSD|^~t!yT5yk(g6OLA7x5S^** z)Z&q(7aHa)kl$@pvc&5_@vPegT%V0jSG%ZM6H)bAQNes!)lykJzF7HA!pV>#y+?qk z0yf{j1mdlq(GEpn0!n=#sa`h^vKtXe)0$8}vLTRq;t2gOL$Ox2PptLj_AJiLC4(zT z801OY7GiGfUzd;K^Iatv!H&2N`DO2Xp{}W{d@WOuZj`YujOkj3;o@y(I6NxKuc-*i zFT~vi51<3r(H+qs7_64mE3E&mtuxKNQn|K9A3RIN*J*wIck&8GZii`w>ZK)~Y?aH; z;b1o~3-WvT!3N8g8Lv?6Mzph4X!5&)B#@&E)Y@%_1soalf`>we8i{KN%72NbT5W` z98BY+L1u|XppD{vVmM&|ZeGV5hJ|jt`UVv;tPF(P*{<%ETENLEnQ6uL2HD+yZqv)TFwE$nrJ{;YQ8pq9RXQ34q6W5q zRbwrRP?6SudV`7MB#+QCDdDH#gWZbz?G|jqmd_l>l~epeP=EztNW3QBKtRIvk&x3+ z3Itw7N2;ry|a!R`&e+NhnMVq^4S%r~~`k z5>Y4S&B8OeUOFb9y}ILpM31wLDK_TW*v*x#gPKeOFjOwHYge_$ZI4T`%I0SnURWfe zZrkBLHZaLQa!)U1l42^;)@okR$|{qNKZ5*l@X`UJ|H<^aD{HB{dhTS0G%WmI*F*PF zUuet2MdtU~tPDbNh0o@&9c-dqT8`_hPB~W@y0d$7=nr;Y%BPF^7}UJ#{Y(18)y$?g z5e37K%0G22d#mfavM@)M+ATB0!zVv_7Jw_FuSWW$(2#jDyX!^2+vnRGkLe@?InV(t z*j0Z7=j5}Ld`m3D`&g&Ff5Dskl4qg&eEee2dGLa#g7xvbcG4zQw<{SBAr<}KHb(Me z{GEG!gd~P(X*cnglN|>0AW6<)kb*mn>bFF9yf4y}5(TXN-PHX;e-nNn>$dkCE-z{E zBP!nTEPm&hof7nnNGB0E1@P>~l3uqEp}7#CIvV~vohDps>fRZe%0|97KH`Ng`!<`IM+GqY=)2RsDX{uRH3=D z)<4Mg(XXCICfZigpjZHQzI?tfV?cZ6Nx|;HrR4dtC(D+=Wg=7h+e7*Xg7RBJOBYHm zZ#gc+1uqv#tnw^q%&PDP?ys6eTdYGS)#@IVTx_2OzU(eo7OvYC3mR6k8Ixx&hD4}R z080}XoBqZXtNJ5oR|*GUv=j$yXfpp(r(0D+rlNk@zI?p9QT~EvLqj24qbE`)r&WYp zJy%dQUs1tlS}AB6^;^wOhj0sJ7qQ*?D$F|a*SDxH(xs^|+^x}w2h$->cFMXKRvL*~ zn8A&xO)Fm0yd^;4TouA_xY5$y5*T%+kd{XR8~1y_p2@^*lQDuoeg7K1U$cw9PLx1~ zX;pm7G%<(T8P9z0krj@A^QgKqB$=(=El%iXQ2tpK?pZc2OD(~qTxwA#QE;J0K{5D#%B`&2>14+f56-?iNpuyn zDEHWdp;0_I)a9jw{f2a@sZ&P-2O+&}GeSp6-k@z1^FrYgS}_mSTPdsMHq)LPwq^|u zL1sY6XVU%HmL}w>EaQ}F05!t2@pp?EO^F~L4vxe&Iu-V5m@c??Z2)eo*Pq&R5n*@p zn{2@kr{Y_KzSj~C>*Hf`WRbxC(2rhMBt{FJ6fVqEOA@#xFxlUr*~1H1DJj&0G1F)I zY7^?y13gMa(AS_PvqWefYfCVNC|x?w-krJCo^?pL#0~rhX(!1gJWvIIciL8Wd3RoH zVS@Lin2dy_iE*0!0b>m=yOv(kE+($<(wRpVOaY?@kBE z1u9+1Dk_9jr#(vZpEO~vR3&>*ji&P|Hev(NEv(TjD`JiqlH}$cXk#(0Nxp02#m~^R zY09p*Bav*lmmIviZ!ri*tEfe5s381B(Wbe$K0>l}YByV3m}qTNh8+o1vI z<`cF7{DadtT~J9yWwI{hG%WuPbsIW++7g0pbX%s$+20=)D6T|2PA5;Bm_>(aEqdji z|HwCM4CB#Z<Nny6nyU=B06c^n7@q?JpIWuC{Ca&E~BY3ESs(}bgYjnehg!|W-O zZtPKV+CNlX5xtZc{zlVMlX?N>I9!}h=IY>5ClR-d%dn2uCO}!y*@{h$^t!G$u1z&9 zmT=-M3=?2mL}*a{v?L{zTWkD1eQWa85TQJLKB7uKr_MYrPCXpDQ+U9Wb{!#y`0rno zo!vnP9M*TK`G4Z(trV7+v#5~&Gk{k*EncoRZx?+&mM4p zJpYwXwO_m*Up8={WE}3}tRIPjy6#r@CstE!A;Ii9oC)`m84{Zrq6QZN z#e>rp1LrYkk3p@N>pq6aZkqm1blxQ&lB#>#ZRz_Rb)zZf=X-K5?Z(PDo`0#N#t2B$ z)ZdokA*|fXkLawUu<3Ad6G{lErZ+JGm2^R?#?|yYH222~?tc%E?^*qV-Orb%|dSOMpCi)W%04=Wb;ZO6(y2UB%N%J4@dRe)~~ z_Rdz)1V>7Z7Cme{syTVuHODVscs zSx==@H&Sv>b8jnT3xEw7S$t{q!M(>OAfccl*rTxYN>S=Ys8vnTKfiRgx^%TFf3>8V z8%2YNTak=i{5FF!j1jYdyB!uU`SRBB@b9~Mz1;X$jjC7`bvQ7JF69Me-~5N>Wl+Y| zu=WkkbE6?L>EVB~&sN;x)zUT!8p?+iyB2?V{`uvIU&L)%CS+Q`v1`bAY$T58Xcpe? z_){0(?;gbfp*>!34Y~ib8z9tsCb;&rvarma`I;MVJ2)$RO;&Q1>8e>mESY;rIW35- zm|sV+%cjgo)9WXz07GB{TeOBA6(j@mc3Qs<6&UC*k`zk?mK*%tD;_YGr3QhnAq688)5$yb8YRc{ulN7Fv?7o?#BgfCSviDO9bhlPy z%0F?Ng~F!AOC=@qRb{hg06taF&%e=TyTeFG+aW|d--;~zEXdJ8L{+(nYDV(JO9d|wM^u0Fm#Trb%7CPiA=+skU`lKf2r&5Y<;i(ld8+&9T@&bWZDj8dM)Z(G|1Od zUQvnLb5MH=gO$G8zfW>Qf?h(p3Oe)pnrYnl)(dXBNmMC$Ts#Sv_t1^z@luTQsULYw z4)+>fV7xEWR8A%05(@aTEe6wv(wqmkqWqI2f=!eAmiwt9%QEoCAHukt=Qa-a^W`qz zgURAEfo3k-jpf!VBWn|1(f<8srl!mjNJ55UXQ;6LA6dD>EN%j1HnWdkzh9F`bU;8c z$%&2}l{r!>EFC7>=*6SlAZk#s20LS94c?DS1kU~JSp4Y=Rlsp*OWo#w^DX|)+GI-p z*5&eeREy{f!N?Z2u(y`p@9xonV&(WS!6k0ueCxOuB6u-$HDkfvK!* zJSpZ*T^h`thph;ud@FAOAk1}SgEi~I8T))r<2<351=3#pnDz{;U=lhh5zwxpz6})3 zY&6N)MC2Vn(gU*6Yhw${g|b2_M>fw{&2INe)JqjXap-+o+J+&%%3d&)RH-lE8yt)} zHjzYrD5MFkbx!0pTY8=N7UYY%&7v?SKiLaW^X_6c+5H`f+bf1ho@A3J_45Q{+F>bT zKodErigf8$f^j~4sT8+HNm~Y6pKf|tFDReN$SkasQ%x~>U@UT<>dBFE4VcG_UCHCI6xw>8XC@TGr2!nrS-J6d+y8Mc4!; zoYv?nEVQ6&`P^U_ITkhbX|Wno!_f8G$`{5S*1WyT&+>Lh`L@bLUqw4S5!|mbh&<-u zUh`e_)xWcF1>up6N8WBhvho{f-R-Z>obEyb-YFu8j&ag6l&m5m)=jVR-%XOj#2&8O z>FWLUiQ0l?( zFF~h>LWfFtGN2ktx}i)EvDl>4?uI{97bc{)IEDf2Yb?I60{=%&u0h5qwh8;fFC|Sg z&K}`x!{72XEoe43y@_~6vy!cvT@VEa7L*Gx~hGq1yXh3%B&9UQfM zoMhcpKMO>ih~y;1IkUmh#La0L1ay_FM=f@{Wm~U}pGDLw$r-|OzD!D?>`{kYf9dC)f!-O;D0--ox$x!kd_!K} z|0?YRMK_y-eIgloUmVh|5>yBNOy*^bLCKKX#TKli!}xE7w(aF^<&60H>RjYFUYjU! zLQRTR4#JKYRE`dj_+5ENCvTqo1Hdj3Z=5gBwFnEQ(m9#!Vjb6Hk$2;4p%T~4WGNrP zUED`1cQUm#-sxOQ(2R=bnp96S490gBt5@zHq{HkBVfE9^CFj!xkCtxzK+c)Jo}@;<%%Xo>=cN~tFP$G|en?Ys%~(ll@P1A6 z;_2n#uzl({b1x0qzUQ*XYbgCG8{YwA*PY1l?Rj>-szSg`Cwu|s2$DTy(8!JZ{@-H` zGbZz=KuwYK_}zaLN4o(zfFF)b)I`2=W z05buw205OM{ugUif8_}!KN{wG4Go>r z!NYj5yf#gOVJ2f7kOD!7TA%-OEOOJ+3zRL7Nh2P0MiZ5$oK(J=3)YJb@NXiexyUc^XK>tweb}&}>GAP!rEXGTVQOwE@$C`)ZO|ZYZD^=aw?;e(Lg(ud zqUfNrPO~e;!kx}hEH6=v;e-RJ`oJ$nCXU1e%#n#Wyj^O?o5T>JIq`46{KUJURqXd? z3lT4DVLq{13djA-=(!F3>~>en`;LmahiYlgtURxbm-f` z6%`f;?$Tazb9Rz=V%33>QQ$_citJh+N{vB1sGMn2#FW`SG#^8HC>DR8w{pl)x#?mJ z3sXf|F^*DeQWAEFoFtaAw9P~`7;CmYq&$+%|3gm1i&tPKhhSggrm5t4Iq2Yewje}` z-Sm1V$g{4ub3oC^yt4JHWPOvWvJPX}Bv$Id=j)_4%Y@2*KdgQu_rh`603uqz0)_{M zpL9$qTc$0SkPP68K8qK@y2h5eB0-M{RimPreewSnn6$_&-K-JGZI8WxGX`p-3)f49 zW}KkcpJJ3QIiTX;DBwLx7%x<;^;2&Y7UV=a2`g|6_>tX{4*I>T zsg1z&!D(96*|yrpaHYf&-}Ec)G^^9aeE-UwV`DA-d4GF+!a8Y@unqlMg2ncD6}CsG zJ7L2+UQHwH#vT9W$DM#C+KP^npv|ElS|gOCVyib%-b0_kxvbvi_&`LEf#d#()V-X! z4(E>4CT|(s>tlS!!T)G2UYgR2#}Vo9vA9I!Pc{xY3Ap; z@XMe!f3@e^`|;o!8aq&$t`$y}0Cl^AuFq4<|KpPi1VL`C7ZFeYy&tE zhZ6)(Mb{BJr#FsI!F<~2VD9v}e?7v?`mYPC(Q@X9SGa_i6ZgPphI%m_?l_(l88@|v zOzUBt2c(u1#OrNOASS!jkXPNd4XP+GF*%nqtPLoMwu~XAku!!z z{qtD;qo>p#;Atzlb}2&d7;bpeA8g8f^*RQ8gU)UD4Nb*sifVqc+V(tnhZ77V zq<{Xgl)*yJ0AS8Zo%qyVA-}3hmswd zPrcGSyG92Erw|&7aR4V6xko5UsX5Ca1?IA-ow)|H|@_&{GA!@|T9Y-HZ8F zbNf}lH;tWc#?$=}qq z?)}NaGQTm*0)irf*OC3(I57VJk5I!Qz|FWxm@o9IFij`l zIv#82RF*#%ByA%#+W$ABXn%tqaHmyvcwA-RS`!YH3%_L>T`{!X1+R6IZ^pqASr{NDp z-vSVLo!|7Jc?t4Jsqn^>lHYSFIt|FyA+)KZPqckGhkek59ZYiVYc}mSB-McSY(%kU zF9LA+Nmi_5D~8!yEq&;$X2h5SiA&vi3;Riv*nNJ?OQkHljV*kgyophF2$)q`gt&lN z!R3S7#nfM6(srHrx_1~cY825LdwYRC%&&O}9$r9M`#w{FST6?&6d6D8W!tCpq#zxR zuChI*V+2&{LURBuqOBF;x{|jLf+jiWKgJaapfuYOS^Lc%~EPSzq zYy;%$<_Xn-^Cb~Id^c0bWR%*v;)ehLrd~uSPm6ZcJSf4$X6{sw-$mt8x zbh(iRI6pso8fj55^rm2*jmIJ74n1ylo;k|zo9bZIH!)8v1ejY73}{EQ_(FH#y))kd zp-*_;27omNF%1G=2+-FCDCcYTHERqaLe_+^T7NG2r1sa%^#|sDFTtJaNqq;BH8_Kx zj!|z8B5pQ5B!&7YkpB-GYf4>Vz=#m#`NMl-HPomA@jzF^Kp}+fOWOwogoHC(CI*C z_ZwkqF%)leDE>Fs=R)r#Wnwu*d@5*L_OPG#6nD?EF%ZB+V2e-zJK38N<;9rIdm`2? zUzT~$P`eV-UFOX$4bG>7f+S~iBb4p9KlfQN%$GU>T66+h^iIiSp3T`cC>CvIFyzo$ z4$1LrIDef^v&itn+EPvmN#||>Tjqdx|if>$M;awhh zl~-K~x8r-J29U;Pm1?O=tFgt;*dL30$zzOrWI-h^>*Y^hXyn|;9NI# z9w78;{ydVkRI(u@KsI$Nl!E3a6YdQeE(+P`g0JoS@l-7P?eL>g2q8VQ6)NB#5i2n& zQ2v*CLRFOyDDI)i~Xk(jdeS?$F#eSqO>ds4x zJh2_2aHC#*8wRh6>TlXrC{_Xn#wkAm$0E~*)JWgh#51n#(NDc$Vu}H=z3jhlP~HrZ z2ILbjUv(CjBy}u0GVmqQB1eQ@>2XXDN+CNmt$y4k7QOv8r<9ZMv3U6BF5acDMEd{} zTpoe!ER6Ap%UlG02u0_p8kZBGk^z%wZ2x2E5ReK}e#NMeCnbxKegf}oiQDsh z7o5UEU6Yfv-i7r3H7*BvY$ajOa`+Bm`IaW+3A45tn+AJnA>F)c_|_R$?>h`6yd@@G zAZ2g>*taEjN^_32yYIiw!G_Jjm+`86O@gs6^L|j%ilC42Ro}V!4HDUpeV+I>e&WZk z(ZZKA-&yu1H+uM|{Nc1d|Az+u+5@uW7InIgFdfE)+&45&@jlVBft|ZC=AZT+aA3CGkq2_vhXY>^Tx)pW<=#P zjj>))u$EW79yU!V$4-S!PBzrW1tjm0by>HzUA8gucVCI?mD_t;Z+_EUvE%3$Qh5`C znSd6&!}LvIgBfI_6#uFmX;}TUdG>3^S2__iY=0DQX9|~Of41Ggz)wUmQ$gZ06^r6k z`b2L_%YUbYke^LM7whAn$poLX7>u&M|CB~HQ{Ss^PIe@chFhr+e`y}Yc6T}09eGPC zL02HQg|{KvP)Ee(aouXYeZMt@jjq@h08TCG_tH03KpMUwuf44UwtZ7zkZE@V**MMM**E|D` zL3(YD(4D9FS}o&enNaM*=$!JztMI=Oxus@x8Hlh-eY#p{wbIjQ%g3R)Q%}qAS|I;# z2srvo?dIw2c(*`skHFZ#--BvTI|%OYuTwd@wL^%)Zx5p>Cd0-PN~yJ>&#d^HIp1W@ zEob0s{U(c1SGQf<+)x-Mb8wiQsUgfsXKny*`pntKo@^(V&p4q_)B-{CEJ;1(Dbv2W%cH57({CWWF@ZfcSm&A$Y2(dZ(_0QSr%Gu}e6?yXYwPNwKeX$Yz)K({aVWQ6e zaXR_k^EqB{5S<%chjl{`;r|V9;*mRsL>K{aZ$fA;5ll5a4= z@Kch4o{*+_kHtt<`Xz82wmO_-aWL$}X2SVLpqXDT!s2kknN9B>@-hp(P68hk#EZrG z(^)WD1j)vKxBwpI)z7k`T@VF`$Z2Badh019PgRU-*1--Qrffg*EM?%es!G+^Bvi`` zHgChm4`)RKlj&b3U@G3aQht2cyV6>&xx58Ec$R zLXWi16F%`?Nw+rW{A@c*r- z@Z@YL1LW30m-Y7*d460NUt_4Z8u!*PbGAoumkRebAA&bW?0Fk9wPmJQ>7zUUW8xJ6 zsB~bY84AzDA5e(iJoxrmnj=)eifWNrcCC}&aSOXPzmz>b2lE@PY}y^BZFLIb%|B+v zVr`uv;SH9hMOsT*Oqier?5LK-5fsnsKOQIR5cbc=%`o*8F{GuL9w>XmLU5NRWS~AC z>+LUICVkIan|(XHnh9g#({w*5B6CZ#`E65UoM!HLoy4ofb{g`-{BtVi=AX-YbK|N* zX4>*D#KFm5`?A)s(5Pe$(}eW_!E+sBKU(lCSF6Gg!HPvZ7ulXn9p{2C`w*+;Y%<>< zz2knEzxOdINVStol>_ZZuod*;Rj4$RJsur{gXBDoj6ee`;YI!F#*|VWI`)@ABch zDa5;8(s_UJk7-k`(8+<$^Ty03ZaoI%qVvD_QlO^|UEqjmTn<0|@(R^@ms(?$MDfI# zYaa;PF9L6IKEoa`S;uXxbzDEbg;EIL|0A@xL`;PC_tpvRXYu^*FTIK>0pNkWMhEo> zeSoRAnaIYGi3tz$O(g8{5BrzclLr?4R{pCcE-{L8uhliZMDi!|Bz@`7m!=0>8MB-X7Xd(n z0O0Au9FQ}9I)2Wo9mFCuf=FVj0kBfc%Tuz>U$L-VvNM~uDxI;cj&kIP-M`6hgpr?f_Dfc!@vE9dcbEIE=553b;tutAHhY@^ zyUDNu8Y$PZ^`QeY>{pKO$2@5fR#@M=nf$zTuD7dSm-LpRz3aDWu6bB;amQLhN3S)m zM;D{Yzm}%i49Zw6#7@HF;3A@^1lnpO`py62xUCwa6S?1|g=jJJnCN3$i+mRl#LeJ0 zTOvM>Qr(L5-Ncqz$uvc`mv(9>Tq+5)`YD$j-i)Ylew-$I)Wk8{={$?TQ;3c9_bcwP*evhtu`x1Yfwgqb$DW z#ci>gZNMI_SQq9_&xi8wS37?~3_LfAe;h`JkZ0;ugQBWxpKN7VxH;V22mRrX`gt}g zsH!5@uc0FC@?glR&sVD(&4x#&y^CW0C$b0i(k~LK#4D7bE7{HwSx_DPkO%I9EV5Zy zWbB=h9{<4i?pQ}ttPj6+fiLHh8!j*0!&51Hc7ydCMgqVFU8Z#AeHT3E{BYFue)v7Z zc{|I6)dxep5_`px5}ksoCD^Dt*1_kMojzSDCDKB2qRtLP2s8btaL%|`k4@#}3}u2) zFPPfdq;NzwIe~vv9i3zgBJcI>Q7f@?TuKOcR}nCJ`eW$TVknVn>+Qr~ildAkzAAj; zbf3LltC5-dt->XNX{zVyb@eGzz}@x%J&Hhx-t#(nDX9dyKZZzv!UNnw8XPV_3D1X4 z{OP;1v(NU&JrlcWG-SImqgZ57rsUR4E4A^_E@H2p$U4oC=Id*m7wPbis_!h})EyeeZ#9|%uC{fj6KsX^i6vIL7fBuyd8X)?-r^2b@}Lp7bg;BUO1 zkj|Ffvd%gr;uPXH^%hgQv(vyN=ER1ZPhlUx?3Ab|U>f;|K2M&kMu zjLaawWc}U#v%YYVjlPIZLqI)iBqvK02wNf&{ZpST>J2#@KjwE^HZ*gRRCu`|{#bag z*ypg#mRxm(p7lSq;*tm?m=t1P)w;Ua%kWn>OxX!qU(|a1&UigaUveonlSOFI*#1E0 zEof^!g%;0iFT}-y-c~};?cSvpzw_>J{=_Sva-UMma^5p0Z)IlH*ByofmQ+8Fa@Wl*bf_S*%*ym~*8d6}7Y z^#{DP-6IM8kQi0Ib&K>KaqU7g+ym>|D6mjtE&sccxbPOYf4$Tn*j;a~)*qsodi}SO zz5pmc@h&1G$4im!U3~k==g_0|pO_ATrfAO^)=uhOZi{nv;P76N-fs_`c7E-|zfZ(o zFGpFQRbA-hl`#Gc$wr31u@7Z$>xTr=HyK?W!Z#UnNuB^2;D!gEdNf+;4Lw$6BCK17NL#lX4>V!t)|#i1Us|BqAz8+soQd= zPT&@!!aq0hH)KpSDV?Xbl1u7FaIlRgecAtc*G$fTZ1l`O+)OxCx{#q(hBy(XTv4@V zUKq&^T(@M$IV%m1cA_bQO)^JN-0>|Pfo_b!ADUf?X(9-EtrQmSOkALUpF25aKu8BP zH!zcI3U^c3SDYFDZr9uuzG023Z%DJSEQuk&6Yvq+-ON*>l!O_P&EVuSUk%Bf*=R>6 zF^|VT48T7O!rv6KNXPlf1hFa?Zgj=dYzdNjnJB-1g|_`)Onn1;Wzn*2$F^-_$F^;D zY}@XjW81cEbdrwMv2ELW`@D1S`(AzPAFMfRjv6(phB7EumJka!Uf;g0!H{5s=EqsX zg@vEJ8O2OVS}e$n8u|e8K>9Cehj5D+2x28pNfk zC5}f-bNOM)c&#(srPI?OwW>NDi~MC%(+wk2-MWg$(K%Q>)%p2n4Z`+KkTLL*3N>29 zEF3QTMgq{?LJn;5ED-D4(BXjJIx<+ng=dy$A}vBiP<@`%0b0a80eaq?26rF5iQ!=m z9evZR2q;@$%6UGeux<5OFM3E;r@VU~TOJ#E>Y>+Ltc>M9_q&{U59D2n5v&C7ID7?X6a9d>3c~!Bp)Hw#D**PTyFO8hv>`4KVOzCKgS9`Om9HPeBK9J^j`Cu zKpuJ|2E1$;&_g}R{l6oM67{-jaZ-^Gjd7o@qwz1TOoe4{Y>ec9nnoC7v9_Hz_2r=r|aG z$w2J0KipqMSY#9)SB|>2fu<}|&Dg`ZYGCDXj4K3Yd`_4j-Ts_)=Ua6?dOmvPQLGZfip%Iac9R+f=^I#~!>^u)0XZO#e&g_UL@erkPhQmA_`4lm;P_>_Yk+Hv6Xp2R>l) z*YY~SM2L{whrQ)!JhJcTkd{7x!Pnj3<07#9rlS3^k3C^53%A6hZtRXRD$gDngAq%e zUPWzNwPovw6F+VKywi*e=QKBct~iTVe0yc0pjZmBi9(QJKE~ag@WA>&Kcs4s-S9N!CMBhX$7XBBc0rBX4WRstxJvYB$Z+lQX z6x2}Y?Y6hbtUntpuCDIotm}mPES??+nS+)L{yaTV`>0CzUx)Qv`#hgNlR`e)hyV8P z?3=Qillbc`(nLM_R-SmA^Yt)^_NqHfkI zf3cdgX?_bFYcDzsem*Q2T}}rXXh~fh3UpYh9*gznx<3VPI?WlLKWnxS`ZTwgvR=rZ ztuC1@6@;@YigNnb?+H5OR#+^l%rak*mFD!yp&#Jx$mRVAVMtfl0Sa#65T8o)fg)!V+=(OjEwJ<-AT3;d)%8n*Mg0KOMBnLvNfx0 znXMkGMlJ((*01YsC!ufSj@eHy2ZXPUBCi7~Bz&pt_q(4k+K66^76Crynhr;ii~e0Q>{9qvW+H zIv*nPMFtZv>Mg$D5*&di!6BijC%u&WWB6#uZogJ|kFDWo9frz&3Cefu>+i&%~V2z5OR8_=gEh!grs?6I%)qnjH?@IJQLn zw&(p*r?=O|!%b^t3j*i6xhfmxaWQ$;fab53`KiELlR68b%Cs-t@h20qLRupDXWY%p z3^%F16%5%qs{b+KM(pJaLe^*)A}2nN@8}r2+evu50B}*ejyDn>4wsYl%|V6m{_u!G zPA;D+tNl29ABpJZ0ki}+oJS`pFk3}+uIzPIu1cn|rc_%7O_w&q$ zBlY^^?dgQ=@g%*OM7=KJDFL!RX9;KHzK0>Qm#6pdTREidojmU&-f1Y6VW{B-z+(93 zfW{dbr~YT{cbfFfKB_dB%!4Xaycpi&bSs!M?4>lsrsfNZ4g0kOTsIC~MBUL8HE&VZLnZ!BzbzZc;@-k;rww#6%FhW1?& zQ}n&4KOXy-)hWFhkl##TI4IVIZ_{b`Z!5i)IB$*lycTYG5E)?w@uNWk<7qO0;KiA{ zE>O=U*FalDrw8ArAYwK*oLy<;RM3z=bhjzX&?6>E_A z_DYktYJ`TjB^22Sgse}KyMbc4VtyFd_(8G$%M{Oqpl} zy^U-0%AKmbkBjRu&Fhm0JeTx5*)__9ty-FB#6ILZ8KJ5XPj5n(#FFfJi${kGdzT9r z_S<{sf$*-x-Z+ULHR)d(x=1dqHKm5%!vKO%_;nfw2jnz9H2lr6&DP8&KXwnrQtI=N zlQ#S)b^a{Nqn}61Ji>J0RPxZsV z`WiKu+Gg&Tg>!8VR{oeik8*Y0QrJAoX)UA;>gTC}e7m zw$l%<_wHN55&I$W9SO6mQ=4RA0}}C4Fy#|1<5$W2uYUdQXlGn5a@$Ov%7UwNHgnYY zyGRkIFR!n0_^)x-ueZYiJv=ce_sBS+_-t;{DW1ja)VU-ma>=J3a2S`XtoAhC}LYfTTnGC#{VT;NEq_=GZ|Ca4|?yI%kMtlVQ zUwqVe>*4wve*YIx60L;AN1*T6pm$@MrOD9LX?7peqSG$*=$v?s$X+v5ysj-p0^> zo%USFN8!k#V#D}1BTFX6L5vM1BOeH9p>LmDd`S3d#1vQ+HNnwNBH``E#NCoj#}$|} zn*T8CNuZ$hXRP(7lMMKsG(Ev9Dt$*H&a?kP&y(YtDc5rTnD69-SEg8#$5rb+{<5_5 z!&~_3`n?2Drx!)YE1)h3aC~TswT=(rDo1c8WST?_tk+cKZM8;-8w#!a=%X3YsAUr_ z=YEd)od5n=y8mO8+fOp?5s$UsZuH-%wCbJv^?MUVlCZK`N_gHjdXC_@Y{YKq@GWM^ zod#gnL7QT&N!-;n?qxw>_bMi6s*3n^qer>fgdo|VEjlfey2nFQT#QE94hX`6EIKH;pRLLkJvEZ#aV0(V{ z^>6W0`EfTmTKKq!rr=nw|9VSir9QFV8^uT*)<~L87Ri%xWHB3UkNW!K5K0CIk;0}T zDYYj)o1dJg!@$!x?_iwfbsw*hs;zjr$+PUq@wwWhHcL?!u58E)Wq@F;|LH(X@GWqv z*@X(Xrp5*VL5DAAmig<2+vsmJ*V&ot(X`tInvdslUHCYxnb?MAL~W3`#r3*W<1A%) zKyV%#KC2U#_guL`42_f|p6{FQ(xpz{J7`UTzSCfx^=JEgd@^L+nT|+So;$RYd-wDA*rYxPNjW<^#yMk*24iZ zam;`(t&iz;C|41|b6WLjLXAcr_^;00wDBatK-*CtTG;2!*0oT&>F;V}12%ESlxP zL@Yyq-}_rsOjQkgWT~~)7sS{r**`hk0Y28x}X>`GL@09M{|)+{ug9ZBS)xx@A&yeboZ-)lY(aK`cIx1YKVZ-F=RA3qd3f4Z$(0M zw>#RqB2#gs;}K2E$C^`xxD*DRx|en@MjawJ9Hi7?e7DX1Qj<#r(q~j&r6f0Uk^mxL zrHvJ20tW^RpQCLooH+V{w9z3~k|&5y?R=TZWJ9IBHO`!P(LRX37mpi7m?obiZAADDt>nPWf6I08s#!`%ZP7Gv?64X zCh-$lSQ?>p63OgBtCrZXv!mLcP)D3fhE|5$ArhUz4c4@(ut+)Zn=|(?$3?YAGWL-O ziQTRPArSJbK@=W3n=fW1BBbs<;0ML?^?D^jvna8^V-`f&irtRVNy(J(HbD3ehnv!O z#YyMuClU0gAk}4sLKL_0%2-b#N-xHot!|os1!X)Z1Nl zOSi^!HXw;E$iT%+J)yExF2Y*Xm?uSx+!g7yjzVbOXKpN@#VD-zB*Wgm@5cY=@qGFI z?%o9$&d#;^J*hc4ey`&x)z#HeX^e-5hqs=5E58kQRtEk6Bli_cSfo6DF4OdagXFHF zvaGG@JttZ|jZN(aF7Jj2>&8KE|3L3RmuFnSCEmrGND7#T@?EcxkMC$UE)0vqyt=ad zfVV5DOw}gbLDtjI!WP*|ofZz4${o$)-6OkLs5Fk7cO?RCm$K9Cv5%jNg+@lMYi|+k z^wRcpQ+KS#CbG+m7%<5{A?Oj`;Xz<`$+wp1Nu1G)fYaCsi;-7VjFPOD9Vv5SuF|Dt zN}R37w%7Nhb~T{|&Btmv$F`Hl;4g334@>yj9E(NXADt=(~*_>``7Y-wf{GUX16(=${ z|EmRn#mLzZA8<#BS30xB1X>u*2-3Ct=Qg=fFz|$5T}wQ>m%etWf^J%p^gbL|9%XB3 zgaGJPa?mb7I!aPVq{wB#;-P=4j*ThrrFr~)t{a0TD(A^eK1pTd`zihEurC5EHfZyc z)x~!tNCLbRzaC2WhV;C~OvF!F#W!{GGleJvjI;jf1^v?4QI;Xq5FVzHPXFqTyiKzN z{VcTbhLrf&U=1|&e?ht~$h>}c-5*9ENA+T$I=(K+{Qr?lT>dWY^%Nq+b#MMBYQ20( zwWOR-#8xUy?$$1b?vWmM{{&BemuIriE0^GR(8(BsxN6JJ5Wi`&MOdF+SDi~&o{vvB zk+VA=Ek$ZGNTzCt&o1)yKg#LY>vo`DZ2**gG7{&O&d0;I;2e#oN-~CEf?y{NkdN*Q z5cTENiFXP0u|~34mU-)B`)Q8*e&J71inf+0erY~S+(y2yZdx4~0`?kkFTK%bneZN; zAiPiY8vV9pcfu(oGG}|SYxABbws?;fL3#AqddlxS>B~E!9w?l(hpJGk?c%$bIe)&C zw^@I>Ga$~q=4}Xu20nnE8K^pi80d({#b)_%a&n6{XKpo>SKBZs(#fmDcQL9To6HpOQ|t%XpQOv7o*+-|JIAusoJGZMpH5+d5m5(sU1LX!)lEEb){bw zy?42%n}PO&)YnVsgL`ZBPU6M1I(2}cq`n?vi`JZ!o+~bS_8(d&0%tiqHXqnp(b=W^ zaxb!gdl`){RQi+@3L$w6@X2NVvc8jy;eXwfB+7!%lN%elO1qCjEt_3exw%(YxwXCE zd`T0BL8OgMbzgz(S5Opan_JSUAIs9rg6rLq74ZQg1!vor`(Ylm8B%}tqYgH&1%Y+S z|Dzy0i}9;Nyu?=8RVHoGSzx<51;@F-DROGd>C!Y)$LU}()G5YGX>aJEb6K{TX{xiE zMm_tcspDcD`(kg1P0wrx&M1;|s<45tV-(c$68Ow7 zdh2ftUfpC6<)z8W!~Lex+Z8ZcMIn5VmRA?`sk(i%J55@| z*jinOK#gS|OMh9dm6H~hi0=AG+Ce{IyN5DB>j%85^J&P3*sz+Lm{p!MNa9%to~a6wPRomW!hULx>RZLUut zU=0upc7TKaiJyDY3X&XgOu zf~it0rUd*{{kbKj+8wM1{UnDCj1|^zicv24g*zpX(}HYo5Nif;C2nrW!qT{QVE3jREk2YwG>cmPej zAZK(MVZRP4K(gh#l zF}I`A=&164v>AEKtX>D{a8a0_m8o)&B~j7WeMk=#=Dh7-t{!Y|oa(ZK2R~+#`NocO zwiKV7$+>kBE+!+~OT}zNyK7+9w$N=HLOoi^eOA$Qs~w+8foy(r1SF7iE#vF~c7d!F zkyazU^fZw0`7A8r{cC|J z<1#Z*n~j{a#<12U-0V_gcusp;VAn`DVmf0_$9y@y^wUhXrLswQR*k{eQ8hk5+?7hx z8KCJ*CFy;hS-jKu;EhQwoa`pzdlr8)s-Tqr;$GX`a|+nYp#1lq(HpokV#)TlZ((X- z0MSB#EE_*Qv5n8;T3+3)ySP}Q;zpyc_eU^}K=Af9Zhw#$B5x?gHQ+^Erw^+wIVCl9 zk>nN}8ddh|YS2en*36D7V`zVlmrhnzMn(qjMb9tA!^5LZrbLAroh3t#Gy(dz2w~ia zDT}a}{buJQ%28Wx)eK?un+aTQj6ZYhO%eHjImiGOXOxFj^c!hl^5WAFQA{08wO3O` zf*r4_C%Bjx8S838Zgm)P7%e8;n3@)t>hTS7Ii;5Rhzf(C@_=de8_`Lf)IlFH$oxUB z+HS#szbKeIl&fzK7Ums?b6(2v7l(P&ESkp1y%(>aBwUpFp?m(GS!mFv8Ev&dTPW1LMhOd`VIkMh+ zJ1j=9k;2nRSgs+i(Tz4>O5+mz-Od*5f07>!`KTSAiX~mAi%hUaveGJ1?}ecyV(xiW zZ~0AWnEo+I5yT$lSvB{&i^XhNfu>UC00E{ z(@n+sEB)ldXm(XpNc*?W^6e7CLER*>y$)H2@6*h+#QQ|9m0|de^F1iWiXz|rcnaP1 z8{fV0(jg^zX^vFQl@JlXmrQ|L;KJsn%fU(mQr>NERGf{2ooLfvK4Tp}J3F#Ol5-7b zCx%D%7KBT5>6!PhsV$oJzp=xexb>|V6N$oA+a9;|mo<5_!l~upp5<(_ znE?g{*g2>}Dbhm;wp&1U;(2qFGZZ*}`wFhL4u6SAN*Ym=$zov_^&7rW-nMsg^7Fd# zy)2S+iz8YV^qRZb^U{%~X)F!>w?um71BZJzIc=`4UeS2bvG*uysj&`}QsJcyEl)=Q z@X-i2rq_FfJzbGpjA;9Z(aE#f94}V94IkVWOl0$mz9(@3_x`N zUuRsK7lp-?@t4PG_7IH{*ii+T5WUxV+D%&7ZQ2w>L>rrUV*nbL2ysTxdIxZ$WQ@Q5 z=)!98WJ-09&P$kkWb7pd!8XE!imPST%^%GEqZC7ftpQVe3DOnKcDt5`*_^&0i_B9z zQr%6y-y$Tizu$BT8-WYsPrWoXHJ3w&Y1Jw}K72D&)K_C6gQzvBJ3E2;2!XpV)~zuZ z42sX>lrJh(72qh1U#s2%*rZ}))!Ubg*S7?QrISY-{P*YDHO)2pSU83s4)cnv@YVd^ z#>%y|O3p)s?yG0P-JHZF%|BV=m1mviY@%zQS50|Oqtc5MLqkJmIi%`&(0*I#s|GGE zT=+aW3goB`TivgON1S&ZrcWc7eAu6St@RfFQ-83lH+`4T%h@26*1)Z<%&+E?K7Ec6 z#T;Q`Ip+!-2vF~APwj7Zk9Xw`&GZqE@=^gsa_Mg9DpR6(AzjPA$a`JUV-JX?j>L8{ zz&698U6t`J$~pcxOme}3AcY+g{VMKG_Iu*88!`VlTgwLRwG_%3y3 zv|l~?r4)tB$>@LaQtX5_Un&P#nZe^Oa(9DrKOCLI`LzB3lY}Lgn_a-nYQ8dhp+51> zGc}h_h_E;m+4ftnB;JCSa66Rz{*LDMbZ{V;*DFiIWtnle_UB){T;T_&er>$KkOmep zofERDK#NS*mDSdc&bC(w4&HVSoGkV;>{P3>p1FTkF>(F1+OgS!c-(>zJ;WHS0gT>T z_;PEu582>qD)_WCkV%Q*Gg3vld?Z%(2WC0D_EQJdQpcu~<})#e>QYO{a?k+s|zVO7cmpBI+|d@81~u_ z$%%bd5Du&OTiw|9GUNgF^ZISzi8ODpF~{r4d$q>6NdWieV(s&Sbde`P$h8M zB;w8(uCKA7lMLM08O%D)pQUxk>fvC|HQtFo!n=3^_f@% zOd;r&=jZPbOgbF6j9oZPf+Kz>tpt^k?%e#pC(mGt^&K+fLZZ#RAXDfl%))?DZ)J(z zQ9&?z-hF18Ktcks6k zU{{+_lC<{kS3=R?h%cUiwcJ2EOa&TciDE{pWu^Bp+vCu@Iek`bhv!i>1S=cMLfJmu zc>a?dY;PZhs`{Or_6IiZ;p43Qf7(>5WQC$#FFMPh&n6{Q%;u5}M`H7PB2I{@@uq9o zBsC8_KnGGg`YeK+EWPftO<(I8e7eWzC^vWmOB^-Nx0d258`wLW2zdJ#SSuK$vvBCE za0JO=@wTDgZo?tZ$ILFOQcy@vSC~vswk3d^87X;F3UQVqP%V_NY9)uIZt$;ynxK}b zj?;*b*9al>j#HRyuZF}VpAx_|yJtt5&AA%RNn01MNs;K73t9%8s`kX3R~5?(-Mkmw zQ7|}s5+2c7p68fy_v>v?%*4S|i@_$VT?{;my#ga>;ExC~e|yB^={zVFZFRlPP_YRN zSmF%df*Wb8!>j#c!d_~0Sn>BKqLbHXdzvqKWo2cnF6hzxNFA^{@kLv855=_hCisI1 zX4DjLbws;47(382CFO0TaV69fle7>em`hdh#GtrM7LfoeA+;{`Zg)$;@WeBP*zPVJ zg^Cw{ab<3ewa-Ce*9fM6{^BXF`FVOQ-X=5;745i#pK>gM4wDzxE3Xwtkh!a1_js=n zrvA7f<$|sBm{Bq%d$*qdtA_fB6q*l1X6oar$N`T-;n0AQ(T~g(L>B0w@CKcehmneN zkiIfV;~P!FYV1+7YjEJ_n?ah-+pJ9EIEP~Z%xf#dK5Z|Css!@=RR zc6~T$fZ2}CW3`{_jz~II%e*hjd#yOx&>Eo|SgVCoC5ZmN)OfDm-1Fq;#MnbIw7DrV|3DZfff)3oFz>o+W|qfKo!0fW<`phBo_2OF zA9XF>6zoi_Gu*y8RvI=AKx?y?o#E~9O5ylGO5ia&(sX#1@=NK7lQt)Bk2xn~sGLs8YtK4Z2r00x$k1>1(o^E~`|C zh-0y6^208B!$1tXEj~<7@fPc+r zW$+Oq{Y~vR{3VO<7n6(cgBs?)tgHdLT330gu9^n4ugcvUN^)dwP)YScM`4k6sI4lp zqhtIRK8xI)mvL_=C{520uOQTtriVPj#A4 zkAY*2<{us2G*lDWd^=*0MPF_sp0ByXZx!6Q{_)igI?Ds>YZS8nLl9IY`8Xpo5sA3V zYoRO_BjdB;F{`9f`g9(@gw&;=2(+uqUmNOMS`KDV&Tg=0}oCf?>QF^=64efoY z1I&i=J|d3*eR(imrAc&3L9wy1U!fKL3OND{NfUu1f#3&-T8FhJ7Bs%Ai;$EVfF9@j z{@Tqh^}GUfBN;e2xTv46uqiUr)!?rKu%WsoD$r|D!oA=$YP3Tu&X#`4>Ufaz8hYS| z+o9RW9p3z;QLLx5r2*A)^zPVD4f+fPsuq!R{pH4kN}?h|&h859Ga-|B zc?W}M44LFn?nl4X3KL3Zr z4`6|KM<76IJ@7ZV;_Rf8hl?wK7u+VzS(LA1OTm^(wloH1NH@!rDXP3~)znDe{9MKS zQp?y{wbAcEM=(%Z)hoE)3!h ziu3T8fR6%tz}-czMQ-0=tNVHG5>axoa8R$~m%tiMBTd^LP;A1NM4A5pv6#CUtG_eU@vrww();{NrVl%I*igppyt`3M{xtyr(aS zlp1lZ+j$l=nV78FxuxUn)C}das3VVAZpF) zkB%AXPg$?siEA3)^lV3DRw(!#ICiTu zT#UyORQX^qcf_uv>D3dW`mJ@3oGP8l;p&%Lw7n7eXkfiyJW!nPgti%m2-L-n+U@-N zI^Z#FKjtjzmW;i{V;*-{fd;hnPg{rQ!=PzEf?wt4#hzbWSUDhXk0x%9rSOkJwbFFC z$)^U0XZk2RzSSEZdtZ%1OdeoM=wkCzhG6c=K01}Y@ThF|Ku^F!uV=3vm!aID(zyfZ zXQJt{^VC{~^WNzjCINS2T90Y0Ex$}b7kx_#RLkv@%08*<{!r#?8;v@J>0jvpjgT_VMY*rdwSVp;DtT=B1L%3K2*r zVO)Rnv6BA6!y3pzV_4}{@u&I*>}E_)+vlHI+t|D>FhOuRKcq{MA31vEp~g4xBIW6i z_vvWp%^0$@*{(BwZpVj<`w}V=Crb6UN2G7+zI?piFW2DTKKuLt9Ka13Y>1Kuw!SzQ z4kbGFvl5BTuSy%;5~}0|G-Ff`UZ;$^WATu8RwjNMJ2@#P@G& zHKtbywFQ&qPWdq4=<<7Lzy4L`{49li++uZnRc%yY;vQ=#4przEPpjEjfVRhOHcc)m= zkC)N?<8QlkQW2$mWIETX&tEBvzdv}v2Veu4M2YF&QZ=C2>xU%}##e|T+mY~4svO#> z{Q86GG;dCb?BnJnJwlFSq2n%5bGeAST|qrd$&VAc-r2ra2=$LVvMKIyZVRHB0<7zi zXjYO=&J`XVDSxk#?Ca9a7tN-1Pq*GOK{Y|iG-_5sayA;Bg9+hGsl*yw$@6H zrt%iHDmHej29KZIcA@K>WWgiR2-w_fHq>k@aUGeNK%J9vQ!|-`HAU7>+vvzm+_ZLX z0sp`z*#r7ZHXW#))MtR1+rr}a9>|RXp=pi&q)gtFT(seE*u95+Xy`Y$hn%A+z`_fX z)dZ1@HvIw#em-SqAGjoG__e)t1Y3iV$u~9m#o26N@Om!lsd`LN#y2%17h}im=S;C# z8PRL_^MrKg&`-z|%G4M{`%C@alXyd4Q)Gd^P(&vYa5sO!y-2`(p=B|lVQXdX0aAdR zcwKIaE{`5oj!F&HqAj7OF{Q3Wsj4Zhu6en(!HxRCt-`@|gcNj9-G=bSC*HGC^^lec zS@;+Og+=Oxh2XbC-1HP2ouyN3*E37xheevsGuKNi_#7O16Nc0n8ene5JDcZ3S3+ik z{@3VLNN|4O5Tyn`zWgkQMMY%@u>+NdTl(W234iB@#g6kT{xqQU5s%~U8@j!@^EeJ< zCK68?f9qQPj0ytumv`ov>D=jqA}RPlpcrYOl|hH|Z>0Oa;nd9$MdPR;<9-MznpUr+YIFhY5`WqOF8YG+! zo;iM(duQwwO>BdbF}FnAYY@z%9RQGZaBHLAO7{f(9PXKKq+o+3oo_qLn6a1J7Y+!f z*^%<9u&;Y~ULWkT-1kXbO-0(bMi(neKjpBw8NrD#e!<=MhkBEN@z>|ZF4Irepv0^D zcfwC1hqn|Mos=GZU;ZezM5lA1FtNwyXNkw%5q9z@Y+s#6E8@zad-36DN-dc`{+mP= z9H_I`ljB5ae}X&_YZ|qdzVoyRLV>qOSfl%8{rslMyNpR5mUHLolTi4@rhY7Jy@zLW zZ!I~G%Nhj;N(mJ;7`3!2EslY^)qD;F)f;{XSsCa7m!#CeikS+RXBB*R3tWq zp_fZgfZV(Bqv1l0F7@Mt3!9kimxa>&$?fs+xZ3J5Ij+6rb+_Ma^_y6-%WAb!L!qw*CbHN2 zR1FZI+eGVCnsxt|;-oKCEu`At#gPbH?euhrxM2}al z_Z!NyPOsz?nq~&sj1G%gm%U0V1zj#LnS&Q;6hFWwH!7ZzvmliK(`Q7+p*rX~O{Xq0qt=OP ze=aya{waF2(YFZY`+1atb?7y%@ob%bF3Tw?S88t)FJD!{x;935Y_90sROGp$?3+Cn zsNWo7*w$TTrBLTIYH#Gl}ST5F`DOMXP*IIw6 z=~9nq5p@f9xE~;Y=#{_Bm@qiY?7OXJY-*xeX!A9(RjzaRHJ2T@oGr4DDKncXF|S;P zH(88h!$J?Q9gC^tQ`(0|wUGuCFXiP?YxRgJKgcc4l9LtmHCo_elUC>G(V)xd>FEUw zF3i-x3%$RCeL#J%_6uf-kv_H=fx?Lt%@X4ag=A)C0`Unzw_Pas)d1|>%a$1%zWy25 z?HH@BsOa#0y>sw7Qejb|4n5mX^Z(GFE^Rcs7VNz~^ZrKh7yFMy6e!s~sw2)g!K8?v zJoY&F&(PLP6eAH@w%{M$rmO}p8ZRd{8nVo8wuD{}2u2h4mQwSs+O0dM{hZKPS7G>H z3wu6e_|~C9e@}4KFfalxPOmPNTQoEnIUBT!OI(~5t+@sQ$U0|h#yg$OZcPs7vl6>B z|2+O^xwzaO*ltX0vuE~DhxB>%l^DiXapoe~Nb~wq`_|7;R^9=1B;ptV4O~g!djIx> z4;rSF@rGqsiQBW1b*d*{$waP+foYZC!ZWFEVZIR+iRWC}20Oj_p@Ju6uP~Zi|0XW$ zFkH3)Tu!~~=y(s(RED>_sSweff%@tD+u@#YaF9~MYnX!pMA&Ytms-&wyNq{r{rBFr zLL9s?WBSBqlc?`&^246d>?!}8OW4pc66iX5&KA{5S40neObR-T{4CCa_^tcEs&+mD zg3gpYEyASDfSrC8FPoWX;Zs;X(ulJ`T>x5Q2)Cs$mzj=@@w$C++)~c(`P|4X_Kb4& zj%`+&P}WmQ9ywXC&>ozL&Dg`^fmrw*ASHf06y*Y-&az34S%k$sJ@+n+C?FY_TO|Vk zu7RMk?Ym>+4Tc#3mig93zK3%Xh zi980pSVS497`_-uOsQv>ekX&Wsks)Q zwZr0l@$6voBwdOD+Q2~?G-&M6wxA5iHQa6&>vnB)cmI&}sVaP6;~EVp6Xf{^T{%u_ zwhOkJ1p2yZbC(6QMQKW`HrZo+AEI)HL9*R-&>GiI99V1osjK{DRc9yN#IU%K4TXf5 z%Mm~Q4q$#DWr{8XdA7p&`L1vZU4;2wxfh`W^;Q%BAoB`p*Vl7H*ywJWUo`y0;6Gtt6eE z%Xl=D{=`j$f0P1gwL9&1`21YgV5~N1s{b6IJgAb)9_AUZ@k@7`CCClT(I~Yfv&+6> z3wknbJW{KqyqUCe6=evmU>qDzKeZfkZ83T2`jzNK)6h6kriS2P#(sErBv_Zn-B9!i zTuifrSpB2+$mr{MqzJ%|_b7#C_v681jB&a?6oWW>3xLta4c7j;xN?f8I3$=zP} z!-v9XD6yQL|Lv3I!hqdFd5P@SsjIFc>qtTbn7BH*R_~tooEES z$;tDn8XE@ND&a=w@&=PV@+$d=*PNX`BW1<2(eop)^Ns3(DvZ|R3SyiUZGrS z&FC};#b=JjARULiH*H*=xDUH(sy1ekaIb`S34(fXpr|`Gyge)pOu;;-mG*43LRI-mZLE4`2_F_)ph@h?B)J)&ShNm+#Sr`S+jV2-RLL z#Q2gPI^Zaw!91%l34ioE-c!n~^sDTi@eh>RBoyGHP!uHrO6GeCyd-Xd+wF`_*!lT) zWT=U81Mp}m^+nv^;F%e>pGFY?Bt(N36$*XGD*er4(KzErv z+iTYTXc71|==OJIL}lU0{^Uz*X8Yaj4`Z**!t$?RbE|!IynSr+N0&7>{$<~0OMzv1 zVj6!^pEtRWlj74^Z}-D*{7*QUCJ+BkppHv`Y?v}D^IKqhb1pI}PJDI6Ju|aV9=_h3 zM+?m^`F0ZVQyYP2O+EANkY||U&3p*byhH+%g7T;Y)13nG3gPs&#zN(avMblMemvr? zJK;dNVg3GB;BL>uXyIh}vCVu&+||yq0~I;>9@${{tkJ`P){zICr^O6)-geUFM3VkY z;$e1@E)UFOI=_#Y>r=etH%EWv(8udo_bT(os8DVj+Q@1Uuo?v#$C|J0SZwA`xkGj5Z5MY%9VOa z0v<}Xw2FZBPfkjzoM1rn=icm|eAU*)>WlBp5`%PvP4J*5BzP?>>=rgg4-KhxjlmyO z-Y|HRdp7=HHM?MRhMWT&T$m)vkr+HAm5;yD_iXITom@mYX-_wkr>TX;#**&<#5?$< zzRqkv&*=>|hRb+iQPEKND17!eU~ksq94O_R)O?WR#`Eq;8b}?52x&vI-}+(d;EvBW zY9-5&+~;&J%`f`;weLeyTAi?c5Aw!w#gIlaELq`4B=7*uv%aE7B;bGXSzfJ}W!;?i zfk@jL23(}UinctTwpm`(fw&I#*zVUbN_IhA3Mb(7f9GHa{(R`W7U^{1ZhY&(G&Uw?<1{v!OeVJ3*l1(hwv)!T-PpFzJnwtH@0`E$ zclN!nwbxpEZ4u0PbH~e1&>yP{@9f)g4uF^0!8jl2fiK%<%46$hS2?G*QO@1NNvqx@ zWyJUn&o8goCRC^lJ9i~U`Epuqh@5QIdUkGieu+lwXAL46D4@aP@NHn}T;XXC?xgp)f#maeFoj)Y@4jj!)sGg&6iJ!8?)8KAyd^^9; z+-cNP-`M&p_;zuyoPogAnGz<5edIhp^xz(L`8@yqBo%(=rO*f83Ets%(6aLE8P&-s zFvDq|j8FXi^9Fw;d=?#5gv=E2!3N7(n_ereZ%lTZM#{d|TU%(7(T%XFlX`3^;@oT! z(GA3JvUWJ6X{*1|x%BU1r{MOuR(LNsamZsUgLLtSwd6`?T%9Q!A7!U7W7yfgyki~3 znr>VL@+;%r2)7w0Eo0wMa4OcsdPjthr||CC_G+b-QqcgcLb@d~oe=~KgHb~w))&ZGV~_BX3i(E1V<7i2_C zk8*PA1oa%OtybUN=;NYwjBYs9M*F0-nLRBdKHltdX5v7MGUf(WFu*dY2)fuO3HEPuvx}f-4_-dg(^m|SdOArefYs=AQ}WeQ!#P9! zEpx*a3)2;fTMdXd5A%QTa=VTNed-ZS$`A2Q&2X0{|B3uG(>Tn^FcEE%9M!QhqiDjj zByr@RbK)w~kFb`H9UK4$uL{C<*+ToF{`{rsCqYIn_`9p?yZvq2Sr6*Y9Gs*V_Z2rI zE)EMi*oL;=9o+3p&Eh8n`pRjNgnfeINHez)12h?l>8TT_?OnNUm}k9N`4>vKB(PO` z;yQCuKXSZ};9F?mpNs+NDOanHRQVzn5Y{C`rGy*Njx;ghzi+W-XXVc^f6TR%znU^9 zaCSV?QvpP3DVAH=A}!ANwt=AV!l1Ab|Igb0ll83w4#|1Um=i|2d+{SQo77|i*n+-?r_wzVW3Fo#87;l=Yy+uPnsG ztNO%Vf<*9}lR?@-K`HPLA1MdDLG`x2pbkMVX6EuuwJT1(N-pxeIR^N{lZEqxWw17C z??&d%clYY0k}r0gI&#KzI*{CjNxa6us6AfXh%{rU}?EY=7E3_%le^8hdj_T8Uh`wP!E5SqOCb9@>mM zxmY_j8DeB2JD8%(Ht1YI-=o#6X;?0e>dzy^rf1C;{<|aC$sMp*%aZvo1E5oHV^b9V zMdJ&eL-l=pHdFCTgu!n2b@rXja05Qsf^=Dl!vzu4T8=W3qj#Romy{BC?t#NpUo~5+5Ix=^CZY z(jk7inxcipMs$Hn`X>>1tU=TYQAZ6r=T zH||_amPJN;$s|k52z!a^qy&zFJ3AnWCs6?*_0e5;T-qw`p6gXX85s%c4|$oiX5-TL z^rIl4WGJE|NAPJ0tqNB_#po~A|zo2>bc?@;6o`iyeKkQKKMl|&FfpMvM z1;~ZRvh;JHqDf`NbfNe7jN@=Fs0!g)A?f=(s}{JlG7yj!aTEXjRqVOZ>xt0oDWd54E%@eC%q#uC zal=01`&FVss7DRcu4J>g8XWt(Sr}?Ppf!JVH0_AP**MSnR0)pGFpWz@x0 zR?6HaO5urvnHi`Iv_Y9Yk@e8uH+okcLB)lZc6D+~x9|NIsfyx#xaGKY3x zD0A;v0&M?(Zi$0hA7Sfxr~eU@pyh2z!OY$^y3&bpss%Ehv$ox^1-wO1O0IM$aIaqX0sC9 zN_nx=>|9O`I;SdeQX?CT74&8%I%&_O{0^=u(h?K)86D2$iacLqti8A0Mw1H?qk;_t zOdL}!;xB3lEjqeifXyxWFm+9txrJ1lob-xlMD?_7UdslQy(^E5*X3{_Od42)R2*&} zsfL?zEnp(AdLv$8D#B=)1BW`sUt(%BcJ)6}@R$V?_@k6@sr)8VFHuTU>5W_*Us$tm zq3(W%-oD&xJ0$50H3n5zK6%F6q2j7m3!v~ zoJvJePfp_a9lAE8wl?K-E ze9t+r?j+f56b2)7!l_Lbl7>*n=uqLZe; z!rMih2*qSXx8$oN;OzmmgK8cxThE!cP=%43YZ%;cDx(`9DIa@dGUH(TI}CY~J@M_^ z1EF@z8WYn4Kzl=<&y9BQVwGqpoiEFaX#Jue1{24F6EDT(=*aoB?D0fYRDljwhYSRc z+aRm1d*9H;N9cHa{^vzY7r?8k(iW}VRR21B(KK6Gc>OyIv)e_Dh%{8}U`@Buv5BEy zXJ0#ou~&!L&20tmsFR`J&Z}nYn`WqcP*GrS%5VH8N*u*02h2AbCB#gACd)RJj6dut zJ0Q9trR-EzAF~^0c&>O~F$HRP_Bqh_ll7ZC@&T^zFCpXhH!MJJ2Eyr>!vSE%M#;Q$ zpEH)%M1=Cbzf=11{+}3$r$B#dMZM_PQaCHVK2_7t`y{7DU+{0!t&VRirZy0)bQgqw z)I;gNrMbJO(0vPeXO9@s-Gmt$xmXIW9!W>>zy7U6W#88m0D}aEb~RmLEy2(0tupH? z4(sEl2G@=co6!}$M4mT{IyDR_7LO?-gbi**I3>%S0)7x_ab z5dX%xhy56Lr%47sGRG?iGBVR!0OTe#pk2ht6FtQqA~Ow0FJG1RbU8wTXdaP!{QN6; zpyIJ_%RzUSA2rE38p#GFf31>zTa?cM-t+XPE`khd^Z8r-C4-$^g1TUw(1)n!XUJU- z*KuHZo**Hw40^_}h(-yENfHakd@|17+~pyxLV$jp=)?#W)xbX!O3z+M2cgXct)Wn} z#n|!M#*hP>5UGu#A|D(Y_X>oWnLpqmF7~VOq|DC2#9_4|J-_dF?>a1<_|$krh2&_| zT`8E_zBlqoWP4*z{(3#@5=FecSR`h?Mxdy#s^=oHZuMzT3WJPBp(69^dS`Zpy+;H0 znWw3&o0?WTO4Go6i#F*-Zr}-rG9|vba?}rGCqeGTpndC+8`qzbaMw2nS4g-Bi_GXY zEI7&M2c#=AU4B;Y7bu~-lw$J>RV)+xnSzY37k~fF=+_Anwpb-|PbhVw5j(Q7o4Sox zbg~)0=8H9j!jAKBIgoJRq?rO_9o*T9cZSOps~s={Xcb~o_?cY!CDIY*661^LX~C7o z=_57jT!?ORU`<^(jeKFigYXoo8-x@HcV)9G}Q zV^rt%ueN-xdajn+sh93AB$NzwlTjo_%lHN)S(V)E`qIo=>;#-KG?oS`@83@qs5kE` z*~wJ-4jBr>X5vkTqZrdl{0c|M?1e`)os!wZWjVBA{>eB+S=f)hlkZ6(=HP33EW;DeVq=;~11_Ie@>>)MbM512ex2P}+HAI4wWlc{Q z-I0c&lv`K;!N*ssc6w9MU>h?1|4jc>Mf0ZH1fvEC`Q)k9ue)%`_MSJv*JN!q5>HhF~8l`YZf2T5)^?Cg8xguJn z^xt{VmE-cMZ1<06sW?eZetUK}O<-O^^*r^{^YLLqH|%}WJ}YVKEExX!Tx4o)t@%=@ z#M%VKMear~X+YrJtBy&mxX@*K7 zypH%uN}pRNHmi*h7$WNlPw6K0WhVDdjQnF7-y2uhHY>W(WI;b)qgikK-CY`1%Nq)w zEM(=5jkXFK?#&PY>#KOW^l