diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c921aec
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+logtbl.c
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..cbd63c7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,47 @@
+MAKEFLAGS = -j8
+CFLAGS = -Wall -std=c99 -s -O2
+DLL = -shared
+DIRS = -Idistorm3.2-package/include -Ibson
+LIBS = -lws2_32 -lshlwapi
+OBJDIR = objects
+
+ifneq ($(OS),Windows_NT)
+ CC = mingw32-gcc
+else
+ CC = gcc
+endif
+
+DISTORM3 = $(wildcard distorm3.2-package/src/*.c)
+DISTORM3OBJ = $(DISTORM3:distorm3.2-package/src/%.c=$(OBJDIR)/distorm3.2/%.o)
+
+CUCKOOSRC = $(wildcard *.c)
+CUCKOOOBJ = $(CUCKOOSRC:%.c=$(OBJDIR)/%.o)
+
+LOGTBLSRC = logtbl.c
+LOGTBLOBJ = $(LOGTBLSRC:%.c=$(OBJDIR)/%.o)
+
+BSONSRC = bson/bson.c bson/encoding.c bson/numbers.c
+BSONOBJ = $(OBJDIR)/bson/bson.o $(OBJDIR)/bson/encoding.o $(OBJDIR)/bson/numbers.o
+
+default: $(OBJDIR) $(LOGTBLSRC) cuckoomon.dll
+
+$(OBJDIR):
+ mkdir $@ $@/bson $@/distorm3.2
+
+$(LOGTBLSRC): netlog.py
+ python netlog.py c-header $@
+
+$(OBJDIR)/distorm3.2/%.o: distorm3.2-package/src/%.c
+ $(CC) $(CFLAGS) $(DIRS) -c $^ -o $@
+
+$(OBJDIR)/bson/%.o: bson/%.c
+ $(CC) $(CFLAGS) $(DIRS) -c $^ -o $@
+
+$(OBJDIR)/%.o: %.c
+ $(CC) $(CFLAGS) $(DIRS) -c $^ -o $@
+
+cuckoomon.dll: $(CUCKOOOBJ) $(DISTORM3OBJ) $(LOGTBLOBJ) $(BSONOBJ)
+ $(CC) $(CFLAGS) $(DLL) $(DIRS) -o $@ $^ $(LIBS)
+
+clean:
+ rm -rf $(OBJDIR) $(LOGTBLSRC) cuckoomon.dll
diff --git a/bson/LICENSE b/bson/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/bson/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/bson/bson.c b/bson/bson.c
new file mode 100644
index 0000000..11a88d7
--- /dev/null
+++ b/bson/bson.c
@@ -0,0 +1,1164 @@
+/* bson.c */
+
+/* Copyright 2009, 2010 10gen Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if _MSC_VER && ! _CRT_SECURE_NO_WARNINGS
+ #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "bson.h"
+#include "encoding.h"
+
+const int initialBufferSize = 128;
+
+/* only need one of these */
+static const int zero = 0;
+
+/* Static data to use with bson_init_empty( ) and bson_shared_empty( ) */
+static char bson_shared_empty_data[] = {5,0,0,0,0};
+
+/* Custom standard function pointers. */
+void *( *bson_malloc_func )( size_t ) = malloc;
+void *( *bson_realloc_func )( void *, size_t ) = realloc;
+void ( *bson_free_func )( void * ) = free;
+#ifdef R_SAFETY_NET
+bson_printf_func bson_printf;
+#else
+bson_printf_func bson_printf = printf;
+#endif
+bson_fprintf_func bson_fprintf = fprintf;
+bson_sprintf_func bson_sprintf = sprintf;
+
+static int _bson_errprintf( const char *, ... );
+bson_printf_func bson_errprintf = _bson_errprintf;
+
+static void _bson_zero( bson *b );
+static size_t _bson_position( const bson *b );
+
+/* ObjectId fuzz functions. */
+static int ( *oid_fuzz_func )( void ) = NULL;
+static int ( *oid_inc_func )( void ) = NULL;
+
+/* ----------------------------
+ READING
+ ------------------------------ */
+
+MONGO_EXPORT void bson_init_zero(bson* b) {
+ memset(b, 0, sizeof(bson) - sizeof(b->stack));
+}
+
+MONGO_EXPORT bson* bson_alloc( void ) {
+ return ( bson* )bson_malloc( sizeof( bson ) );
+}
+
+MONGO_EXPORT void bson_dealloc( bson* b ) {
+ bson_free( b );
+}
+
+/* When passed a char * of a BSON data block, returns its reported size */
+static int bson_finished_data_size( const char *data ) {
+ int i;
+ bson_little_endian32( &i, data );
+ return i;
+}
+
+int bson_init_finished_data( bson *b, char *data, bson_bool_t ownsData ) {
+ _bson_zero( b );
+ b->data = data;
+ b->dataSize = bson_finished_data_size( data );
+ b->ownsData = ownsData;
+ b->finished = 1;
+ return BSON_OK;
+}
+
+int bson_init_finished_data_with_copy( bson *b, const char *data ) {
+ int dataSize = bson_finished_data_size( data );
+ if ( bson_init_size( b, dataSize ) == BSON_ERROR ) return BSON_ERROR;
+ memcpy( b->data, data, dataSize );
+ b->finished = 1;
+ return BSON_OK;
+}
+
+MONGO_EXPORT bson_bool_t bson_init_empty( bson *obj ) {
+ bson_init_finished_data( obj, bson_shared_empty_data, 0 );
+ return BSON_OK;
+}
+
+MONGO_EXPORT const bson *bson_shared_empty( void ) {
+ static const bson shared_empty = { bson_shared_empty_data, bson_shared_empty_data, 128, 1, 0 };
+ return &shared_empty;
+}
+
+MONGO_EXPORT int bson_copy( bson *out, const bson *in ) {
+ if ( !out || !in ) return BSON_ERROR;
+ if ( !in->finished ) return BSON_ERROR;
+ return bson_init_finished_data_with_copy( out, in->data );
+}
+
+MONGO_EXPORT int bson_size( const bson *b ) {
+ int i;
+ if ( ! b || ! b->data )
+ return 0;
+ bson_little_endian32( &i, b->data );
+ return i;
+}
+
+static size_t _bson_position( const bson *b ) {
+ return b->cur - b->data;
+}
+
+MONGO_EXPORT size_t bson_buffer_size( const bson *b ) {
+ return _bson_position(b) + 1;
+}
+
+
+MONGO_EXPORT const char *bson_data( const bson *b ) {
+ return (const char *)b->data;
+}
+
+static char hexbyte( char hex ) {
+ if (hex >= '0' && hex <= '9')
+ return (hex - '0');
+ else if (hex >= 'A' && hex <= 'F')
+ return (hex - 'A' + 10);
+ else if (hex >= 'a' && hex <= 'f')
+ return (hex - 'a' + 10);
+ else
+ return 0x0;
+}
+
+MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str ) {
+ int i;
+ for ( i=0; i<12; i++ ) {
+ oid->bytes[i] = ( hexbyte( str[2*i] ) << 4 ) | hexbyte( str[2*i + 1] );
+ }
+}
+
+MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str ) {
+ static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+ int i;
+ for ( i=0; i<12; i++ ) {
+ str[2*i] = hex[( oid->bytes[i] & 0xf0 ) >> 4];
+ str[2*i + 1] = hex[ oid->bytes[i] & 0x0f ];
+ }
+ str[24] = '\0';
+}
+
+MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) ) {
+ oid_fuzz_func = func;
+}
+
+MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) ) {
+ oid_inc_func = func;
+}
+
+MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid ) {
+ static int incr = 0;
+ static int fuzz = 0;
+ int i;
+ time_t t = time( NULL );
+
+ if( oid_inc_func )
+ i = oid_inc_func();
+ else
+ i = incr++;
+
+ if ( !fuzz ) {
+ if ( oid_fuzz_func )
+ fuzz = oid_fuzz_func();
+ else {
+ srand( ( int )t );
+ fuzz = rand();
+ }
+ }
+
+ bson_big_endian32( &oid->ints[0], &t );
+ oid->ints[1] = fuzz;
+ bson_big_endian32( &oid->ints[2], &i );
+}
+
+MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ) {
+ time_t out = 0;
+ bson_big_endian32( &out, &oid->ints[0] );
+
+ return out;
+}
+
+MONGO_EXPORT void bson_print( const bson *b ) {
+ bson_print_raw( b->data , 0 );
+}
+
+MONGO_EXPORT void bson_print_raw( const char *data , int depth ) {
+ bson_iterator i;
+ const char *key;
+ int temp;
+ bson_timestamp_t ts;
+ char oidhex[25];
+ bson scope;
+ bson_iterator_from_buffer( &i, data );
+
+ while ( bson_iterator_next( &i ) ) {
+ bson_type t = bson_iterator_type( &i );
+ if ( t == 0 )
+ break;
+ key = bson_iterator_key( &i );
+
+ for ( temp=0; temp<=depth; temp++ )
+ bson_printf( "\t" );
+ bson_printf( "%s : %d \t " , key , t );
+ switch ( t ) {
+ case BSON_DOUBLE:
+ bson_printf( "%f" , bson_iterator_double( &i ) );
+ break;
+ case BSON_STRING:
+ bson_printf( "%s" , bson_iterator_string( &i ) );
+ break;
+ case BSON_SYMBOL:
+ bson_printf( "SYMBOL: %s" , bson_iterator_string( &i ) );
+ break;
+ case BSON_OID:
+ bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
+ bson_printf( "%s" , oidhex );
+ break;
+ case BSON_BOOL:
+ bson_printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
+ break;
+ case BSON_DATE:
+ bson_printf( "%ld" , ( long int )bson_iterator_date( &i ) );
+ break;
+ case BSON_BINDATA:
+ bson_printf( "BSON_BINDATA" );
+ break;
+ case BSON_UNDEFINED:
+ bson_printf( "BSON_UNDEFINED" );
+ break;
+ case BSON_NULL:
+ bson_printf( "BSON_NULL" );
+ break;
+ case BSON_REGEX:
+ bson_printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) );
+ break;
+ case BSON_CODE:
+ bson_printf( "BSON_CODE: %s", bson_iterator_code( &i ) );
+ break;
+ case BSON_CODEWSCOPE:
+ bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
+ bson_iterator_code_scope_init( &i, &scope, 0 );
+ bson_printf( "\n\t SCOPE: " );
+ bson_print( &scope );
+ bson_destroy( &scope );
+ break;
+ case BSON_INT:
+ bson_printf( "%d" , bson_iterator_int( &i ) );
+ break;
+ case BSON_LONG:
+ bson_printf( "%lld" , ( uint64_t )bson_iterator_long( &i ) );
+ break;
+ case BSON_TIMESTAMP:
+ ts = bson_iterator_timestamp( &i );
+ bson_printf( "i: %d, t: %d", ts.i, ts.t );
+ break;
+ case BSON_OBJECT:
+ case BSON_ARRAY:
+ bson_printf( "\n" );
+ bson_print_raw( bson_iterator_value( &i ) , depth + 1 );
+ break;
+ default:
+ bson_errprintf( "can't print type : %d\n" , t );
+ }
+ bson_printf( "\n" );
+ }
+}
+
+/* ----------------------------
+ ITERATOR
+ ------------------------------ */
+
+MONGO_EXPORT bson_iterator* bson_iterator_alloc( void ) {
+ return ( bson_iterator* )bson_malloc( sizeof( bson_iterator ) );
+}
+
+MONGO_EXPORT void bson_iterator_dealloc( bson_iterator* i ) {
+ bson_free( i );
+}
+
+MONGO_EXPORT void bson_iterator_init( bson_iterator *i, const bson *b ) {
+ i->cur = b->data + 4;
+ i->first = 1;
+}
+
+MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) {
+ i->cur = buffer + 4;
+ i->first = 1;
+}
+
+MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) {
+ bson_iterator_init( it, (bson *)obj );
+ while( bson_iterator_next( it ) ) {
+ if ( strcmp( name, bson_iterator_key( it ) ) == 0 )
+ break;
+ }
+ return bson_iterator_type( it );
+}
+
+MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i ) {
+ return *( i->cur );
+}
+
+MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ) {
+ size_t ds;
+
+ if ( i->first ) {
+ i->first = 0;
+ return ( bson_type )( *i->cur );
+ }
+
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_EOO:
+ return BSON_EOO; /* don't advance */
+ case BSON_UNDEFINED:
+ case BSON_NULL:
+ case BSON_MINKEY:
+ case BSON_MAXKEY:
+ ds = 0;
+ break;
+ case BSON_BOOL:
+ ds = 1;
+ break;
+ case BSON_INT:
+ ds = 4;
+ break;
+ case BSON_LONG:
+ case BSON_DOUBLE:
+ case BSON_TIMESTAMP:
+ case BSON_DATE:
+ ds = 8;
+ break;
+ case BSON_OID:
+ ds = 12;
+ break;
+ case BSON_STRING:
+ case BSON_SYMBOL:
+ case BSON_CODE:
+ ds = 4 + bson_iterator_int_raw( i );
+ break;
+ case BSON_BINDATA:
+ ds = 5 + bson_iterator_int_raw( i );
+ break;
+ case BSON_OBJECT:
+ case BSON_ARRAY:
+ case BSON_CODEWSCOPE:
+ ds = bson_iterator_int_raw( i );
+ break;
+ case BSON_DBREF:
+ ds = 4+12 + bson_iterator_int_raw( i );
+ break;
+ case BSON_REGEX: {
+ const char *s = bson_iterator_value( i );
+ const char *p = s;
+ p += strlen( p )+1;
+ p += strlen( p )+1;
+ ds = p-s;
+ break;
+ }
+
+ default: {
+ char msg[] = "unknown type: 000000000000";
+ bson_numstr( msg+14, ( unsigned )( i->cur[0] ) );
+ bson_fatal_msg( 0, msg );
+ return 0;
+ }
+ }
+
+ i->cur += 1 + strlen( i->cur + 1 ) + 1 + ds;
+
+ return ( bson_type )( *i->cur );
+}
+
+MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i ) {
+ // problem to convert 0xFF to 255
+ return ( bson_type )( unsigned char )i->cur[0];
+}
+
+MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i ) {
+ return i->cur + 1;
+}
+
+MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i ) {
+ const char *t = i->cur + 1;
+ t += strlen( t ) + 1;
+ return t;
+}
+
+/* types */
+
+int bson_iterator_int_raw( const bson_iterator *i ) {
+ int out;
+ bson_little_endian32( &out, bson_iterator_value( i ) );
+ return out;
+}
+
+double bson_iterator_double_raw( const bson_iterator *i ) {
+ double out;
+ bson_little_endian64( &out, bson_iterator_value( i ) );
+ return out;
+}
+
+int64_t bson_iterator_long_raw( const bson_iterator *i ) {
+ int64_t out;
+ bson_little_endian64( &out, bson_iterator_value( i ) );
+ return out;
+}
+
+bson_bool_t bson_iterator_bool_raw( const bson_iterator *i ) {
+ return bson_iterator_value( i )[0];
+}
+
+MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ) {
+ return ( bson_oid_t * )bson_iterator_value( i );
+}
+
+MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ) {
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_INT:
+ return bson_iterator_int_raw( i );
+ case BSON_LONG:
+ return ( int )bson_iterator_long_raw( i );
+ case BSON_DOUBLE:
+ return ( int )bson_iterator_double_raw( i );
+ default:
+ return 0;
+ }
+}
+
+MONGO_EXPORT double bson_iterator_double( const bson_iterator *i ) {
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_INT:
+ return bson_iterator_int_raw( i );
+ case BSON_LONG:
+ return ( double )bson_iterator_long_raw( i );
+ case BSON_DOUBLE:
+ return bson_iterator_double_raw( i );
+ default:
+ return 0;
+ }
+}
+
+MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i ) {
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_INT:
+ return bson_iterator_int_raw( i );
+ case BSON_LONG:
+ return bson_iterator_long_raw( i );
+ case BSON_DOUBLE:
+ return ( int64_t)bson_iterator_double_raw( i );
+ default:
+ return 0;
+ }
+}
+
+MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) {
+ bson_timestamp_t ts;
+ bson_little_endian32( &( ts.i ), bson_iterator_value( i ) );
+ bson_little_endian32( &( ts.t ), bson_iterator_value( i ) + 4 );
+ return ts;
+}
+
+
+MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i ) {
+ int time;
+ bson_little_endian32( &time, bson_iterator_value( i ) + 4 );
+ return time;
+}
+
+
+MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i ) {
+ int increment;
+ bson_little_endian32( &increment, bson_iterator_value( i ) );
+ return increment;
+}
+
+
+MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i ) {
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_BOOL:
+ return bson_iterator_bool_raw( i );
+ case BSON_INT:
+ return bson_iterator_int_raw( i ) != 0;
+ case BSON_LONG:
+ return bson_iterator_long_raw( i ) != 0;
+ case BSON_DOUBLE:
+ return bson_iterator_double_raw( i ) != 0;
+ case BSON_EOO:
+ case BSON_NULL:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i ) {
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_STRING:
+ case BSON_SYMBOL:
+ return bson_iterator_value( i ) + 4;
+ default:
+ return "";
+ }
+}
+
+int bson_iterator_string_len( const bson_iterator *i ) {
+ return bson_iterator_int_raw( i );
+}
+
+MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i ) {
+ switch ( bson_iterator_type( i ) ) {
+ case BSON_STRING:
+ case BSON_CODE:
+ return bson_iterator_value( i ) + 4;
+ case BSON_CODEWSCOPE:
+ return bson_iterator_value( i ) + 8;
+ default:
+ return NULL;
+ }
+}
+
+MONGO_EXPORT void bson_iterator_code_scope_init( const bson_iterator *i, bson *scope, bson_bool_t copyData ) {
+ if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) {
+ int codeLen = bson_finished_data_size( bson_iterator_value( i )+4 );
+ const char * scopeData = bson_iterator_value( i )+8+codeLen;
+ if( copyData )
+ bson_init_finished_data_with_copy( scope, scopeData );
+ else
+ bson_init_finished_data( scope, (char *)scopeData, 0 );
+ }
+ else {
+ bson_init_empty( scope );
+ }
+}
+
+MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i ) {
+ return bson_iterator_long_raw( i );
+}
+
+MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i ) {
+ return bson_iterator_date( i ) / 1000;
+}
+
+MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i ) {
+ return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
+ ? bson_iterator_int_raw( i ) - 4
+ : bson_iterator_int_raw( i );
+}
+
+MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i ) {
+ return bson_iterator_value( i )[4];
+}
+
+MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i ) {
+ return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
+ ? bson_iterator_value( i ) + 9
+ : bson_iterator_value( i ) + 5;
+}
+
+MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i ) {
+ return bson_iterator_value( i );
+}
+
+MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i ) {
+ const char *p = bson_iterator_value( i );
+ return p + strlen( p ) + 1;
+
+}
+
+MONGO_EXPORT void bson_iterator_subobject_init( const bson_iterator *i, bson *sub, bson_bool_t copyData ) {
+ const char *data = bson_iterator_value( i );
+ if( copyData )
+ bson_init_finished_data_with_copy( sub, data );
+ else
+ bson_init_finished_data( sub, (char *)data, 0 );
+}
+
+MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) {
+ bson_iterator_from_buffer( sub, bson_iterator_value( i ) );
+}
+
+/* ----------------------------
+ BUILDING
+ ------------------------------ */
+
+static void _bson_zero( bson *b ) {
+ memset( b, 0, sizeof( bson ) );
+}
+
+MONGO_EXPORT int bson_init( bson *b ) {
+ return bson_init_size( b, initialBufferSize );
+}
+
+int bson_init_size( bson *b, int size ) {
+ _bson_zero( b );
+ if( size != 0 )
+ {
+ char * data = (char *) bson_malloc( size );
+ if (data == NULL) return BSON_ERROR;
+ b->data = data;
+ b->dataSize = size;
+ }
+ b->ownsData = 1;
+ b->cur = b->data + 4;
+ return BSON_OK;
+}
+
+int bson_init_unfinished_data( bson *b, char *data, int dataSize, bson_bool_t ownsData ) {
+ _bson_zero( b );
+ b->data = data;
+ b->dataSize = dataSize;
+ b->ownsData = ownsData;
+ return BSON_OK;
+}
+
+static int _bson_append_grow_stack( bson * b ) {
+ if ( !b->stackPtr ) {
+ // If this is an empty bson structure, initially use the struct-local (fixed-size) stack
+ b->stackPtr = b->stack;
+ b->stackSize = sizeof( b->stack ) / sizeof( size_t );
+ }
+ else if ( b->stackPtr == b->stack ) {
+ // Once we require additional capacity, set up a dynamically resized stack
+ size_t *new_stack = ( size_t * ) bson_malloc( 2 * sizeof( b->stack ) );
+ if ( new_stack ) {
+ b->stackPtr = new_stack;
+ b->stackSize = 2 * sizeof( b->stack ) / sizeof( size_t );
+ memcpy( b->stackPtr, b->stack, sizeof( b->stack ) );
+ }
+ else {
+ return BSON_ERROR;
+ }
+ }
+ else {
+ // Double the capacity of the dynamically-resized stack
+ size_t *new_stack = ( size_t * ) bson_realloc( b->stackPtr, ( b->stackSize * 2 ) * sizeof( size_t ) );
+ if ( new_stack ) {
+ b->stackPtr = new_stack;
+ b->stackSize *= 2;
+ }
+ else {
+ return BSON_ERROR;
+ }
+ }
+ return BSON_OK;
+}
+
+static void bson_append_byte( bson *b, char c ) {
+ b->cur[0] = c;
+ b->cur++;
+}
+
+static void bson_append( bson *b, const void *data, size_t len ) {
+ memcpy( b->cur , data , len );
+ b->cur += len;
+}
+
+static void bson_append32( bson *b, const void *data ) {
+ bson_little_endian32( b->cur, data );
+ b->cur += 4;
+}
+
+static void bson_append32_as_int( bson *b, int data ) {
+ bson_little_endian32( b->cur, &data );
+ b->cur += 4;
+}
+
+static void bson_append64( bson *b, const void *data ) {
+ bson_little_endian64( b->cur, data );
+ b->cur += 8;
+}
+
+int bson_ensure_space( bson *b, const size_t bytesNeeded ) {
+ size_t pos = _bson_position(b);
+ char *orig = b->data;
+ int new_size;
+
+ if ( pos + bytesNeeded <= (size_t) b->dataSize )
+ return BSON_OK;
+
+ new_size = (int) ( 1.5 * ( b->dataSize + bytesNeeded ) );
+
+ if( new_size < b->dataSize ) {
+ if( ( b->dataSize + bytesNeeded ) < INT_MAX )
+ new_size = INT_MAX;
+ else {
+ b->err = BSON_SIZE_OVERFLOW;
+ return BSON_ERROR;
+ }
+ }
+
+ if ( ! b->ownsData ) {
+ b->err = BSON_DOES_NOT_OWN_DATA;
+ return BSON_ERROR;
+ }
+
+ b->data = bson_realloc( b->data, new_size );
+ if ( !b->data )
+ bson_fatal_msg( !!b->data, "realloc() failed" );
+
+ b->dataSize = new_size;
+ b->cur += b->data - orig;
+
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_finish( bson *b ) {
+ int i;
+
+ if( b->err & BSON_NOT_UTF8 )
+ return BSON_ERROR;
+
+ if ( ! b->finished ) {
+ bson_fatal_msg(!b->stackPos, "Subobject not finished before bson_finish().");
+ if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
+ bson_append_byte( b, 0 );
+ if ( _bson_position(b) >= INT32_MAX ) {
+ b->err = BSON_SIZE_OVERFLOW;
+ return BSON_ERROR;
+ }
+ i = ( int ) _bson_position(b);
+ bson_little_endian32( b->data, &i );
+ b->finished = 1;
+ }
+
+ return BSON_OK;
+}
+
+MONGO_EXPORT void bson_destroy( bson *b ) {
+ if ( b ) {
+ if ( b->ownsData && b->data != NULL ) {
+ bson_free( b->data );
+ }
+ b->data = NULL;
+ b->dataSize = 0;
+ b->ownsData = 0;
+ if ( b->stackPtr && b->stackPtr != b->stack ) {
+ bson_free( b->stackPtr );
+ b->stackPtr = NULL;
+ }
+ b->stackSize = 0;
+ b->stackPos = 0;
+ b->err = 0;
+ b->cur = 0;
+ b->finished = 1;
+ }
+}
+
+static int bson_append_estart( bson *b, int type, const char *name, const size_t dataSize ) {
+ const size_t len = strlen( name ) + 1;
+
+ if ( b->finished ) {
+ b->err |= BSON_ALREADY_FINISHED;
+ return BSON_ERROR;
+ }
+
+ if ( bson_ensure_space( b, 1 + len + dataSize ) == BSON_ERROR ) {
+ return BSON_ERROR;
+ }
+
+ if( bson_check_field_name( b, ( const char * )name, len - 1 ) == BSON_ERROR ) {
+ bson_builder_error( b );
+ return BSON_ERROR;
+ }
+
+ bson_append_byte( b, ( char )type );
+ bson_append( b, name, len );
+ return BSON_OK;
+}
+
+/* ----------------------------
+ BUILDING TYPES
+ ------------------------------ */
+
+MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i ) {
+ if ( bson_append_estart( b, BSON_INT, name, 4 ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append32( b , &i );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i ) {
+ if ( bson_append_estart( b , BSON_LONG, name, 8 ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append64( b , &i );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d ) {
+ if ( bson_append_estart( b, BSON_DOUBLE, name, 8 ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append64( b , &d );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) {
+ if ( bson_append_estart( b, BSON_BOOL, name, 1 ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append_byte( b , i != 0 );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_null( bson *b, const char *name ) {
+ if ( bson_append_estart( b , BSON_NULL, name, 0 ) == BSON_ERROR )
+ return BSON_ERROR;
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ) {
+ if ( bson_append_estart( b, BSON_UNDEFINED, name, 0 ) == BSON_ERROR )
+ return BSON_ERROR;
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_maxkey( bson *b, const char *name ) {
+ if ( bson_append_estart( b, BSON_MAXKEY, name, 0 ) == BSON_ERROR )
+ return BSON_ERROR;
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_minkey( bson *b, const char *name ) {
+ if ( bson_append_estart( b, BSON_MINKEY, name, 0 ) == BSON_ERROR )
+ return BSON_ERROR;
+ return BSON_OK;
+}
+
+static int bson_append_string_base( bson *b, const char *name,
+ const char *value, size_t len, bson_type type ) {
+
+ size_t sl = len + 1;
+ if ( sl > INT32_MAX ) {
+ b->err = BSON_SIZE_OVERFLOW;
+ /* string too long */
+ return BSON_ERROR;
+ }
+ if ( bson_check_string( b, ( const char * )value, sl - 1 ) == BSON_ERROR )
+ return BSON_ERROR;
+ if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
+ return BSON_ERROR;
+ }
+ bson_append32_as_int( b , ( int )sl );
+ bson_append( b , value , sl - 1 );
+ bson_append( b , "\0" , 1 );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *value ) {
+ return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING );
+}
+
+MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *value ) {
+ return bson_append_string_base( b, name, value, strlen ( value ), BSON_SYMBOL );
+}
+
+MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *value ) {
+ return bson_append_string_base( b, name, value, strlen ( value ), BSON_CODE );
+}
+
+MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, size_t len ) {
+ return bson_append_string_base( b, name, value, len, BSON_STRING );
+}
+
+MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, size_t len ) {
+ return bson_append_string_base( b, name, value, len, BSON_SYMBOL );
+}
+
+MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, size_t len ) {
+ return bson_append_string_base( b, name, value, len, BSON_CODE );
+}
+
+MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name,
+ const char *code, size_t len, const bson *scope ) {
+
+ size_t sl, size;
+ if ( !scope ) return BSON_ERROR;
+ sl = len + 1;
+ size = 4 + 4 + sl + bson_size( scope );
+ if ( size > (size_t)INT32_MAX ) {
+ b->err = BSON_SIZE_OVERFLOW;
+ return BSON_ERROR;
+ }
+ if ( bson_append_estart( b, BSON_CODEWSCOPE, name, size ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append32_as_int( b, ( int )size );
+ bson_append32( b, &sl );
+ bson_append( b, code, sl );
+ bson_append( b, scope->data, bson_size( scope ) );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) {
+ return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
+}
+
+MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len ) {
+ if ( type == BSON_BIN_BINARY_OLD ) {
+ size_t subtwolen = len + 4;
+ if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+4+len ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append32_as_int( b, ( int )subtwolen );
+ bson_append_byte( b, type );
+ bson_append32_as_int( b, ( int )len );
+ bson_append( b, str, len );
+ }
+ else {
+ if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+len ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append32_as_int( b, ( int )len );
+ bson_append_byte( b, type );
+ bson_append( b, str, len );
+ }
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) {
+ if ( bson_append_estart( b, BSON_OID, name, 12 ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append( b , oid , 12 );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name ) {
+ bson_oid_t oid;
+ bson_oid_gen( &oid );
+ return bson_append_oid( b, name, &oid );
+}
+
+MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) {
+ const size_t plen = strlen( pattern )+1;
+ const size_t olen = strlen( opts )+1;
+ if ( bson_append_estart( b, BSON_REGEX, name, plen + olen ) == BSON_ERROR )
+ return BSON_ERROR;
+ if ( bson_check_string( b, pattern, plen - 1 ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append( b , pattern , plen );
+ bson_append( b , opts , olen );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson ) {
+ if ( !bson ) return BSON_ERROR;
+ if ( bson_append_estart( b, BSON_OBJECT, name, bson_size( bson ) ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append( b , bson->data , bson_size( bson ) );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
+ bson_iterator next = *elem;
+ size_t size;
+
+ bson_iterator_next( &next );
+ size = next.cur - elem->cur;
+
+ if ( name_or_null == NULL ) {
+ if( bson_ensure_space( b, size ) == BSON_ERROR )
+ return BSON_ERROR;
+ bson_append( b, elem->cur, size );
+ }
+ else {
+ size_t data_size = size - 2 - strlen( bson_iterator_key( elem ) );
+ bson_append_estart( b, elem->cur[0], name_or_null, data_size );
+ bson_append( b, bson_iterator_value( elem ), data_size );
+ }
+
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) {
+ if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
+
+ bson_append32( b , &( ts->i ) );
+ bson_append32( b , &( ts->t ) );
+
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment ) {
+ if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
+
+ bson_append32( b , &increment );
+ bson_append32( b , &time );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis ) {
+ if ( bson_append_estart( b, BSON_DATE, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
+ bson_append64( b , &millis );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs ) {
+ return bson_append_date( b, name, ( bson_date_t )secs * 1000 );
+}
+
+MONGO_EXPORT int bson_append_start_object( bson *b, const char *name ) {
+ if ( bson_append_estart( b, BSON_OBJECT, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
+ if ( b->stackPos >= b->stackSize && _bson_append_grow_stack( b ) == BSON_ERROR ) return BSON_ERROR;
+ b->stackPtr[ b->stackPos++ ] = _bson_position(b);
+ bson_append32( b , &zero );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_start_array( bson *b, const char *name ) {
+ if ( bson_append_estart( b, BSON_ARRAY, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
+ if ( b->stackPos >= b->stackSize && _bson_append_grow_stack( b ) == BSON_ERROR ) return BSON_ERROR;
+ b->stackPtr[ b->stackPos++ ] = _bson_position(b);
+ bson_append32( b , &zero );
+ return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_finish_object( bson *b ) {
+ char *start;
+ int i;
+ if (!b) return BSON_ERROR;
+ if (!b->stackPos) { b->err = BSON_NOT_IN_SUBOBJECT; return BSON_ERROR; }
+ if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
+ bson_append_byte( b , 0 );
+
+ start = b->data + b->stackPtr[ --b->stackPos ];
+ if ( b->cur - start >= INT32_MAX ) {
+ b->err = BSON_SIZE_OVERFLOW;
+ return BSON_ERROR;
+ }
+ i = ( int )( b->cur - start );
+ bson_little_endian32( start, &i );
+
+ return BSON_OK;
+}
+
+MONGO_EXPORT double bson_int64_to_double( int64_t i64 ) {
+ return (double)i64;
+}
+
+MONGO_EXPORT int bson_append_finish_array( bson *b ) {
+ return bson_append_finish_object( b );
+}
+
+/* Error handling and allocators. */
+
+static bson_err_handler err_handler = NULL;
+
+MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ) {
+ bson_err_handler old = err_handler;
+ err_handler = func;
+ return old;
+}
+
+MONGO_EXPORT void bson_free( void *ptr ) {
+ bson_free_func( ptr );
+}
+
+MONGO_EXPORT void *bson_malloc( size_t size ) {
+ void *p;
+ p = bson_malloc_func( size );
+ bson_fatal_msg( !!p, "malloc() failed" );
+ return p;
+}
+
+void *bson_realloc( void *ptr, size_t size ) {
+ void *p;
+ p = bson_realloc_func( ptr, size );
+ bson_fatal_msg( !!p, "realloc() failed" );
+ return p;
+}
+
+int _bson_errprintf( const char *format, ... ) {
+ va_list ap;
+ int ret = 0;
+ va_start( ap, format );
+#ifndef R_SAFETY_NET
+ ret = vfprintf( stderr, format, ap );
+#endif
+ va_end( ap );
+
+ return ret;
+}
+
+/**
+ * This method is invoked when a non-fatal bson error is encountered.
+ * Calls the error handler if available.
+ *
+ * @param
+ */
+void bson_builder_error( bson *b ) {
+ if( err_handler )
+ err_handler( "BSON error." );
+}
+
+void bson_fatal( int ok ) {
+ bson_fatal_msg( ok, "" );
+}
+
+void bson_fatal_msg( int ok , const char *msg ) {
+ if ( ok )
+ return;
+
+ if ( err_handler ) {
+ err_handler( msg );
+ }
+#ifndef R_SAFETY_NET
+ bson_errprintf( "error: %s\n" , msg );
+ exit( -5 );
+#endif
+}
+
+
+/* Efficiently copy an integer to a string. */
+extern const char bson_numstrs[1000][4];
+
+void bson_numstr( char *str, int i ) {
+ if( i < 1000 )
+ memcpy( str, bson_numstrs[i], 4 );
+ else
+ bson_sprintf( str,"%d", i );
+}
+
+MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp ) {
+ const char *in = ( const char * )inp;
+ char *out = ( char * )outp;
+
+ out[0] = in[7];
+ out[1] = in[6];
+ out[2] = in[5];
+ out[3] = in[4];
+ out[4] = in[3];
+ out[5] = in[2];
+ out[6] = in[1];
+ out[7] = in[0];
+
+}
+
+MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp ) {
+ const char *in = ( const char * )inp;
+ char *out = ( char * )outp;
+
+ out[0] = in[3];
+ out[1] = in[2];
+ out[2] = in[1];
+ out[3] = in[0];
+}
diff --git a/bson/bson.h b/bson/bson.h
new file mode 100644
index 0000000..739b406
--- /dev/null
+++ b/bson/bson.h
@@ -0,0 +1,1180 @@
+/**
+ * @file bson.h
+ * @brief BSON Declarations
+ */
+
+/* Copyright 2009-2012 10gen Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BSON_H_
+#define BSON_H_
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef __GNUC__
+#define MONGO_INLINE static __inline__
+#define MONGO_EXPORT
+#else
+#define MONGO_INLINE static
+#ifdef MONGO_STATIC_BUILD
+#define MONGO_EXPORT
+#elif defined(MONGO_DLL_BUILD)
+#define MONGO_EXPORT __declspec(dllexport)
+#else
+#define MONGO_EXPORT __declspec(dllimport)
+#endif
+#endif
+
+#ifdef __cplusplus
+#define MONGO_EXTERN_C_START extern "C" {
+#define MONGO_EXTERN_C_END }
+#else
+#define MONGO_EXTERN_C_START
+#define MONGO_EXTERN_C_END
+#endif
+
+#if defined(MONGO_HAVE_STDINT) || __STDC_VERSION__ >= 199901L
+#include
+#elif defined(MONGO_HAVE_UNISTD)
+#include
+#elif defined(MONGO_USE__INT64)
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#define INT32_MAX 0x7fffffffL
+#elif defined(MONGO_USE_LONG_LONG_INT)
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#else
+#error Must compile with c99 or define MONGO_HAVE_STDINT, MONGO_HAVE_UNISTD, MONGO_USE__INT64, or MONGO_USE_LONG_LONG_INT.
+#endif
+
+#ifdef MONGO_BIG_ENDIAN
+#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) )
+#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) )
+#define bson_big_endian64(out, in) ( memcpy(out, in, 8) )
+#define bson_big_endian32(out, in) ( memcpy(out, in, 4) )
+#else
+#define bson_little_endian64(out, in) ( memcpy(out, in, 8) )
+#define bson_little_endian32(out, in) ( memcpy(out, in, 4) )
+#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) )
+#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) )
+#endif
+
+MONGO_EXTERN_C_START
+
+#define BSON_OK 0
+#define BSON_ERROR -1
+
+enum bson_error_t {
+ BSON_SIZE_OVERFLOW = (1 << 0), /**< Trying to create a BSON object larger than INT_MAX. */
+ BSON_ALREADY_FINISHED = (1 << 4), /**< Trying to modify a finished BSON object. */
+ BSON_NOT_IN_SUBOBJECT = (1 << 5), /**< Trying bson_append_finish_object() and not in sub */
+ BSON_DOES_NOT_OWN_DATA = (1 << 6) /**< Trying to expand a BSON object which does not own its data block. */
+};
+
+enum bson_validity_t {
+ BSON_VALID = 0, /**< BSON is valid and UTF-8 compliant. */
+ BSON_NOT_UTF8 = (1 << 1), /**< A key or a string is not valid UTF-8. */
+ BSON_FIELD_HAS_DOT = (1 << 2), /**< Warning: key contains '.' character. */
+ BSON_FIELD_INIT_DOLLAR = (1 << 3) /**< Warning: key starts with '$' character. */
+};
+
+enum bson_binary_subtype_t {
+ BSON_BIN_BINARY = 0,
+ BSON_BIN_FUNC = 1,
+ BSON_BIN_BINARY_OLD = 2,
+ BSON_BIN_UUID = 3,
+ BSON_BIN_MD5 = 5,
+ BSON_BIN_USER = 128
+};
+
+typedef enum {
+ BSON_EOO = 0,
+ BSON_DOUBLE = 1,
+ BSON_STRING = 2,
+ BSON_OBJECT = 3,
+ BSON_ARRAY = 4,
+ BSON_BINDATA = 5,
+ BSON_UNDEFINED = 6,
+ BSON_OID = 7,
+ BSON_BOOL = 8,
+ BSON_DATE = 9,
+ BSON_NULL = 10,
+ BSON_REGEX = 11,
+ BSON_DBREF = 12, /**< Deprecated. */
+ BSON_CODE = 13,
+ BSON_SYMBOL = 14,
+ BSON_CODEWSCOPE = 15,
+ BSON_INT = 16,
+ BSON_TIMESTAMP = 17,
+ BSON_LONG = 18,
+ BSON_MAXKEY = 127,
+ BSON_MINKEY = 255
+} bson_type;
+
+typedef int bson_bool_t;
+
+typedef struct {
+ const char *cur;
+ bson_bool_t first;
+} bson_iterator;
+
+typedef struct {
+ char *data; /**< Pointer to a block of data in this BSON object. */
+ char *cur; /**< Pointer to the current position. */
+ int dataSize; /**< The number of bytes allocated to char *data. */
+ bson_bool_t finished; /**< When finished, the BSON object can no longer be modified. */
+ bson_bool_t ownsData; /**< Whether destroying this object will deallocate its data block */
+ int err; /**< Bitfield representing errors or warnings on this buffer */
+ int stackSize; /**< Number of elements in the current stack */
+ int stackPos; /**< Index of current stack position. */
+ size_t* stackPtr; /**< Pointer to the current stack */
+ size_t stack[32]; /**< A stack used to keep track of nested BSON elements.
+ Must be at end of bson struct so _bson_zero does not clear. */
+} bson;
+
+#pragma pack(1)
+typedef union {
+ char bytes[12];
+ int ints[3];
+} bson_oid_t;
+#pragma pack()
+
+typedef int64_t bson_date_t; /* milliseconds since epoch UTC */
+
+typedef struct {
+ int i; /* increment */
+ int t; /* time in seconds */
+} bson_timestamp_t;
+
+/* ----------------------------
+ READING
+ ------------------------------ */
+
+/**
+ * Zero a bson struct. All fields are set to zero except the stack.
+ *
+ * @note Mainly used internally, but can be called for safety
+ * purposes so that a later call to bson_destroy() doesn't flip out.
+ * It is safe to call this function on a NULL pointer in which case
+ * there is no effect.
+ * @param b the BSON object to zero.
+ *
+ */
+MONGO_EXPORT void bson_init_zero( bson *b );
+
+/**
+ * Allocate memory for a new BSON object.
+ *
+ * @note After using this function, you must initialize the object
+ * using bson_init_finished_data( ), bson_init_empty( ), bson_init( ),
+ * or one of the other init functions.
+ *
+ * @return a new BSON object.
+ */
+MONGO_EXPORT bson* bson_alloc( void );
+
+/**
+ * Deallocate a BSON object.
+ *
+ * @note You must call bson_destroy( ) before calling this function.
+ */
+MONGO_EXPORT void bson_dealloc( bson* b );
+
+/**
+ * Initialize a BSON object for reading and set its data
+ * pointer to the provided char*.
+ *
+ * @note When done using the bson object, you must pass
+ * the object to bson_destroy( ).
+ *
+ * @param b the BSON object to initialize.
+ * @param data the finalized raw BSON data.
+ * @param ownsData when true, bson_destroy() will free the data block.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_init_finished_data( bson *b, char *data, bson_bool_t ownsData );
+
+/**
+ * Initialize a BSON object for reading and copy finalized
+ * BSON data from the provided char*.
+ *
+ * @note When done using the bson object, you must pass
+ * the object to bson_destroy( ).
+ *
+ * @param b the BSON object to initialize.
+ * @param data the finalized raw BSON data to copy.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_init_finished_data_with_copy( bson *b, const char *data );
+
+/**
+ * Size of a BSON object.
+ *
+ * @param b the BSON object.
+ *
+ * @return the size.
+ */
+MONGO_EXPORT int bson_size( const bson *b );
+
+/**
+ * Minimum finished size of an unfinished BSON object given current contents.
+ *
+ * @param b the BSON object.
+ *
+ * @return the BSON object's minimum finished size
+ */
+MONGO_EXPORT size_t bson_buffer_size( const bson *b );
+
+/**
+ * Print a string representation of a BSON object.
+ *
+ * @param b the BSON object to print.
+ */
+MONGO_EXPORT void bson_print( const bson *b );
+
+/**
+ * Return a pointer to the raw buffer stored by this bson object.
+ *
+ * @param b a BSON object
+ */
+MONGO_EXPORT const char *bson_data( const bson *b );
+
+/**
+ * Returns true if bson_data(b) {b->data} is not null; else, false.
+ *
+ * @note Convenience function for determining if bson data was returned by a function.
+ * Check required after calls to mongo_create_index(), mongo_create_simple_index(),
+ * mongo_cmd_get_last_error() and mongo_cmd_get_prev_error().
+ * @param b the bson struct to inspect.
+ */
+
+MONGO_EXPORT int bson_has_data( const bson *b );
+
+/**
+ * Print a string representation of a BSON object.
+ *
+ * @param bson the raw data to print.
+ * @param depth the depth to recurse the object.x
+ */
+MONGO_EXPORT void bson_print_raw( const char *bson , int depth );
+
+/**
+ * Advance a bson_iterator to the named field.
+ *
+ * @param it the bson_iterator to use.
+ * @param obj the BSON object to use.
+ * @param name the name of the field to find.
+ *
+ * @return the type of the found object or BSON_EOO if it is not found.
+ */
+MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name );
+
+
+MONGO_EXPORT bson_iterator* bson_iterator_alloc( void );
+MONGO_EXPORT void bson_iterator_dealloc(bson_iterator*);
+/**
+ * Initialize a bson_iterator.
+ *
+ * @param i the bson_iterator to initialize.
+ * @param bson the BSON object to associate with the iterator.
+ */
+MONGO_EXPORT void bson_iterator_init( bson_iterator *i , const bson *b );
+
+/**
+ * Initialize a bson iterator from a const char* buffer. Note
+ * that this is mostly used internally.
+ *
+ * @param i the bson_iterator to initialize.
+ * @param buffer the buffer to point to.
+ */
+MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer );
+
+/* more returns true for eoo. best to loop with bson_iterator_next(&it) */
+/**
+ * Check to see if the bson_iterator has more data.
+ *
+ * @param i the iterator.
+ *
+ * @return returns true if there is more data.
+ */
+MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i );
+
+/**
+ * Point the iterator at the next BSON object.
+ *
+ * @param i the bson_iterator.
+ *
+ * @return the type of the next BSON object.
+ */
+MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i );
+
+/**
+ * Get the type of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the type of the current BSON object.
+ */
+MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i );
+
+/**
+ * Get the key of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the key of the current BSON object.
+ */
+MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i );
+
+/**
+ * Get the value of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i );
+
+/* these convert to the right type (return 0 if non-numeric) */
+/**
+ * Get the double value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+MONGO_EXPORT double bson_iterator_double( const bson_iterator *i );
+
+/**
+ * Get the int value of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+MONGO_EXPORT int bson_iterator_int( const bson_iterator *i );
+
+/**
+ * Get the long value of the BSON object currently pointed to by the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i );
+
+/* return the bson timestamp as a whole or in parts */
+/**
+ * Get the timestamp value of the BSON object currently pointed to by
+ * the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i );
+MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i );
+MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i );
+
+/**
+ * Get the boolean value of the BSON object currently pointed to by
+ * the iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+/* false: boolean false, 0 in any type, or null */
+/* true: anything else (even empty strings and objects) */
+MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i );
+
+/**
+ * Get the double value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+/* these assume you are using the right type */
+double bson_iterator_double_raw( const bson_iterator *i );
+
+/**
+ * Get the int value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+int bson_iterator_int_raw( const bson_iterator *i );
+
+/**
+ * Get the long value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+int64_t bson_iterator_long_raw( const bson_iterator *i );
+
+/**
+ * Get the bson_bool_t value of the BSON object currently pointed to by the
+ * iterator. Assumes the correct type is used.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+bson_bool_t bson_iterator_bool_raw( const bson_iterator *i );
+
+/**
+ * Get the bson_oid_t value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i );
+
+/**
+ * Get the string value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON object.
+ */
+/* these can also be used with bson_code and bson_symbol*/
+MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i );
+
+/**
+ * Get the string length of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the length of the current BSON object.
+ */
+int bson_iterator_string_len( const bson_iterator *i );
+
+/**
+ * Get the code value of the BSON object currently pointed to by the
+ * iterator. Works with bson_code, bson_codewscope, and BSON_STRING
+ * returns NULL for everything else.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the code value of the current BSON object.
+ */
+/* works with bson_code, bson_codewscope, and BSON_STRING */
+/* returns NULL for everything else */
+MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i );
+
+/**
+ * Get the code scope value of the BSON object currently pointed to
+ * by the iterator. Calls bson_init_empty on scope if current object is
+ * not BSON_CODEWSCOPE.
+ *
+ * @note When copyData is false, the scope becomes invalid when the
+ * iterator's data buffer is deallocated. For either value of
+ * copyData, you must pass the scope object to bson_destroy
+ * when you are done using it.
+ *
+ * @param i the bson_iterator.
+ * @param scope an uninitialized BSON object to receive the scope.
+ * @param copyData when true, makes a copy of the scope data which will remain
+ * valid when the iterator's data buffer is deallocated.
+ */
+MONGO_EXPORT void bson_iterator_code_scope_init( const bson_iterator *i, bson *scope, bson_bool_t copyData );
+
+/**
+ * Get the date value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the date value of the current BSON object.
+ */
+/* both of these only work with bson_date */
+MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i );
+
+/**
+ * Get the time value of the BSON object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the time value of the current BSON object.
+ */
+MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i );
+
+/**
+ * Get the length of the BSON binary object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the length of the current BSON binary object.
+ */
+MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i );
+
+/**
+ * Get the type of the BSON binary object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the type of the current BSON binary object.
+ */
+MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i );
+
+/**
+ * Get the value of the BSON binary object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON binary object.
+ */
+MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i );
+
+/**
+ * Get the value of the BSON regex object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator
+ *
+ * @return the value of the current BSON regex object.
+ */
+MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i );
+
+/**
+ * Get the options of the BSON regex object currently pointed to by the
+ * iterator.
+ *
+ * @param i the bson_iterator.
+ *
+ * @return the options of the current BSON regex object.
+ */
+MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i );
+
+/* these work with BSON_OBJECT and BSON_ARRAY */
+/**
+ * Get the BSON subobject currently pointed to by the
+ * iterator.
+ *
+ * @note When copyData is 0, the subobject becomes invalid when its parent's
+ * data buffer is deallocated. For either value of copyData, you must
+ * pass the subobject to bson_destroy when you are done using it.
+ *
+ * @param i the bson_iterator.
+ * @param sub an unitialized BSON object which will become the new subobject.
+ */
+MONGO_EXPORT void bson_iterator_subobject_init( const bson_iterator *i, bson *sub, bson_bool_t copyData );
+
+/**
+ * Get a bson_iterator that on the BSON subobject.
+ *
+ * @param i the bson_iterator.
+ * @param sub the iterator to point at the BSON subobject.
+ */
+MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub );
+
+/* str must be at least 24 hex chars + null byte */
+/**
+ * Create a bson_oid_t from a string.
+ *
+ * @param oid the bson_oid_t destination.
+ * @param str a null terminated string comprised of at least 24 hex chars.
+ */
+MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str );
+
+/**
+ * Create a string representation of the bson_oid_t.
+ *
+ * @param oid the bson_oid_t source.
+ * @param str the string representation destination.
+ */
+MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str );
+
+/**
+ * Create a bson_oid object.
+ *
+ * @param oid the destination for the newly created bson_oid_t.
+ */
+MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid );
+
+/**
+ * Set a function to be used to generate the second four bytes
+ * of an object id.
+ *
+ * @param func a pointer to a function that returns an int.
+ */
+MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) );
+
+/**
+ * Set a function to be used to generate the incrementing part
+ * of an object id (last four bytes). If you need thread-safety
+ * in generating object ids, you should set this function.
+ *
+ * @param func a pointer to a function that returns an int.
+ */
+MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) );
+
+/**
+ * Get the time a bson_oid_t was created.
+ *
+ * @param oid the bson_oid_t.
+ */
+MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was created */
+
+/* ----------------------------
+ BUILDING
+ ------------------------------ */
+
+/**
+ * Initialize a BSON object for building and allocate a data buffer.
+ *
+ * @note You must initialize each new bson object using this,
+ * bson_init_finished_data( ), or one of the other init functions.
+ * When done using the BSON object, you must pass it to bson_destroy( ).
+ *
+ * @param b the BSON object to initialize.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_init( bson *b );
+
+/**
+ * Initialize a BSON object for building and allocate a data buffer
+ * of a given size.
+ *
+ * @note When done using the bson object, you must pass it
+ * to bson_destroy( ).
+ *
+ * @param b the BSON object to initialize.
+ * @param size the initial size of the buffer.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+int bson_init_size( bson *b, int size );
+
+/**
+ * Initialize a BSON object for building, using the provided char*
+ * of the given size. When ownsData is true, the BSON object may
+ * reallocate the data block as needed, and bson_destroy will free
+ * it.
+ *
+ * See also bson_init_finished_data( )
+ *
+ * @note When done using the BSON object, you must pass
+ * it to bson_destroy( ).
+ *
+ * @param b the BSON object to initialize.
+ * @param data the raw BSON data.
+ * @param ownsData when true, bson_ensure_space() may reallocate the block and
+ * bson_destroy() will free it
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+int bson_init_unfinished_data( bson *b, char *data, int dataSize, bson_bool_t ownsData );
+
+/**
+ * Grow a bson object.
+ *
+ * @param b the bson to grow.
+ * @param bytesNeeded the additional number of bytes needed.
+ *
+ * @return BSON_OK or BSON_ERROR with the bson error object set.
+ * Exits if allocation fails.
+ */
+int bson_ensure_space( bson *b, const size_t bytesNeeded );
+
+/**
+ * Finalize a bson object.
+ *
+ * @param b the bson object to finalize.
+ *
+ * @return the standard error code. To deallocate memory,
+ * call bson_destroy on the bson object.
+ */
+MONGO_EXPORT int bson_finish( bson *b );
+
+/**
+ * Destroy a bson object and deallocate its data buffer.
+ *
+ * @param b the bson object to destroy.
+ *
+ */
+MONGO_EXPORT void bson_destroy( bson *b );
+
+/**
+ * Initialize a BSON object to an emoty object with a shared, static data
+ * buffer.
+ *
+ * @note You must NOT modify this object's data. It is safe though not
+ * required to call bson_destroy( ) on this object.
+ *
+ * @param obj the BSON object to initialize.
+ *
+ * @return BSON_OK
+ */
+MONGO_EXPORT bson_bool_t bson_init_empty( bson *obj );
+
+/**
+ * Return a pointer to an empty, shared, static BSON object.
+ *
+ * @note This object is owned by the driver. You must NOT modify it
+ * and must NOT call bson_destroy( ) on it.
+ *
+ * @return the shared initialized BSON object.
+ */
+MONGO_EXPORT const bson *bson_shared_empty( void );
+
+/**
+ * Make a complete copy of the a BSON object.
+ * The source bson object must be in a finished
+ * state; otherwise, the copy will fail.
+ *
+ * @param out the copy destination BSON object.
+ * @param in the copy source BSON object.
+ */
+MONGO_EXPORT int bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if out==NULL */
+
+/**
+ * Append a previously created bson_oid_t to a bson object.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the bson_oid_t.
+ * @param oid the bson_oid_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid );
+
+/**
+ * Append a bson_oid_t to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the bson_oid_t.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name );
+
+/**
+ * Append an int to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the int.
+ * @param i the int to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i );
+
+/**
+ * Append an long to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the long.
+ * @param i the long to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i );
+
+/**
+ * Append an double to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the double.
+ * @param d the double to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d );
+
+/**
+ * Append a string to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the string.
+ * @param str the string to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+*/
+MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *str );
+
+/**
+ * Append len bytes of a string to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the string.
+ * @param str the string to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, size_t len );
+
+/**
+ * Append a symbol to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the symbol.
+ * @param str the symbol to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *str );
+
+/**
+ * Append len bytes of a symbol to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the symbol.
+ * @param str the symbol to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, size_t len );
+
+/**
+ * Append code to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the code to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *str );
+
+/**
+ * Append len bytes of code to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the code to append.
+ * @param len the number of bytes from str to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, size_t len );
+
+/**
+ * Append code to a bson with scope.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the string to append.
+ * @param scope a BSON object containing the scope.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope );
+
+/**
+ * Append len bytes of code to a bson with scope.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the code.
+ * @param str the string to append.
+ * @param len the number of bytes from str to append.
+ * @param scope a BSON object containing the scope.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, size_t size, const bson *scope );
+
+/**
+ * Append binary data to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the data.
+ * @param type the binary data type.
+ * @param str the binary data.
+ * @param len the length of the data.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, size_t len );
+
+/**
+ * Append a bson_bool_t to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the boolean value.
+ * @param v the bson_bool_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t v );
+
+/**
+ * Append a null value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the null value.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_null( bson *b, const char *name );
+
+/**
+ * Append an undefined value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the undefined value.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_undefined( bson *b, const char *name );
+
+/**
+ * Append a maxkey value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the maxkey value.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_maxkey( bson *b, const char *name );
+
+/**
+ * Append a minkey value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the minkey value.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_minkey( bson *b, const char *name );
+
+/**
+ * Append a regex value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the regex value.
+ * @param pattern the regex pattern to append.
+ * @param the regex options.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts );
+
+/**
+ * Append bson data to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the bson data.
+ * @param bson the bson object to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson );
+
+/**
+ * Append a BSON element to a bson from the current point of an iterator.
+ *
+ * @param b the bson to append to.
+ * @param name_or_null the key for the BSON element, or NULL.
+ * @param elem the bson_iterator.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem );
+
+/**
+ * Append a bson_timestamp_t value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the timestampe value.
+ * @param ts the bson_timestamp_t value to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts );
+MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment );
+
+/* these both append a bson_date */
+/**
+ * Append a bson_date_t value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the date value.
+ * @param millis the bson_date_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis );
+
+/**
+ * Append a time_t value to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the key for the date value.
+ * @param secs the time_t to append.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs );
+
+/**
+ * Start appending a new object to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the name of the new object.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_start_object( bson *b, const char *name );
+
+/**
+ * Start appending a new array to a bson.
+ *
+ * @param b the bson to append to.
+ * @param name the name of the new array.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_start_array( bson *b, const char *name );
+
+/**
+ * Finish appending a new object or array to a bson.
+ *
+ * @param b the bson to append to.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_finish_object( bson *b );
+
+/**
+ * Finish appending a new object or array to a bson. This
+ * is simply an alias for bson_append_finish_object.
+ *
+ * @param b the bson to append to.
+ *
+ * @return BSON_OK or BSON_ERROR.
+ */
+MONGO_EXPORT int bson_append_finish_array( bson *b );
+
+void bson_numstr( char *str, int i );
+
+void bson_incnumstr( char *str );
+
+/* Error handling and standard library function over-riding. */
+/* -------------------------------------------------------- */
+
+/* bson_err_handlers shouldn't return!!! */
+typedef void( *bson_err_handler )( const char *errmsg );
+
+typedef int (*bson_printf_func)( const char *, ... );
+typedef int (*bson_fprintf_func)( FILE *, const char *, ... );
+typedef int (*bson_sprintf_func)( char *, const char *, ... );
+
+extern void *( *bson_malloc_func )( size_t );
+extern void *( *bson_realloc_func )( void *, size_t );
+extern void ( *bson_free_func )( void * );
+
+extern bson_printf_func bson_printf;
+extern bson_fprintf_func bson_fprintf;
+extern bson_sprintf_func bson_sprintf;
+extern bson_printf_func bson_errprintf;
+
+MONGO_EXPORT void bson_free( void *ptr );
+
+/**
+ * Allocates memory and checks return value, exiting fatally if malloc() fails.
+ *
+ * @param size bytes to allocate.
+ *
+ * @return a pointer to the allocated memory.
+ *
+ * @sa malloc(3)
+ */
+MONGO_EXPORT void *bson_malloc( size_t size );
+
+/**
+ * Changes the size of allocated memory and checks return value,
+ * exiting fatally if realloc() fails.
+ *
+ * @param ptr pointer to the space to reallocate.
+ * @param size bytes to allocate.
+ *
+ * @return a pointer to the allocated memory.
+ *
+ * @sa realloc()
+ */
+void *bson_realloc( void *ptr, size_t size );
+
+/**
+ * Set a function for error handling.
+ *
+ * @param func a bson_err_handler function.
+ *
+ * @return the old error handling function, or NULL.
+ */
+MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func );
+
+/* does nothing if ok != 0 */
+/**
+ * Exit fatally.
+ *
+ * @param ok exits if ok is equal to 0.
+ */
+void bson_fatal( int ok );
+
+/**
+ * Exit fatally with an error message.
+ *
+ * @param ok exits if ok is equal to 0.
+ * @param msg prints to stderr before exiting.
+ */
+void bson_fatal_msg( int ok, const char *msg );
+
+/**
+ * Invoke the error handler, but do not exit.
+ *
+ * @param b the buffer object.
+ */
+void bson_builder_error( bson *b );
+
+/**
+ * Cast an int64_t to double. This is necessary for embedding in
+ * certain environments.
+ *
+ */
+MONGO_EXPORT double bson_int64_to_double( int64_t i64 );
+
+MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp );
+MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp );
+
+MONGO_EXTERN_C_END
+#endif
diff --git a/bson/encoding.c b/bson/encoding.c
new file mode 100644
index 0000000..9a9017b
--- /dev/null
+++ b/bson/encoding.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2009-2012 10gen, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Portions Copyright 2001 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+
+#include "bson.h"
+#include "encoding.h"
+
+/*
+ * Index into the table below with the first byte of a UTF-8 sequence to
+ * get the number of trailing bytes that are supposed to follow it.
+ */
+static const char trailingBytesForUTF8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Utility routine to tell whether a sequence of bytes is legal UTF-8.
+ * This must be called with the length pre-determined by the first byte.
+ * The length can be set by:
+ * length = trailingBytesForUTF8[*source]+1;
+ * and the sequence is illegal right away if there aren't that many bytes
+ * available.
+ * If presented with a length > 4, this returns 0. The Unicode
+ * definition of UTF-8 goes up to 4-byte sequences.
+ */
+static int isLegalUTF8( const unsigned char *source, int length ) {
+ unsigned char a;
+ const unsigned char *srcptr = source + length;
+ switch ( length ) {
+ default:
+ return 0;
+ /* Everything else falls through when "true"... */
+ case 4:
+ if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0;
+ case 3:
+ if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0;
+ case 2:
+ if ( ( a = ( *--srcptr ) ) > 0xBF ) return 0;
+ switch ( *source ) {
+ /* no fall-through in this inner switch */
+ case 0xE0:
+ if ( a < 0xA0 ) return 0;
+ break;
+ case 0xF0:
+ if ( a < 0x90 ) return 0;
+ break;
+ case 0xF4:
+ if ( a > 0x8F ) return 0;
+ break;
+ default:
+ if ( a < 0x80 ) return 0;
+ }
+ case 1:
+ if ( *source >= 0x80 && *source < 0xC2 ) return 0;
+ if ( *source > 0xF4 ) return 0;
+ }
+ return 1;
+}
+
+/* If the name is part of a db ref ($ref, $db, or $id), then return true. */
+static int bson_string_is_db_ref( const unsigned char *string, const size_t length ) {
+ int result = 0;
+
+ if( length >= 4 ) {
+ if( string[1] == 'r' && string[2] == 'e' && string[3] == 'f' )
+ result = 1;
+ }
+ else if( length >= 3 ) {
+ if( string[1] == 'i' && string[2] == 'd' )
+ result = 1;
+ else if( string[1] == 'd' && string[2] == 'b' )
+ result = 1;
+ }
+
+ return result;
+}
+
+static int bson_validate_string( bson *b, const unsigned char *string,
+ const size_t length, const char check_utf8, const char check_dot,
+ const char check_dollar ) {
+
+ size_t position = 0;
+ int sequence_length = 1;
+
+ if( check_dollar && string[0] == '$' ) {
+ if( !bson_string_is_db_ref( string, length ) )
+ b->err |= BSON_FIELD_INIT_DOLLAR;
+ }
+
+ while ( position < length ) {
+ if ( check_dot && *( string + position ) == '.' ) {
+ b->err |= BSON_FIELD_HAS_DOT;
+ }
+
+ if ( check_utf8 ) {
+ sequence_length = trailingBytesForUTF8[*( string + position )] + 1;
+ if ( ( position + sequence_length ) > length ) {
+ b->err |= BSON_NOT_UTF8;
+ return BSON_ERROR;
+ }
+ if ( !isLegalUTF8( string + position, sequence_length ) ) {
+ b->err |= BSON_NOT_UTF8;
+ return BSON_ERROR;
+ }
+ }
+ position += sequence_length;
+ }
+
+ return BSON_OK;
+}
+
+
+int bson_check_string( bson *b, const char *string,
+ const size_t length ) {
+
+ return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 );
+}
+
+int bson_check_field_name( bson *b, const char *string,
+ const size_t length ) {
+
+ return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 );
+}
diff --git a/bson/encoding.h b/bson/encoding.h
new file mode 100644
index 0000000..ec34c2e
--- /dev/null
+++ b/bson/encoding.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009-2012 10gen, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BSON_ENCODING_H_
+#define BSON_ENCODING_H_
+
+MONGO_EXTERN_C_START
+
+/**
+ * Check that a field name is valid UTF8, does not start with a '$',
+ * and contains no '.' characters. Set bson bit field appropriately.
+ * Note that we don't need to check for '\0' because we're using
+ * strlen(3), which stops at '\0'.
+ *
+ * @param b The bson object to which field name will be appended.
+ * @param string The field name as char*.
+ * @param length The length of the field name.
+ *
+ * @return BSON_OK if valid UTF8 and BSON_ERROR if not. All BSON strings must be
+ * valid UTF8. This function will also check whether the string
+ * contains '.' or starts with '$', since the validity of this depends on context.
+ * Set the value of b->err appropriately.
+ */
+int bson_check_field_name( bson *b, const char *string,
+ const size_t length );
+
+/**
+ * Check that a string is valid UTF8. Sets the buffer bit field appropriately.
+ *
+ * @param b The bson object to which string will be appended.
+ * @param string The string to check.
+ * @param length The length of the string.
+ *
+ * @return BSON_OK if valid UTF-8; otherwise, BSON_ERROR.
+ * Sets b->err on error.
+ */
+bson_bool_t bson_check_string( bson *b, const char *string,
+ const size_t length );
+
+MONGO_EXTERN_C_END
+#endif
diff --git a/bson/numbers.c b/bson/numbers.c
new file mode 100644
index 0000000..b3032d5
--- /dev/null
+++ b/bson/numbers.c
@@ -0,0 +1,127 @@
+/* Copyright 2009-2012 10gen Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* all the numbers that fit in a 4 byte string */
+const char bson_numstrs[1000][4] = {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
+ "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
+ "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
+ "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
+ "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
+ "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
+
+ "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
+ "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
+ "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
+ "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
+ "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
+ "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
+ "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
+ "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
+ "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
+ "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
+
+ "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
+ "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
+ "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
+ "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
+ "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
+ "250", "251", "252", "253", "254", "255", "256", "257", "258", "259",
+ "260", "261", "262", "263", "264", "265", "266", "267", "268", "269",
+ "270", "271", "272", "273", "274", "275", "276", "277", "278", "279",
+ "280", "281", "282", "283", "284", "285", "286", "287", "288", "289",
+ "290", "291", "292", "293", "294", "295", "296", "297", "298", "299",
+
+ "300", "301", "302", "303", "304", "305", "306", "307", "308", "309",
+ "310", "311", "312", "313", "314", "315", "316", "317", "318", "319",
+ "320", "321", "322", "323", "324", "325", "326", "327", "328", "329",
+ "330", "331", "332", "333", "334", "335", "336", "337", "338", "339",
+ "340", "341", "342", "343", "344", "345", "346", "347", "348", "349",
+ "350", "351", "352", "353", "354", "355", "356", "357", "358", "359",
+ "360", "361", "362", "363", "364", "365", "366", "367", "368", "369",
+ "370", "371", "372", "373", "374", "375", "376", "377", "378", "379",
+ "380", "381", "382", "383", "384", "385", "386", "387", "388", "389",
+ "390", "391", "392", "393", "394", "395", "396", "397", "398", "399",
+
+ "400", "401", "402", "403", "404", "405", "406", "407", "408", "409",
+ "410", "411", "412", "413", "414", "415", "416", "417", "418", "419",
+ "420", "421", "422", "423", "424", "425", "426", "427", "428", "429",
+ "430", "431", "432", "433", "434", "435", "436", "437", "438", "439",
+ "440", "441", "442", "443", "444", "445", "446", "447", "448", "449",
+ "450", "451", "452", "453", "454", "455", "456", "457", "458", "459",
+ "460", "461", "462", "463", "464", "465", "466", "467", "468", "469",
+ "470", "471", "472", "473", "474", "475", "476", "477", "478", "479",
+ "480", "481", "482", "483", "484", "485", "486", "487", "488", "489",
+ "490", "491", "492", "493", "494", "495", "496", "497", "498", "499",
+
+ "500", "501", "502", "503", "504", "505", "506", "507", "508", "509",
+ "510", "511", "512", "513", "514", "515", "516", "517", "518", "519",
+ "520", "521", "522", "523", "524", "525", "526", "527", "528", "529",
+ "530", "531", "532", "533", "534", "535", "536", "537", "538", "539",
+ "540", "541", "542", "543", "544", "545", "546", "547", "548", "549",
+ "550", "551", "552", "553", "554", "555", "556", "557", "558", "559",
+ "560", "561", "562", "563", "564", "565", "566", "567", "568", "569",
+ "570", "571", "572", "573", "574", "575", "576", "577", "578", "579",
+ "580", "581", "582", "583", "584", "585", "586", "587", "588", "589",
+ "590", "591", "592", "593", "594", "595", "596", "597", "598", "599",
+
+ "600", "601", "602", "603", "604", "605", "606", "607", "608", "609",
+ "610", "611", "612", "613", "614", "615", "616", "617", "618", "619",
+ "620", "621", "622", "623", "624", "625", "626", "627", "628", "629",
+ "630", "631", "632", "633", "634", "635", "636", "637", "638", "639",
+ "640", "641", "642", "643", "644", "645", "646", "647", "648", "649",
+ "650", "651", "652", "653", "654", "655", "656", "657", "658", "659",
+ "660", "661", "662", "663", "664", "665", "666", "667", "668", "669",
+ "670", "671", "672", "673", "674", "675", "676", "677", "678", "679",
+ "680", "681", "682", "683", "684", "685", "686", "687", "688", "689",
+ "690", "691", "692", "693", "694", "695", "696", "697", "698", "699",
+
+ "700", "701", "702", "703", "704", "705", "706", "707", "708", "709",
+ "710", "711", "712", "713", "714", "715", "716", "717", "718", "719",
+ "720", "721", "722", "723", "724", "725", "726", "727", "728", "729",
+ "730", "731", "732", "733", "734", "735", "736", "737", "738", "739",
+ "740", "741", "742", "743", "744", "745", "746", "747", "748", "749",
+ "750", "751", "752", "753", "754", "755", "756", "757", "758", "759",
+ "760", "761", "762", "763", "764", "765", "766", "767", "768", "769",
+ "770", "771", "772", "773", "774", "775", "776", "777", "778", "779",
+ "780", "781", "782", "783", "784", "785", "786", "787", "788", "789",
+ "790", "791", "792", "793", "794", "795", "796", "797", "798", "799",
+
+ "800", "801", "802", "803", "804", "805", "806", "807", "808", "809",
+ "810", "811", "812", "813", "814", "815", "816", "817", "818", "819",
+ "820", "821", "822", "823", "824", "825", "826", "827", "828", "829",
+ "830", "831", "832", "833", "834", "835", "836", "837", "838", "839",
+ "840", "841", "842", "843", "844", "845", "846", "847", "848", "849",
+ "850", "851", "852", "853", "854", "855", "856", "857", "858", "859",
+ "860", "861", "862", "863", "864", "865", "866", "867", "868", "869",
+ "870", "871", "872", "873", "874", "875", "876", "877", "878", "879",
+ "880", "881", "882", "883", "884", "885", "886", "887", "888", "889",
+ "890", "891", "892", "893", "894", "895", "896", "897", "898", "899",
+
+ "900", "901", "902", "903", "904", "905", "906", "907", "908", "909",
+ "910", "911", "912", "913", "914", "915", "916", "917", "918", "919",
+ "920", "921", "922", "923", "924", "925", "926", "927", "928", "929",
+ "930", "931", "932", "933", "934", "935", "936", "937", "938", "939",
+ "940", "941", "942", "943", "944", "945", "946", "947", "948", "949",
+ "950", "951", "952", "953", "954", "955", "956", "957", "958", "959",
+ "960", "961", "962", "963", "964", "965", "966", "967", "968", "969",
+ "970", "971", "972", "973", "974", "975", "976", "977", "978", "979",
+ "980", "981", "982", "983", "984", "985", "986", "987", "988", "989",
+ "990", "991", "992", "993", "994", "995", "996", "997", "998", "999",
+};
diff --git a/config.c b/config.c
new file mode 100644
index 0000000..655c3cf
--- /dev/null
+++ b/config.c
@@ -0,0 +1,79 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2012 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "ntapi.h"
+#include "config.h"
+
+void read_config()
+{
+ // TODO unicode support
+ char buf[512], config_fname[MAX_PATH];
+ sprintf(config_fname, "%s\\%d.ini",
+ getenv("TEMP"), GetCurrentProcessId());
+
+ FILE *fp = fopen(config_fname, "r");
+ if(fp != NULL) {
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ // cut off the newline
+ char *p = strchr(buf, '\r');
+ if(p != NULL) *p = 0;
+ p = strchr(buf, '\n');
+ if(p != NULL) *p = 0;
+
+ // split key=value
+ p = strchr(buf, '=');
+ if(p != NULL) {
+ *p = 0;
+
+ const char *key = buf, *value = p + 1;
+
+ if(!strcmp(key, "pipe")) {
+ strncpy(g_config.pipe_name, value,
+ ARRAYSIZE(g_config.pipe_name));
+ }
+ else if(!strcmp(key, "results")) {
+ strncpy(g_config.results, value,
+ ARRAYSIZE(g_config.results));
+ }
+ else if(!strcmp(key, "analyzer")) {
+ strncpy(g_config.analyzer, value,
+ ARRAYSIZE(g_config.analyzer));
+ }
+ else if(!strcmp(key, "first-process")) {
+ g_config.first_process = value[0] == '1';
+ }
+ else if(!strcmp(key, "startup-time")) {
+ g_config.startup_time = atoi(value);
+ }
+ else if(!strcmp(key, "retaddr-check")) {
+ g_config.retaddr_check = value[0] == '1';
+ }
+ else if(!strcmp(key, "host-ip")) {
+ g_config.host_ip = inet_addr(value);
+ }
+ else if(!strcmp(key, "host-port")) {
+ g_config.host_port = atoi(value);
+ }
+ }
+ }
+ fclose(fp);
+ DeleteFile(config_fname);
+ }
+}
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..14a3b82
--- /dev/null
+++ b/config.h
@@ -0,0 +1,43 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2012 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+struct {
+ // name of the pipe to communicate with cuckoo
+ char pipe_name[MAX_PATH];
+
+ // results directory, has to be hidden
+ char results[MAX_PATH];
+
+ // analyzer directory, has to be hidden
+ char analyzer[MAX_PATH];
+
+ // is this the first process or not?
+ int first_process;
+
+ // how many milliseconds since startup
+ unsigned int startup_time;
+
+ // do we want to enable the retaddr check?
+ int retaddr_check;
+
+ // server ip and port
+ unsigned int host_ip;
+ unsigned short host_port;
+} g_config;
+
+void read_config();
diff --git a/cuckoomon.c b/cuckoomon.c
new file mode 100644
index 0000000..f3c422f
--- /dev/null
+++ b/cuckoomon.c
@@ -0,0 +1,426 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "ntapi.h"
+#include "misc.h"
+#include "hooking.h"
+#include "hooks.h"
+#include "log.h"
+#include "pipe.h"
+#include "ignore.h"
+#include "hook_file.h"
+#include "hook_sleep.h"
+#include "config.h"
+
+#define HOOK(library, funcname) {L###library, #funcname, NULL, \
+ &New_##funcname, (void **) &Old_##funcname}
+
+#define HOOK2(library, funcname, recursion) {L###library, #funcname, NULL, \
+ &New2_##funcname, (void **) &Old2_##funcname, recursion}
+
+static hook_t g_hooks[] = {
+
+ //
+ // Special Hooks
+ //
+ // NOTE: due to the fact that the "special" hooks don't use a hook count
+ // (whereas the "normal" hooks, those with allow_hook_recursion set to
+ // zero, do) we have to hook the "special" hooks first. Otherwise the
+ // execution flow will end up in an infinite loop, because of hook count
+ // and whatnot.
+ //
+ // In other words, do *NOT* place "special" hooks behind "normal" hooks.
+ //
+
+ HOOK2(ntdll, LdrLoadDll, TRUE),
+ HOOK2(kernel32, CreateProcessInternalW, TRUE),
+
+ //
+ // File Hooks
+ //
+
+ HOOK(ntdll, NtCreateFile),
+ HOOK(ntdll, NtOpenFile),
+ HOOK(ntdll, NtReadFile),
+ HOOK(ntdll, NtWriteFile),
+ HOOK(ntdll, NtDeleteFile),
+ HOOK(ntdll, NtDeviceIoControlFile),
+ HOOK(ntdll, NtQueryDirectoryFile),
+ HOOK(ntdll, NtQueryInformationFile),
+ HOOK(ntdll, NtSetInformationFile),
+ HOOK(ntdll, NtOpenDirectoryObject),
+ HOOK(ntdll, NtCreateDirectoryObject),
+
+ // CreateDirectoryExA calls CreateDirectoryExW
+ // CreateDirectoryW does not call CreateDirectoryExW
+ HOOK(kernel32, CreateDirectoryW),
+ HOOK(kernel32, CreateDirectoryExW),
+
+ HOOK(kernel32, RemoveDirectoryA),
+ HOOK(kernel32, RemoveDirectoryW),
+
+ // lowest variant of MoveFile()
+ HOOK(kernel32, MoveFileWithProgressW),
+
+ HOOK(kernel32, FindFirstFileExA),
+ HOOK(kernel32, FindFirstFileExW),
+
+ // Covered by NtCreateFile() but still grap this information
+ HOOK(kernel32, CopyFileA),
+ HOOK(kernel32, CopyFileW),
+ HOOK(kernel32, CopyFileExW),
+
+ // Covered by NtSetInformationFile() but still grap this information
+ HOOK(kernel32, DeleteFileA),
+ HOOK(kernel32, DeleteFileW),
+
+ //
+ // Registry Hooks
+ //
+ // Note: Most, if not all, of the Registry API go natively from both the
+ // A as well as the W versions. In other words, we have to hook all the
+ // ascii *and* unicode APIs of those functions.
+ //
+
+ HOOK(advapi32, RegOpenKeyExA),
+ HOOK(advapi32, RegOpenKeyExW),
+
+ HOOK(advapi32, RegCreateKeyExA),
+ HOOK(advapi32, RegCreateKeyExW),
+
+ // Note that RegDeleteKeyEx() is available for 64bit XP/Vista+
+ HOOK(advapi32, RegDeleteKeyA),
+ HOOK(advapi32, RegDeleteKeyW),
+
+ // RegEnumKeyA() calls RegEnumKeyExA(), but RegEnumKeyW() does *not*
+ // call RegEnumKeyExW()
+ HOOK(advapi32, RegEnumKeyW),
+ HOOK(advapi32, RegEnumKeyExA),
+ HOOK(advapi32, RegEnumKeyExW),
+
+ HOOK(advapi32, RegEnumValueA),
+ HOOK(advapi32, RegEnumValueW),
+
+ HOOK(advapi32, RegSetValueExA),
+ HOOK(advapi32, RegSetValueExW),
+
+ HOOK(advapi32, RegQueryValueExA),
+ HOOK(advapi32, RegQueryValueExW),
+
+ HOOK(advapi32, RegDeleteValueA),
+ HOOK(advapi32, RegDeleteValueW),
+
+ HOOK(advapi32, RegQueryInfoKeyA),
+ HOOK(advapi32, RegQueryInfoKeyW),
+
+ HOOK(advapi32, RegCloseKey),
+
+ //
+ // Native Registry Hooks
+ //
+
+ HOOK(ntdll, NtCreateKey),
+ HOOK(ntdll, NtOpenKey),
+ HOOK(ntdll, NtOpenKeyEx),
+ HOOK(ntdll, NtRenameKey),
+ HOOK(ntdll, NtReplaceKey),
+ HOOK(ntdll, NtEnumerateKey),
+ HOOK(ntdll, NtEnumerateValueKey),
+ HOOK(ntdll, NtSetValueKey),
+ HOOK(ntdll, NtQueryValueKey),
+ HOOK(ntdll, NtQueryMultipleValueKey),
+ HOOK(ntdll, NtDeleteKey),
+ HOOK(ntdll, NtDeleteValueKey),
+ HOOK(ntdll, NtLoadKey),
+ HOOK(ntdll, NtLoadKey2),
+ HOOK(ntdll, NtLoadKeyEx),
+ HOOK(ntdll, NtQueryKey),
+ HOOK(ntdll, NtSaveKey),
+ HOOK(ntdll, NtSaveKeyEx),
+
+ //
+ // Window Hooks
+ //
+
+ HOOK(user32, FindWindowA),
+ HOOK(user32, FindWindowW),
+ HOOK(user32, FindWindowExA),
+ HOOK(user32, FindWindowExW),
+
+ //
+ // Sync Hooks
+ //
+
+ HOOK(ntdll, NtCreateMutant),
+ HOOK(ntdll, NtOpenMutant),
+ HOOK(ntdll, NtCreateNamedPipeFile),
+
+ //
+ // Process Hooks
+ //
+
+ HOOK(ntdll, NtCreateProcess),
+ HOOK(ntdll, NtCreateProcessEx),
+ HOOK(ntdll, NtCreateUserProcess),
+ HOOK(ntdll, RtlCreateUserProcess),
+ //HOOK(ntdll, NtOpenProcess),
+ HOOK(ntdll, NtTerminateProcess),
+ HOOK(ntdll, NtCreateSection),
+ HOOK(ntdll, NtMakeTemporaryObject),
+ HOOK(ntdll, NtMakePermanentObject),
+ HOOK(ntdll, NtOpenSection),
+ //HOOK(kernel32, CreateProcessInternalW),
+ HOOK(ntdll, ZwMapViewOfSection),
+ HOOK(kernel32, ExitProcess),
+
+ // all variants of ShellExecute end up in ShellExecuteExW
+ HOOK(shell32, ShellExecuteExW),
+ HOOK(ntdll, NtUnmapViewOfSection),
+ // HOOK(ntdll, NtAllocateVirtualMemory),
+ HOOK(ntdll, NtReadVirtualMemory),
+ HOOK(kernel32, ReadProcessMemory),
+ HOOK(ntdll, NtWriteVirtualMemory),
+ HOOK(kernel32, WriteProcessMemory),
+ HOOK(ntdll, NtProtectVirtualMemory),
+ HOOK(kernel32, VirtualProtectEx),
+ HOOK(ntdll, NtFreeVirtualMemory),
+ //HOOK(kernel32, VirtualFreeEx),
+
+ HOOK(msvcrt, system),
+
+ //
+ // Thread Hooks
+ //
+
+ HOOK(ntdll, NtCreateThread),
+ HOOK(ntdll, NtCreateThreadEx),
+ HOOK(ntdll, NtOpenThread),
+ HOOK(ntdll, NtGetContextThread),
+ HOOK(ntdll, NtSetContextThread),
+ HOOK(ntdll, NtSuspendThread),
+ HOOK(ntdll, NtResumeThread),
+ HOOK(ntdll, NtTerminateThread),
+ HOOK(kernel32, CreateThread),
+ HOOK(kernel32, CreateRemoteThread),
+ HOOK(kernel32, ExitThread),
+ HOOK(ntdll, RtlCreateUserThread),
+
+ //
+ // Misc Hooks
+ //
+
+ HOOK(user32, SetWindowsHookExA),
+ HOOK(user32, SetWindowsHookExW),
+ HOOK(user32, UnhookWindowsHookEx),
+ //HOOK(ntdll, LdrLoadDll),
+ HOOK(ntdll, LdrGetDllHandle),
+ HOOK(ntdll, LdrGetProcedureAddress),
+ HOOK(kernel32, DeviceIoControl),
+ HOOK(user32, ExitWindowsEx),
+ HOOK(kernel32, IsDebuggerPresent),
+ HOOK(advapi32, LookupPrivilegeValueW),
+ //HOOK(ntdll, NtClose),
+ HOOK(kernel32, WriteConsoleA),
+ HOOK(kernel32, WriteConsoleW),
+ HOOK(user32, GetSystemMetrics),
+ HOOK(user32, GetCursorPos),
+
+ //
+ // Network Hooks
+ //
+
+ HOOK(urlmon, URLDownloadToFileW),
+ HOOK(wininet, InternetOpenA),
+ HOOK(wininet, InternetOpenW),
+ HOOK(wininet, InternetConnectA),
+ HOOK(wininet, InternetConnectW),
+ HOOK(wininet, InternetOpenUrlA),
+ HOOK(wininet, InternetOpenUrlW),
+ HOOK(wininet, HttpOpenRequestA),
+ HOOK(wininet, HttpOpenRequestW),
+ HOOK(wininet, HttpSendRequestA),
+ HOOK(wininet, HttpSendRequestW),
+ HOOK(wininet, InternetReadFile),
+ HOOK(wininet, InternetWriteFile),
+ HOOK(wininet, InternetCloseHandle),
+
+ HOOK(dnsapi, DnsQuery_A),
+ HOOK(dnsapi, DnsQuery_UTF8),
+ HOOK(dnsapi, DnsQuery_W),
+ HOOK(ws2_32, getaddrinfo),
+ HOOK(ws2_32, GetAddrInfoW),
+
+ //
+ // Service Hooks
+ //
+
+ HOOK(advapi32, OpenSCManagerA),
+ HOOK(advapi32, OpenSCManagerW),
+ HOOK(advapi32, CreateServiceA),
+ HOOK(advapi32, CreateServiceW),
+ HOOK(advapi32, OpenServiceA),
+ HOOK(advapi32, OpenServiceW),
+ HOOK(advapi32, StartServiceA),
+ HOOK(advapi32, StartServiceW),
+ HOOK(advapi32, ControlService),
+ HOOK(advapi32, DeleteService),
+
+ //
+ // Sleep Hooks
+ //
+
+ HOOK(ntdll, NtDelayExecution),
+ HOOK(kernel32, GetLocalTime),
+ HOOK(kernel32, GetSystemTime),
+ HOOK(kernel32, GetTickCount),
+ HOOK(ntdll, NtQuerySystemTime),
+
+ //
+ // Socket Hooks
+ //
+
+ HOOK(ws2_32, WSAStartup),
+ HOOK(ws2_32, gethostbyname),
+ HOOK(ws2_32, socket),
+ HOOK(ws2_32, connect),
+ HOOK(ws2_32, send),
+ HOOK(ws2_32, sendto),
+ HOOK(ws2_32, recv),
+ HOOK(ws2_32, recvfrom),
+ HOOK(ws2_32, accept),
+ HOOK(ws2_32, bind),
+ HOOK(ws2_32, listen),
+ HOOK(ws2_32, select),
+ HOOK(ws2_32, setsockopt),
+ HOOK(ws2_32, ioctlsocket),
+ HOOK(ws2_32, closesocket),
+ HOOK(ws2_32, shutdown),
+
+ HOOK(ws2_32, WSARecv),
+ HOOK(ws2_32, WSARecvFrom),
+ HOOK(ws2_32, WSASend),
+ HOOK(ws2_32, WSASendTo),
+ HOOK(ws2_32, WSASocketA),
+ HOOK(ws2_32, WSASocketW),
+
+ // HOOK(wsock32, connect),
+ // HOOK(wsock32, send),
+ // HOOK(wsock32, recv),
+
+ HOOK(mswsock, ConnectEx),
+ HOOK(mswsock, TransmitFile),
+};
+
+// get a random hooking method, except for hook_jmp_direct
+//#define HOOKTYPE randint(HOOK_NOP_JMP_DIRECT, HOOK_MOV_EAX_INDIRECT_PUSH_RETN)
+// error testing with hook_jmp_direct only
+#define HOOKTYPE HOOK_JMP_DIRECT
+
+void set_hooks_dll(const wchar_t *library, int len)
+{
+ for (int i = 0; i < ARRAYSIZE(g_hooks); i++) {
+ if(!wcsnicmp(g_hooks[i].library, library, len)) {
+ hook_api(&g_hooks[i], HOOKTYPE);
+ }
+ }
+}
+
+void set_hooks()
+{
+ // the hooks contain executable code as well, so they have to be RWX
+ DWORD old_protect;
+ VirtualProtect(g_hooks, sizeof(g_hooks), PAGE_EXECUTE_READWRITE,
+ &old_protect);
+
+ hook_disable();
+
+ // now, hook each api :)
+ for (int i = 0; i < ARRAYSIZE(g_hooks); i++) {
+ if(g_hooks[i].allow_hook_recursion != FALSE) {
+ hook_api(&g_hooks[i], HOOKTYPE);
+ }
+ else {
+ hook_api(&g_hooks[i], HOOKTYPE);
+ }
+ }
+
+ hook_enable();
+}
+
+BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
+{
+ if(dwReason == DLL_PROCESS_ATTACH) {
+ // make sure advapi32 is loaded
+ LoadLibrary("advapi32");
+
+ // there's a small list of processes which we don't want to inject
+ if(is_ignored_process()) {
+ return TRUE;
+ }
+
+ // hide our module from peb
+ hide_module_from_peb(hModule);
+
+ // obtain all protected pids
+ int pids[MAX_PROTECTED_PIDS], length = sizeof(pids);
+ pipe2(pids, &length, "GETPIDS");
+ for (int i = 0; i < length / sizeof(pids[0]); i++) {
+ add_protected_pid(pids[i]);
+ }
+
+ // initialize file stuff
+ file_init();
+
+ // read the config settings
+ read_config();
+ g_pipe_name = g_config.pipe_name;
+
+ // initialize the log file
+ log_init(g_config.host_ip, g_config.host_port, 0);
+
+ // initialize the Sleep() skipping stuff
+ init_sleep_skip(g_config.first_process);
+
+ // we skip a random given amount of milliseconds each run
+ init_startup_time(g_config.startup_time);
+
+ // disable the retaddr check if the user wants so
+ if(g_config.retaddr_check == 0) {
+ hook_disable_retaddr_check();
+ }
+
+ // initialize all hooks
+ set_hooks();
+
+ // notify analyzer.py that we've loaded
+ char name[64];
+ sprintf(name, "CuckooEvent%d", GetCurrentProcessId());
+ HANDLE event_handle = OpenEvent(EVENT_ALL_ACCESS, FALSE, name);
+ if(event_handle != NULL) {
+ SetEvent(event_handle);
+ CloseHandle(event_handle);
+ }
+ }
+ else if(dwReason == DLL_PROCESS_DETACH) {
+ log_free();
+ }
+
+ return TRUE;
+}
diff --git a/distorm3.2-package/COPYING b/distorm3.2-package/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/distorm3.2-package/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/distorm3.2-package/include/distorm.h b/distorm3.2-package/include/distorm.h
new file mode 100644
index 0000000..ed073af
--- /dev/null
+++ b/distorm3.2-package/include/distorm.h
@@ -0,0 +1,462 @@
+/* diStorm3 3.2 */
+
+/*
+distorm.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef DISTORM_H
+#define DISTORM_H
+
+/*
+ * 64 bit offsets support:
+ * If the diStorm library you use was compiled with 64 bits offsets,
+ * make sure you compile your own code with the following macro set:
+ * SUPPORT_64BIT_OFFSET
+ * Otherwise comment it out, or you will get a linker error of an unresolved symbol...
+ * Turned on by default!
+ */
+
+#if !(defined(DISTORM_STATIC) || defined(DISTORM_DYNAMIC))
+ /* Define this macro for outer projects by default. */
+ #define SUPPORT_64BIT_OFFSET
+#endif
+
+/* TINYC has a problem with some 64bits library functions, so ignore 64 bit offsets. */
+#ifdef __TINYC__
+ #undef SUPPORT_64BIT_OFFSET
+#endif
+
+/* If your compiler doesn't support stdint.h, define your own 64 bits type. */
+#ifdef SUPPORT_64BIT_OFFSET
+ #ifdef _MSC_VER
+ #define OFFSET_INTEGER unsigned __int64
+ #else
+ #include
+ #define OFFSET_INTEGER uint64_t
+ #endif
+#else
+ /* 32 bit offsets are used. */
+ #define OFFSET_INTEGER unsigned long
+#endif
+
+#ifdef _MSC_VER
+/* Since MSVC isn't shipped with stdint.h, we will have our own: */
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef signed __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+#endif
+
+/* Support C++ compilers */
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* *** Helper Macros *** */
+
+/* Get the ISC of the instruction, used with the definitions below. */
+#define META_GET_ISC(meta) (((meta) >> 3) & 0x1f)
+#define META_SET_ISC(di, isc) (((di)->meta) |= ((isc) << 3))
+/* Get the flow control flags of the instruction, see 'features for decompose' below. */
+#define META_GET_FC(meta) ((meta) & 0x7)
+
+/* Get the target address of a branching instruction. O_PC operand type. */
+#define INSTRUCTION_GET_TARGET(di) ((_OffsetType)(((di)->addr + (di)->imm.addr + (di)->size)))
+/* Get the target address of a RIP-relative memory indirection. */
+#define INSTRUCTION_GET_RIP_TARGET(di) ((_OffsetType)(((di)->addr + (di)->disp + (di)->size)))
+
+/*
+ * Operand Size or Adderss size are stored inside the flags:
+ * 0 - 16 bits
+ * 1 - 32 bits
+ * 2 - 64 bits
+ * 3 - reserved
+ *
+ * If you call these set-macros more than once, you will have to clean the bits before doing so.
+ */
+#define FLAG_SET_OPSIZE(di, size) ((di->flags) |= (((size) & 3) << 8))
+#define FLAG_SET_ADDRSIZE(di, size) ((di->flags) |= (((size) & 3) << 10))
+#define FLAG_GET_OPSIZE(flags) (((flags) >> 8) & 3)
+#define FLAG_GET_ADDRSIZE(flags) (((flags) >> 10) & 3)
+/* To get the LOCK/REPNZ/REP prefixes. */
+#define FLAG_GET_PREFIX(flags) ((flags) & 7)
+
+/*
+ * Macros to extract segment registers from 'segment':
+ */
+#define SEGMENT_DEFAULT 0x80
+#define SEGMENT_SET(di, seg) ((di->segment) |= seg)
+#define SEGMENT_GET(segment) (((segment) == R_NONE) ? R_NONE : ((segment) & 0x7f))
+#define SEGMENT_IS_DEFAULT(segment) (((segment) & SEGMENT_DEFAULT) == SEGMENT_DEFAULT)
+
+
+/* Decodes modes of the disassembler, 16 bits or 32 bits or 64 bits for AMD64, x86-64. */
+typedef enum { Decode16Bits = 0, Decode32Bits = 1, Decode64Bits = 2 } _DecodeType;
+
+typedef OFFSET_INTEGER _OffsetType;
+
+typedef struct {
+ _OffsetType codeOffset, nextOffset; /* nextOffset is OUT only. */
+ const uint8_t* code;
+ int codeLen; /* Using signed integer makes it easier to detect an underflow. */
+ _DecodeType dt;
+ unsigned int features;
+} _CodeInfo;
+
+typedef enum { O_NONE, O_REG, O_IMM, O_IMM1, O_IMM2, O_DISP, O_SMEM, O_MEM, O_PC, O_PTR } _OperandType;
+
+typedef union {
+ /* Used by O_IMM: */
+ int8_t sbyte;
+ uint8_t byte;
+ int16_t sword;
+ uint16_t word;
+ int32_t sdword;
+ uint32_t dword;
+ int64_t sqword; /* All immediates are SIGN-EXTENDED to 64 bits! */
+ uint64_t qword;
+
+ /* Used by O_PC: (Use GET_TARGET_ADDR).*/
+ _OffsetType addr; /* It's a relative offset as for now. */
+
+ /* Used by O_PTR: */
+ struct {
+ uint16_t seg;
+ /* Can be 16 or 32 bits, size is in ops[n].size. */
+ uint32_t off;
+ } ptr;
+
+ /* Used by O_IMM1 (i1) and O_IMM2 (i2). ENTER instruction only. */
+ struct {
+ uint32_t i1;
+ uint32_t i2;
+ } ex;
+} _Value;
+
+typedef struct {
+ /* Type of operand:
+ O_NONE: operand is to be ignored.
+ O_REG: index holds global register index.
+ O_IMM: instruction.imm.
+ O_IMM1: instruction.imm.ex.i1.
+ O_IMM2: instruction.imm.ex.i2.
+ O_DISP: memory dereference with displacement only, instruction.disp.
+ O_SMEM: simple memory dereference with optional displacement (a single register memory dereference).
+ O_MEM: complex memory dereference (optional fields: s/i/b/disp).
+ O_PC: the relative address of a branch instruction (instruction.imm.addr).
+ O_PTR: the absolute target address of a far branch instruction (instruction.imm.ptr.seg/off).
+ */
+ uint8_t type; /* _OperandType */
+
+ /* Index of:
+ O_REG: holds global register index
+ O_SMEM: holds the 'base' register. E.G: [ECX], [EBX+0x1234] are both in operand.index.
+ O_MEM: holds the 'index' register. E.G: [EAX*4] is in operand.index.
+ */
+ uint8_t index;
+
+ /* Size of:
+ O_REG: register
+ O_IMM: instruction.imm
+ O_IMM1: instruction.imm.ex.i1
+ O_IMM2: instruction.imm.ex.i2
+ O_DISP: instruction.disp
+ O_SMEM: size of indirection.
+ O_MEM: size of indirection.
+ O_PC: size of the relative offset
+ O_PTR: size of instruction.imm.ptr.off (16 or 32)
+ */
+ uint16_t size;
+} _Operand;
+
+#define OPCODE_ID_NONE 0
+/* Instruction could not be disassembled. */
+#define FLAG_NOT_DECODABLE ((uint16_t)-1)
+/* The instruction locks memory access. */
+#define FLAG_LOCK (1 << 0)
+/* The instruction is prefixed with a REPNZ. */
+#define FLAG_REPNZ (1 << 1)
+/* The instruction is prefixed with a REP, this can be a REPZ, it depends on the specific instruction. */
+#define FLAG_REP (1 << 2)
+/* Indicates there is a hint taken for Jcc instructions only. */
+#define FLAG_HINT_TAKEN (1 << 3)
+/* Indicates there is a hint non-taken for Jcc instructions only. */
+#define FLAG_HINT_NOT_TAKEN (1 << 4)
+/* The Imm value is signed extended. */
+#define FLAG_IMM_SIGNED (1 << 5)
+/* The destination operand is writable. */
+#define FLAG_DST_WR (1 << 6)
+/* The instruction uses RIP-relative indirection. */
+#define FLAG_RIP_RELATIVE (1 << 7)
+
+/* No register was defined. */
+#define R_NONE ((uint8_t)-1)
+
+#define REGS64_BASE (0)
+#define REGS32_BASE (16)
+#define REGS16_BASE (32)
+#define REGS8_BASE (48)
+#define REGS8_REX_BASE (64)
+#define SREGS_BASE (68)
+/* #define RIP 74 */
+#define FPUREGS_BASE (75)
+#define MMXREGS_BASE (83)
+#define SSEREGS_BASE (91)
+#define AVXREGS_BASE (107)
+#define CREGS_BASE (123)
+#define DREGS_BASE (132)
+
+#define OPERANDS_NO (4)
+
+typedef struct {
+ /* Used by ops[n].type == O_IMM/O_IMM1&O_IMM2/O_PTR/O_PC. Its size is ops[n].size. */
+ _Value imm;
+ /* Used by ops[n].type == O_SMEM/O_MEM/O_DISP. Its size is dispSize. */
+ uint64_t disp;
+ /* Virtual address of first byte of instruction. */
+ _OffsetType addr;
+ /* General flags of instruction, holds prefixes and more, if FLAG_NOT_DECODABLE, instruction is invalid. */
+ uint16_t flags;
+ /* Unused prefixes mask, for each bit that is set that prefix is not used (LSB is byte [addr + 0]). */
+ uint16_t unusedPrefixesMask;
+ /* Mask of registers that were used in the operands, only used for quick look up, in order to know *some* operand uses that register class. */
+ uint16_t usedRegistersMask;
+ /* ID of opcode in the global opcode table. Use for mnemonic look up. */
+ uint16_t opcode;
+ /* Up to four operands per instruction, ignored if ops[n].type == O_NONE. */
+ _Operand ops[OPERANDS_NO];
+ /* Size of the whole instruction. */
+ uint8_t size;
+ /* Segment information of memory indirection, default segment, or overriden one, can be -1. Use SEGMENT macros. */
+ uint8_t segment;
+ /* Used by ops[n].type == O_MEM. Base global register index (might be R_NONE), scale size (2/4/8), ignored for 0 or 1. */
+ uint8_t base, scale;
+ uint8_t dispSize;
+ /* Meta defines the instruction set class, and the flow control flags. Use META macros. */
+ uint8_t meta;
+} _DInst;
+
+#ifndef DISTORM_LIGHT
+
+/* Static size of strings. Do not change this value. Keep Python wrapper in sync. */
+#define MAX_TEXT_SIZE (48)
+typedef struct {
+ unsigned int length;
+ unsigned char p[MAX_TEXT_SIZE]; /* p is a null terminated string. */
+} _WString;
+
+/*
+ * Old decoded instruction structure in text format.
+ * Used only for backward compatibility with diStorm64.
+ * This structure holds all information the disassembler generates per instruction.
+ */
+typedef struct {
+ _WString mnemonic; /* Mnemonic of decoded instruction, prefixed if required by REP, LOCK etc. */
+ _WString operands; /* Operands of the decoded instruction, up to 3 operands, comma-seperated. */
+ _WString instructionHex; /* Hex dump - little endian, including prefixes. */
+ unsigned int size; /* Size of decoded instruction. */
+ _OffsetType offset; /* Start offset of the decoded instruction. */
+} _DecodedInst;
+
+#endif /* DISTORM_LIGHT */
+
+/* Register masks for quick look up, each mask indicates one of a register-class that is being used in some operand. */
+#define RM_AX 1 /* AL, AH, AX, EAX, RAX */
+#define RM_CX 2 /* CL, CH, CX, ECX, RCX */
+#define RM_DX 4 /* DL, DH, DX, EDX, RDX */
+#define RM_BX 8 /* BL, BH, BX, EBX, RBX */
+#define RM_SP 0x10 /* SPL, SP, ESP, RSP */
+#define RM_BP 0x20 /* BPL, BP, EBP, RBP */
+#define RM_SI 0x40 /* SIL, SI, ESI, RSI */
+#define RM_DI 0x80 /* DIL, DI, EDI, RDI */
+#define RM_FPU 0x100 /* ST(0) - ST(7) */
+#define RM_MMX 0x200 /* MM0 - MM7 */
+#define RM_SSE 0x400 /* XMM0 - XMM15 */
+#define RM_AVX 0x800 /* YMM0 - YMM15 */
+#define RM_CR 0x1000 /* CR0, CR2, CR3, CR4, CR8 */
+#define RM_DR 0x2000 /* DR0, DR1, DR2, DR3, DR6, DR7 */
+/* RIP should be checked using the 'flags' field and FLAG_RIP_RELATIVE.
+ * Segments should be checked using the segment macros.
+ * For now R8 - R15 are not supported and non general purpose registers map into same RM.
+ */
+
+/*
+ * Instructions Set classes:
+ * if you want a better understanding of the available classes, look at disOps project, file: x86sets.py.
+ */
+/* Indicates the instruction belongs to the General Integer set. */
+#define ISC_INTEGER 1
+/* Indicates the instruction belongs to the 387 FPU set. */
+#define ISC_FPU 2
+/* Indicates the instruction belongs to the P6 set. */
+#define ISC_P6 3
+/* Indicates the instruction belongs to the MMX set. */
+#define ISC_MMX 4
+/* Indicates the instruction belongs to the SSE set. */
+#define ISC_SSE 5
+/* Indicates the instruction belongs to the SSE2 set. */
+#define ISC_SSE2 6
+/* Indicates the instruction belongs to the SSE3 set. */
+#define ISC_SSE3 7
+/* Indicates the instruction belongs to the SSSE3 set. */
+#define ISC_SSSE3 8
+/* Indicates the instruction belongs to the SSE4.1 set. */
+#define ISC_SSE4_1 9
+/* Indicates the instruction belongs to the SSE4.2 set. */
+#define ISC_SSE4_2 10
+/* Indicates the instruction belongs to the AMD's SSE4.A set. */
+#define ISC_SSE4_A 11
+/* Indicates the instruction belongs to the 3DNow! set. */
+#define ISC_3DNOW 12
+/* Indicates the instruction belongs to the 3DNow! Extensions set. */
+#define ISC_3DNOWEXT 13
+/* Indicates the instruction belongs to the VMX (Intel) set. */
+#define ISC_VMX 14
+/* Indicates the instruction belongs to the SVM (AMD) set. */
+#define ISC_SVM 15
+/* Indicates the instruction belongs to the AVX (Intel) set. */
+#define ISC_AVX 16
+/* Indicates the instruction belongs to the FMA (Intel) set. */
+#define ISC_FMA 17
+/* Indicates the instruction belongs to the AES/AVX (Intel) set. */
+#define ISC_AES 18
+/* Indicates the instruction belongs to the CLMUL (Intel) set. */
+#define ISC_CLMUL 19
+
+/* Features for decompose: */
+#define DF_NONE 0
+/* The decoder will limit addresses to a maximum of 16 bits. */
+#define DF_MAXIMUM_ADDR16 1
+/* The decoder will limit addresses to a maximum of 32 bits. */
+#define DF_MAXIMUM_ADDR32 2
+/* The decoder will return only flow control instructions (and filter the others internally). */
+#define DF_RETURN_FC_ONLY 4
+/* The decoder will stop and return to the caller when the instruction 'CALL' (near and far) was decoded. */
+#define DF_STOP_ON_CALL 8
+/* The decoder will stop and return to the caller when the instruction 'RET' (near and far) was decoded. */
+#define DF_STOP_ON_RET 0x10
+/* The decoder will stop and return to the caller when the instruction system-call/ret was decoded. */
+#define DF_STOP_ON_SYS 0x20
+/* The decoder will stop and return to the caller when any of the branch 'JMP', (near and far) instructions were decoded. */
+#define DF_STOP_ON_UNC_BRANCH 0x40
+/* The decoder will stop and return to the caller when any of the conditional branch instruction were decoded. */
+#define DF_STOP_ON_CND_BRANCH 0x80
+/* The decoder will stop and return to the caller when the instruction 'INT' (INT, INT1, INTO, INT 3) was decoded. */
+#define DF_STOP_ON_INT 0x100
+/* The decoder will stop and return to the caller when any of the 'CMOVxx' instruction was decoded. */
+#define DF_STOP_ON_CMOV 0x200
+/* The decoder will stop and return to the caller when any flow control instruction was decoded. */
+#define DF_STOP_ON_FLOW_CONTROL (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_UNC_BRANCH | DF_STOP_ON_CND_BRANCH | DF_STOP_ON_INT | DF_STOP_ON_CMOV)
+
+/* Indicates the instruction is not a flow-control instruction. */
+#define FC_NONE 0
+/* Indicates the instruction is one of: CALL, CALL FAR. */
+#define FC_CALL 1
+/* Indicates the instruction is one of: RET, IRET, RETF. */
+#define FC_RET 2
+/* Indicates the instruction is one of: SYSCALL, SYSRET, SYSENTER, SYSEXIT. */
+#define FC_SYS 3
+/* Indicates the instruction is one of: JMP, JMP FAR. */
+#define FC_UNC_BRANCH 4
+/*
+ * Indicates the instruction is one of:
+ * JCXZ, JO, JNO, JB, JAE, JZ, JNZ, JBE, JA, JS, JNS, JP, JNP, JL, JGE, JLE, JG, LOOP, LOOPZ, LOOPNZ.
+ */
+#define FC_CND_BRANCH 5
+/* Indiciates the instruction is one of: INT, INT1, INT 3, INTO, UD2. */
+#define FC_INT 6
+/* Indicates the instruction is one of: CMOVxx. */
+#define FC_CMOV 7
+
+/* Return code of the decoding function. */
+typedef enum { DECRES_NONE, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR, DECRES_FILTERED } _DecodeResult;
+
+/* Define the following interface functions only for outer projects. */
+#if !(defined(DISTORM_STATIC) || defined(DISTORM_DYNAMIC))
+
+/* distorm_decode
+ * Input:
+ * offset - Origin of the given code (virtual address that is), NOT an offset in code.
+ * code - Pointer to the code buffer to be disassembled.
+ * length - Amount of bytes that should be decoded from the code buffer.
+ * dt - Decoding mode, 16 bits (Decode16Bits), 32 bits (Decode32Bits) or AMD64 (Decode64Bits).
+ * result - Array of type _DecodeInst which will be used by this function in order to return the disassembled instructions.
+ * maxInstructions - The maximum number of entries in the result array that you pass to this function, so it won't exceed its bound.
+ * usedInstructionsCount - Number of the instruction that successfully were disassembled and written to the result array.
+ * Output: usedInstructionsCount will hold the number of entries used in the result array
+ * and the result array itself will be filled with the disassembled instructions.
+ * Return: DECRES_SUCCESS on success (no more to disassemble), DECRES_INPUTERR on input error (null code buffer, invalid decoding mode, etc...),
+ * DECRES_MEMORYERR when there are not enough entries to use in the result array, BUT YOU STILL have to check for usedInstructionsCount!
+ * Side-Effects: Even if the return code is DECRES_MEMORYERR, there might STILL be data in the
+ * array you passed, this function will try to use as much entries as possible!
+ * Notes: 1)The minimal size of maxInstructions is 15.
+ * 2)You will have to synchronize the offset,code and length by yourself if you pass code fragments and not a complete code block!
+ */
+#ifdef SUPPORT_64BIT_OFFSET
+
+ _DecodeResult distorm_decompose64(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ #define distorm_decompose distorm_decompose64
+
+#ifndef DISTORM_LIGHT
+ /* If distorm-light is defined, we won't export these text-formatting functionality. */
+ _DecodeResult distorm_decode64(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ void distorm_format64(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result);
+ #define distorm_decode distorm_decode64
+ #define distorm_format distorm_format64
+#endif /*DISTORM_LIGHT*/
+
+#else /*SUPPORT_64BIT_OFFSET*/
+
+ _DecodeResult distorm_decompose32(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ #define distorm_decompose distorm_decompose32
+
+#ifndef DISTORM_LIGHT
+ /* If distorm-light is defined, we won't export these text-formatting functionality. */
+ _DecodeResult distorm_decode32(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ void distorm_format32(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result);
+ #define distorm_decode distorm_decode32
+ #define distorm_format distorm_format32
+#endif /*DISTORM_LIGHT*/
+
+#endif
+
+/*
+ * distorm_version
+ * Input:
+ * none
+ *
+ * Output: unsigned int - version of compiled library.
+ */
+unsigned int distorm_version();
+
+#endif /* DISTORM_STATIC */
+
+#ifdef __cplusplus
+} /* End Of Extern */
+#endif
+
+#endif /* DISTORM_H */
diff --git a/distorm3.2-package/include/mnemonics.h b/distorm3.2-package/include/mnemonics.h
new file mode 100644
index 0000000..652d64b
--- /dev/null
+++ b/distorm3.2-package/include/mnemonics.h
@@ -0,0 +1,312 @@
+/*
+mnemonics.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef MNEMONICS_H
+#define MNEMONICS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef DISTORM_LIGHT
+
+typedef struct WMnemonic {
+ unsigned char length;
+ unsigned char p[1]; /* p is a null terminated string, which contains 'length' characters. */
+} _WMnemonic;
+
+typedef struct WRegister {
+ unsigned int length;
+ unsigned char p[6]; /* p is a null terminated string. */
+} _WRegister;
+
+extern const unsigned char _MNEMONICS[];
+extern const _WRegister _REGISTERS[];
+
+#endif /* DISTORM_LIGHT */
+
+#ifdef __cplusplus
+} /* End Of Extern */
+#endif
+
+#define GET_REGISTER_NAME(r) (unsigned char*)_REGISTERS[(r)].p
+#define GET_MNEMONIC_NAME(m) ((_WMnemonic*)&_MNEMONICS[(m)])->p
+
+typedef enum {
+ I_UNDEFINED = 0, I_AAA = 66, I_AAD = 389, I_AAM = 384, I_AAS = 76, I_ADC = 31, I_ADD = 11, I_ADDPD = 3110,
+ I_ADDPS = 3103, I_ADDSD = 3124, I_ADDSS = 3117, I_ADDSUBPD = 6394, I_ADDSUBPS = 6404,
+ I_AESDEC = 9209, I_AESDECLAST = 9226, I_AESENC = 9167, I_AESENCLAST = 9184,
+ I_AESIMC = 9150, I_AESKEYGENASSIST = 9795, I_AND = 41, I_ANDNPD = 3021, I_ANDNPS = 3013,
+ I_ANDPD = 2990, I_ANDPS = 2983, I_ARPL = 111, I_BLENDPD = 9372, I_BLENDPS = 9353,
+ I_BLENDVPD = 7619, I_BLENDVPS = 7609, I_BOUND = 104, I_BSF = 4346, I_BSR = 4358,
+ I_BSWAP = 960, I_BT = 872, I_BTC = 934, I_BTR = 912, I_BTS = 887, I_CALL = 456,
+ I_CALL_FAR = 260, I_CBW = 228, I_CDQ = 250, I_CDQE = 239, I_CLC = 492, I_CLD = 512,
+ I_CLFLUSH = 4329, I_CLGI = 1833, I_CLI = 502, I_CLTS = 541, I_CMC = 487, I_CMOVA = 694,
+ I_CMOVAE = 663, I_CMOVB = 656, I_CMOVBE = 686, I_CMOVG = 754, I_CMOVGE = 738,
+ I_CMOVL = 731, I_CMOVLE = 746, I_CMOVNO = 648, I_CMOVNP = 723, I_CMOVNS = 708,
+ I_CMOVNZ = 678, I_CMOVO = 641, I_CMOVP = 716, I_CMOVS = 701, I_CMOVZ = 671,
+ I_CMP = 71, I_CMPEQPD = 4449, I_CMPEQPS = 4370, I_CMPEQSD = 4607, I_CMPEQSS = 4528,
+ I_CMPLEPD = 4467, I_CMPLEPS = 4388, I_CMPLESD = 4625, I_CMPLESS = 4546, I_CMPLTPD = 4458,
+ I_CMPLTPS = 4379, I_CMPLTSD = 4616, I_CMPLTSS = 4537, I_CMPNEQPD = 4488, I_CMPNEQPS = 4409,
+ I_CMPNEQSD = 4646, I_CMPNEQSS = 4567, I_CMPNLEPD = 4508, I_CMPNLEPS = 4429,
+ I_CMPNLESD = 4666, I_CMPNLESS = 4587, I_CMPNLTPD = 4498, I_CMPNLTPS = 4419,
+ I_CMPNLTSD = 4656, I_CMPNLTSS = 4577, I_CMPORDPD = 4518, I_CMPORDPS = 4439,
+ I_CMPORDSD = 4676, I_CMPORDSS = 4597, I_CMPS = 301, I_CMPUNORDPD = 4476, I_CMPUNORDPS = 4397,
+ I_CMPUNORDSD = 4634, I_CMPUNORDSS = 4555, I_CMPXCHG = 898, I_CMPXCHG16B = 6373,
+ I_CMPXCHG8B = 6362, I_COMISD = 2779, I_COMISS = 2771, I_CPUID = 865, I_CQO = 255,
+ I_CRC32 = 9258, I_CVTDQ2PD = 6787, I_CVTDQ2PS = 3307, I_CVTPD2DQ = 6797, I_CVTPD2PI = 2681,
+ I_CVTPD2PS = 3233, I_CVTPH2PS = 4161, I_CVTPI2PD = 2495, I_CVTPI2PS = 2485,
+ I_CVTPS2DQ = 3317, I_CVTPS2PD = 3223, I_CVTPS2PH = 4171, I_CVTPS2PI = 2671,
+ I_CVTSD2SI = 2701, I_CVTSD2SS = 3253, I_CVTSI2SD = 2515, I_CVTSI2SS = 2505,
+ I_CVTSS2SD = 3243, I_CVTSS2SI = 2691, I_CVTTPD2DQ = 6776, I_CVTTPD2PI = 2614,
+ I_CVTTPS2DQ = 3327, I_CVTTPS2PI = 2603, I_CVTTSD2SI = 2636, I_CVTTSS2SI = 2625,
+ I_CWD = 245, I_CWDE = 233, I_DAA = 46, I_DAS = 56, I_DEC = 86, I_DIV = 1630,
+ I_DIVPD = 3499, I_DIVPS = 3492, I_DIVSD = 3513, I_DIVSS = 3506, I_DPPD = 9615,
+ I_DPPS = 9602, I_EMMS = 4100, I_ENTER = 340, I_EXTRACTPS = 9480, I_EXTRQ = 4136,
+ I_F2XM1 = 1176, I_FABS = 1107, I_FADD = 1007, I_FADDP = 1533, I_FBLD = 1585,
+ I_FBSTP = 1591, I_FCHS = 1101, I_FCLEX = 7289, I_FCMOVB = 1360, I_FCMOVBE = 1376,
+ I_FCMOVE = 1368, I_FCMOVNB = 1429, I_FCMOVNBE = 1447, I_FCMOVNE = 1438, I_FCMOVNU = 1457,
+ I_FCMOVU = 1385, I_FCOM = 1019, I_FCOMI = 1496, I_FCOMIP = 1607, I_FCOMP = 1025,
+ I_FCOMPP = 1547, I_FCOS = 1295, I_FDECSTP = 1222, I_FDIV = 1045, I_FDIVP = 1578,
+ I_FDIVR = 1051, I_FDIVRP = 1570, I_FEDISI = 1472, I_FEMMS = 574, I_FENI = 1466,
+ I_FFREE = 1511, I_FIADD = 1301, I_FICOM = 1315, I_FICOMP = 1322, I_FIDIV = 1345,
+ I_FIDIVR = 1352, I_FILD = 1402, I_FIMUL = 1308, I_FINCSTP = 1231, I_FINIT = 7304,
+ I_FIST = 1416, I_FISTP = 1422, I_FISTTP = 1408, I_FISUB = 1330, I_FISUBR = 1337,
+ I_FLD = 1058, I_FLD1 = 1125, I_FLDCW = 1082, I_FLDENV = 1074, I_FLDL2E = 1139,
+ I_FLDL2T = 1131, I_FLDLG2 = 1154, I_FLDLN2 = 1162, I_FLDPI = 1147, I_FLDZ = 1170,
+ I_FMUL = 1013, I_FMULP = 1540, I_FNCLEX = 7281, I_FNINIT = 7296, I_FNOP = 1095,
+ I_FNSAVE = 7311, I_FNSTCW = 7266, I_FNSTENV = 7249, I_FNSTSW = 7326, I_FPATAN = 1197,
+ I_FPREM = 1240, I_FPREM1 = 1214, I_FPTAN = 1190, I_FRNDINT = 1272, I_FRSTOR = 1503,
+ I_FSAVE = 7319, I_FSCALE = 1281, I_FSETPM = 1480, I_FSIN = 1289, I_FSINCOS = 1263,
+ I_FSQRT = 1256, I_FST = 1063, I_FSTCW = 7274, I_FSTENV = 7258, I_FSTP = 1068,
+ I_FSTSW = 7334, I_FSUB = 1032, I_FSUBP = 1563, I_FSUBR = 1038, I_FSUBRP = 1555,
+ I_FTST = 1113, I_FUCOM = 1518, I_FUCOMI = 1488, I_FUCOMIP = 1598, I_FUCOMP = 1525,
+ I_FUCOMPP = 1393, I_FXAM = 1119, I_FXCH = 1089, I_FXRSTOR = 9892, I_FXRSTOR64 = 9901,
+ I_FXSAVE = 9864, I_FXSAVE64 = 9872, I_FXTRACT = 1205, I_FYL2X = 1183, I_FYL2XP1 = 1247,
+ I_GETSEC = 633, I_HADDPD = 4181, I_HADDPS = 4189, I_HLT = 482, I_HSUBPD = 4215,
+ I_HSUBPS = 4223, I_IDIV = 1635, I_IMUL = 117, I_IN = 447, I_INC = 81, I_INS = 123,
+ I_INSERTPS = 9547, I_INSERTQ = 4143, I_INT = 367, I_INT_3 = 360, I_INT1 = 476,
+ I_INTO = 372, I_INVD = 555, I_INVEPT = 8284, I_INVLPG = 1711, I_INVLPGA = 1847,
+ I_INVPCID = 8301, I_INVVPID = 8292, I_IRET = 378, I_JA = 166, I_JAE = 147,
+ I_JB = 143, I_JBE = 161, I_JCXZ = 427, I_JECXZ = 433, I_JG = 202, I_JGE = 192,
+ I_JL = 188, I_JLE = 197, I_JMP = 462, I_JMP_FAR = 467, I_JNO = 138, I_JNP = 183,
+ I_JNS = 174, I_JNZ = 156, I_JO = 134, I_JP = 179, I_JRCXZ = 440, I_JS = 170,
+ I_JZ = 152, I_LAHF = 289, I_LAR = 522, I_LDDQU = 6994, I_LDMXCSR = 9922, I_LDS = 335,
+ I_LEA = 223, I_LEAVE = 347, I_LES = 330, I_LFENCE = 4265, I_LFS = 917, I_LGDT = 1687,
+ I_LGS = 922, I_LIDT = 1693, I_LLDT = 1652, I_LMSW = 1705, I_LODS = 313, I_LOOP = 421,
+ I_LOOPNZ = 406, I_LOOPZ = 414, I_LSL = 527, I_LSS = 907, I_LTR = 1658, I_LZCNT = 4363,
+ I_MASKMOVDQU = 7119, I_MASKMOVQ = 7109, I_MAXPD = 3559, I_MAXPS = 3552, I_MAXSD = 3573,
+ I_MAXSS = 3566, I_MFENCE = 4291, I_MINPD = 3439, I_MINPS = 3432, I_MINSD = 3453,
+ I_MINSS = 3446, I_MONITOR = 1755, I_MOV = 218, I_MOVAPD = 2459, I_MOVAPS = 2451,
+ I_MOVBE = 9251, I_MOVD = 3920, I_MOVDDUP = 2186, I_MOVDQ2Q = 6522, I_MOVDQA = 3946,
+ I_MOVDQU = 3954, I_MOVHLPS = 2151, I_MOVHPD = 2345, I_MOVHPS = 2337, I_MOVLHPS = 2328,
+ I_MOVLPD = 2168, I_MOVLPS = 2160, I_MOVMSKPD = 2815, I_MOVMSKPS = 2805, I_MOVNTDQ = 6849,
+ I_MOVNTDQA = 7895, I_MOVNTI = 952, I_MOVNTPD = 2556, I_MOVNTPS = 2547, I_MOVNTQ = 6841,
+ I_MOVNTSD = 2574, I_MOVNTSS = 2565, I_MOVQ = 3926, I_MOVQ2DQ = 6513, I_MOVS = 295,
+ I_MOVSD = 2110, I_MOVSHDUP = 2353, I_MOVSLDUP = 2176, I_MOVSS = 2103, I_MOVSX = 939,
+ I_MOVSXD = 10019, I_MOVUPD = 2095, I_MOVUPS = 2087, I_MOVZX = 927, I_MPSADBW = 9628,
+ I_MUL = 1625, I_MULPD = 3170, I_MULPS = 3163, I_MULSD = 3184, I_MULSS = 3177,
+ I_MWAIT = 1764, I_NEG = 1620, I_NOP = 581, I_NOT = 1615, I_OR = 27, I_ORPD = 3053,
+ I_ORPS = 3047, I_OUT = 451, I_OUTS = 128, I_PABSB = 7688, I_PABSD = 7718, I_PABSW = 7703,
+ I_PACKSSDW = 3849, I_PACKSSWB = 3681, I_PACKUSDW = 7916, I_PACKUSWB = 3759,
+ I_PADDB = 7204, I_PADDD = 7234, I_PADDQ = 6481, I_PADDSB = 6930, I_PADDSW = 6947,
+ I_PADDUSB = 6620, I_PADDUSW = 6639, I_PADDW = 7219, I_PALIGNR = 9410, I_PAND = 6607,
+ I_PANDN = 6665, I_PAUSE = 10027, I_PAVGB = 6680, I_PAVGUSB = 2078, I_PAVGW = 6725,
+ I_PBLENDVB = 7599, I_PBLENDW = 9391, I_PCLMULQDQ = 9647, I_PCMPEQB = 4043,
+ I_PCMPEQD = 4081, I_PCMPEQQ = 7876, I_PCMPEQW = 4062, I_PCMPESTRI = 9726,
+ I_PCMPESTRM = 9703, I_PCMPGTB = 3702, I_PCMPGTD = 3740, I_PCMPGTQ = 8087,
+ I_PCMPGTW = 3721, I_PCMPISTRI = 9772, I_PCMPISTRM = 9749, I_PEXTRB = 9429,
+ I_PEXTRD = 9446, I_PEXTRQ = 9454, I_PEXTRW = 6311, I_PF2ID = 1914, I_PF2IW = 1907,
+ I_PFACC = 2028, I_PFADD = 1977, I_PFCMPEQ = 2035, I_PFCMPGE = 1938, I_PFCMPGT = 1984,
+ I_PFMAX = 1993, I_PFMIN = 1947, I_PFMUL = 2044, I_PFNACC = 1921, I_PFPNACC = 1929,
+ I_PFRCP = 1954, I_PFRCPIT1 = 2000, I_PFRCPIT2 = 2051, I_PFRSQIT1 = 2010, I_PFRSQRT = 1961,
+ I_PFSUB = 1970, I_PFSUBR = 2020, I_PHADDD = 7375, I_PHADDSW = 7392, I_PHADDW = 7358,
+ I_PHMINPOSUW = 8259, I_PHSUBD = 7451, I_PHSUBSW = 7468, I_PHSUBW = 7434, I_PI2FD = 1900,
+ I_PI2FW = 1893, I_PINSRB = 9530, I_PINSRD = 9568, I_PINSRQ = 9576, I_PINSRW = 6294,
+ I_PMADDUBSW = 7411, I_PMADDWD = 7073, I_PMAXSB = 8174, I_PMAXSD = 8191, I_PMAXSW = 6964,
+ I_PMAXUB = 6648, I_PMAXUD = 8225, I_PMAXUW = 8208, I_PMINSB = 8106, I_PMINSD = 8123,
+ I_PMINSW = 6902, I_PMINUB = 6590, I_PMINUD = 8157, I_PMINUW = 8140, I_PMOVMSKB = 6531,
+ I_PMOVSXBD = 7754, I_PMOVSXBQ = 7775, I_PMOVSXBW = 7733, I_PMOVSXDQ = 7838,
+ I_PMOVSXWD = 7796, I_PMOVSXWQ = 7817, I_PMOVZXBD = 7982, I_PMOVZXBQ = 8003,
+ I_PMOVZXBW = 7961, I_PMOVZXDQ = 8066, I_PMOVZXWD = 8024, I_PMOVZXWQ = 8045,
+ I_PMULDQ = 7859, I_PMULHRSW = 7538, I_PMULHRW = 2061, I_PMULHUW = 6740, I_PMULHW = 6759,
+ I_PMULLD = 8242, I_PMULLW = 6496, I_PMULUDQ = 7054, I_POP = 22, I_POPA = 98,
+ I_POPCNT = 4338, I_POPF = 277, I_POR = 6919, I_PREFETCH = 1872, I_PREFETCHNTA = 2402,
+ I_PREFETCHT0 = 2415, I_PREFETCHT1 = 2427, I_PREFETCHT2 = 2439, I_PREFETCHW = 1882,
+ I_PSADBW = 7092, I_PSHUFB = 7341, I_PSHUFD = 3988, I_PSHUFHW = 3996, I_PSHUFLW = 4005,
+ I_PSHUFW = 3980, I_PSIGNB = 7487, I_PSIGND = 7521, I_PSIGNW = 7504, I_PSLLD = 7024,
+ I_PSLLDQ = 9847, I_PSLLQ = 7039, I_PSLLW = 7009, I_PSRAD = 6710, I_PSRAW = 6695,
+ I_PSRLD = 6451, I_PSRLDQ = 9830, I_PSRLQ = 6466, I_PSRLW = 6436, I_PSUBB = 7144,
+ I_PSUBD = 7174, I_PSUBQ = 7189, I_PSUBSB = 6868, I_PSUBSW = 6885, I_PSUBUSB = 6552,
+ I_PSUBUSW = 6571, I_PSUBW = 7159, I_PSWAPD = 2070, I_PTEST = 7629, I_PUNPCKHBW = 3780,
+ I_PUNPCKHDQ = 3826, I_PUNPCKHQDQ = 3895, I_PUNPCKHWD = 3803, I_PUNPCKLBW = 3612,
+ I_PUNPCKLDQ = 3658, I_PUNPCKLQDQ = 3870, I_PUNPCKLWD = 3635, I_PUSH = 16,
+ I_PUSHA = 91, I_PUSHF = 270, I_PXOR = 6981, I_RCL = 977, I_RCPPS = 2953, I_RCPSS = 2960,
+ I_RCR = 982, I_RDFSBASE = 9882, I_RDGSBASE = 9912, I_RDMSR = 600, I_RDPMC = 607,
+ I_RDRAND = 9980, I_RDTSC = 593, I_RDTSCP = 1864, I_RET = 325, I_RETF = 354,
+ I_ROL = 967, I_ROR = 972, I_ROUNDPD = 9296, I_ROUNDPS = 9277, I_ROUNDSD = 9334,
+ I_ROUNDSS = 9315, I_RSM = 882, I_RSQRTPS = 2915, I_RSQRTSS = 2924, I_SAHF = 283,
+ I_SAL = 997, I_SALC = 394, I_SAR = 1002, I_SBB = 36, I_SCAS = 319, I_SETA = 807,
+ I_SETAE = 780, I_SETB = 774, I_SETBE = 800, I_SETG = 859, I_SETGE = 845, I_SETL = 839,
+ I_SETLE = 852, I_SETNO = 767, I_SETNP = 832, I_SETNS = 819, I_SETNZ = 793,
+ I_SETO = 761, I_SETP = 826, I_SETS = 813, I_SETZ = 787, I_SFENCE = 4321, I_SGDT = 1675,
+ I_SHL = 987, I_SHLD = 876, I_SHR = 992, I_SHRD = 892, I_SHUFPD = 6336, I_SHUFPS = 6328,
+ I_SIDT = 1681, I_SKINIT = 1839, I_SLDT = 1641, I_SMSW = 1699, I_SQRTPD = 2855,
+ I_SQRTPS = 2847, I_SQRTSD = 2871, I_SQRTSS = 2863, I_STC = 497, I_STD = 517,
+ I_STGI = 1827, I_STI = 507, I_STMXCSR = 9951, I_STOS = 307, I_STR = 1647, I_SUB = 51,
+ I_SUBPD = 3379, I_SUBPS = 3372, I_SUBSD = 3393, I_SUBSS = 3386, I_SWAPGS = 1856,
+ I_SYSCALL = 532, I_SYSENTER = 614, I_SYSEXIT = 624, I_SYSRET = 547, I_TEST = 206,
+ I_TZCNT = 4351, I_UCOMISD = 2742, I_UCOMISS = 2733, I_UD2 = 569, I_UNPCKHPD = 2296,
+ I_UNPCKHPS = 2286, I_UNPCKLPD = 2254, I_UNPCKLPS = 2244, I_VADDPD = 3139,
+ I_VADDPS = 3131, I_VADDSD = 3155, I_VADDSS = 3147, I_VADDSUBPD = 6414, I_VADDSUBPS = 6425,
+ I_VAESDEC = 9217, I_VAESDECLAST = 9238, I_VAESENC = 9175, I_VAESENCLAST = 9196,
+ I_VAESIMC = 9158, I_VAESKEYGENASSIST = 9812, I_VANDNPD = 3038, I_VANDNPS = 3029,
+ I_VANDPD = 3005, I_VANDPS = 2997, I_VBLENDPD = 9381, I_VBLENDPS = 9362, I_VBLENDVPD = 9681,
+ I_VBLENDVPS = 9670, I_VBROADCASTF128 = 7672, I_VBROADCASTSD = 7658, I_VBROADCASTSS = 7644,
+ I_VCMPEQPD = 5088, I_VCMPEQPS = 4686, I_VCMPEQSD = 5892, I_VCMPEQSS = 5490,
+ I_VCMPEQ_OSPD = 5269, I_VCMPEQ_OSPS = 4867, I_VCMPEQ_OSSD = 6073, I_VCMPEQ_OSSS = 5671,
+ I_VCMPEQ_UQPD = 5175, I_VCMPEQ_UQPS = 4773, I_VCMPEQ_UQSD = 5979, I_VCMPEQ_UQSS = 5577,
+ I_VCMPEQ_USPD = 5378, I_VCMPEQ_USPS = 4976, I_VCMPEQ_USSD = 6182, I_VCMPEQ_USSS = 5780,
+ I_VCMPFALSEPD = 5210, I_VCMPFALSEPS = 4808, I_VCMPFALSESD = 6014, I_VCMPFALSESS = 5612,
+ I_VCMPFALSE_OSPD = 5419, I_VCMPFALSE_OSPS = 5017, I_VCMPFALSE_OSSD = 6223,
+ I_VCMPFALSE_OSSS = 5821, I_VCMPGEPD = 5237, I_VCMPGEPS = 4835, I_VCMPGESD = 6041,
+ I_VCMPGESS = 5639, I_VCMPGE_OQPD = 5449, I_VCMPGE_OQPS = 5047, I_VCMPGE_OQSD = 6253,
+ I_VCMPGE_OQSS = 5851, I_VCMPGTPD = 5247, I_VCMPGTPS = 4845, I_VCMPGTSD = 6051,
+ I_VCMPGTSS = 5649, I_VCMPGT_OQPD = 5462, I_VCMPGT_OQPS = 5060, I_VCMPGT_OQSD = 6266,
+ I_VCMPGT_OQSS = 5864, I_VCMPLEPD = 5108, I_VCMPLEPS = 4706, I_VCMPLESD = 5912,
+ I_VCMPLESS = 5510, I_VCMPLE_OQPD = 5295, I_VCMPLE_OQPS = 4893, I_VCMPLE_OQSD = 6099,
+ I_VCMPLE_OQSS = 5697, I_VCMPLTPD = 5098, I_VCMPLTPS = 4696, I_VCMPLTSD = 5902,
+ I_VCMPLTSS = 5500, I_VCMPLT_OQPD = 5282, I_VCMPLT_OQPS = 4880, I_VCMPLT_OQSD = 6086,
+ I_VCMPLT_OQSS = 5684, I_VCMPNEQPD = 5131, I_VCMPNEQPS = 4729, I_VCMPNEQSD = 5935,
+ I_VCMPNEQSS = 5533, I_VCMPNEQ_OQPD = 5223, I_VCMPNEQ_OQPS = 4821, I_VCMPNEQ_OQSD = 6027,
+ I_VCMPNEQ_OQSS = 5625, I_VCMPNEQ_OSPD = 5435, I_VCMPNEQ_OSPS = 5033, I_VCMPNEQ_OSSD = 6239,
+ I_VCMPNEQ_OSSS = 5837, I_VCMPNEQ_USPD = 5323, I_VCMPNEQ_USPS = 4921, I_VCMPNEQ_USSD = 6127,
+ I_VCMPNEQ_USSS = 5725, I_VCMPNGEPD = 5188, I_VCMPNGEPS = 4786, I_VCMPNGESD = 5992,
+ I_VCMPNGESS = 5590, I_VCMPNGE_UQPD = 5391, I_VCMPNGE_UQPS = 4989, I_VCMPNGE_UQSD = 6195,
+ I_VCMPNGE_UQSS = 5793, I_VCMPNGTPD = 5199, I_VCMPNGTPS = 4797, I_VCMPNGTSD = 6003,
+ I_VCMPNGTSS = 5601, I_VCMPNGT_UQPD = 5405, I_VCMPNGT_UQPS = 5003, I_VCMPNGT_UQSD = 6209,
+ I_VCMPNGT_UQSS = 5807, I_VCMPNLEPD = 5153, I_VCMPNLEPS = 4751, I_VCMPNLESD = 5957,
+ I_VCMPNLESS = 5555, I_VCMPNLE_UQPD = 5351, I_VCMPNLE_UQPS = 4949, I_VCMPNLE_UQSD = 6155,
+ I_VCMPNLE_UQSS = 5753, I_VCMPNLTPD = 5142, I_VCMPNLTPS = 4740, I_VCMPNLTSD = 5946,
+ I_VCMPNLTSS = 5544, I_VCMPNLT_UQPD = 5337, I_VCMPNLT_UQPS = 4935, I_VCMPNLT_UQSD = 6141,
+ I_VCMPNLT_UQSS = 5739, I_VCMPORDPD = 5164, I_VCMPORDPS = 4762, I_VCMPORDSD = 5968,
+ I_VCMPORDSS = 5566, I_VCMPORD_SPD = 5365, I_VCMPORD_SPS = 4963, I_VCMPORD_SSD = 6169,
+ I_VCMPORD_SSS = 5767, I_VCMPTRUEPD = 5257, I_VCMPTRUEPS = 4855, I_VCMPTRUESD = 6061,
+ I_VCMPTRUESS = 5659, I_VCMPTRUE_USPD = 5475, I_VCMPTRUE_USPS = 5073, I_VCMPTRUE_USSD = 6279,
+ I_VCMPTRUE_USSS = 5877, I_VCMPUNORDPD = 5118, I_VCMPUNORDPS = 4716, I_VCMPUNORDSD = 5922,
+ I_VCMPUNORDSS = 5520, I_VCMPUNORD_SPD = 5308, I_VCMPUNORD_SPS = 4906, I_VCMPUNORD_SSD = 6112,
+ I_VCMPUNORD_SSS = 5710, I_VCOMISD = 2796, I_VCOMISS = 2787, I_VCVTDQ2PD = 6819,
+ I_VCVTDQ2PS = 3338, I_VCVTPD2DQ = 6830, I_VCVTPD2PS = 3274, I_VCVTPS2DQ = 3349,
+ I_VCVTPS2PD = 3263, I_VCVTSD2SI = 2722, I_VCVTSD2SS = 3296, I_VCVTSI2SD = 2536,
+ I_VCVTSI2SS = 2525, I_VCVTSS2SD = 3285, I_VCVTSS2SI = 2711, I_VCVTTPD2DQ = 6807,
+ I_VCVTTPS2DQ = 3360, I_VCVTTSD2SI = 2659, I_VCVTTSS2SI = 2647, I_VDIVPD = 3528,
+ I_VDIVPS = 3520, I_VDIVSD = 3544, I_VDIVSS = 3536, I_VDPPD = 9621, I_VDPPS = 9608,
+ I_VERR = 1663, I_VERW = 1669, I_VEXTRACTF128 = 9516, I_VEXTRACTPS = 9491,
+ I_VFMADD132PD = 8387, I_VFMADD132PS = 8374, I_VFMADD132SD = 8413, I_VFMADD132SS = 8400,
+ I_VFMADD213PD = 8667, I_VFMADD213PS = 8654, I_VFMADD213SD = 8693, I_VFMADD213SS = 8680,
+ I_VFMADD231PD = 8947, I_VFMADD231PS = 8934, I_VFMADD231SD = 8973, I_VFMADD231SS = 8960,
+ I_VFMADDSUB132PD = 8326, I_VFMADDSUB132PS = 8310, I_VFMADDSUB213PD = 8606,
+ I_VFMADDSUB213PS = 8590, I_VFMADDSUB231PD = 8886, I_VFMADDSUB231PS = 8870,
+ I_VFMSUB132PD = 8439, I_VFMSUB132PS = 8426, I_VFMSUB132SD = 8465, I_VFMSUB132SS = 8452,
+ I_VFMSUB213PD = 8719, I_VFMSUB213PS = 8706, I_VFMSUB213SD = 8745, I_VFMSUB213SS = 8732,
+ I_VFMSUB231PD = 8999, I_VFMSUB231PS = 8986, I_VFMSUB231SD = 9025, I_VFMSUB231SS = 9012,
+ I_VFMSUBADD132PD = 8358, I_VFMSUBADD132PS = 8342, I_VFMSUBADD213PD = 8638,
+ I_VFMSUBADD213PS = 8622, I_VFMSUBADD231PD = 8918, I_VFMSUBADD231PS = 8902,
+ I_VFNMADD132PD = 8492, I_VFNMADD132PS = 8478, I_VFNMADD132SD = 8520, I_VFNMADD132SS = 8506,
+ I_VFNMADD213PD = 8772, I_VFNMADD213PS = 8758, I_VFNMADD213SD = 8800, I_VFNMADD213SS = 8786,
+ I_VFNMADD231PD = 9052, I_VFNMADD231PS = 9038, I_VFNMADD231SD = 9080, I_VFNMADD231SS = 9066,
+ I_VFNMSUB132PD = 8548, I_VFNMSUB132PS = 8534, I_VFNMSUB132SD = 8576, I_VFNMSUB132SS = 8562,
+ I_VFNMSUB213PD = 8828, I_VFNMSUB213PS = 8814, I_VFNMSUB213SD = 8856, I_VFNMSUB213SS = 8842,
+ I_VFNMSUB231PD = 9108, I_VFNMSUB231PS = 9094, I_VFNMSUB231SD = 9136, I_VFNMSUB231SS = 9122,
+ I_VHADDPD = 4197, I_VHADDPS = 4206, I_VHSUBPD = 4231, I_VHSUBPS = 4240, I_VINSERTF128 = 9503,
+ I_VINSERTPS = 9557, I_VLDDQU = 7001, I_VLDMXCSR = 9941, I_VMASKMOVDQU = 7131,
+ I_VMASKMOVPD = 7949, I_VMASKMOVPS = 7937, I_VMAXPD = 3588, I_VMAXPS = 3580,
+ I_VMAXSD = 3604, I_VMAXSS = 3596, I_VMCALL = 1719, I_VMCLEAR = 9997, I_VMFUNC = 1787,
+ I_VMINPD = 3468, I_VMINPS = 3460, I_VMINSD = 3484, I_VMINSS = 3476, I_VMLAUNCH = 1727,
+ I_VMLOAD = 1811, I_VMMCALL = 1802, I_VMOVAPD = 2476, I_VMOVAPS = 2467, I_VMOVD = 3932,
+ I_VMOVDDUP = 2234, I_VMOVDQA = 3962, I_VMOVDQU = 3971, I_VMOVHLPS = 2195,
+ I_VMOVHPD = 2382, I_VMOVHPS = 2373, I_VMOVLHPS = 2363, I_VMOVLPD = 2214, I_VMOVLPS = 2205,
+ I_VMOVMSKPD = 2836, I_VMOVMSKPS = 2825, I_VMOVNTDQ = 6858, I_VMOVNTDQA = 7905,
+ I_VMOVNTPD = 2593, I_VMOVNTPS = 2583, I_VMOVQ = 3939, I_VMOVSD = 2143, I_VMOVSHDUP = 2391,
+ I_VMOVSLDUP = 2223, I_VMOVSS = 2135, I_VMOVUPD = 2126, I_VMOVUPS = 2117, I_VMPSADBW = 9637,
+ I_VMPTRLD = 9988, I_VMPTRST = 6385, I_VMREAD = 4128, I_VMRESUME = 1737, I_VMRUN = 1795,
+ I_VMSAVE = 1819, I_VMULPD = 3199, I_VMULPS = 3191, I_VMULSD = 3215, I_VMULSS = 3207,
+ I_VMWRITE = 4152, I_VMXOFF = 1747, I_VMXON = 10006, I_VORPD = 3066, I_VORPS = 3059,
+ I_VPABSB = 7695, I_VPABSD = 7725, I_VPABSW = 7710, I_VPACKSSDW = 3859, I_VPACKSSWB = 3691,
+ I_VPACKUSDW = 7926, I_VPACKUSWB = 3769, I_VPADDB = 7211, I_VPADDD = 7241,
+ I_VPADDQ = 6488, I_VPADDSB = 6938, I_VPADDSW = 6955, I_VPADDUSW = 6629, I_VPADDW = 7226,
+ I_VPALIGNR = 9419, I_VPAND = 6613, I_VPANDN = 6672, I_VPAVGB = 6687, I_VPAVGW = 6732,
+ I_VPBLENDVB = 9692, I_VPBLENDW = 9400, I_VPCLMULQDQ = 9658, I_VPCMPEQB = 4052,
+ I_VPCMPEQD = 4090, I_VPCMPEQQ = 7885, I_VPCMPEQW = 4071, I_VPCMPESTRI = 9737,
+ I_VPCMPESTRM = 9714, I_VPCMPGTB = 3711, I_VPCMPGTD = 3749, I_VPCMPGTQ = 8096,
+ I_VPCMPGTW = 3730, I_VPCMPISTRI = 9783, I_VPCMPISTRM = 9760, I_VPERM2F128 = 9265,
+ I_VPERMILPD = 7570, I_VPERMILPS = 7559, I_VPEXTRB = 9437, I_VPEXTRD = 9462,
+ I_VPEXTRQ = 9471, I_VPEXTRW = 6319, I_VPHADDD = 7383, I_VPHADDSW = 7401, I_VPHADDW = 7366,
+ I_VPHMINPOSUW = 8271, I_VPHSUBD = 7459, I_VPHSUBSW = 7477, I_VPHSUBW = 7442,
+ I_VPINSRB = 9538, I_VPINSRD = 9584, I_VPINSRQ = 9593, I_VPINSRW = 6302, I_VPMADDUBSW = 7422,
+ I_VPMADDWD = 7082, I_VPMAXSB = 8182, I_VPMAXSD = 8199, I_VPMAXSW = 6972, I_VPMAXUB = 6656,
+ I_VPMAXUD = 8233, I_VPMAXUW = 8216, I_VPMINSB = 8114, I_VPMINSD = 8131, I_VPMINSW = 6910,
+ I_VPMINUB = 6598, I_VPMINUD = 8165, I_VPMINUW = 8148, I_VPMOVMSKB = 6541,
+ I_VPMOVSXBD = 7764, I_VPMOVSXBQ = 7785, I_VPMOVSXBW = 7743, I_VPMOVSXDQ = 7848,
+ I_VPMOVSXWD = 7806, I_VPMOVSXWQ = 7827, I_VPMOVZXBD = 7992, I_VPMOVZXBQ = 8013,
+ I_VPMOVZXBW = 7971, I_VPMOVZXDQ = 8076, I_VPMOVZXWD = 8034, I_VPMOVZXWQ = 8055,
+ I_VPMULDQ = 7867, I_VPMULHRSW = 7548, I_VPMULHUW = 6749, I_VPMULHW = 6767,
+ I_VPMULLD = 8250, I_VPMULLW = 6504, I_VPMULUDQ = 7063, I_VPOR = 6924, I_VPSADBW = 7100,
+ I_VPSHUFB = 7349, I_VPSHUFD = 4014, I_VPSHUFHW = 4023, I_VPSHUFLW = 4033,
+ I_VPSIGNB = 7495, I_VPSIGND = 7529, I_VPSIGNW = 7512, I_VPSLLD = 7031, I_VPSLLDQ = 9855,
+ I_VPSLLQ = 7046, I_VPSLLW = 7016, I_VPSRAD = 6717, I_VPSRAW = 6702, I_VPSRLD = 6458,
+ I_VPSRLDQ = 9838, I_VPSRLQ = 6473, I_VPSRLW = 6443, I_VPSUBB = 7151, I_VPSUBD = 7181,
+ I_VPSUBQ = 7196, I_VPSUBSB = 6876, I_VPSUBSW = 6893, I_VPSUBUSB = 6561, I_VPSUBUSW = 6580,
+ I_VPSUBW = 7166, I_VPTEST = 7636, I_VPUNPCKHBW = 3791, I_VPUNPCKHDQ = 3837,
+ I_VPUNPCKHQDQ = 3907, I_VPUNPCKHWD = 3814, I_VPUNPCKLBW = 3623, I_VPUNPCKLDQ = 3669,
+ I_VPUNPCKLQDQ = 3882, I_VPUNPCKLWD = 3646, I_VPXOR = 6987, I_VRCPPS = 2967,
+ I_VRCPSS = 2975, I_VROUNDPD = 9305, I_VROUNDPS = 9286, I_VROUNDSD = 9343,
+ I_VROUNDSS = 9324, I_VRSQRTPS = 2933, I_VRSQRTSS = 2943, I_VSHUFPD = 6353,
+ I_VSHUFPS = 6344, I_VSQRTPD = 2888, I_VSQRTPS = 2879, I_VSQRTSD = 2906, I_VSQRTSS = 2897,
+ I_VSTMXCSR = 9970, I_VSUBPD = 3408, I_VSUBPS = 3400, I_VSUBSD = 3424, I_VSUBSS = 3416,
+ I_VTESTPD = 7590, I_VTESTPS = 7581, I_VUCOMISD = 2761, I_VUCOMISS = 2751,
+ I_VUNPCKHPD = 2317, I_VUNPCKHPS = 2306, I_VUNPCKLPD = 2275, I_VUNPCKLPS = 2264,
+ I_VXORPD = 3095, I_VXORPS = 3087, I_VZEROALL = 4118, I_VZEROUPPER = 4106,
+ I_WAIT = 10013, I_WBINVD = 561, I_WRFSBASE = 9931, I_WRGSBASE = 9960, I_WRMSR = 586,
+ I_XADD = 946, I_XCHG = 212, I_XGETBV = 1771, I_XLAT = 400, I_XOR = 61, I_XORPD = 3080,
+ I_XORPS = 3073, I_XRSTOR = 4273, I_XRSTOR64 = 4281, I_XSAVE = 4249, I_XSAVE64 = 4256,
+ I_XSAVEOPT = 4299, I_XSAVEOPT64 = 4309, I_XSETBV = 1779
+} _InstructionType;
+
+typedef enum {
+ R_RAX, R_RCX, R_RDX, R_RBX, R_RSP, R_RBP, R_RSI, R_RDI, R_R8, R_R9, R_R10, R_R11, R_R12, R_R13, R_R14, R_R15,
+ R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI, R_R8D, R_R9D, R_R10D, R_R11D, R_R12D, R_R13D, R_R14D, R_R15D,
+ R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI, R_R8W, R_R9W, R_R10W, R_R11W, R_R12W, R_R13W, R_R14W, R_R15W,
+ R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH, R_R8B, R_R9B, R_R10B, R_R11B, R_R12B, R_R13B, R_R14B, R_R15B,
+ R_SPL, R_BPL, R_SIL, R_DIL,
+ R_ES, R_CS, R_SS, R_DS, R_FS, R_GS,
+ R_RIP,
+ R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7,
+ R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
+ R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7, R_XMM8, R_XMM9, R_XMM10, R_XMM11, R_XMM12, R_XMM13, R_XMM14, R_XMM15,
+ R_YMM0, R_YMM1, R_YMM2, R_YMM3, R_YMM4, R_YMM5, R_YMM6, R_YMM7, R_YMM8, R_YMM9, R_YMM10, R_YMM11, R_YMM12, R_YMM13, R_YMM14, R_YMM15,
+ R_CR0, R_UNUSED0, R_CR2, R_CR3, R_CR4, R_UNUSED1, R_UNUSED2, R_UNUSED3, R_CR8,
+ R_DR0, R_DR1, R_DR2, R_DR3, R_UNUSED4, R_UNUSED5, R_DR6, R_DR7
+} _RegisterType;
+
+#endif /* MNEMONICS_H */
diff --git a/distorm3.2-package/src/config.h b/distorm3.2-package/src/config.h
new file mode 100644
index 0000000..30f7d39
--- /dev/null
+++ b/distorm3.2-package/src/config.h
@@ -0,0 +1,181 @@
+/*
+config.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+/* diStorm version number. */
+#define __DISTORMV__ 0x030200
+
+#include /* memset, memcpy - can be easily self implemented for libc independency. */
+
+#include "../include/distorm.h"
+
+
+/*
+ * 64 bit offsets support:
+ * This macro should be defined from compiler command line flags, e.g: -DSUPPORT_64BIT_OFFSET
+ * Note: make sure that the caller (library user) defines it too!
+ */
+/* #define SUPPORT_64BIT_OFFSET */
+
+/*
+ * If you compile diStorm as a dynamic library (.dll or .so) file, make sure you uncomment the next line.
+ * So the interface functions will be exported, otherwise they are useable only for static library.
+ * For example, this macro is being set for compiling diStorm as a .dll for Python with CTypes.
+ */
+/* #define DISTORM_DYNAMIC */
+
+/*
+ * If DISTORM_LIGHT is defined, everything involved in formatting the instructions
+ * as text will be excluded from compilation.
+ * distorm_decode(..) and distorm_format(..) will not be available.
+ * This will decrease the size of the executable and leave you with decomposition functionality only.
+ *
+ * Note: it should be either set in the preprocessor definitions manually or in command line -D switch.
+ * #define DISTORM_LIGHT
+ */
+
+/*
+ * diStorm now supports little/big endian CPU's.
+ * It should detect the endianness according to predefined macro's of the compiler.
+ * If you don't use GCC/MSVC you will have to define it on your own.
+ */
+
+/* These macros are used in order to make the code portable. */
+#ifdef __GNUC__
+
+#include
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_ static
+/* GCC ignores this directive... */
+/*#define _FASTCALL_ __attribute__((__fastcall__))*/
+
+/* Set endianity (supposed to be LE though): */
+#ifdef __BIG_ENDIAN__
+ #define BE_SYSTEM
+#endif
+
+/* End of __GCC__ */
+
+#elif __WATCOMC__
+
+#include
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_ __inline
+
+/* End of __WATCOMC__ */
+
+#elif __DMC__
+
+#include
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_ __inline
+
+/* End of __DMC__ */
+
+#elif __TINYC__
+
+#include
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_
+
+/* End of __TINYC__ */
+
+#elif _MSC_VER
+
+/* stdint alternative is defined in distorm.h */
+
+#define _DLLEXPORT_ __declspec(dllexport)
+#define _FASTCALL_ __fastcall
+#define _INLINE_ __inline
+
+/* Set endianity (supposed to be LE though): */
+#if !defined(_M_IX86) && !defined(_M_X64)
+ #define BE_SYSTEM
+#endif
+
+#endif /* #elif _MSC_VER */
+
+/* If the library isn't compiled as a dynamic library don't export any functions. */
+#ifndef DISTORM_DYNAMIC
+#undef _DLLEXPORT_
+#define _DLLEXPORT_
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/* Define stream read functions for big endian systems. */
+#ifdef BE_SYSTEM
+/*
+ * These functions can read from the stream safely!
+ * Swap endianity of input to little endian.
+ */
+static _INLINE_ int16_t RSHORT(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8);
+}
+static _INLINE_ uint16_t RUSHORT(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8);
+}
+static _INLINE_ int32_t RLONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
+}
+static _INLINE_ uint32_t RULONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
+}
+static _INLINE_ int64_t RLLONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56);
+}
+static _INLINE_ uint64_t RULLONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56);
+}
+#else
+/* Little endian macro's will just make the cast. */
+#define RSHORT(x) *(int16_t *)x
+#define RUSHORT(x) *(uint16_t *)x
+#define RLONG(x) *(int32_t *)x
+#define RULONG(x) *(uint32_t *)x
+#define RLLONG(x) *(int64_t *)x
+#define RULLONG(x) *(uint64_t *)x
+#endif
+
+#endif /* CONFIG_H */
diff --git a/distorm3.2-package/src/decoder.c b/distorm3.2-package/src/decoder.c
new file mode 100644
index 0000000..8123753
--- /dev/null
+++ b/distorm3.2-package/src/decoder.c
@@ -0,0 +1,606 @@
+/*
+decoder.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "decoder.h"
+#include "instructions.h"
+#include "insts.h"
+#include "prefix.h"
+#include "x86defs.h"
+#include "operands.h"
+#include "../include/mnemonics.h"
+
+
+/* Instruction Prefixes - Opcode - ModR/M - SIB - Displacement - Immediate */
+
+static _DecodeType decode_get_effective_addr_size(_DecodeType dt, _iflags decodedPrefixes)
+{
+ /*
+ * This table is to map from the current decoding mode to an effective address size:
+ * Decode16 -> Decode32
+ * Decode32 -> Decode16
+ * Decode64 -> Decode32
+ */
+ static _DecodeType AddrSizeTable[] = {Decode32Bits, Decode16Bits, Decode32Bits};
+
+ /* Switch to non default mode if prefix exists, only for ADDRESS SIZE. */
+ if (decodedPrefixes & INST_PRE_ADDR_SIZE) dt = AddrSizeTable[dt];
+ return dt;
+}
+
+static _DecodeType decode_get_effective_op_size(_DecodeType dt, _iflags decodedPrefixes, unsigned int rex, _iflags instFlags)
+{
+ /*
+ * This table is to map from the current decoding mode to an effective operand size:
+ * Decode16 -> Decode32
+ * Decode32 -> Decode16
+ * Decode64 -> Decode16
+ * Not that in 64bits it's a bit more complicated, because of REX and promoted instructions.
+ */
+ static _DecodeType OpSizeTable[] = {Decode32Bits, Decode16Bits, Decode16Bits};
+
+ if (decodedPrefixes & INST_PRE_OP_SIZE) return OpSizeTable[dt];
+
+ if (dt == Decode64Bits) {
+ /*
+ * REX Prefix toggles data size to 64 bits.
+ * Operand size prefix toggles data size to 16.
+ * Default data size is 32 bits.
+ * Promoted instructions are 64 bits if they don't require a REX perfix.
+ * Non promoted instructions are 64 bits if the REX prefix exists.
+ */
+ /* Automatically promoted instructions have only INST_64BITS SET! */
+ if (((instFlags & (INST_64BITS | INST_PRE_REX)) == INST_64BITS) ||
+ /* Other instructions in 64 bits can be promoted only with a REX prefix. */
+ ((decodedPrefixes & INST_PRE_REX) && (rex & PREFIX_EX_W))) dt = Decode64Bits;
+ else dt = Decode32Bits; /* Default. */
+ }
+ return dt;
+}
+
+static _DecodeResult decode_inst(_CodeInfo* ci, _PrefixState* ps, _DInst* di)
+{
+ /* The ModR/M byte of the current instruction. */
+ unsigned int modrm = 0;
+
+ /* The REX/VEX prefix byte value. */
+ unsigned int vrex = ps->vrex;
+
+ /*
+ * Backup original input, so we can use it later if a problem occurs
+ * (like not enough data for decoding, invalid opcode, etc).
+ */
+ const uint8_t* startCode = ci->code;
+
+ /* Holds the info about the current found instruction. */
+ _InstInfo* ii = NULL;
+
+ /* Used only for special CMP instructions which have pseudo opcodes suffix. */
+ unsigned char cmpType = 0;
+
+ /*
+ * Indicates whether it is right to LOCK the instruction by decoding its first operand.
+ * Only then you know if it's ok to output the LOCK prefix's text...
+ * Used for first operand only.
+ */
+ int lockable = FALSE;
+
+ /* Calcualte (and cache) effective-operand-size and effective-address-size only once. */
+ _DecodeType effOpSz, effAdrSz;
+ _iflags instFlags;
+
+ ii = inst_lookup(ci, ps);
+ if (ii == NULL) goto _Undecodable;
+ instFlags = INST_INFO_FLAGS(ii);
+
+ /*
+ * If both REX and OpSize are available we will have to disable the OpSize, because REX has precedence.
+ * However, only if REX.W is set !
+ * We had to wait with this test, since the operand size may be a mandatory prefix,
+ * and we know it only after prefetching.
+ */
+ if ((ps->prefixExtType == PET_REX) &&
+ (ps->decodedPrefixes & INST_PRE_OP_SIZE) &&
+ (!ps->isOpSizeMandatory) &&
+ (vrex & PREFIX_EX_W)) {
+ ps->decodedPrefixes &= ~INST_PRE_OP_SIZE;
+ prefixes_ignore(ps, PFXIDX_OP_SIZE);
+ }
+
+ /*
+ * In this point we know the instruction we are about to decode and its operands (unless, it's an invalid one!),
+ * so it makes it the right time for decoding-type suitability testing.
+ * Which practically means, don't allow 32 bits instructions in 16 bits decoding mode, but do allow
+ * 16 bits instructions in 32 bits decoding mode, of course...
+
+ * NOTE: Make sure the instruction set for 32 bits has explicitly this specfic flag set.
+ * NOTE2: Make sure the instruction set for 64 bits has explicitly this specfic flag set.
+
+ * If this is the case, drop what we've got and restart all over after DB'ing that byte.
+
+ * Though, don't drop an instruction which is also supported in 16 and 32 bits.
+ */
+
+ /* ! ! ! DISABLED UNTIL FURTHER NOTICE ! ! ! Decode16Bits CAN NOW DECODE 32 BITS INSTRUCTIONS ! ! !*/
+ /* if (ii && (dt == Decode16Bits) && (instFlags & INST_32BITS) && (~instFlags & INST_16BITS)) ii = NULL; */
+
+ /* Drop instructions which are invalid in 64 bits. */
+ if ((ci->dt == Decode64Bits) && (instFlags & INST_INVALID_64BITS)) goto _Undecodable;
+
+ /* If it's only a 64 bits instruction drop it in other decoding modes. */
+ if ((ci->dt != Decode64Bits) && (instFlags & INST_64BITS_FETCH)) goto _Undecodable;
+
+ if (instFlags & INST_MODRM_REQUIRED) {
+ /* If the ModRM byte is not part of the opcode, skip the last byte code, so code points now to ModRM. */
+ if (~instFlags & INST_MODRM_INCLUDED) {
+ ci->code++;
+ if (--ci->codeLen < 0) goto _Undecodable;
+ }
+ modrm = *ci->code;
+
+ /* Some instructions enforce that reg=000, so validate that. (Specifically EXTRQ). */
+ if ((instFlags & INST_FORCE_REG0) && (((modrm >> 3) & 7) != 0)) goto _Undecodable;
+ /* Some instructions enforce that mod=11, so validate that. */
+ if ((instFlags & INST_MODRR_REQUIRED) && (modrm < INST_DIVIDED_MODRM)) goto _Undecodable;
+ }
+
+ ci->code++; /* Skip the last byte we just read (either last opcode's byte code or a ModRM). */
+
+ /* Cache the effective operand-size and address-size. */
+ effOpSz = decode_get_effective_op_size(ci->dt, ps->decodedPrefixes, vrex, instFlags);
+ effAdrSz = decode_get_effective_addr_size(ci->dt, ps->decodedPrefixes);
+
+ memset(di, 0, sizeof(_DInst));
+ di->base = R_NONE;
+
+ /*
+ * Try to extract the next operand only if the latter exists.
+ * For example, if there is not first operand, no reason to try to extract second operand...
+ * I decided that a for-break is better for readability in this specific case than goto.
+ * Note: do-while with a constant 0 makes the compiler warning about it.
+ */
+ for (;;) {
+ if (ii->d != OT_NONE) {
+ if (!operands_extract(ci, di, ii, (_OpType)ii->d, ONT_1, modrm, ps, effOpSz, effAdrSz, &lockable)) goto _Undecodable;
+ } else break;
+
+ if (ii->s != OT_NONE) {
+ if (!operands_extract(ci, di, ii, (_OpType)ii->s, ONT_2, modrm, ps, effOpSz, effAdrSz, NULL)) goto _Undecodable;
+ } else break;
+
+ /* Use third operand, only if the flags says this InstInfo requires it. */
+ if (instFlags & INST_USE_OP3) {
+ if (!operands_extract(ci, di, ii, (_OpType)((_InstInfoEx*)ii)->op3, ONT_3, modrm, ps, effOpSz, effAdrSz, NULL)) goto _Undecodable;
+ } else break;
+
+ /* Support for a fourth operand is added for (i.e:) INSERTQ instruction. */
+ if (instFlags & INST_USE_OP4) {
+ if (!operands_extract(ci, di, ii, (_OpType)((_InstInfoEx*)ii)->op4, ONT_4, modrm, ps, effOpSz, effAdrSz, NULL)) goto _Undecodable;
+ }
+ break;
+ } /* Continue here after all operands were extracted. */
+
+ /* If it were a 3DNow! instruction, we will have to find the instruction itself now that we got its operands extracted. */
+ if (instFlags & INST_3DNOW_FETCH) {
+ ii = inst_lookup_3dnow(ci);
+ if (ii == NULL) goto _Undecodable;
+ instFlags = INST_INFO_FLAGS(ii);
+ }
+
+ /* Check whether pseudo opcode is needed, only for CMP instructions: */
+ if (instFlags & INST_PSEUDO_OPCODE) {
+ if (--ci->codeLen < 0) goto _Undecodable;
+ cmpType = *ci->code;
+ ci->code++;
+ if (instFlags & INST_PRE_VEX) {
+ /* AVX Comparison type must be between 0 to 32, otherwise Reserved. */
+ if (cmpType >= INST_VCMP_MAX_RANGE) goto _Undecodable;
+ } else {
+ /* SSE Comparison type must be between 0 to 8, otherwise Reserved. */
+ if (cmpType >= INST_CMP_MAX_RANGE) goto _Undecodable;
+ }
+ }
+
+ /*
+ * There's a limit of 15 bytes on instruction length. The only way to violate
+ * this limit is by putting redundant prefixes before an instruction.
+ * start points to first prefix if any, otherwise it points to instruction first byte.
+ */
+ if ((ci->code - ps->start) > INST_MAXIMUM_SIZE) goto _Undecodable; /* Drop instruction. */
+
+ /*
+ * If we reached here the instruction was fully decoded, we located the instruction in the DB and extracted operands.
+ * Use the correct mnemonic according to the DT.
+ * If we are in 32 bits decoding mode it doesn't necessarily mean we will choose mnemonic2, alas,
+ * it means that if there is a mnemonic2, it will be used.
+ */
+
+ /* Start with prefix LOCK. */
+ if ((lockable == TRUE) && (instFlags & INST_PRE_LOCK)) {
+ ps->usedPrefixes |= INST_PRE_LOCK;
+ di->flags |= FLAG_LOCK;
+ } else if ((instFlags & INST_PRE_REPNZ) && (ps->decodedPrefixes & INST_PRE_REPNZ)) {
+ ps->usedPrefixes |= INST_PRE_REPNZ;
+ di->flags |= FLAG_REPNZ;
+ } else if ((instFlags & INST_PRE_REP) && (ps->decodedPrefixes & INST_PRE_REP)) {
+ ps->usedPrefixes |= INST_PRE_REP;
+ di->flags |= FLAG_REP;
+ }
+
+ /* If it's JeCXZ the ADDR_SIZE prefix affects them. */
+ if ((instFlags & (INST_PRE_ADDR_SIZE | INST_USE_EXMNEMONIC)) == (INST_PRE_ADDR_SIZE | INST_USE_EXMNEMONIC)) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ if (effAdrSz == Decode16Bits) di->opcode = ii->opcodeId;
+ else if (effAdrSz == Decode32Bits) di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ /* Ignore REX.W in 64bits, JECXZ is promoted. */
+ else /* Decode64Bits */ di->opcode = ((_InstInfoEx*)ii)->opcodeId3;
+ }
+
+ /* LOOPxx instructions are also native instruction, but they are special case ones, ADDR_SIZE prefix affects them. */
+ else if ((instFlags & (INST_PRE_ADDR_SIZE | INST_NATIVE)) == (INST_PRE_ADDR_SIZE | INST_NATIVE)) {
+ di->opcode = ii->opcodeId;
+
+ /* If LOOPxx gets here from 64bits, it must be Decode32Bits because Address Size perfix is set. */
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ }
+ /*
+ * Note:
+ * If the instruction is prefixed by operand size we will format it in the non-default decoding mode!
+ * So there might be a situation that an instruction of 32 bit gets formatted in 16 bits decoding mode.
+ * Both ways should end up with a correct and expected formatting of the text.
+ */
+ else if (effOpSz == Decode16Bits) { /* Decode16Bits */
+
+ /* Set operand size. */
+ FLAG_SET_OPSIZE(di, Decode16Bits);
+
+ /*
+ * If it's a special instruction which has two mnemonics, then use the 16 bits one + update usedPrefixes.
+ * Note: use 16 bits mnemonic if that instruction supports 32 bit or 64 bit explicitly.
+ */
+ if ((instFlags & INST_USE_EXMNEMONIC) && ((instFlags & (INST_32BITS | INST_64BITS)) == 0)) ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ di->opcode = ii->opcodeId;
+ } else if (effOpSz == Decode32Bits) { /* Decode32Bits */
+
+ /* Set operand size. */
+ FLAG_SET_OPSIZE(di, Decode32Bits);
+
+ /* Give a chance for special mnemonic instruction in 32 bits decoding. */
+ if (instFlags & INST_USE_EXMNEMONIC) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* Is it a special instruction which has another mnemonic for mod=11 ? */
+ if (instFlags & INST_MNEMONIC_MODRM_BASED) {
+ if (modrm >= INST_DIVIDED_MODRM) di->opcode = ii->opcodeId;
+ else di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ } else di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ } else di->opcode = ii->opcodeId;
+ } else { /* Decode64Bits, note that some instructions might be decoded in Decode32Bits above. */
+
+ /* Set operand size. */
+ FLAG_SET_OPSIZE(di, Decode64Bits);
+
+ if (instFlags & (INST_USE_EXMNEMONIC | INST_USE_EXMNEMONIC2)) {
+ /*
+ * We shouldn't be here for MODRM based mnemonics with a MOD=11,
+ * because they must not use REX (otherwise it will get to the wrong instruction which share same opcode).
+ * See XRSTOR and XSAVEOPT.
+ */
+ if ((instFlags & INST_MNEMONIC_MODRM_BASED) && (modrm >= INST_DIVIDED_MODRM)) goto _Undecodable;
+
+ /* Use third mnemonic, for 64 bits. */
+ if ((instFlags & INST_USE_EXMNEMONIC2) && (vrex & PREFIX_EX_W)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ di->opcode = ((_InstInfoEx*)ii)->opcodeId3;
+ } else di->opcode = ((_InstInfoEx*)ii)->opcodeId2; /* Use second mnemonic. */
+ } else di->opcode = ii->opcodeId;
+ }
+
+ /* If it's a native instruction use OpSize Prefix. */
+ if ((instFlags & INST_NATIVE) && (ps->decodedPrefixes & INST_PRE_OP_SIZE)) ps->usedPrefixes |= INST_PRE_OP_SIZE;
+
+ /* Check VEX mnemonics: */
+ if ((instFlags & INST_PRE_VEX) &&
+ (((((_InstInfoEx*)ii)->flagsEx & INST_MNEMONIC_VEXW_BASED) && (vrex & PREFIX_EX_W)) ||
+ ((((_InstInfoEx*)ii)->flagsEx & INST_MNEMONIC_VEXL_BASED) && (vrex & PREFIX_EX_L)))) {
+ di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ }
+
+ /* Or is it a special CMP instruction which needs a pseudo opcode suffix ? */
+ if (instFlags & INST_PSEUDO_OPCODE) {
+ /*
+ * The opcodeId is the offset to the FIRST pseudo compare mnemonic,
+ * we will have to fix it so it offsets into the corrected mnemonic.
+ * Therefore, we use another table to fix the offset.
+ */
+ if (instFlags & INST_PRE_VEX) {
+ /* Use the AVX pesudo compare mnemonics table. */
+ di->opcode = ii->opcodeId + VCmpMnemonicOffsets[cmpType];
+ } else {
+ /* Use the SSE psuedo compare mnemonics table. */
+ di->opcode = ii->opcodeId + CmpMnemonicOffsets[cmpType];
+ }
+ }
+
+ /*
+ * Store the address size inside the flags.
+ * This is necessary for the caller to know the size of rSP when using PUSHA for example.
+ */
+ FLAG_SET_ADDRSIZE(di, effAdrSz);
+
+ /* Copy DST_WR flag. */
+ if (instFlags & INST_DST_WR) di->flags |= FLAG_DST_WR;
+
+ /* Set the unused prefixes mask. */
+ di->unusedPrefixesMask = prefixes_set_unused_mask(ps);
+
+ /* Copy instruction meta. */
+ di->meta = ii->meta;
+ if (di->segment == 0) di->segment = R_NONE;
+
+ /* Take into account the O_MEM base register for the mask. */
+ if (di->base != R_NONE) di->usedRegistersMask |= _REGISTERTORCLASS[di->base];
+
+ /* Calculate the size of the instruction we've just decoded. */
+ di->size = (uint8_t)((ci->code - startCode) & 0xff);
+ return DECRES_SUCCESS;
+
+_Undecodable: /* If the instruction couldn't be decoded for some reason, drop the first byte. */
+ memset(di, 0, sizeof(_DInst));
+ di->base = R_NONE;
+
+ di->size = 1;
+ /* Clean prefixes just in case... */
+ ps->usedPrefixes = 0;
+
+ /* Special case for WAIT instruction: If it's dropped, you have to return a valid instruction! */
+ if (*startCode == INST_WAIT_INDEX) {
+ di->opcode = I_WAIT;
+ META_SET_ISC(di, ISC_INTEGER);
+ return DECRES_SUCCESS;
+ }
+
+ /* Mark that we didn't manage to decode the instruction well, caller will drop it. */
+ return DECRES_INPUTERR;
+}
+
+/*
+ * decode_internal
+ *
+ * supportOldIntr - Since now we work with new structure instead of the old _DecodedInst, we are still interested in backward compatibility.
+ * So although, the array is now of type _DInst, we want to read it in jumps of the old array element's size.
+ * This is in order to save memory allocation for conversion between the new and the old structures.
+ * It really means we can do the conversion in-place now.
+ */
+_DecodeResult decode_internal(_CodeInfo* _ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount)
+{
+ _PrefixState ps;
+ unsigned int prefixSize;
+ _CodeInfo ci;
+
+ _OffsetType codeOffset = _ci->codeOffset;
+ const uint8_t* code = _ci->code;
+ int codeLen = _ci->codeLen;
+
+ /*
+ * This is used for printing only, it is the real offset of where the whole instruction begins.
+ * We need this variable in addition to codeOffset, because prefixes might change the real offset an instruction begins at.
+ * So we keep track of both.
+ */
+ _OffsetType startInstOffset = 0;
+
+ const uint8_t* p;
+
+ /* Current working decoded instruction in results. */
+ unsigned int nextPos = 0;
+ _DInst *pdi = NULL;
+
+ _OffsetType addrMask = (_OffsetType)-1;
+
+ _DecodeResult decodeResult;
+
+#ifdef DISTORM_LIGHT
+ supportOldIntr; /* Unreferenced. */
+#endif
+
+ if (_ci->features & DF_MAXIMUM_ADDR32) addrMask = 0xffffffff;
+ else if (_ci->features & DF_MAXIMUM_ADDR16) addrMask = 0xffff;
+
+ /* No entries are used yet. */
+ *usedInstructionsCount = 0;
+ ci.dt = _ci->dt;
+ _ci->nextOffset = codeOffset;
+
+ /* Decode instructions as long as we have what to decode/enough room in entries. */
+ while (codeLen > 0) {
+
+ /* startInstOffset holds the displayed offset of current instruction. */
+ startInstOffset = codeOffset;
+
+ memset(&ps, 0, (size_t)((char*)&ps.pfxIndexer[0] - (char*)&ps));
+ memset(ps.pfxIndexer, PFXIDX_NONE, sizeof(int) * PFXIDX_MAX);
+ ps.start = code;
+ ps.last = code;
+ prefixSize = 0;
+
+ if (prefixes_is_valid(*code, ci.dt)) {
+ prefixes_decode(code, codeLen, &ps, ci.dt);
+ /* Count prefixes, start points to first prefix. */
+ prefixSize = (unsigned int)(ps.last - ps.start);
+ /*
+ * It might be that we will just notice that we ran out of bytes, or only prefixes
+ * so we will have to drop everything and halt.
+ * Also take into consideration of flow control instruction filter.
+ */
+ codeLen -= prefixSize;
+ if ((codeLen == 0) || (prefixSize == INST_MAXIMUM_SIZE)) {
+ if (~_ci->features & DF_RETURN_FC_ONLY) {
+ /* Make sure there is enough room. */
+ if (nextPos + (ps.last - code) > maxResultCount) return DECRES_MEMORYERR;
+
+ for (p = code; p < ps.last; p++, startInstOffset++) {
+ /* Use next entry. */
+#ifndef DISTORM_LIGHT
+ if (supportOldIntr) {
+ pdi = (_DInst*)((char*)result + nextPos * sizeof(_DecodedInst));
+ }
+ else
+#endif /* DISTORM_LIGHT */
+ {
+ pdi = &result[nextPos];
+ }
+ nextPos++;
+ memset(pdi, 0, sizeof(_DInst));
+
+ pdi->flags = FLAG_NOT_DECODABLE;
+ pdi->imm.byte = *p;
+ pdi->size = 1;
+ pdi->addr = startInstOffset & addrMask;
+ }
+ *usedInstructionsCount = nextPos; /* Include them all. */
+ }
+ if (codeLen == 0) break; /* Bye bye, out of bytes. */
+ }
+ code += prefixSize;
+ codeOffset += prefixSize;
+
+ /* If we got only prefixes continue to next instruction. */
+ if (prefixSize == INST_MAXIMUM_SIZE) continue;
+ }
+
+ /*
+ * Now we decode the instruction and only then we do further prefixes handling.
+ * This is because the instruction could not be decoded at all, or an instruction requires
+ * a mandatory prefix, or some of the prefixes were useless, etc...
+
+ * Even if there were a mandatory prefix, we already took into account its size as a normal prefix.
+ * so prefixSize includes that, and the returned size in pdi is simply the size of the real(=without prefixes) instruction.
+ */
+ if (ci.dt == Decode64Bits) {
+ if (ps.decodedPrefixes & INST_PRE_REX) {
+ /* REX prefix must precede first byte of instruction. */
+ if (ps.rexPos != (code - 1)) {
+ ps.decodedPrefixes &= ~INST_PRE_REX;
+ ps.prefixExtType = PET_NONE;
+ prefixes_ignore(&ps, PFXIDX_REX);
+ }
+ /*
+ * We will disable operand size prefix,
+ * if it exists only after decoding the instruction, since it might be a mandatory prefix.
+ * This will be done after calling inst_lookup in decode_inst.
+ */
+ }
+ /* In 64 bits, segment overrides of CS, DS, ES and SS are ignored. So don't take'em into account. */
+ if (ps.decodedPrefixes & INST_PRE_SEGOVRD_MASK32) {
+ ps.decodedPrefixes &= ~INST_PRE_SEGOVRD_MASK32;
+ prefixes_ignore(&ps, PFXIDX_SEG);
+ }
+ }
+
+ /* Make sure there is at least one more entry to use, for the upcoming instruction. */
+ if (nextPos + 1 > maxResultCount) return DECRES_MEMORYERR;
+#ifndef DISTORM_LIGHT
+ if (supportOldIntr) {
+ pdi = (_DInst*)((char*)result + nextPos * sizeof(_DecodedInst));
+ }
+ else
+#endif /* DISTORM_LIGHT */
+ {
+ pdi = &result[nextPos];
+ }
+ nextPos++;
+
+ /*
+ * The reason we copy these two again is because we have to keep track on the input ourselves.
+ * There might be a case when an instruction is invalid, and then it will be counted as one byte only.
+ * But that instruction already read a byte or two from the stream and only then returned the error.
+ * Thus, we end up unsynchronized on the stream.
+ * This way, we are totally safe, because we keep track after the call to decode_inst, using the returned size.
+ */
+ ci.code = code;
+ ci.codeLen = codeLen;
+ /* Nobody uses codeOffset in the decoder itself, so spare it. */
+
+ decodeResult = decode_inst(&ci, &ps, pdi);
+
+ /* See if we need to filter this instruction. */
+ if ((_ci->features & DF_RETURN_FC_ONLY) && (META_GET_FC(pdi->meta) == FC_NONE)) decodeResult = DECRES_FILTERED;
+
+ /* Set address to the beginning of the instruction. */
+ pdi->addr = startInstOffset & addrMask;
+ /* pdi->disp &= addrMask; */
+
+ /* Advance to next instruction. */
+ codeLen -= pdi->size;
+ codeOffset += pdi->size;
+ code += pdi->size;
+
+ /* Instruction's size should include prefixes. */
+ pdi->size += (uint8_t)prefixSize;
+
+ /* Drop all prefixes and the instruction itself, because the instruction wasn't successfully decoded. */
+ if ((decodeResult == DECRES_INPUTERR) && (~_ci->features & DF_RETURN_FC_ONLY)) {
+ nextPos--; /* Undo last result. */
+ if ((prefixSize + 1) > 0) { /* 1 for the first instruction's byte. */
+ if ((nextPos + prefixSize + 1) > maxResultCount) return DECRES_MEMORYERR;
+
+ for (p = ps.start; p < ps.last + 1; p++, startInstOffset++) {
+ /* Use next entry. */
+#ifndef DISTORM_LIGHT
+ if (supportOldIntr) {
+ pdi = (_DInst*)((char*)result + nextPos * sizeof(_DecodedInst));
+ }
+ else
+#endif /* DISTORM_LIGHT */
+ {
+ pdi = &result[nextPos];
+ }
+ nextPos++;
+
+ memset(pdi, 0, sizeof(_DInst));
+ pdi->flags = FLAG_NOT_DECODABLE;
+ pdi->imm.byte = *p;
+ pdi->size = 1;
+ pdi->addr = startInstOffset & addrMask;
+ }
+ }
+ } else if (decodeResult == DECRES_FILTERED) nextPos--; /* Return it to pool, since it was filtered. */
+
+ /* Alright, the caller can read, at least, up to this one. */
+ *usedInstructionsCount = nextPos;
+ /* Fix next offset. */
+ _ci->nextOffset = codeOffset;
+
+ /* Check whether we need to stop on any flow control instruction. */
+ if ((decodeResult == DECRES_SUCCESS) && (_ci->features & DF_STOP_ON_FLOW_CONTROL)) {
+ if (((_ci->features & DF_STOP_ON_CALL) && (META_GET_FC(pdi->meta) == FC_CALL)) ||
+ ((_ci->features & DF_STOP_ON_RET) && (META_GET_FC(pdi->meta) == FC_RET)) ||
+ ((_ci->features & DF_STOP_ON_SYS) && (META_GET_FC(pdi->meta) == FC_SYS)) ||
+ ((_ci->features & DF_STOP_ON_UNC_BRANCH) && (META_GET_FC(pdi->meta) == FC_UNC_BRANCH)) ||
+ ((_ci->features & DF_STOP_ON_CND_BRANCH) && (META_GET_FC(pdi->meta) == FC_CND_BRANCH)) ||
+ ((_ci->features & DF_STOP_ON_INT) && (META_GET_FC(pdi->meta) == FC_INT)) ||
+ ((_ci->features & DF_STOP_ON_CMOV) && (META_GET_FC(pdi->meta) == FC_CMOV)))
+ return DECRES_SUCCESS;
+ }
+ }
+
+ return DECRES_SUCCESS;
+}
diff --git a/distorm3.2-package/src/decoder.h b/distorm3.2-package/src/decoder.h
new file mode 100644
index 0000000..2f9961a
--- /dev/null
+++ b/distorm3.2-package/src/decoder.h
@@ -0,0 +1,33 @@
+/*
+decoder.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2011 Gil Dabah
+
+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
+*/
+
+
+#ifndef DECODER_H
+#define DECODER_H
+
+#include "config.h"
+
+typedef unsigned int _iflags;
+
+_DecodeResult decode_internal(_CodeInfo* ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount);
+
+#endif /* DECODER_H */
diff --git a/distorm3.2-package/src/distorm.c b/distorm3.2-package/src/distorm.c
new file mode 100644
index 0000000..2b865a6
--- /dev/null
+++ b/distorm3.2-package/src/distorm.c
@@ -0,0 +1,384 @@
+/*
+distorm.c
+
+diStorm3 C Library Interface
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "../include/distorm.h"
+#include "config.h"
+#include "decoder.h"
+#include "x86defs.h"
+#include "textdefs.h"
+#include "wstring.h"
+#include "../include/mnemonics.h"
+
+/* C DLL EXPORTS */
+#ifdef SUPPORT_64BIT_OFFSET
+ _DLLEXPORT_ _DecodeResult distorm_decompose64(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#else
+ _DLLEXPORT_ _DecodeResult distorm_decompose32(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#endif
+{
+ if (usedInstructionsCount == NULL) {
+ return DECRES_SUCCESS;
+ }
+
+ /* DECRES_SUCCESS still may indicate we may have something in the result, so zero it first thing. */
+ *usedInstructionsCount = 0;
+
+ if ((ci == NULL) ||
+ (ci->codeLen < 0) ||
+ ((ci->dt != Decode16Bits) && (ci->dt != Decode32Bits) && (ci->dt != Decode64Bits)) ||
+ (ci->code == NULL) ||
+ (result == NULL) ||
+ ((ci->features & (DF_MAXIMUM_ADDR16 | DF_MAXIMUM_ADDR32)) == (DF_MAXIMUM_ADDR16 | DF_MAXIMUM_ADDR32)))
+ {
+ return DECRES_INPUTERR;
+ }
+
+ /* Assume length=0 is success. */
+ if (ci->codeLen == 0) {
+ return DECRES_SUCCESS;
+ }
+
+ return decode_internal(ci, FALSE, result, maxInstructions, usedInstructionsCount);
+}
+
+#ifndef DISTORM_LIGHT
+
+/* Helper function to concat an explicit size when it's unknown from the operands. */
+static void distorm_format_size(_WString* str, const _DInst* di, int opNum)
+{
+ /*
+ * We only have to output the size explicitly if it's not clear from the operands.
+ * For example:
+ * mov al, [0x1234] -> The size is 8, we know it from the AL register operand.
+ * mov [0x1234], 0x11 -> Now we don't know the size. Pam pam pam
+ *
+ * If given operand number is higher than 2, then output the size anyways.
+ */
+ if (((opNum >= 2) || ((di->ops[0].type != O_REG) && (di->ops[1].type != O_REG))) ||
+ /* INS/OUTS are exception, because DX is a port specifier and not a real src/dst register. */
+ ((di->opcode == I_INS) || (di->opcode == I_OUTS))) {
+ switch (di->ops[opNum].size)
+ {
+ case 0: break; /* OT_MEM's unknown size. */
+ case 8: strcat_WSN(str, "BYTE "); break;
+ case 16: strcat_WSN(str, "WORD "); break;
+ case 32: strcat_WSN(str, "DWORD "); break;
+ case 64: strcat_WSN(str, "QWORD "); break;
+ case 80: strcat_WSN(str, "TBYTE "); break;
+ case 128: strcat_WSN(str, "DQWORD "); break;
+ case 256: strcat_WSN(str, "YWORD "); break;
+ default: /* Big oh uh if it gets here. */ break;
+ }
+ }
+}
+
+static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t addrMask)
+{
+ int64_t tmpDisp64;
+
+ if (di->dispSize) {
+ chrcat_WS(str, ((int64_t)di->disp < 0) ? MINUS_DISP_CHR : PLUS_DISP_CHR);
+ if ((int64_t)di->disp < 0) tmpDisp64 = -(int64_t)di->disp;
+ else tmpDisp64 = di->disp;
+ tmpDisp64 &= addrMask;
+ str_code_hqw(str, (uint8_t*)&tmpDisp64);
+ }
+}
+
+#ifdef SUPPORT_64BIT_OFFSET
+ _DLLEXPORT_ void distorm_format64(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result)
+#else
+ _DLLEXPORT_ void distorm_format32(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result)
+#endif
+{
+ _WString* str;
+ unsigned int i, isDefault;
+ int64_t tmpDisp64;
+ uint64_t addrMask = (uint64_t)-1;
+ uint8_t segment;
+ const _WMnemonic* mnemonic;
+
+ /* Set address mask, when default is for 64bits addresses. */
+ if (ci->features & DF_MAXIMUM_ADDR32) addrMask = 0xffffffff;
+ else if (ci->features & DF_MAXIMUM_ADDR16) addrMask = 0xffff;
+
+ /* Copy other fields. */
+ result->size = di->size;
+ result->offset = di->addr & addrMask;
+
+ if (di->flags == FLAG_NOT_DECODABLE) {
+ str = &result->mnemonic;
+ strclear_WS(&result->operands);
+ strcpy_WSN(str, "DB ");
+ str_code_hb(str, di->imm.byte);
+ strclear_WS(&result->instructionHex);
+ str_hex_b(&result->instructionHex, di->imm.byte);
+ return; /* Skip to next instruction. */
+ }
+
+ str = &result->instructionHex;
+ strclear_WS(str);
+ for (i = 0; i < di->size; i++)
+ str_hex_b(str, ci->code[(unsigned int)(di->addr - ci->codeOffset + i)]);
+
+ str = &result->mnemonic;
+ switch (FLAG_GET_PREFIX(di->flags))
+ {
+ case FLAG_LOCK:
+ strcpy_WSN(str, "LOCK ");
+ break;
+ case FLAG_REP:
+ strcpy_WSN(str, "REP ");
+ break;
+ case FLAG_REPNZ:
+ strcpy_WSN(str, "REPNZ ");
+ break;
+ default:
+ /* Init mnemonic string, cause next touch is concatenation. */
+ strclear_WS(str);
+ break;
+ }
+
+ mnemonic = (const _WMnemonic*)&_MNEMONICS[di->opcode];
+ memcpy((int8_t*)&str->p[str->length], mnemonic->p, mnemonic->length + 1);
+ str->length += mnemonic->length;
+
+ /* Format operands: */
+ str = &result->operands;
+ strclear_WS(str);
+
+ /* Special treatment for String instructions. */
+ if ((META_GET_ISC(di->meta) == ISC_INTEGER) &&
+ ((di->opcode == I_MOVS) ||
+ (di->opcode == I_CMPS) ||
+ (di->opcode == I_STOS) ||
+ (di->opcode == I_LODS) ||
+ (di->opcode == I_SCAS)))
+ {
+ /*
+ * No operands are needed if the address size is the default one,
+ * and no segment is overridden, so add the suffix letter,
+ * to indicate size of operation and continue to next instruction.
+ */
+ if ((FLAG_GET_ADDRSIZE(di->flags) == ci->dt) && (SEGMENT_IS_DEFAULT(di->segment))) {
+ str = &result->mnemonic;
+ switch (di->ops[0].size)
+ {
+ case 8: chrcat_WS(str, 'B'); break;
+ case 16: chrcat_WS(str, 'W'); break;
+ case 32: chrcat_WS(str, 'D'); break;
+ case 64: chrcat_WS(str, 'Q'); break;
+ }
+ return;
+ }
+ }
+
+ for (i = 0; ((i < OPERANDS_NO) && (di->ops[i].type != O_NONE)); i++) {
+ if (i > 0) strcat_WSN(str, ", ");
+ switch (di->ops[i].type)
+ {
+ case O_REG:
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->ops[i].index]);
+ break;
+ case O_IMM:
+ /* If the instruction is 'push', show explicit size (except byte imm). */
+ if (di->opcode == I_PUSH && di->ops[i].size != 8) distorm_format_size(str, di, i);
+ /* Special fix for negative sign extended immediates. */
+ if ((di->flags & FLAG_IMM_SIGNED) && (di->ops[i].size == 8)) {
+ if (di->imm.sbyte < 0) {
+ chrcat_WS(str, MINUS_DISP_CHR);
+ str_code_hb(str, -di->imm.sbyte);
+ break;
+ }
+ }
+ if (di->ops[i].size == 64) str_code_hqw(str, (uint8_t*)&di->imm.qword);
+ else str_code_hdw(str, di->imm.dword);
+ break;
+ case O_IMM1:
+ str_code_hdw(str, di->imm.ex.i1);
+ break;
+ case O_IMM2:
+ str_code_hdw(str, di->imm.ex.i2);
+ break;
+ case O_DISP:
+ distorm_format_size(str, di, i);
+ chrcat_WS(str, OPEN_CHR);
+ if ((SEGMENT_GET(di->segment) != R_NONE) && !SEGMENT_IS_DEFAULT(di->segment)) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[SEGMENT_GET(di->segment)]);
+ chrcat_WS(str, SEG_OFF_CHR);
+ }
+ tmpDisp64 = di->disp & addrMask;
+ str_code_hqw(str, (uint8_t*)&tmpDisp64);
+ chrcat_WS(str, CLOSE_CHR);
+ break;
+ case O_SMEM:
+ distorm_format_size(str, di, i);
+ chrcat_WS(str, OPEN_CHR);
+
+ /*
+ * This is where we need to take special care for String instructions.
+ * If we got here, it means we need to explicitly show their operands.
+ * The problem with CMPS and MOVS is that they have two(!) memory operands.
+ * So we have to complete it ourselves, since the structure supplies only the segment that can be overridden.
+ * And make the rest of the String operations explicit.
+ */
+ segment = SEGMENT_GET(di->segment);
+ isDefault = SEGMENT_IS_DEFAULT(di->segment);
+ switch (di->opcode)
+ {
+ case I_MOVS:
+ isDefault = FALSE;
+ if (i == 0) segment = R_ES;
+ break;
+ case I_CMPS:
+ isDefault = FALSE;
+ if (i == 1) segment = R_ES;
+ break;
+ case I_INS:
+ case I_LODS:
+ case I_STOS:
+ case I_SCAS: isDefault = FALSE; break;
+ }
+ if (!isDefault && (segment != R_NONE)) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[segment]);
+ chrcat_WS(str, SEG_OFF_CHR);
+ }
+
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->ops[i].index]);
+
+ distorm_format_signed_disp(str, di, addrMask);
+ chrcat_WS(str, CLOSE_CHR);
+ break;
+ case O_MEM:
+ distorm_format_size(str, di, i);
+ chrcat_WS(str, OPEN_CHR);
+ if ((SEGMENT_GET(di->segment) != R_NONE) && !SEGMENT_IS_DEFAULT(di->segment)) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[SEGMENT_GET(di->segment)]);
+ chrcat_WS(str, SEG_OFF_CHR);
+ }
+ if (di->base != R_NONE) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->base]);
+ chrcat_WS(str, PLUS_DISP_CHR);
+ }
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->ops[i].index]);
+ if (di->scale != 0) {
+ chrcat_WS(str, '*');
+ if (di->scale == 2) chrcat_WS(str, '2');
+ else if (di->scale == 4) chrcat_WS(str, '4');
+ else /* if (di->scale == 8) */ chrcat_WS(str, '8');
+ }
+
+ distorm_format_signed_disp(str, di, addrMask);
+ chrcat_WS(str, CLOSE_CHR);
+ break;
+ case O_PC:
+#ifdef SUPPORT_64BIT_OFFSET
+ str_off64(str, (di->imm.sqword + di->addr + di->size) & addrMask);
+#else
+ str_code_hdw(str, ((_OffsetType)di->imm.sdword + di->addr + di->size) & (uint32_t)addrMask);
+#endif
+ break;
+ case O_PTR:
+ str_code_hdw(str, di->imm.ptr.seg);
+ chrcat_WS(str, SEG_OFF_CHR);
+ str_code_hdw(str, di->imm.ptr.off);
+ break;
+ }
+ }
+
+ if (di->flags & FLAG_HINT_TAKEN) strcat_WSN(str, " ;TAKEN");
+ else if (di->flags & FLAG_HINT_NOT_TAKEN) strcat_WSN(str, " ;NOT TAKEN");
+}
+
+#ifdef SUPPORT_64BIT_OFFSET
+ _DLLEXPORT_ _DecodeResult distorm_decode64(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#else
+ _DLLEXPORT_ _DecodeResult distorm_decode32(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#endif
+{
+ _DecodeResult res;
+ _DInst di;
+ _CodeInfo ci;
+ unsigned int instsCount = 0, i;
+
+ *usedInstructionsCount = 0;
+
+ /* I use codeLen as a signed variable in order to ease detection of underflow... and besides - */
+ if (codeLen < 0) {
+ return DECRES_INPUTERR;
+ }
+
+ if ((dt != Decode16Bits) && (dt != Decode32Bits) && (dt != Decode64Bits)) {
+ return DECRES_INPUTERR;
+ }
+
+ if (code == NULL || result == NULL) {
+ return DECRES_INPUTERR;
+ }
+
+ /* Assume length=0 is success. */
+ if (codeLen == 0) {
+ return DECRES_SUCCESS;
+ }
+
+ /*
+ * We have to format the result into text. But the interal decoder works with the new structure of _DInst.
+ * Therefore, we will pass the result array(!) from the caller and the interal decoder will fill it in with _DInst's.
+ * Then we will copy each result to a temporary structure, and use it to reformat that specific result.
+ *
+ * This is all done to save memory allocation and to work on the same result array in-place!!!
+ * It's a bit ugly, I have to admit, but worth it.
+ */
+
+ ci.codeOffset = codeOffset;
+ ci.code = code;
+ ci.codeLen = codeLen;
+ ci.dt = dt;
+ ci.features = DF_NONE;
+ if (dt == Decode16Bits) ci.features = DF_MAXIMUM_ADDR16;
+ else if (dt == Decode32Bits) ci.features = DF_MAXIMUM_ADDR32;
+
+ res = decode_internal(&ci, TRUE, (_DInst*)result, maxInstructions, &instsCount);
+ for (i = 0; i < instsCount; i++) {
+ if ((*usedInstructionsCount + i) >= maxInstructions) return DECRES_MEMORYERR;
+
+ /* Copy the current decomposed result to a temp structure, so we can override the result with text. */
+ memcpy(&di, (char*)result + (i * sizeof(_DecodedInst)), sizeof(_DInst));
+#ifdef SUPPORT_64BIT_OFFSET
+ distorm_format64(&ci, &di, &result[i]);
+#else
+ distorm_format32(&ci, &di, &result[i]);
+#endif
+ }
+
+ *usedInstructionsCount = instsCount;
+ return res;
+}
+
+#endif /* DISTORM_LIGHT */
+
+_DLLEXPORT_ unsigned int distorm_version()
+{
+ return __DISTORMV__;
+}
diff --git a/distorm3.2-package/src/instructions.c b/distorm3.2-package/src/instructions.c
new file mode 100644
index 0000000..df122b9
--- /dev/null
+++ b/distorm3.2-package/src/instructions.c
@@ -0,0 +1,584 @@
+/*
+instructions.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "instructions.h"
+
+#include "insts.h"
+#include "prefix.h"
+#include "x86defs.h"
+#include "../include/mnemonics.h"
+
+
+/* Helper macros to extract the type or index from an inst-node value. */
+#define INST_NODE_INDEX(n) ((n) & 0x1fff)
+#define INST_NODE_TYPE(n) ((n) >> 13)
+
+/*
+I use the trie data structure as I found it most fitting to a disassembler mechanism.
+When you read a byte and have to decide if it's enough or you should read more bytes, 'till you get to the instruction information.
+It's really fast because you POP the instruction info in top 3 iterates on the DB, because an instruction can be formed from two bytes + 3 bits reg from the ModR/M byte.
+For a simple explanation, check this out:
+http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Trie/
+Futher reading: http://en.wikipedia.org/wiki/Trie
+
+The first GATE (array you read off a trie data structure), as I call them, is statically allocated by the compiler.
+The second and third gates if used are being allocated dynamically by the instructions-insertion functionality.
+
+How would such a thing look in memory, say we support 4 instructions with 3 bytes top (means 2 dynamically allocated gates).
+
+->
+|-------| 0,
+|0| -------------------------------> |-------|
+|1|RET | 1, |0|AND |
+|2| -----> |-------| |1|XOR |
+|3|INT3 | |0|PUSH | |2|OR | 0,3,
+|-------| |1|POP | |3| --------->|-------|
+ |2|PUSHF| |-------| |0|ROR |
+ |3|POPF | |1|ROL |
+ |-------| |2|SHR |
+ |3|SHL |
+ |-------|
+
+Of course, this is NOT how Intel instructions set looks!!!
+but I just wanted to give a small demonstration.
+Now the instructions you get from such a trie DB goes like this:
+
+0, 0 - AND
+0, 1 - XOR
+0, 2 - OR
+0, 3, 0, ROR
+0, 3, 1, ROL
+0, 3, 2, SHR
+0, 3, 3, SHL
+1 - RET
+2, 0 - PUSH
+2, 1 - POP
+2, 2 - PUSHF
+2, 3 - POPF
+3 - INT3
+
+I guess it's clear by now.
+So now, if you read 0, you know that you have to enter the second gate(list) with the second byte specifying the index.
+But if you read 1, you know that you go to an instruction (in this case, a RET).
+That's why there's an Instruction-Node structure, it tells you whether you got to an instruction or another list
+so you should keep on reading byte).
+
+In Intel, you could go through 4 gates at top, because there're instructions which are built from 2 bytes and another smaller list
+for the REG part, or newest SSE4 instructions which use 4 bytes for opcode.
+Therefore, Intel's first gate is 256 long, and other gates are 256 (/72) or 8 long, yes, it costs pretty much alot of memory
+for non-used defined instructions, but I think that it still rocks.
+*/
+
+/*
+ * A helper function to look up the correct inst-info structure.
+ * It does one fetch from the index-table, and then another to get the inst-info.
+ * Note that it takes care about basic inst-info or inst-info-ex.
+ * The caller should worry about boundary checks and whether it accesses a last-level table.
+ */
+static _InstInfo* inst_get_info(_InstNode in, int index)
+{
+ int instIndex = 0;
+
+ in = InstructionsTree[INST_NODE_INDEX(in) + index];
+ if (in == INT_NOTEXISTS) return NULL;
+
+ instIndex = INST_NODE_INDEX(in);
+ return INST_NODE_TYPE(in) == INT_INFO ? &InstInfos[instIndex] : (_InstInfo*)&InstInfosEx[instIndex];
+}
+
+/*
+ * This function is responsible to return the instruction information of the first found in code.
+ * It returns the _InstInfo of the found instruction, otherwise NULL.
+ * code should point to the ModR/M byte upon exit (if used), or after the instruction binary code itself.
+ * This function is NOT decoding-type dependant, it is up to the caller to see whether the instruction is valid.
+ * Get the instruction info, using a Trie data structure.
+ *
+ * Sometimes normal prefixes become mandatory prefixes, which means they are now part of the instruction opcode bytes.
+
+ * This is a bit tricky now,
+ * if the first byte is a REP (F3) prefix, we will have to give a chance to an SSE instruction.
+ * If an instruction doesn't exist, we will make it as a prefix and re-locateinst.
+ * A case such that a REP prefix is being changed into an instruction byte and also an SSE instruction will not be found can't happen,
+ * simply because there are no collisions between string instruction and SSE instructions (they are escaped).
+
+ * As for S/SSE2/3, check for F2 and 66 as well.
+
+ * In 64 bits, we have to make sure that we will skip the REX prefix, if it exists.
+ * There's a specific case, where a 66 is mandatory but it was dropped because REG.W was used,
+ * but it doesn't behave as an operand size prefix but as a mandatory, so we will have to take it into account.
+
+ * For example (64 bits decoding mode):
+ * 66 98 CBW
+ * 48 98 CDQE
+ * 66 48 98: db 0x66; CDQE
+ * Shows that operand size is dropped.
+
+ * Now, it's a mandatory prefix and NOT an operand size one.
+ * 66480f2dc0 db 0x48; CVTPD2PI XMM0, XMM0
+ * Although this instruction doesn't require a REX.W, it just shows, that even if it did - it doesn't matter.
+ * REX.W is dropped because it's not requried, but the decode function disabled the operand size even so.
+ */
+static _InstInfo* inst_lookup_prefixed(_InstNode in, _PrefixState* ps)
+{
+ int checkOpSize = FALSE;
+ int index = 0;
+ _InstInfo* ii = NULL;
+
+ /* Check prefixes of current decoded instruction (None, 0x66, 0xf3, 0xf2). */
+ switch (ps->decodedPrefixes & (INST_PRE_OP_SIZE | INST_PRE_REPS))
+ {
+ case 0:
+ /* Non-prefixed, index = 0. */
+ index = 0;
+ break;
+ case INST_PRE_OP_SIZE:
+ /* 0x66, index = 1. */
+ index = 1;
+ /* Mark that we used it as a mandatory prefix. */
+ ps->isOpSizeMandatory = TRUE;
+ ps->decodedPrefixes &= ~INST_PRE_OP_SIZE;
+ break;
+ case INST_PRE_REP:
+ /* 0xf3, index = 2. */
+ index = 2;
+ ps->decodedPrefixes &= ~INST_PRE_REP;
+ break;
+ case INST_PRE_REPNZ:
+ /* 0xf2, index = 3. */
+ index = 3;
+ ps->decodedPrefixes &= ~INST_PRE_REPNZ;
+ break;
+ default:
+ /*
+ * Now we got a problem, since there are a few mandatory prefixes at once.
+ * There is only one case when it's ok, when the operand size prefix is for real (not mandatory).
+ * Otherwise we will have to return NULL, since the instruction is illegal.
+ * Therefore we will start with REPNZ and REP prefixes,
+ * try to get the instruction and only then check for the operand size prefix.
+ */
+
+ /* If both REPNZ and REP are together, it's illegal for sure. */
+ if ((ps->decodedPrefixes & INST_PRE_REPS) == INST_PRE_REPS) return NULL;
+
+ /* Now we know it's either REPNZ+OPSIZE or REP+OPSIZE, so examine the instruction. */
+ if (ps->decodedPrefixes & INST_PRE_REPNZ) {
+ index = 3;
+ ps->decodedPrefixes &= ~INST_PRE_REPNZ;
+ } else if (ps->decodedPrefixes & INST_PRE_REP) {
+ index = 2;
+ ps->decodedPrefixes &= ~INST_PRE_REP;
+ }
+ /* Mark to verify the operand-size prefix of the fetched instruction below. */
+ checkOpSize = TRUE;
+ break;
+ }
+
+ /* Fetch the inst-info from the index. */
+ ii = inst_get_info(in, index);
+
+ if (checkOpSize) {
+ /* If the instruction doesn't support operand size prefix, then it's illegal. */
+ if ((ii == NULL) || (~INST_INFO_FLAGS(ii) & INST_PRE_OP_SIZE)) return NULL;
+ }
+
+ /* If there was a prefix, but the instruction wasn't found. Try to fall back to use the normal instruction. */
+ if (ii == NULL) ii = inst_get_info(in, 0);
+ return ii;
+}
+
+/* A helper function to look up special VEX instructions.
+ * See if it's a MOD based instruction and fix index if required.
+ * Only after a first lookup (that was done by caller), we can tell if we need to fix the index.
+ * Because these are coupled instructions
+ * (which means that the base instruction hints about the other instruction).
+ * Note that caller should check if it's a MOD dependent instruction before getting in here.
+ */
+static _InstInfo* inst_vex_mod_lookup(_CodeInfo* ci, _InstNode in, _InstInfo* ii, unsigned int index)
+{
+ /* Advance to read the MOD from ModRM byte. */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ if (*ci->code < INST_DIVIDED_MODRM) {
+ /* MOD is not 11, therefore change the index to 8 - 12 range in the prefixed table. */
+ index += 4;
+ /* Make a second lookup for this special instruction. */
+ return inst_get_info(in, index);
+ }
+ /* Return the original one, in case we didn't find a stuited instruction. */
+ return ii;
+}
+
+static _InstInfo* inst_vex_lookup(_CodeInfo* ci, _PrefixState* ps)
+{
+ _InstNode in = 0;
+ unsigned int pp = 0, start = 0;
+ unsigned int index = 4; /* VEX instructions start at index 4 in the Prefixed table. */
+ uint8_t vex = *ps->vexPos, vex2 = 0, v = 0;
+ int instType = 0, instIndex = 0;
+
+ /* The VEX instruction will #ud if any of 66, f0, f2, f3, REX prefixes precede. */
+ _iflags illegal = (INST_PRE_OP_SIZE | INST_PRE_LOCK | INST_PRE_REP | INST_PRE_REPNZ | INST_PRE_REX);
+ if ((ps->decodedPrefixes & illegal) != 0) return NULL;
+
+ /* Read the some fields from the VEX prefix we need to extract the instruction. */
+ if (ps->prefixExtType == PET_VEX2BYTES) {
+ ps->vexV = v = (~vex >> 3) & 0xf;
+ pp = vex & 3;
+ /* Implied leading 0x0f byte by default for 2 bytes VEX prefix. */
+ start = 1;
+ } else { /* PET_VEX3BYTES */
+ start = vex & 0x1f;
+ vex2 = *(ps->vexPos + 1);
+ ps->vexV = v = (~vex2 >> 3) & 0xf;
+ pp = vex2 & 3;
+ }
+
+ /* start can be either 1 (0x0f), 2 (0x0f, 0x038) or 3 (0x0f, 0x3a), otherwise it's illegal. */
+ switch (start)
+ {
+ case 1: in = Table_0F; break;
+ case 2: in = Table_0F_38; break;
+ case 3: in = Table_0F_3A; break;
+ default: return NULL;
+ }
+
+ /* pp is actually the implied mandatory prefix, apply it to the index. */
+ index += pp; /* (None, 0x66, 0xf3, 0xf2) */
+
+ /* Read a byte from the stream. */
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+
+ in = InstructionsTree[INST_NODE_INDEX(in) + *ci->code];
+ if (in == INT_NOTEXISTS) return NULL;
+
+ instType = INST_NODE_TYPE(in);
+ instIndex = INST_NODE_INDEX(in);
+
+ /*
+ * If we started with 0f38 or 0f3a so it's a prefixed table,
+ * therefore it's surely a VEXed instruction (because of a high index).
+ * However, starting with 0f, could also lead immediately to a prefixed table for some bytes.
+ * it might return NULL, if the index is invalid.
+ */
+ if (instType == INT_LIST_PREFIXED) {
+ _InstInfo* ii = inst_get_info(in, index);
+ /* See if the instruction is dependent on MOD. */
+ if ((ii != NULL) && (((_InstInfoEx*)ii)->flagsEx & INST_MODRR_BASED)) {
+ ii = inst_vex_mod_lookup(ci, in, ii, index);
+ }
+ return ii;
+ }
+
+ /*
+ * If we reached here, obviously we started with 0f. VEXed instructions must be nodes of a prefixed table.
+ * But since we found an instruction (or divided one), just return NULL.
+ * They cannot lead to a VEXed instruction.
+ */
+ if ((instType == INT_INFO) || (instType == INT_INFOEX) || (instType == INT_LIST_DIVIDED)) return NULL;
+
+ /* Now we are left with handling either GROUP or FULL tables, therefore we will read another byte from the stream. */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+
+ if (instType == INT_LIST_GROUP) {
+ in = InstructionsTree[instIndex + ((*ci->code >> 3) & 7)];
+ /* Continue below to check prefixed table. */
+ } else if (instType == INT_LIST_FULL) {
+ in = InstructionsTree[instIndex + *ci->code];
+ /* Continue below to check prefixed table. */
+ }
+
+ /* Now that we got to the last table in the trie, check for a prefixed table. */
+ if (INST_NODE_TYPE(in) == INT_LIST_PREFIXED) {
+ _InstInfo* ii = inst_get_info(in, index);
+ /* See if the instruction is dependent on MOD. */
+ if ((ii != NULL) && (((_InstInfoEx*)ii)->flagsEx & INST_MODRR_BASED)) {
+ ii = inst_vex_mod_lookup(ci, in, ii, index);
+ }
+ return ii;
+ }
+
+ /* No VEXed instruction was found. */
+ return NULL;
+}
+
+_InstInfo* inst_lookup(_CodeInfo* ci, _PrefixState* ps)
+{
+ unsigned int tmpIndex0 = 0, tmpIndex1 = 0, tmpIndex2 = 0, rex = ps->vrex;
+ int instType = 0;
+ _InstNode in = 0;
+ _InstInfo* ii = NULL;
+ int isWaitIncluded = FALSE;
+
+ /* See whether we have to handle a VEX prefixed instruction. */
+ if (ps->decodedPrefixes & INST_PRE_VEX) {
+ ii = inst_vex_lookup(ci, ps);
+ if (ii != NULL) {
+ /* Make sure that VEX.L exists when forced. */
+ if ((((_InstInfoEx*)ii)->flagsEx & INST_FORCE_VEXL) && (~ps->vrex & PREFIX_EX_L)) return NULL;
+ /* If the instruction doesn't use VEX.vvvv it must be zero. */
+ if ((((_InstInfoEx*)ii)->flagsEx & INST_VEX_V_UNUSED) && ps->vexV) return NULL;
+ }
+ return ii;
+ }
+
+ /* Read first byte. */
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ tmpIndex0 = *ci->code;
+
+ /* Check for special 0x9b, WAIT instruction, which can be part of some instructions(x87). */
+ if (tmpIndex0 == INST_WAIT_INDEX) {
+ /* Only OCST_1dBYTES get a chance to include this byte as part of the opcode. */
+ isWaitIncluded = TRUE;
+
+ /* Ignore all prefixes, since they are useless and operate on the WAIT instruction itself. */
+ prefixes_ignore_all(ps);
+
+ /* Move to next code byte as a new whole instruction. */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL; /* Faster to return NULL, it will be detected as WAIT later anyway. */
+ /* Since we got a WAIT prefix, we re-read the first byte. */
+ tmpIndex0 = *ci->code;
+ }
+
+ /* Walk first byte in InstructionsTree root. */
+ in = InstructionsTree[tmpIndex0];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ /* Single byte instruction (OCST_1BYTE). */
+ if ((instType < INT_INFOS) && (!isWaitIncluded)) {
+ /* Some single byte instructions need extra treatment. */
+ switch (tmpIndex0)
+ {
+ case INST_ARPL_INDEX:
+ /*
+ * ARPL/MOVSXD share the same opcode, and both have different operands and mnemonics, of course.
+ * Practically, I couldn't come up with a comfortable way to merge the operands' types of ARPL/MOVSXD.
+ * And since the DB can't be patched dynamically, because the DB has to be multi-threaded compliant,
+ * I have no choice but to check for ARPL/MOVSXD right here - "right about now, the funk soul brother, check it out now, the funk soul brother...", fatboy slim
+ */
+ return ci->dt == Decode64Bits ? &II_movsxd : &II_arpl;
+
+ case INST_NOP_INDEX: /* Nopnopnop */
+ /* Check for Pause, since it's prefixed with 0xf3, which is not a real mandatory prefix. */
+ if (ps->decodedPrefixes & INST_PRE_REP) {
+ /* Flag this prefix as used. */
+ ps->usedPrefixes |= INST_PRE_REP;
+ return &II_pause;
+ }
+
+ /*
+ * Treat NOP/XCHG specially.
+ * If we're not in 64bits restore XCHG to NOP, since in the DB it's XCHG.
+ * Else if we're in 64bits examine REX, if exists, and decide which instruction should go to output.
+ * 48 90 XCHG RAX, RAX is a true NOP (eat REX in this case because it's valid).
+ * 90 XCHG EAX, EAX is a true NOP (and not high dword of RAX = 0 although it should be a 32 bits operation).
+ * Note that if the REX.B is used, then the register is not RAX anymore but R8, which means it's not a NOP.
+ */
+ if (rex & PREFIX_EX_W) ps->usedPrefixes |= INST_PRE_REX;
+ if ((ci->dt != Decode64Bits) || (~rex & PREFIX_EX_B)) return &II_nop;
+ break;
+
+ case INST_LEA_INDEX:
+ /* Ignore segment override prefixes for LEA instruction. */
+ ps->decodedPrefixes &= ~INST_PRE_SEGOVRD_MASK;
+ /* Update unused mask for ignoring segment prefix. */
+ prefixes_ignore(ps, PFXIDX_SEG);
+ break;
+ }
+
+ /* Return the 1 byte instruction we found. */
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+ }
+
+ /* Read second byte, still doens't mean all of its bits are used (I.E: ModRM). */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ tmpIndex1 = *ci->code;
+
+ /* Try single byte instruction + reg bits (OCST_13BYTES). */
+ if ((instType == INT_LIST_GROUP) && (!isWaitIncluded)) return inst_get_info(in, (tmpIndex1 >> 3) & 7);
+
+ /* Try single byte instruction + reg byte OR one whole byte (OCST_1dBYTES). */
+ if (instType == INT_LIST_DIVIDED) {
+ /* OCST_1dBYTES is relatively simple to OCST_2dBYTES, since it's really divided at 0xc0. */
+ if (tmpIndex1 < INST_DIVIDED_MODRM) {
+ /* An instruction which requires a ModR/M byte. Thus it's 1.3 bytes long instruction. */
+ tmpIndex1 = (tmpIndex1 >> 3) & 7; /* Isolate the 3 REG/OPCODE bits. */
+ } else { /* Normal 2 bytes instruction. */
+ /*
+ * Divided instructions can't be in the range of 0x8-0xc0.
+ * That's because 0-8 are used for 3 bits group.
+ * And 0xc0-0xff are used for not-divided instruction.
+ * So the inbetween range is omitted, thus saving some more place in the tables.
+ */
+ tmpIndex1 -= INST_DIVIDED_MODRM - 8;
+ }
+
+ in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex1];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ if (instType < INT_INFOS) {
+ /* If the instruction doesn't support the wait (marked as opsize) as part of the opcode, it's illegal. */
+ ii = instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+ if ((~INST_INFO_FLAGS(ii) & INST_PRE_OP_SIZE) && (isWaitIncluded)) return NULL;
+ return ii;
+ }
+ /*
+ * If we got here the instruction can support the wait prefix, so see if it was part of the stream.
+ * Examine prefixed table, specially used for 0x9b, since it's optional.
+ * No Wait: index = 0.
+ * Wait Exists, index = 1.
+ */
+ return inst_get_info(in, isWaitIncluded);
+ }
+
+ /* Don't allow to continue if WAIT is part of the opcode, because there are no instructions that include it. */
+ if (isWaitIncluded) return NULL;
+
+ /* Try 2 bytes long instruction (doesn't include ModRM byte). */
+ if (instType == INT_LIST_FULL) {
+ in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex1];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ /* This is where we check if we just read two escape bytes in a row, which means it is a 3DNow! instruction. */
+ if ((tmpIndex0 == _3DNOW_ESCAPE_BYTE) && (tmpIndex1 == _3DNOW_ESCAPE_BYTE)) return &II_3dnow;
+
+ /* 2 bytes instruction (OCST_2BYTES). */
+ if (instType < INT_INFOS)
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+
+ /*
+ * 2 bytes + mandatory perfix.
+ * Mandatory prefixes can be anywhere in the prefixes.
+ * There cannot be more than one mandatory prefix, unless it's a normal operand size prefix.
+ */
+ if (instType == INT_LIST_PREFIXED) return inst_lookup_prefixed(in, ps);
+ }
+
+ /* Read third byte, still doens't mean all of its bits are used (I.E: ModRM). */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ tmpIndex2 = *ci->code;
+
+ /* Try 2 bytes + reg instruction (OCST_23BYTES). */
+ if (instType == INT_LIST_GROUP) {
+ in = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex2 >> 3) & 7)];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ if (instType < INT_INFOS)
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+
+ /* It has to be a prefixed table then. */
+ return inst_lookup_prefixed(in, ps);
+ }
+
+ /* Try 2 bytes + divided range (OCST_2dBYTES). */
+ if (instType == INT_LIST_DIVIDED) {
+ _InstNode in2 = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex2 >> 3) & 7)];
+ /*
+ * Do NOT check for NULL here, since we do a bit of a guess work,
+ * hence we don't override 'in', cause we might still need it.
+ */
+ instType = INST_NODE_TYPE(in2);
+
+ if (instType == INT_INFO) ii = &InstInfos[INST_NODE_INDEX(in2)];
+ else if (instType == INT_INFOEX) ii = (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in2)];
+
+ /*
+ * OCST_2dBYTES is complex, because there are a few instructions which are not divided in some special cases.
+ * If the instruction wasn't divided (but still it must be a 2.3 because we are in divided category)
+ * or it was an official 2.3 (because its index was less than 0xc0) -
+ * Then it means the instruction should be using the REG bits, otherwise give a chance to range 0xc0-0xff.
+ */
+ /* If we found an instruction only by its REG bits, AND it is not divided, then return it. */
+ if ((ii != NULL) && (INST_INFO_FLAGS(ii) & INST_NOT_DIVIDED)) return ii;
+ /* Otherwise, if the range is above 0xc0, try the special divided range (range 0x8-0xc0 is omitted). */
+ if (tmpIndex2 >= INST_DIVIDED_MODRM) return inst_get_info(in, tmpIndex2 - INST_DIVIDED_MODRM + 8);
+
+ /* It might be that we got here without touching ii in the above if statements, then it becomes an invalid instruction prolly. */
+ return ii;
+ }
+
+ /* Try 3 full bytes (OCST_3BYTES - no ModRM byte). */
+ if (instType == INT_LIST_FULL) {
+ /* OCST_3BYTES. */
+ in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex2];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ if (instType < INT_INFOS)
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+
+ if (instType == INT_LIST_PREFIXED) return inst_lookup_prefixed(in, ps);
+ }
+
+ /* Kahtchinggg, damn. */
+ return NULL;
+}
+
+/*
+* 3DNow! instruction handling:
+
+* This is used when we encounter a 3DNow! instruction.
+* We can't really locate a 3DNow! instruction before we see two escaped bytes,
+* 0x0f, 0x0f. Then we have to extract operands which are, dest=mmx register, src=mmx register or quadword indirection.
+* When we are finished with the extraction of operands we can resume to locate the instruction by reading another byte
+* which tells us which 3DNow instruction we really tracked down...
+* So in order to tell the extract operands function which operands the 3DNow! instruction require, we need to set up some
+* generic instruction info for 3DNow! instructions.
+
+* In the inst_lookup itself, when we read an OCST_3BYTES which the two first bytes are 0x0f and 0x0f.
+* we will return this special generic II for the specific operands we are interested in (MM, MM64).
+* Then after extracting the operand, we'll call a completion routine for locating the instruction
+* which will be called only for 3DNow! instructions, distinguished by a flag, and it will read the last byte of the 3 bytes.
+*
+* The id of this opcode should not be used, the following function should change it anyway.
+*/
+_InstInfo* inst_lookup_3dnow(_CodeInfo* ci)
+{
+ /* Start off from the two escape bytes gates... which is 3DNow! table.*/
+ _InstNode in = Table_0F_0F;
+
+ int index;
+
+ /* Make sure we can read a byte off the stream. */
+ if (ci->codeLen < 1) return NULL;
+
+ index = *ci->code;
+
+ ci->codeLen -= 1;
+ ci->code += 1;
+ return inst_get_info(in, index);
+}
diff --git a/distorm3.2-package/src/instructions.h b/distorm3.2-package/src/instructions.h
new file mode 100644
index 0000000..43be7d9
--- /dev/null
+++ b/distorm3.2-package/src/instructions.h
@@ -0,0 +1,444 @@
+/*
+instructions.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef INSTRUCTIONS_H
+#define INSTRUCTIONS_H
+
+#include "config.h"
+#include "prefix.h"
+
+
+/*
+ * Operand type possibilities:
+ * Note "_FULL" suffix indicates to decode the operand as 16 bits or 32 bits depends on DecodeType -
+ * actually, it depends on the decoding mode, unless there's an operand/address size prefix.
+ * For example, the code: 33 c0 could be decoded/executed as XOR AX, AX or XOR EAX, EAX.
+ */
+typedef enum OpType {
+ /* No operand is set */
+ OT_NONE = 0,
+
+ /* Read a byte(8 bits) immediate */
+ OT_IMM8,
+ /* Force a read of a word(16 bits) immediate, used by ret only */
+ OT_IMM16,
+ /* Read a word/dword immediate */
+ OT_IMM_FULL,
+ /* Read a double-word(32 bits) immediate */
+ OT_IMM32,
+
+ /* Read a signed extended byte(8 bits) immediate */
+ OT_SEIMM8,
+
+ /*
+ * Special immediates for instructions which have more than one immediate,
+ * which is an exception from standard instruction format.
+ * As to version v1.0: ENTER, INSERTQ, EXTRQ are the only problematic ones.
+ */
+ /* 16 bits immediate using the first imm-slot */
+ OT_IMM16_1,
+ /* 8 bits immediate using the first imm-slot */
+ OT_IMM8_1,
+ /* 8 bits immediate using the second imm-slot */
+ OT_IMM8_2,
+
+ /* Use a 8bit register */
+ OT_REG8,
+ /* Use a 16bit register */
+ OT_REG16,
+ /* Use a 16/32/64bit register */
+ OT_REG_FULL,
+ /* Use a 32bit register */
+ OT_REG32,
+ /*
+ * If used with REX the reg operand size becomes 64 bits, otherwise 32 bits.
+ * VMX instructions are promoted automatically without a REX prefix.
+ */
+ OT_REG32_64,
+ /* Used only by MOV CR/DR(n). Promoted with REX onlly. */
+ OT_FREG32_64_RM,
+
+ /* Use or read (indirection) a 8bit register or immediate byte */
+ OT_RM8,
+ /* Some instructions force 16 bits (mov sreg, rm16) */
+ OT_RM16,
+ /* Use or read a 16/32/64bit register or immediate word/dword/qword */
+ OT_RM_FULL,
+ /*
+ * 32 or 64 bits (with REX) operand size indirection memory operand.
+ * Some instructions are promoted automatically without a REX prefix.
+ */
+ OT_RM32_64,
+ /* 16 or 32 bits RM. This is used only with MOVZXD instruction in 64bits. */
+ OT_RM16_32,
+ /* Same as OT_RMXX but POINTS to 16 bits [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM16,
+ /* Same as OT_RMXX but POINTS to 32 bits (single precision) [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM32,
+ /* Same as OT_RMXX but POINTS to 64 bits (double precision) [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM64,
+ /* Same as OT_RMXX but POINTS to 80 bits (extended precision) [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM80,
+
+ /*
+ * Special operand type for SSE4 where the ModR/M might
+ * be a 32 bits register or 8 bits memory indirection operand.
+ */
+ OT_R32_M8,
+ /*
+ * Special ModR/M for PINSRW, which need a 16 bits memory operand or 32 bits register.
+ * In 16 bits decoding mode R32 becomes R16, operand size cannot affect this.
+ */
+ OT_R32_M16,
+ /*
+ * Special type for SSE4, ModR/M might be a 32 bits or 64 bits (with REX) register or
+ * a 8 bits memory indirection operand.
+ */
+ OT_R32_64_M8,
+ /*
+ * Special type for SSE4, ModR/M might be a 32 bits or 64 bits (with REX) register or
+ * a 16 bits memory indirection operand.
+ */
+ OT_R32_64_M16,
+ /*
+ * Special operand type for MOV reg16/32/64/mem16, segReg 8C /r. and SMSW.
+ * It supports all decoding modes, but if used as a memory indirection it's a 16 bit ModR/M indirection.
+ */
+ OT_RFULL_M16,
+
+ /* Use a control register */
+ OT_CREG,
+ /* Use a debug register */
+ OT_DREG,
+ /* Use a segment register */
+ OT_SREG,
+ /*
+ * SEG is encoded in the flags of the opcode itself!
+ * This is used for specific "push SS" where SS is a segment where
+ * each "push SS" has an absolutely different opcode byte.
+ * We need this to detect whether an operand size prefix is used.
+ */
+ OT_SEG,
+
+ /* Use AL */
+ OT_ACC8,
+ /* Use AX (FSTSW) */
+ OT_ACC16,
+ /* Use AX/EAX/RAX */
+ OT_ACC_FULL,
+ /* Use AX/EAX, no REX is possible for RAX, used only with IN/OUT which don't support 64 bit registers */
+ OT_ACC_FULL_NOT64,
+
+ /*
+ * Read one word (seg), and a word/dword/qword (depends on operand size) from memory.
+ * JMP FAR [EBX] means EBX point to 16:32 ptr.
+ */
+ OT_MEM16_FULL,
+ /* Read one word (seg) and a word/dword/qword (depends on operand size), usually SEG:OFF, JMP 1234:1234 */
+ OT_PTR16_FULL,
+ /* Read one word (limit) and a dword/qword (limit) (depends on operand size), used by SGDT, SIDT, LGDT, LIDT. */
+ OT_MEM16_3264,
+
+ /* Read a byte(8 bits) immediate and calculate it relatively to the current offset of the instruction being decoded */
+ OT_RELCB,
+ /* Read a word/dword immediate and calculate it relatively to the current offset of the instruction being decoded */
+ OT_RELC_FULL,
+
+ /* Use general memory indirection, with varying sizes: */
+ OT_MEM,
+ /* Used when a memory indirection is required, but if the mod field is 11, this operand will be ignored. */
+ OT_MEM_OPT,
+ OT_MEM32,
+ /* Memory dereference for MOVNTI, either 32 or 64 bits (with REX). */
+ OT_MEM32_64,
+ OT_MEM64,
+ OT_MEM128,
+ /* Used for cmpxchg8b/16b. */
+ OT_MEM64_128,
+
+ /* Read an immediate as an absolute address, size is known by instruction, used by MOV (memory offset) only */
+ OT_MOFFS8,
+ OT_MOFFS_FULL,
+ /* Use an immediate of 1, as for SHR R/M, 1 */
+ OT_CONST1,
+ /* Use CL, as for SHR R/M, CL */
+ OT_REGCL,
+
+ /*
+ * Instruction-Block for one byte long instructions, used by INC/DEC/PUSH/POP/XCHG,
+ * REG is extracted from the value of opcode
+ * Use a 8bit register
+ */
+ OT_IB_RB,
+ /* Use a 16/32/64bit register */
+ OT_IB_R_FULL,
+
+ /* Use [(r)SI] as INDIRECTION, for repeatable instructions */
+ OT_REGI_ESI,
+ /* Use [(r)DI] as INDIRECTION, for repeatable instructions */
+ OT_REGI_EDI,
+ /* Use [(r)BX + AL] as INDIRECTIOM, used by XLAT only */
+ OT_REGI_EBXAL,
+ /* Use [(r)AX] as INDIRECTION, used by AMD's SVM instructions */
+ OT_REGI_EAX,
+ /* Use DX, as for OUTS DX, BYTE [SI] */
+ OT_REGDX,
+ /* Use ECX in INVLPGA instruction */
+ OT_REGECX,
+
+ /* FPU registers: */
+ OT_FPU_SI, /* ST(i) */
+ OT_FPU_SSI, /* ST(0), ST(i) */
+ OT_FPU_SIS, /* ST(i), ST(0) */
+
+ /* MMX registers: */
+ OT_MM,
+ /* Extract the MMX register from the RM bits this time (used when the REG bits are used for opcode extension) */
+ OT_MM_RM,
+ /* ModR/M points to 32 bits MMX variable */
+ OT_MM32,
+ /* ModR/M points to 32 bits MMX variable */
+ OT_MM64,
+
+ /* SSE registers: */
+ OT_XMM,
+ /* Extract the SSE register from the RM bits this time (used when the REG bits are used for opcode extension) */
+ OT_XMM_RM,
+ /* ModR/M points to 16 bits SSE variable */
+ OT_XMM16,
+ /* ModR/M points to 32 bits SSE variable */
+ OT_XMM32,
+ /* ModR/M points to 64 bits SSE variable */
+ OT_XMM64,
+ /* ModR/M points to 128 bits SSE variable */
+ OT_XMM128,
+ /* Implied XMM0 register as operand, used in SSE4. */
+ OT_REGXMM0,
+
+ /* AVX operands: */
+
+ /* ModR/M for 32 bits. */
+ OT_RM32,
+ /* Reg32/Reg64 (prefix width) or Mem8. */
+ OT_REG32_64_M8,
+ /* Reg32/Reg64 (prefix width) or Mem16. */
+ OT_REG32_64_M16,
+ /* Reg32/Reg 64 depends on prefix width only. */
+ OT_WREG32_64,
+ /* RM32/RM64 depends on prefix width only. */
+ OT_WRM32_64,
+ /* XMM or Mem32/Mem64 depends on perfix width only. */
+ OT_WXMM32_64,
+ /* XMM is encoded in VEX.VVVV. */
+ OT_VXMM,
+ /* XMM is encoded in the high nibble of an immediate byte. */
+ OT_XMM_IMM,
+ /* YMM/XMM is dependent on VEX.L. */
+ OT_YXMM,
+ /* YMM/XMM (depends on prefix length) is encoded in the high nibble of an immediate byte. */
+ OT_YXMM_IMM,
+ /* YMM is encoded in reg. */
+ OT_YMM,
+ /* YMM or Mem256. */
+ OT_YMM256,
+ /* YMM is encoded in VEX.VVVV. */
+ OT_VYMM,
+ /* YMM/XMM is dependent on VEX.L, and encoded in VEX.VVVV. */
+ OT_VYXMM,
+ /* YMM/XMM or Mem64/Mem256 is dependent on VEX.L. */
+ OT_YXMM64_256,
+ /* YMM/XMM or Mem128/Mem256 is dependent on VEX.L. */
+ OT_YXMM128_256,
+ /* XMM or Mem64/Mem256 is dependent on VEX.L. */
+ OT_LXMM64_128,
+ /* Mem128/Mem256 is dependent on VEX.L. */
+ OT_LMEM128_256
+} _OpType;
+
+/* Flags for instruction: */
+
+/* Empty flags indicator: */
+#define INST_FLAGS_NONE (0)
+/* The instruction we are going to decode requires ModR/M encoding. */
+#define INST_MODRM_REQUIRED (1)
+/* Special treatment for instructions which are in the divided-category but still needs the whole byte for ModR/M... */
+#define INST_NOT_DIVIDED (1 << 1)
+/*
+ * Used explicitly in repeatable instructions,
+ * which needs a suffix letter in their mnemonic to specify operation-size (depend on operands).
+ */
+#define INST_16BITS (1 << 2)
+/* If the opcode is supported by 80286 and upper models (16/32 bits). */
+#define INST_32BITS (1 << 3)
+/*
+ * Prefix flags (6 types: lock/rep, seg override, addr-size, oper-size, REX, VEX)
+ * There are several specific instructions that can follow LOCK prefix,
+ * note that they must be using a memory operand form, otherwise they generate an exception.
+ */
+#define INST_PRE_LOCK (1 << 4)
+/* REPNZ prefix for string instructions only - means an instruction can follow it. */
+#define INST_PRE_REPNZ (1 << 5)
+/* REP prefix for string instructions only - means an instruction can follow it. */
+#define INST_PRE_REP (1 << 6)
+/* CS override prefix. */
+#define INST_PRE_CS (1 << 7)
+/* SS override prefix. */
+#define INST_PRE_SS (1 << 8)
+/* DS override prefix. */
+#define INST_PRE_DS (1 << 9)
+/* ES override prefix. */
+#define INST_PRE_ES (1 << 10)
+/* FS override prefix. Funky Segment :) */
+#define INST_PRE_FS (1 << 11)
+/* GS override prefix. Groovy Segment, of course not, duh ! */
+#define INST_PRE_GS (1 << 12)
+/* Switch operand size from 32 to 16 and vice versa. */
+#define INST_PRE_OP_SIZE (1 << 13)
+/* Switch address size from 32 to 16 and vice versa. */
+#define INST_PRE_ADDR_SIZE (1 << 14)
+/* Native instructions which needs suffix letter to indicate their operation-size (and don't depend on operands). */
+#define INST_NATIVE (1 << 15)
+/* Use extended mnemonic, means it's an _InstInfoEx structure, which contains another mnemonic for 32 bits specifically. */
+#define INST_USE_EXMNEMONIC (1 << 16)
+/* Use third operand, means it's an _InstInfoEx structure, which contains another operand for special instructions. */
+#define INST_USE_OP3 (1 << 17)
+/* Use fourth operand, means it's an _InstInfoEx structure, which contains another operand for special instructions. */
+#define INST_USE_OP4 (1 << 18)
+/* The instruction's mnemonic depends on the mod value of the ModR/M byte (mod=11, mod!=11). */
+#define INST_MNEMONIC_MODRM_BASED (1 << 19)
+/* The instruction uses a ModR/M byte which the MOD must be 11 (for registers operands only). */
+#define INST_MODRR_REQUIRED (1 << 20)
+/* The way of 3DNow! instructions are built, we have to handle their locating specially. Suffix imm8 tells which instruction it is. */
+#define INST_3DNOW_FETCH (1 << 21)
+/* The instruction needs two suffixes, one for the comparison type (imm8) and the second for its operation size indication (second mnemonic). */
+#define INST_PSEUDO_OPCODE (1 << 22)
+/* Invalid instruction at 64 bits decoding mode. */
+#define INST_INVALID_64BITS (1 << 23)
+/* Specific instruction can be promoted to 64 bits (without REX, it is promoted automatically). */
+#define INST_64BITS (1 << 24)
+/* Indicates the instruction must be REX prefixed in order to use 64 bits operands. */
+#define INST_PRE_REX (1 << 25)
+/* Third mnemonic is set. */
+#define INST_USE_EXMNEMONIC2 (1 << 26)
+/* Instruction is only valid in 64 bits decoding mode. */
+#define INST_64BITS_FETCH (1 << 27)
+/* Forces that the ModRM-REG/Opcode field will be 0. (For EXTRQ). */
+#define INST_FORCE_REG0 (1 << 28)
+/* Indicates that instruction is encoded with a VEX prefix. */
+#define INST_PRE_VEX (1 << 29)
+/* Indicates that the instruction is encoded with a ModRM byte (REG field specifically). */
+#define INST_MODRM_INCLUDED (1 << 30)
+/* Indicates that the first (/destination) operand of the instruction is writable. */
+#define INST_DST_WR (1 << 31)
+
+#define INST_PRE_REPS (INST_PRE_REPNZ | INST_PRE_REP)
+#define INST_PRE_LOKREP_MASK (INST_PRE_LOCK | INST_PRE_REPNZ | INST_PRE_REP)
+#define INST_PRE_SEGOVRD_MASK32 (INST_PRE_CS | INST_PRE_SS | INST_PRE_DS | INST_PRE_ES)
+#define INST_PRE_SEGOVRD_MASK64 (INST_PRE_FS | INST_PRE_GS)
+#define INST_PRE_SEGOVRD_MASK (INST_PRE_SEGOVRD_MASK32 | INST_PRE_SEGOVRD_MASK64)
+
+/* Extended flags for VEX: */
+/* Indicates that the instruction might have VEX.L encoded. */
+#define INST_VEX_L (1)
+/* Indicates that the instruction might have VEX.W encoded. */
+#define INST_VEX_W (1 << 1)
+/* Indicates that the mnemonic of the instruction is based on the VEX.W bit. */
+#define INST_MNEMONIC_VEXW_BASED (1 << 2)
+/* Indicates that the mnemonic of the instruction is based on the VEX.L bit. */
+#define INST_MNEMONIC_VEXL_BASED (1 << 3)
+/* Forces the instruction to be encoded with VEX.L, otherwise it's undefined. */
+#define INST_FORCE_VEXL (1 << 4)
+/*
+ * Indicates that the instruction is based on the MOD field of the ModRM byte.
+ * (MOD==11: got the right instruction, else skip +4 in prefixed table for the correct instruction).
+ */
+#define INST_MODRR_BASED (1 << 5)
+/* Indicates that the instruction doesn't use the VVVV field of the VEX prefix, if it does then it's undecodable. */
+#define INST_VEX_V_UNUSED (1 << 6)
+
+/*
+ * Indicates which operand is being decoded.
+ * Destination (1st), Source (2nd), op3 (3rd), op4 (4th).
+ * Used to set the operands' fields in the _DInst structure!
+ */
+typedef enum {ONT_NONE = -1, ONT_1 = 0, ONT_2 = 1, ONT_3 = 2, ONT_4 = 3} _OperandNumberType;
+
+/*
+ * Info about the instruction, source/dest types, its name in text and flags.
+ * This structure is used for the instructions DB and NOT for the disassembled result code!
+ * This is the BASE structure, there are extentions to this structure below.
+ */
+
+typedef struct {
+ uint8_t flagsIndex; /* An index into FlagsTables. */
+ uint8_t s, d; /* OpType. */
+ uint8_t meta; /* Hi 5 bits = Instruction set class | Lo 3 bits = flow control flags. */
+ uint16_t opcodeId; /* The opcodeId is really a byte-offset into the mnemonics table. */
+} _InstInfo;
+
+/*
+ * There are merely few instructions which need a second mnemonic for 32 bits.
+ * Or a third for 64 bits. Therefore sometimes the second mnemonic is empty but not the third.
+ * In all decoding modes the first mnemonic is the default.
+ * A flag will indicate it uses another mnemonic.
+ *
+ * There are a couple of (SSE4) instructions in the whole DB which need both op3 and 3rd mnemonic for 64bits,
+ * therefore, I decided to make the extended structure contain all extra info in the same structure.
+ * There are a few instructions (SHLD/SHRD/IMUL and SSE too) which use third operand (or a fourth).
+ * A flag will indicate it uses a third/fourth operand.
+ *
+ */
+typedef struct {
+ /* Base structure (doesn't get accessed directly from code). */
+ _InstInfo BASE;
+
+ /* Extended starts here. */
+ uint8_t flagsEx; /* 8 bits are enough, in the future we might make it a bigger integer. */
+ uint8_t op3, op4; /* OpType. */
+ uint16_t opcodeId2, opcodeId3;
+} _InstInfoEx;
+
+/* Trie data structure node type: */
+typedef enum {
+ INT_NOTEXISTS = 0, /* Not exists. */
+ INT_INFO = 1, /* It's an instruction info. */
+ INT_INFOEX,
+ INT_LIST_GROUP,
+ INT_LIST_FULL,
+ INT_LIST_DIVIDED,
+ INT_LIST_PREFIXED
+} _InstNodeType;
+
+/* Used to check instType < INT_INFOS, means we got an inst-info. Cause it has to be only one of them. */
+#define INT_INFOS (INT_LIST_GROUP)
+
+/* Instruction node is treated as { int index:13; int type:3; } */
+typedef uint16_t _InstNode;
+
+/* Helper macro to read the actual flags that are associated with an inst-info. */
+#define INST_INFO_FLAGS(ii) (FlagsTable[(ii)->flagsIndex])
+
+_InstInfo* inst_lookup(_CodeInfo* ci, _PrefixState* ps);
+_InstInfo* inst_lookup_3dnow(_CodeInfo* ci);
+
+#endif /* INSTRUCTIONS_H */
diff --git a/distorm3.2-package/src/insts.c b/distorm3.2-package/src/insts.c
new file mode 100644
index 0000000..4c9179b
--- /dev/null
+++ b/distorm3.2-package/src/insts.c
@@ -0,0 +1,7343 @@
+/*
+insts.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "config.h"
+#include "insts.h"
+#include "instructions.h"
+
+
+/*
+ * GENERATED BY disOps at Mon May 07 05:39:59 2012
+ */
+
+/* See x86defs.c if you get an error here. */
+_iflags FlagsTable[97 + 5] = {
+INST_MODRM_REQUIRED,
+INST_MODRM_REQUIRED | INST_PRE_REX | INST_64BITS,
+INST_FLAGS_NONE,
+INST_FLAGS_NONE,
+INST_32BITS | INST_MODRM_REQUIRED | INST_3DNOW_FETCH,
+0x80000011,
+0x80000000,
+0x800400,
+0x80800400,
+0x800080,
+0x800100,
+0x80800100,
+0x800200,
+0x80800200,
+0x800000,
+0x1,
+0x0,
+0x80800000,
+0x1000000,
+0x81000000,
+0x808000,
+0x800001,
+0x1000001,
+0x80020001,
+0x1002000,
+0x60,
+0x64,
+0x80000001,
+0x4010000,
+0x1008000,
+0x80000060,
+0x83000064,
+0x3000064,
+0x83000000,
+0x3008000,
+0x200,
+0xc000,
+0x4014000,
+0x8,
+0x81000009,
+0x9,
+0x80000009,
+0x1000808,
+0x81000808,
+0x80020009,
+0x1001008,
+0x81001008,
+0x80000019,
+0x3000009,
+0x83000009,
+0x83000008,
+0xc0000011,
+0x40000001,
+0xc0800011,
+0x40800001,
+0xc0000019,
+0xc1000001,
+0xc0000001,
+0x40000000,
+0x40000008,
+0x40000009,
+0x41000001,
+0x43000001,
+0xc0000003,
+0x40000003,
+0x48000000,
+0x200009,
+0x20000009,
+0x60020009,
+0x60000009,
+0x80090009,
+0x200b0009,
+0x20020009,
+0x80100009,
+0x21100009,
+0x87000009,
+0x20009,
+0x20000008,
+0x1000009,
+0x10020009,
+0x160009,
+0x100009,
+0x47000009,
+0x47090009,
+0x40090009,
+0x80002009,
+0xc0000009,
+0x2001,
+0x80002001,
+0x410009,
+0x20420009,
+0x20060009,
+0x120009,
+0x21020009,
+0xc7000019,
+0x20100009,
+0x40002009,
+0x40002008,
+0x4020009,
+0x40100009,
+0x60120009,
+0x41000009
+};
+
+_InstNode Table_0F = 256;
+_InstNode Table_0F_0F = 1312;
+_InstNode Table_0F_38 = 1768;
+_InstNode Table_0F_3A = 2024;
+
+_InstInfo InstInfos[] = {
+ /*II_00*/ {0x5, 9, 15, 8, 11},
+ /*II_01*/ {0x5, 11, 17, 8, 11},
+ /*II_02*/ {0x5, 15, 9, 8, 11},
+ /*II_03*/ {0x5, 17, 11, 8, 11},
+ /*II_04*/ {0x6, 1, 33, 8, 11},
+ /*II_05*/ {0x6, 3, 35, 8, 11},
+ /*II_06*/ {0x7, 0, 32, 8, 16},
+ /*II_07*/ {0x8, 0, 32, 8, 22},
+ /*II_08*/ {0x5, 9, 15, 8, 27},
+ /*II_09*/ {0x5, 11, 17, 8, 27},
+ /*II_0A*/ {0x5, 15, 9, 8, 27},
+ /*II_0B*/ {0x5, 17, 11, 8, 27},
+ /*II_0C*/ {0x6, 1, 33, 8, 27},
+ /*II_0D*/ {0x6, 3, 35, 8, 27},
+ /*II_0E*/ {0x9, 0, 32, 8, 16},
+ /*II_10*/ {0x5, 9, 15, 8, 31},
+ /*II_11*/ {0x5, 11, 17, 8, 31},
+ /*II_12*/ {0x5, 15, 9, 8, 31},
+ /*II_13*/ {0x5, 17, 11, 8, 31},
+ /*II_14*/ {0x6, 1, 33, 8, 31},
+ /*II_15*/ {0x6, 3, 35, 8, 31},
+ /*II_16*/ {0xa, 0, 32, 8, 16},
+ /*II_17*/ {0xb, 0, 32, 8, 22},
+ /*II_18*/ {0x5, 9, 15, 8, 36},
+ /*II_19*/ {0x5, 11, 17, 8, 36},
+ /*II_1A*/ {0x5, 15, 9, 8, 36},
+ /*II_1B*/ {0x5, 17, 11, 8, 36},
+ /*II_1C*/ {0x6, 1, 33, 8, 36},
+ /*II_1D*/ {0x6, 3, 35, 8, 36},
+ /*II_1E*/ {0xc, 0, 32, 8, 16},
+ /*II_1F*/ {0xd, 0, 32, 8, 22},
+ /*II_20*/ {0x5, 9, 15, 8, 41},
+ /*II_21*/ {0x5, 11, 17, 8, 41},
+ /*II_22*/ {0x5, 15, 9, 8, 41},
+ /*II_23*/ {0x5, 17, 11, 8, 41},
+ /*II_24*/ {0x6, 1, 33, 8, 41},
+ /*II_25*/ {0x6, 3, 35, 8, 41},
+ /*II_27*/ {0xe, 0, 0, 8, 46},
+ /*II_28*/ {0x5, 9, 15, 8, 51},
+ /*II_29*/ {0x5, 11, 17, 8, 51},
+ /*II_2A*/ {0x5, 15, 9, 8, 51},
+ /*II_2B*/ {0x5, 17, 11, 8, 51},
+ /*II_2C*/ {0x6, 1, 33, 8, 51},
+ /*II_2D*/ {0x6, 3, 35, 8, 51},
+ /*II_2F*/ {0xe, 0, 0, 8, 56},
+ /*II_30*/ {0x5, 9, 15, 8, 61},
+ /*II_31*/ {0x5, 11, 17, 8, 61},
+ /*II_32*/ {0x5, 15, 9, 8, 61},
+ /*II_33*/ {0x5, 17, 11, 8, 61},
+ /*II_34*/ {0x6, 1, 33, 8, 61},
+ /*II_35*/ {0x6, 3, 35, 8, 61},
+ /*II_37*/ {0xe, 0, 0, 8, 66},
+ /*II_38*/ {0xf, 9, 15, 8, 71},
+ /*II_39*/ {0xf, 11, 17, 8, 71},
+ /*II_3A*/ {0xf, 15, 9, 8, 71},
+ /*II_3B*/ {0xf, 17, 11, 8, 71},
+ /*II_3C*/ {0x10, 1, 33, 8, 71},
+ /*II_3D*/ {0x10, 3, 35, 8, 71},
+ /*II_3F*/ {0xe, 0, 0, 8, 76},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_40*/ {0x11, 0, 54, 8, 81},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_48*/ {0x11, 0, 54, 8, 86},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_50*/ {0x12, 0, 54, 8, 16},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_58*/ {0x13, 0, 54, 8, 22},
+ /*II_60*/ {0x14, 0, 0, 8, 91},
+ /*II_61*/ {0x14, 0, 0, 8, 98},
+ /*II_62*/ {0x15, 42, 11, 8, 104},
+ /*II_63*/ {0x16, 10, 16, 8, 111},
+ /*II_68*/ {0x12, 0, 3, 8, 16},
+ /*II_6A*/ {0x18, 0, 5, 8, 16},
+ /*II_6C*/ {0x19, 59, 56, 8, 123},
+ /*II_6D*/ {0x1a, 59, 56, 8, 123},
+ /*II_6E*/ {0x19, 55, 59, 8, 128},
+ /*II_6F*/ {0x1a, 55, 59, 8, 128},
+ /*II_70*/ {0x12, 0, 40, 13, 134},
+ /*II_71*/ {0x12, 0, 40, 13, 138},
+ /*II_72*/ {0x12, 0, 40, 13, 143},
+ /*II_73*/ {0x12, 0, 40, 13, 147},
+ /*II_74*/ {0x12, 0, 40, 13, 152},
+ /*II_75*/ {0x12, 0, 40, 13, 156},
+ /*II_76*/ {0x12, 0, 40, 13, 161},
+ /*II_77*/ {0x12, 0, 40, 13, 166},
+ /*II_78*/ {0x12, 0, 40, 13, 170},
+ /*II_79*/ {0x12, 0, 40, 13, 174},
+ /*II_7A*/ {0x12, 0, 40, 13, 179},
+ /*II_7B*/ {0x12, 0, 40, 13, 183},
+ /*II_7C*/ {0x12, 0, 40, 13, 188},
+ /*II_7D*/ {0x12, 0, 40, 13, 192},
+ /*II_7E*/ {0x12, 0, 40, 13, 197},
+ /*II_7F*/ {0x12, 0, 40, 13, 202},
+ /*II_84*/ {0xf, 9, 15, 8, 206},
+ /*II_85*/ {0xf, 11, 17, 8, 206},
+ /*II_86*/ {0x5, 9, 15, 8, 212},
+ /*II_87*/ {0x5, 11, 17, 8, 212},
+ /*II_88*/ {0x1b, 9, 15, 8, 218},
+ /*II_89*/ {0x1b, 11, 17, 8, 218},
+ /*II_8A*/ {0x1b, 15, 9, 8, 218},
+ /*II_8B*/ {0x1b, 17, 11, 8, 218},
+ /*II_8C*/ {0x1b, 31, 28, 8, 218},
+ /*II_8D*/ {0x1b, 42, 11, 8, 223},
+ /*II_8E*/ {0x1b, 28, 31, 8, 218},
+ /*II_90*/ {0x6, 35, 54, 8, 212},
+ /*II_91*/ {0x6, 35, 54, 8, 212},
+ /*II_92*/ {0x6, 35, 54, 8, 212},
+ /*II_93*/ {0x6, 35, 54, 8, 212},
+ /*II_94*/ {0x6, 35, 54, 8, 212},
+ /*II_95*/ {0x6, 35, 54, 8, 212},
+ /*II_96*/ {0x6, 35, 54, 8, 212},
+ /*II_97*/ {0x6, 35, 54, 8, 212},
+ /*II_9A*/ {0xe, 0, 38, 9, 260},
+ /*II_9C*/ {0x1d, 0, 0, 8, 270},
+ /*II_9D*/ {0x1d, 0, 0, 8, 277},
+ /*II_9E*/ {0x10, 0, 0, 8, 283},
+ /*II_9F*/ {0x10, 0, 0, 8, 289},
+ /*II_A0*/ {0x6, 49, 33, 8, 218},
+ /*II_A1*/ {0x6, 50, 35, 8, 218},
+ /*II_A2*/ {0x6, 33, 49, 8, 218},
+ /*II_A3*/ {0x6, 35, 50, 8, 218},
+ /*II_A4*/ {0x1e, 55, 56, 8, 295},
+ /*II_A5*/ {0x1f, 55, 56, 8, 295},
+ /*II_A6*/ {0x19, 56, 55, 8, 301},
+ /*II_A7*/ {0x20, 56, 55, 8, 301},
+ /*II_A8*/ {0x10, 1, 33, 8, 206},
+ /*II_A9*/ {0x10, 3, 35, 8, 206},
+ /*II_AA*/ {0x19, 33, 56, 8, 307},
+ /*II_AB*/ {0x20, 35, 56, 8, 307},
+ /*II_AC*/ {0x19, 55, 33, 8, 313},
+ /*II_AD*/ {0x20, 55, 35, 8, 313},
+ /*II_AE*/ {0x19, 33, 56, 8, 319},
+ /*II_AF*/ {0x20, 35, 56, 8, 319},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B0*/ {0x6, 1, 53, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_B8*/ {0x21, 3, 54, 8, 218},
+ /*II_C2*/ {0x12, 0, 2, 10, 325},
+ /*II_C3*/ {0x12, 0, 0, 10, 325},
+ /*II_C4*/ {0x15, 37, 11, 8, 330},
+ /*II_C5*/ {0x15, 37, 11, 8, 335},
+ /*II_C8*/ {0x12, 8, 6, 8, 340},
+ /*II_C9*/ {0x12, 0, 0, 8, 347},
+ /*II_CA*/ {0x22, 0, 2, 10, 354},
+ /*II_CB*/ {0x22, 0, 0, 10, 354},
+ /*II_CC*/ {0x10, 0, 0, 14, 360},
+ /*II_CD*/ {0x10, 0, 1, 14, 367},
+ /*II_CE*/ {0xe, 0, 0, 14, 372},
+ /*II_CF*/ {0x22, 0, 0, 10, 378},
+ /*II_D4*/ {0xe, 0, 1, 8, 384},
+ /*II_D5*/ {0xe, 0, 1, 8, 389},
+ /*II_D6*/ {0xe, 0, 0, 8, 394},
+ /*II_D7*/ {0x23, 0, 57, 8, 400},
+ /*II_E0*/ {0x24, 0, 40, 13, 406},
+ /*II_E1*/ {0x24, 0, 40, 13, 414},
+ /*II_E2*/ {0x24, 0, 40, 13, 421},
+ /*II_E4*/ {0x6, 1, 33, 8, 447},
+ /*II_E5*/ {0x6, 1, 36, 8, 447},
+ /*II_E6*/ {0x10, 33, 1, 8, 451},
+ /*II_E7*/ {0x10, 36, 1, 8, 451},
+ /*II_E8*/ {0x12, 0, 41, 9, 456},
+ /*II_E9*/ {0x12, 0, 41, 12, 462},
+ /*II_EA*/ {0xe, 0, 38, 12, 467},
+ /*II_EB*/ {0x12, 0, 40, 12, 462},
+ /*II_EC*/ {0x6, 59, 33, 8, 447},
+ /*II_ED*/ {0x6, 59, 36, 8, 447},
+ /*II_EE*/ {0x10, 33, 59, 8, 451},
+ /*II_EF*/ {0x10, 36, 59, 8, 451},
+ /*II_F1*/ {0x10, 0, 0, 14, 476},
+ /*II_F4*/ {0x10, 0, 0, 8, 482},
+ /*II_F5*/ {0x10, 0, 0, 8, 487},
+ /*II_F8*/ {0x10, 0, 0, 8, 492},
+ /*II_F9*/ {0x10, 0, 0, 8, 497},
+ /*II_FA*/ {0x10, 0, 0, 8, 502},
+ /*II_FB*/ {0x10, 0, 0, 8, 507},
+ /*II_FC*/ {0x10, 0, 0, 8, 512},
+ /*II_FD*/ {0x10, 0, 0, 8, 517},
+ /*II_0F_02*/ {0xf, 16, 11, 8, 522},
+ /*II_0F_03*/ {0xf, 16, 11, 8, 527},
+ /*II_0F_05*/ {0x26, 0, 0, 27, 532},
+ /*II_0F_06*/ {0x26, 0, 0, 8, 541},
+ /*II_0F_07*/ {0x26, 0, 0, 27, 547},
+ /*II_0F_08*/ {0x26, 0, 0, 8, 555},
+ /*II_0F_09*/ {0x26, 0, 0, 8, 561},
+ /*II_0F_0B*/ {0x26, 0, 0, 14, 569},
+ /*II_0F_0E*/ {0x10, 0, 0, 96, 574},
+ /*II_0F_1F*/ {0xf, 0, 17, 8, 581},
+ /*II_0F_20*/ {0x27, 29, 14, 8, 218},
+ /*II_0F_21*/ {0x27, 30, 14, 8, 218},
+ /*II_0F_22*/ {0x27, 14, 29, 8, 218},
+ /*II_0F_23*/ {0x27, 14, 30, 8, 218},
+ /*II_0F_30*/ {0x26, 0, 0, 8, 586},
+ /*II_0F_31*/ {0x26, 0, 0, 8, 593},
+ /*II_0F_32*/ {0x26, 0, 0, 8, 600},
+ /*II_0F_33*/ {0x26, 0, 0, 8, 607},
+ /*II_0F_34*/ {0x26, 0, 0, 27, 614},
+ /*II_0F_35*/ {0x26, 0, 0, 27, 624},
+ /*II_0F_37*/ {0x28, 0, 0, 8, 633},
+ /*II_0F_40*/ {0x29, 17, 11, 31, 641},
+ /*II_0F_41*/ {0x29, 17, 11, 31, 648},
+ /*II_0F_42*/ {0x29, 17, 11, 31, 656},
+ /*II_0F_43*/ {0x29, 17, 11, 31, 663},
+ /*II_0F_44*/ {0x29, 17, 11, 31, 671},
+ /*II_0F_45*/ {0x29, 17, 11, 31, 678},
+ /*II_0F_46*/ {0x29, 17, 11, 31, 686},
+ /*II_0F_47*/ {0x29, 17, 11, 31, 694},
+ /*II_0F_48*/ {0x29, 17, 11, 31, 701},
+ /*II_0F_49*/ {0x29, 17, 11, 31, 708},
+ /*II_0F_4A*/ {0x29, 17, 11, 31, 716},
+ /*II_0F_4B*/ {0x29, 17, 11, 31, 723},
+ /*II_0F_4C*/ {0x29, 17, 11, 31, 731},
+ /*II_0F_4D*/ {0x29, 17, 11, 31, 738},
+ /*II_0F_4E*/ {0x29, 17, 11, 31, 746},
+ /*II_0F_4F*/ {0x29, 17, 11, 31, 754},
+ /*II_0F_80*/ {0x26, 0, 41, 13, 134},
+ /*II_0F_81*/ {0x26, 0, 41, 13, 138},
+ /*II_0F_82*/ {0x26, 0, 41, 13, 143},
+ /*II_0F_83*/ {0x26, 0, 41, 13, 147},
+ /*II_0F_84*/ {0x26, 0, 41, 13, 152},
+ /*II_0F_85*/ {0x26, 0, 41, 13, 156},
+ /*II_0F_86*/ {0x26, 0, 41, 13, 161},
+ /*II_0F_87*/ {0x26, 0, 41, 13, 166},
+ /*II_0F_88*/ {0x26, 0, 41, 13, 170},
+ /*II_0F_89*/ {0x26, 0, 41, 13, 174},
+ /*II_0F_8A*/ {0x26, 0, 41, 13, 179},
+ /*II_0F_8B*/ {0x26, 0, 41, 13, 183},
+ /*II_0F_8C*/ {0x26, 0, 41, 13, 188},
+ /*II_0F_8D*/ {0x26, 0, 41, 13, 192},
+ /*II_0F_8E*/ {0x26, 0, 41, 13, 197},
+ /*II_0F_8F*/ {0x26, 0, 41, 13, 202},
+ /*II_0F_90*/ {0x29, 0, 15, 8, 761},
+ /*II_0F_91*/ {0x29, 0, 15, 8, 767},
+ /*II_0F_92*/ {0x29, 0, 15, 8, 774},
+ /*II_0F_93*/ {0x29, 0, 15, 8, 780},
+ /*II_0F_94*/ {0x29, 0, 15, 8, 787},
+ /*II_0F_95*/ {0x29, 0, 15, 8, 793},
+ /*II_0F_96*/ {0x29, 0, 15, 8, 800},
+ /*II_0F_97*/ {0x29, 0, 15, 8, 807},
+ /*II_0F_98*/ {0x29, 0, 15, 8, 813},
+ /*II_0F_99*/ {0x29, 0, 15, 8, 819},
+ /*II_0F_9A*/ {0x29, 0, 15, 8, 826},
+ /*II_0F_9B*/ {0x29, 0, 15, 8, 832},
+ /*II_0F_9C*/ {0x29, 0, 15, 8, 839},
+ /*II_0F_9D*/ {0x29, 0, 15, 8, 845},
+ /*II_0F_9E*/ {0x29, 0, 15, 8, 852},
+ /*II_0F_9F*/ {0x29, 0, 15, 8, 859},
+ /*II_0F_A0*/ {0x2a, 0, 32, 8, 16},
+ /*II_0F_A1*/ {0x2b, 0, 32, 8, 22},
+ /*II_0F_A2*/ {0x26, 0, 0, 8, 865},
+ /*II_0F_A3*/ {0x29, 11, 17, 8, 872},
+ /*II_0F_A8*/ {0x2d, 0, 32, 8, 16},
+ /*II_0F_A9*/ {0x2e, 0, 32, 8, 22},
+ /*II_0F_AA*/ {0x26, 0, 0, 8, 882},
+ /*II_0F_AB*/ {0x2f, 11, 17, 8, 887},
+ /*II_0F_AF*/ {0x29, 17, 11, 8, 117},
+ /*II_0F_B0*/ {0x2f, 9, 15, 8, 898},
+ /*II_0F_B1*/ {0x2f, 11, 17, 8, 898},
+ /*II_0F_B2*/ {0x30, 37, 11, 8, 907},
+ /*II_0F_B3*/ {0x2f, 11, 17, 8, 912},
+ /*II_0F_B4*/ {0x30, 37, 11, 8, 917},
+ /*II_0F_B5*/ {0x30, 37, 11, 8, 922},
+ /*II_0F_B6*/ {0x29, 15, 11, 8, 927},
+ /*II_0F_B7*/ {0x31, 16, 11, 8, 927},
+ /*II_0F_B9*/ {0x26, 0, 0, 14, 569},
+ /*II_0F_BB*/ {0x2f, 11, 17, 8, 934},
+ /*II_0F_BE*/ {0x29, 15, 11, 8, 939},
+ /*II_0F_BF*/ {0x31, 16, 11, 8, 939},
+ /*II_0F_C0*/ {0x2f, 9, 15, 8, 946},
+ /*II_0F_C1*/ {0x2f, 11, 17, 8, 946},
+ /*II_0F_C3*/ {0x31, 13, 45, 48, 952},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_0F_C8*/ {0x32, 0, 54, 8, 960},
+ /*II_80_00*/ {0x33, 1, 15, 8, 11},
+ /*II_80_01*/ {0x33, 1, 15, 8, 27},
+ /*II_80_02*/ {0x33, 1, 15, 8, 31},
+ /*II_80_03*/ {0x33, 1, 15, 8, 36},
+ /*II_80_04*/ {0x33, 1, 15, 8, 41},
+ /*II_80_05*/ {0x33, 1, 15, 8, 51},
+ /*II_80_06*/ {0x33, 1, 15, 8, 61},
+ /*II_80_07*/ {0x34, 1, 15, 8, 71},
+ /*II_81_00*/ {0x33, 3, 17, 8, 11},
+ /*II_81_01*/ {0x33, 3, 17, 8, 27},
+ /*II_81_02*/ {0x33, 3, 17, 8, 31},
+ /*II_81_03*/ {0x33, 3, 17, 8, 36},
+ /*II_81_04*/ {0x33, 3, 17, 8, 41},
+ /*II_81_05*/ {0x33, 3, 17, 8, 51},
+ /*II_81_06*/ {0x33, 3, 17, 8, 61},
+ /*II_81_07*/ {0x34, 3, 17, 8, 71},
+ /*II_82_00*/ {0x35, 1, 15, 8, 11},
+ /*II_82_01*/ {0x35, 1, 15, 8, 27},
+ /*II_82_02*/ {0x35, 1, 15, 8, 31},
+ /*II_82_03*/ {0x35, 1, 15, 8, 36},
+ /*II_82_04*/ {0x35, 1, 15, 8, 41},
+ /*II_82_05*/ {0x35, 1, 15, 8, 51},
+ /*II_82_06*/ {0x35, 1, 15, 8, 61},
+ /*II_82_07*/ {0x36, 1, 15, 8, 71},
+ /*II_83_00*/ {0x33, 5, 17, 8, 11},
+ /*II_83_01*/ {0x37, 5, 17, 8, 27},
+ /*II_83_02*/ {0x33, 5, 17, 8, 31},
+ /*II_83_03*/ {0x33, 5, 17, 8, 36},
+ /*II_83_04*/ {0x37, 5, 17, 8, 41},
+ /*II_83_05*/ {0x33, 5, 17, 8, 51},
+ /*II_83_06*/ {0x37, 5, 17, 8, 61},
+ /*II_83_07*/ {0x34, 5, 17, 8, 71},
+ /*II_8F_00*/ {0x38, 0, 17, 8, 22},
+ /*II_C0_00*/ {0x39, 1, 15, 8, 967},
+ /*II_C0_01*/ {0x39, 1, 15, 8, 972},
+ /*II_C0_02*/ {0x39, 1, 15, 8, 977},
+ /*II_C0_03*/ {0x39, 1, 15, 8, 982},
+ /*II_C0_04*/ {0x39, 1, 15, 8, 987},
+ /*II_C0_05*/ {0x39, 1, 15, 8, 992},
+ /*II_C0_06*/ {0x39, 1, 15, 8, 997},
+ /*II_C0_07*/ {0x39, 1, 15, 8, 1002},
+ /*II_C1_00*/ {0x39, 1, 17, 8, 967},
+ /*II_C1_01*/ {0x39, 1, 17, 8, 972},
+ /*II_C1_02*/ {0x39, 1, 17, 8, 977},
+ /*II_C1_03*/ {0x39, 1, 17, 8, 982},
+ /*II_C1_04*/ {0x39, 1, 17, 8, 987},
+ /*II_C1_05*/ {0x39, 1, 17, 8, 992},
+ /*II_C1_06*/ {0x39, 1, 17, 8, 997},
+ /*II_C1_07*/ {0x39, 1, 17, 8, 1002},
+ /*II_C6_00*/ {0x39, 1, 15, 8, 218},
+ /*II_C7_00*/ {0x39, 3, 17, 8, 218},
+ /*II_D0_00*/ {0x39, 51, 15, 8, 967},
+ /*II_D0_01*/ {0x39, 51, 15, 8, 972},
+ /*II_D0_02*/ {0x39, 51, 15, 8, 977},
+ /*II_D0_03*/ {0x39, 51, 15, 8, 982},
+ /*II_D0_04*/ {0x39, 51, 15, 8, 987},
+ /*II_D0_05*/ {0x39, 51, 15, 8, 992},
+ /*II_D0_06*/ {0x39, 51, 15, 8, 997},
+ /*II_D0_07*/ {0x39, 51, 15, 8, 1002},
+ /*II_D1_00*/ {0x39, 51, 17, 8, 967},
+ /*II_D1_01*/ {0x39, 51, 17, 8, 972},
+ /*II_D1_02*/ {0x39, 51, 17, 8, 977},
+ /*II_D1_03*/ {0x39, 51, 17, 8, 982},
+ /*II_D1_04*/ {0x39, 51, 17, 8, 987},
+ /*II_D1_05*/ {0x39, 51, 17, 8, 992},
+ /*II_D1_06*/ {0x39, 51, 17, 8, 997},
+ /*II_D1_07*/ {0x39, 51, 17, 8, 1002},
+ /*II_D2_00*/ {0x39, 52, 15, 8, 967},
+ /*II_D2_01*/ {0x39, 52, 15, 8, 972},
+ /*II_D2_02*/ {0x39, 52, 15, 8, 977},
+ /*II_D2_03*/ {0x39, 52, 15, 8, 982},
+ /*II_D2_04*/ {0x39, 52, 15, 8, 987},
+ /*II_D2_05*/ {0x39, 52, 15, 8, 992},
+ /*II_D2_06*/ {0x39, 52, 15, 8, 997},
+ /*II_D2_07*/ {0x39, 52, 15, 8, 1002},
+ /*II_D3_00*/ {0x39, 52, 17, 8, 967},
+ /*II_D3_01*/ {0x39, 52, 17, 8, 972},
+ /*II_D3_02*/ {0x39, 52, 17, 8, 977},
+ /*II_D3_03*/ {0x39, 52, 17, 8, 982},
+ /*II_D3_04*/ {0x39, 52, 17, 8, 987},
+ /*II_D3_05*/ {0x39, 52, 17, 8, 992},
+ /*II_D3_06*/ {0x39, 52, 17, 8, 997},
+ /*II_D3_07*/ {0x39, 52, 17, 8, 1002},
+ /*II_D8_00*/ {0x34, 0, 21, 16, 1007},
+ /*II_D8_01*/ {0x34, 0, 21, 16, 1013},
+ /*II_D8_02*/ {0x34, 0, 21, 16, 1019},
+ /*II_D8_03*/ {0x34, 0, 21, 16, 1025},
+ /*II_D8_04*/ {0x34, 0, 21, 16, 1032},
+ /*II_D8_05*/ {0x34, 0, 21, 16, 1038},
+ /*II_D8_06*/ {0x34, 0, 21, 16, 1045},
+ /*II_D8_07*/ {0x34, 0, 21, 16, 1051},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C0*/ {0x3a, 0, 62, 16, 1007},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_C8*/ {0x3a, 0, 62, 16, 1013},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D0*/ {0x3a, 0, 61, 16, 1019},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_D9*/ {0x3a, 0, 0, 16, 1025},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_D8*/ {0x3a, 0, 61, 16, 1025},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E0*/ {0x3a, 0, 62, 16, 1032},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_E8*/ {0x3a, 0, 62, 16, 1038},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F0*/ {0x3a, 0, 62, 16, 1045},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D8_F8*/ {0x3a, 0, 62, 16, 1051},
+ /*II_D9_00*/ {0x34, 0, 21, 16, 1058},
+ /*II_D9_02*/ {0x34, 0, 21, 16, 1063},
+ /*II_D9_03*/ {0x34, 0, 21, 16, 1068},
+ /*II_D9_04*/ {0x34, 0, 42, 16, 1074},
+ /*II_D9_05*/ {0x34, 0, 42, 16, 1082},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C0*/ {0x3a, 0, 61, 16, 1058},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_C9*/ {0x3a, 0, 0, 16, 1089},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_C8*/ {0x3a, 0, 61, 16, 1089},
+ /*II_D9_D0*/ {0x3a, 0, 0, 16, 1095},
+ /*II_D9_E0*/ {0x3a, 0, 0, 16, 1101},
+ /*II_D9_E1*/ {0x3a, 0, 0, 16, 1107},
+ /*II_D9_E4*/ {0x3a, 0, 0, 16, 1113},
+ /*II_D9_E5*/ {0x3a, 0, 0, 16, 1119},
+ /*II_D9_E8*/ {0x3a, 0, 0, 16, 1125},
+ /*II_D9_E9*/ {0x3a, 0, 0, 16, 1131},
+ /*II_D9_EA*/ {0x3a, 0, 0, 16, 1139},
+ /*II_D9_EB*/ {0x3a, 0, 0, 16, 1147},
+ /*II_D9_EC*/ {0x3a, 0, 0, 16, 1154},
+ /*II_D9_ED*/ {0x3a, 0, 0, 16, 1162},
+ /*II_D9_EE*/ {0x3a, 0, 0, 16, 1170},
+ /*II_D9_F0*/ {0x3a, 0, 0, 16, 1176},
+ /*II_D9_F1*/ {0x3a, 0, 0, 16, 1183},
+ /*II_D9_F2*/ {0x3a, 0, 0, 16, 1190},
+ /*II_D9_F3*/ {0x3a, 0, 0, 16, 1197},
+ /*II_D9_F4*/ {0x3a, 0, 0, 16, 1205},
+ /*II_D9_F5*/ {0x3a, 0, 0, 16, 1214},
+ /*II_D9_F6*/ {0x3a, 0, 0, 16, 1222},
+ /*II_D9_F7*/ {0x3a, 0, 0, 16, 1231},
+ /*II_D9_F8*/ {0x3a, 0, 0, 16, 1240},
+ /*II_D9_F9*/ {0x3a, 0, 0, 16, 1247},
+ /*II_D9_FA*/ {0x3a, 0, 0, 16, 1256},
+ /*II_D9_FB*/ {0x3a, 0, 0, 16, 1263},
+ /*II_D9_FC*/ {0x3a, 0, 0, 16, 1272},
+ /*II_D9_FD*/ {0x3a, 0, 0, 16, 1281},
+ /*II_D9_FE*/ {0x3a, 0, 0, 16, 1289},
+ /*II_D9_FF*/ {0x3a, 0, 0, 16, 1295},
+ /*II_DA_00*/ {0x34, 0, 21, 16, 1301},
+ /*II_DA_01*/ {0x34, 0, 21, 16, 1308},
+ /*II_DA_02*/ {0x34, 0, 21, 16, 1315},
+ /*II_DA_03*/ {0x34, 0, 21, 16, 1322},
+ /*II_DA_04*/ {0x34, 0, 21, 16, 1330},
+ /*II_DA_05*/ {0x34, 0, 21, 16, 1337},
+ /*II_DA_06*/ {0x34, 0, 21, 16, 1345},
+ /*II_DA_07*/ {0x34, 0, 21, 16, 1352},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C0*/ {0x3b, 0, 62, 24, 1360},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_C8*/ {0x3b, 0, 62, 24, 1368},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D0*/ {0x3b, 0, 62, 24, 1376},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_D8*/ {0x3b, 0, 62, 24, 1385},
+ /*II_DA_E9*/ {0x3a, 0, 0, 16, 1393},
+ /*II_DB_00*/ {0x34, 0, 21, 16, 1402},
+ /*II_DB_01*/ {0x3c, 0, 21, 56, 1408},
+ /*II_DB_02*/ {0x34, 0, 21, 16, 1416},
+ /*II_DB_03*/ {0x34, 0, 21, 16, 1422},
+ /*II_DB_05*/ {0x34, 0, 23, 16, 1058},
+ /*II_DB_07*/ {0x34, 0, 23, 16, 1068},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C0*/ {0x3b, 0, 62, 24, 1429},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_C8*/ {0x3b, 0, 62, 24, 1438},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D0*/ {0x3b, 0, 62, 24, 1447},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_D8*/ {0x3b, 0, 62, 24, 1457},
+ /*II_DB_E0*/ {0x3a, 0, 0, 16, 1466},
+ /*II_DB_E1*/ {0x3a, 0, 0, 16, 1472},
+ /*II_DB_E4*/ {0x3a, 0, 0, 16, 1480},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_E8*/ {0x3b, 0, 62, 16, 1488},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DB_F0*/ {0x3b, 0, 62, 24, 1496},
+ /*II_DC_00*/ {0x34, 0, 22, 16, 1007},
+ /*II_DC_01*/ {0x34, 0, 22, 16, 1013},
+ /*II_DC_02*/ {0x34, 0, 22, 16, 1019},
+ /*II_DC_03*/ {0x34, 0, 22, 16, 1025},
+ /*II_DC_04*/ {0x34, 0, 22, 16, 1032},
+ /*II_DC_05*/ {0x34, 0, 22, 16, 1038},
+ /*II_DC_06*/ {0x34, 0, 22, 16, 1045},
+ /*II_DC_07*/ {0x34, 0, 22, 16, 1051},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C0*/ {0x3a, 0, 63, 16, 1007},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_C8*/ {0x3a, 0, 63, 16, 1013},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E0*/ {0x3a, 0, 63, 16, 1038},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_E8*/ {0x3a, 0, 63, 16, 1032},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F0*/ {0x3a, 0, 63, 16, 1051},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DC_F8*/ {0x3a, 0, 63, 16, 1045},
+ /*II_DD_00*/ {0x34, 0, 22, 16, 1058},
+ /*II_DD_01*/ {0x3c, 0, 22, 56, 1408},
+ /*II_DD_02*/ {0x34, 0, 22, 16, 1063},
+ /*II_DD_03*/ {0x34, 0, 22, 16, 1068},
+ /*II_DD_04*/ {0x34, 0, 42, 16, 1503},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_C0*/ {0x3a, 0, 61, 16, 1511},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D0*/ {0x3a, 0, 61, 16, 1063},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_D8*/ {0x3a, 0, 61, 16, 1068},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E1*/ {0x3a, 0, 0, 16, 1518},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E0*/ {0x3a, 0, 63, 16, 1518},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DD_E9*/ {0x3a, 0, 0, 16, 1525},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DD_E8*/ {0x3a, 0, 61, 16, 1525},
+ /*II_DE_00*/ {0x34, 0, 20, 16, 1301},
+ /*II_DE_01*/ {0x34, 0, 20, 16, 1308},
+ /*II_DE_02*/ {0x34, 0, 20, 16, 1315},
+ /*II_DE_03*/ {0x34, 0, 20, 16, 1322},
+ /*II_DE_04*/ {0x34, 0, 20, 16, 1330},
+ /*II_DE_05*/ {0x34, 0, 20, 16, 1337},
+ /*II_DE_06*/ {0x34, 0, 20, 16, 1345},
+ /*II_DE_07*/ {0x34, 0, 20, 16, 1352},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C1*/ {0x3a, 0, 0, 16, 1533},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C0*/ {0x3a, 0, 63, 16, 1533},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_C9*/ {0x3a, 0, 0, 16, 1540},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_C8*/ {0x3a, 0, 63, 16, 1540},
+ /*II_DE_D9*/ {0x3a, 0, 0, 16, 1547},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E1*/ {0x3a, 0, 0, 16, 1555},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E0*/ {0x3a, 0, 63, 16, 1555},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_E9*/ {0x3a, 0, 0, 16, 1563},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_E8*/ {0x3a, 0, 63, 16, 1563},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F1*/ {0x3a, 0, 0, 16, 1570},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F0*/ {0x3a, 0, 63, 16, 1570},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DE_F9*/ {0x3a, 0, 0, 16, 1578},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DE_F8*/ {0x3a, 0, 63, 16, 1578},
+ /*II_DF_00*/ {0x34, 0, 20, 16, 1402},
+ /*II_DF_01*/ {0x3c, 0, 20, 56, 1408},
+ /*II_DF_02*/ {0x34, 0, 20, 16, 1416},
+ /*II_DF_03*/ {0x34, 0, 20, 16, 1422},
+ /*II_DF_04*/ {0x34, 0, 23, 16, 1585},
+ /*II_DF_05*/ {0x34, 0, 22, 16, 1402},
+ /*II_DF_06*/ {0x34, 0, 23, 16, 1591},
+ /*II_DF_07*/ {0x34, 0, 22, 16, 1422},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_E8*/ {0x3b, 0, 62, 16, 1598},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_DF_F0*/ {0x3b, 0, 62, 16, 1607},
+ /*II_F6_00*/ {0x34, 1, 15, 8, 206},
+ /*II_F6_02*/ {0x33, 0, 15, 8, 1615},
+ /*II_F6_03*/ {0x33, 0, 15, 8, 1620},
+ /*II_F6_04*/ {0x39, 0, 15, 8, 1625},
+ /*II_F6_05*/ {0x39, 0, 15, 8, 117},
+ /*II_F6_06*/ {0x39, 0, 15, 8, 1630},
+ /*II_F6_07*/ {0x39, 0, 15, 8, 1635},
+ /*II_F7_00*/ {0x34, 3, 17, 8, 206},
+ /*II_F7_02*/ {0x33, 0, 17, 8, 1615},
+ /*II_F7_03*/ {0x33, 0, 17, 8, 1620},
+ /*II_F7_04*/ {0x39, 0, 17, 8, 1625},
+ /*II_F7_05*/ {0x39, 0, 17, 8, 117},
+ /*II_F7_06*/ {0x39, 0, 17, 8, 1630},
+ /*II_F7_07*/ {0x39, 0, 17, 8, 1635},
+ /*II_FE_00*/ {0x33, 0, 15, 8, 81},
+ /*II_FE_01*/ {0x33, 0, 15, 8, 86},
+ /*II_FF_00*/ {0x33, 0, 17, 8, 81},
+ /*II_FF_01*/ {0x33, 0, 17, 8, 86},
+ /*II_FF_02*/ {0x3d, 0, 17, 9, 456},
+ /*II_FF_03*/ {0x3e, 0, 37, 9, 260},
+ /*II_FF_04*/ {0x3d, 0, 17, 12, 462},
+ /*II_FF_05*/ {0x3e, 0, 37, 12, 467},
+ /*II_FF_06*/ {0x3d, 0, 17, 8, 16},
+ /*II_0F_00_00*/ {0x34, 0, 17, 8, 1641},
+ /*II_0F_00_01*/ {0x34, 0, 16, 8, 1647},
+ /*II_0F_00_02*/ {0x34, 0, 16, 8, 1652},
+ /*II_0F_00_03*/ {0x3c, 0, 16, 8, 1658},
+ /*II_0F_00_04*/ {0x34, 0, 16, 8, 1663},
+ /*II_0F_00_05*/ {0x34, 0, 16, 8, 1669},
+ /*II_0F_01_00*/ {0x3d, 0, 39, 8, 1675},
+ /*II_0F_01_01*/ {0x3d, 0, 39, 8, 1681},
+ /*II_0F_01_02*/ {0x3d, 0, 39, 8, 1687},
+ /*II_0F_01_03*/ {0x3d, 0, 39, 8, 1693},
+ /*II_0F_01_04*/ {0x3f, 0, 28, 8, 1699},
+ /*II_0F_01_06*/ {0x40, 0, 16, 8, 1705},
+ /*II_0F_01_07*/ {0x3c, 0, 42, 8, 1711},
+ /*II_0F_01_C1*/ {0x3b, 0, 0, 112, 1719},
+ /*II_0F_01_C2*/ {0x3b, 0, 0, 112, 1727},
+ /*II_0F_01_C3*/ {0x3b, 0, 0, 112, 1737},
+ /*II_0F_01_C4*/ {0x3b, 0, 0, 112, 1747},
+ /*II_0F_01_C8*/ {0x3b, 0, 0, 8, 1755},
+ /*II_0F_01_C9*/ {0x3b, 0, 0, 8, 1764},
+ /*II_0F_01_D0*/ {0x26, 0, 0, 8, 1771},
+ /*II_0F_01_D1*/ {0x26, 0, 0, 8, 1779},
+ /*II_0F_01_D4*/ {0x3b, 0, 0, 112, 1787},
+ /*II_0F_01_D8*/ {0x3c, 0, 58, 120, 1795},
+ /*II_0F_01_D9*/ {0x3b, 0, 0, 120, 1802},
+ /*II_0F_01_DA*/ {0x3b, 0, 58, 120, 1811},
+ /*II_0F_01_DB*/ {0x3b, 0, 58, 120, 1819},
+ /*II_0F_01_DC*/ {0x3b, 0, 0, 120, 1827},
+ /*II_0F_01_DD*/ {0x3b, 0, 0, 120, 1833},
+ /*II_0F_01_DE*/ {0x3b, 0, 58, 120, 1839},
+ /*II_0F_01_DF*/ {0x3b, 60, 58, 120, 1847},
+ /*II_0F_01_F8*/ {0x41, 0, 0, 8, 1856},
+ /*II_0F_01_F9*/ {0x41, 0, 0, 8, 1864},
+ /*II_0F_0D_00*/ {0x3c, 0, 42, 96, 1872},
+ /*II_0F_0D_01*/ {0x3c, 0, 42, 96, 1882},
+ /*II_0F_0F_0C*/ {0x42, 67, 64, 104, 1893},
+ /*II_0F_0F_0D*/ {0x42, 67, 64, 96, 1900},
+ /*II_0F_0F_1C*/ {0x42, 67, 64, 104, 1907},
+ /*II_0F_0F_1D*/ {0x42, 67, 64, 96, 1914},
+ /*II_0F_0F_8A*/ {0x42, 67, 64, 104, 1921},
+ /*II_0F_0F_8E*/ {0x42, 67, 64, 104, 1929},
+ /*II_0F_0F_90*/ {0x42, 67, 64, 96, 1938},
+ /*II_0F_0F_94*/ {0x42, 67, 64, 96, 1947},
+ /*II_0F_0F_96*/ {0x42, 67, 64, 96, 1954},
+ /*II_0F_0F_97*/ {0x42, 67, 64, 96, 1961},
+ /*II_0F_0F_9A*/ {0x42, 67, 64, 96, 1970},
+ /*II_0F_0F_9E*/ {0x42, 67, 64, 96, 1977},
+ /*II_0F_0F_A0*/ {0x42, 67, 64, 96, 1984},
+ /*II_0F_0F_A4*/ {0x42, 67, 64, 96, 1993},
+ /*II_0F_0F_A6*/ {0x42, 67, 64, 96, 2000},
+ /*II_0F_0F_A7*/ {0x42, 67, 64, 96, 2010},
+ /*II_0F_0F_AA*/ {0x42, 67, 64, 96, 2020},
+ /*II_0F_0F_AE*/ {0x42, 67, 64, 96, 2028},
+ /*II_0F_0F_B0*/ {0x42, 67, 64, 96, 2035},
+ /*II_0F_0F_B4*/ {0x42, 67, 64, 96, 2044},
+ /*II_0F_0F_B6*/ {0x42, 67, 64, 96, 2051},
+ /*II_0F_0F_B7*/ {0x42, 67, 64, 96, 2061},
+ /*II_0F_0F_BB*/ {0x42, 67, 64, 104, 2070},
+ /*II_0F_0F_BF*/ {0x42, 67, 64, 96, 2078},
+ /*II_0F_10*/ {0x29, 73, 68, 40, 2087},
+ /*II_66_0F_10*/ {0x29, 73, 68, 48, 2095},
+ /*II_F3_0F_10*/ {0x29, 71, 68, 40, 2103},
+ /*II_F2_0F_10*/ {0x29, 72, 68, 48, 2110},
+ /*II_0F_11*/ {0x29, 68, 73, 40, 2087},
+ /*II_66_0F_11*/ {0x29, 68, 73, 48, 2095},
+ /*II_F3_0F_11*/ {0x29, 68, 71, 40, 2103},
+ /*II_F2_0F_11*/ {0x29, 68, 72, 48, 2110},
+ /*II_66_0F_12*/ {0x29, 46, 68, 48, 2168},
+ /*II_F3_0F_12*/ {0x29, 72, 68, 56, 2176},
+ /*II_F2_0F_12*/ {0x29, 72, 68, 56, 2186},
+ /*II_0F_13*/ {0x29, 68, 46, 40, 2160},
+ /*II_66_0F_13*/ {0x29, 68, 46, 48, 2168},
+ /*II_0F_14*/ {0x28, 73, 68, 40, 2244},
+ /*II_66_0F_14*/ {0x28, 73, 68, 48, 2254},
+ /*II_0F_15*/ {0x28, 73, 68, 40, 2286},
+ /*II_66_0F_15*/ {0x28, 73, 68, 48, 2296},
+ /*II_66_0F_16*/ {0x29, 46, 68, 48, 2345},
+ /*II_F3_0F_16*/ {0x29, 73, 68, 56, 2353},
+ /*II_0F_17*/ {0x29, 68, 46, 40, 2337},
+ /*II_66_0F_17*/ {0x29, 68, 46, 48, 2345},
+ /*II_0F_18_00*/ {0x3c, 0, 42, 40, 2402},
+ /*II_0F_18_01*/ {0x3c, 0, 42, 40, 2415},
+ /*II_0F_18_02*/ {0x3c, 0, 42, 40, 2427},
+ /*II_0F_18_03*/ {0x3c, 0, 42, 40, 2439},
+ /*II_0F_28*/ {0x29, 73, 68, 40, 2451},
+ /*II_66_0F_28*/ {0x29, 73, 68, 48, 2459},
+ /*II_0F_29*/ {0x29, 68, 73, 40, 2451},
+ /*II_66_0F_29*/ {0x29, 68, 73, 48, 2459},
+ /*II_0F_2A*/ {0x28, 67, 68, 40, 2485},
+ /*II_66_0F_2A*/ {0x28, 67, 68, 48, 2495},
+ /*II_F3_0F_2A*/ {0x30, 18, 68, 40, 2505},
+ /*II_F2_0F_2A*/ {0x30, 18, 68, 48, 2515},
+ /*II_0F_2B*/ {0x29, 68, 47, 40, 2547},
+ /*II_66_0F_2B*/ {0x29, 68, 47, 48, 2556},
+ /*II_F3_0F_2B*/ {0x29, 68, 44, 88, 2565},
+ /*II_F2_0F_2B*/ {0x29, 68, 46, 88, 2574},
+ /*II_0F_2C*/ {0x28, 72, 64, 40, 2603},
+ /*II_66_0F_2C*/ {0x28, 73, 64, 48, 2614},
+ /*II_F3_0F_2C*/ {0x30, 71, 13, 40, 2625},
+ /*II_F2_0F_2C*/ {0x30, 72, 13, 48, 2636},
+ /*II_0F_2D*/ {0x28, 72, 64, 40, 2671},
+ /*II_66_0F_2D*/ {0x28, 73, 68, 48, 2681},
+ /*II_F3_0F_2D*/ {0x30, 71, 13, 40, 2691},
+ /*II_F2_0F_2D*/ {0x30, 72, 13, 48, 2701},
+ /*II_0F_2E*/ {0x28, 71, 68, 40, 2733},
+ /*II_66_0F_2E*/ {0x28, 72, 68, 48, 2742},
+ /*II_0F_2F*/ {0x28, 71, 68, 40, 2771},
+ /*II_66_0F_2F*/ {0x28, 72, 68, 48, 2779},
+ /*II_0F_50*/ {0x49, 69, 12, 40, 2805},
+ /*II_66_0F_50*/ {0x49, 69, 12, 48, 2815},
+ /*II_0F_51*/ {0x28, 73, 68, 40, 2847},
+ /*II_66_0F_51*/ {0x28, 73, 68, 48, 2855},
+ /*II_F3_0F_51*/ {0x28, 71, 68, 40, 2863},
+ /*II_F2_0F_51*/ {0x28, 72, 68, 48, 2871},
+ /*II_0F_52*/ {0x28, 73, 68, 40, 2915},
+ /*II_F3_0F_52*/ {0x28, 71, 68, 40, 2924},
+ /*II_0F_53*/ {0x28, 73, 68, 40, 2953},
+ /*II_F3_0F_53*/ {0x28, 71, 68, 40, 2960},
+ /*II_0F_54*/ {0x28, 73, 68, 40, 2983},
+ /*II_66_0F_54*/ {0x28, 73, 68, 48, 2990},
+ /*II_0F_55*/ {0x28, 73, 68, 40, 3013},
+ /*II_66_0F_55*/ {0x28, 73, 68, 48, 3021},
+ /*II_0F_56*/ {0x28, 73, 68, 40, 3047},
+ /*II_66_0F_56*/ {0x28, 73, 68, 48, 3053},
+ /*II_0F_57*/ {0x28, 73, 68, 40, 3073},
+ /*II_66_0F_57*/ {0x28, 73, 68, 48, 3080},
+ /*II_0F_58*/ {0x28, 73, 68, 40, 3103},
+ /*II_66_0F_58*/ {0x28, 73, 68, 48, 3110},
+ /*II_F3_0F_58*/ {0x28, 71, 68, 40, 3117},
+ /*II_F2_0F_58*/ {0x28, 72, 68, 48, 3124},
+ /*II_0F_59*/ {0x28, 73, 68, 40, 3163},
+ /*II_66_0F_59*/ {0x28, 73, 68, 48, 3170},
+ /*II_F3_0F_59*/ {0x28, 71, 68, 40, 3177},
+ /*II_F2_0F_59*/ {0x28, 72, 68, 48, 3184},
+ /*II_0F_5A*/ {0x28, 72, 68, 48, 3223},
+ /*II_66_0F_5A*/ {0x28, 73, 68, 48, 3233},
+ /*II_F3_0F_5A*/ {0x28, 71, 68, 48, 3243},
+ /*II_F2_0F_5A*/ {0x28, 72, 68, 48, 3253},
+ /*II_0F_5B*/ {0x28, 73, 68, 48, 3307},
+ /*II_66_0F_5B*/ {0x28, 73, 68, 48, 3317},
+ /*II_F3_0F_5B*/ {0x28, 73, 68, 48, 3327},
+ /*II_0F_5C*/ {0x28, 73, 68, 40, 3372},
+ /*II_66_0F_5C*/ {0x28, 73, 68, 48, 3379},
+ /*II_F3_0F_5C*/ {0x28, 71, 68, 40, 3386},
+ /*II_F2_0F_5C*/ {0x28, 72, 68, 48, 3393},
+ /*II_0F_5D*/ {0x28, 73, 68, 40, 3432},
+ /*II_66_0F_5D*/ {0x28, 73, 68, 48, 3439},
+ /*II_F3_0F_5D*/ {0x28, 71, 68, 40, 3446},
+ /*II_F2_0F_5D*/ {0x28, 72, 68, 48, 3453},
+ /*II_0F_5E*/ {0x28, 73, 68, 40, 3492},
+ /*II_66_0F_5E*/ {0x28, 73, 68, 48, 3499},
+ /*II_F3_0F_5E*/ {0x28, 71, 68, 40, 3506},
+ /*II_F2_0F_5E*/ {0x28, 72, 68, 48, 3513},
+ /*II_0F_5F*/ {0x28, 73, 68, 40, 3552},
+ /*II_66_0F_5F*/ {0x28, 73, 68, 48, 3559},
+ /*II_F3_0F_5F*/ {0x28, 71, 68, 40, 3566},
+ /*II_F2_0F_5F*/ {0x28, 72, 68, 48, 3573},
+ /*II_0F_60*/ {0x28, 66, 64, 32, 3612},
+ /*II_66_0F_60*/ {0x28, 73, 68, 48, 3612},
+ /*II_0F_61*/ {0x28, 66, 64, 32, 3635},
+ /*II_66_0F_61*/ {0x28, 73, 68, 48, 3635},
+ /*II_0F_62*/ {0x28, 66, 64, 32, 3658},
+ /*II_66_0F_62*/ {0x28, 73, 68, 48, 3658},
+ /*II_0F_63*/ {0x28, 67, 64, 32, 3681},
+ /*II_66_0F_63*/ {0x28, 73, 68, 48, 3681},
+ /*II_0F_64*/ {0x28, 67, 64, 32, 3702},
+ /*II_66_0F_64*/ {0x28, 73, 68, 48, 3702},
+ /*II_0F_65*/ {0x28, 67, 64, 32, 3721},
+ /*II_66_0F_65*/ {0x28, 73, 68, 48, 3721},
+ /*II_0F_66*/ {0x28, 67, 64, 32, 3740},
+ /*II_66_0F_66*/ {0x28, 73, 68, 48, 3740},
+ /*II_0F_67*/ {0x28, 67, 64, 32, 3759},
+ /*II_66_0F_67*/ {0x28, 73, 68, 48, 3759},
+ /*II_0F_68*/ {0x28, 67, 64, 32, 3780},
+ /*II_66_0F_68*/ {0x28, 73, 68, 48, 3780},
+ /*II_0F_69*/ {0x28, 67, 64, 32, 3803},
+ /*II_66_0F_69*/ {0x28, 73, 68, 48, 3803},
+ /*II_0F_6A*/ {0x28, 67, 64, 32, 3826},
+ /*II_66_0F_6A*/ {0x28, 73, 68, 48, 3826},
+ /*II_0F_6B*/ {0x28, 67, 64, 32, 3849},
+ /*II_66_0F_6B*/ {0x28, 73, 68, 48, 3849},
+ /*II_66_0F_6C*/ {0x28, 73, 68, 48, 3870},
+ /*II_66_0F_6D*/ {0x28, 73, 68, 48, 3895},
+ /*II_0F_6F*/ {0x29, 67, 64, 32, 3926},
+ /*II_66_0F_6F*/ {0x29, 73, 68, 48, 3946},
+ /*II_F3_0F_6F*/ {0x29, 73, 68, 48, 3954},
+ /*II_0F_74*/ {0x28, 67, 64, 32, 4043},
+ /*II_66_0F_74*/ {0x28, 73, 68, 48, 4043},
+ /*II_0F_75*/ {0x28, 67, 64, 32, 4062},
+ /*II_66_0F_75*/ {0x28, 73, 68, 48, 4062},
+ /*II_0F_76*/ {0x28, 67, 64, 32, 4081},
+ /*II_66_0F_76*/ {0x28, 73, 68, 48, 4081},
+ /*II_0F_77*/ {0x26, 0, 0, 32, 4100},
+ /*II_0F_78*/ {0x4e, 13, 18, 112, 4128},
+ /*II_0F_79*/ {0x4e, 18, 13, 112, 4152},
+ /*II_66_0F_79*/ {0x28, 69, 68, 88, 4136},
+ /*II_F2_0F_79*/ {0x51, 69, 68, 88, 4143},
+ /*II_0F_7A_30*/ {0x26, 72, 68, 112, 4161},
+ /*II_0F_7A_31*/ {0x26, 68, 72, 112, 4171},
+ /*II_66_0F_7C*/ {0x28, 73, 68, 56, 4181},
+ /*II_F2_0F_7C*/ {0x28, 73, 68, 56, 4189},
+ /*II_66_0F_7D*/ {0x28, 73, 68, 56, 4215},
+ /*II_F2_0F_7D*/ {0x28, 73, 68, 56, 4223},
+ /*II_F3_0F_7E*/ {0x29, 72, 68, 48, 3926},
+ /*II_0F_7F*/ {0x29, 64, 67, 32, 3926},
+ /*II_66_0F_7F*/ {0x29, 68, 73, 48, 3946},
+ /*II_F3_0F_7F*/ {0x29, 68, 73, 48, 3954},
+ /*II_F3_0F_B8*/ {0x55, 17, 11, 80, 4338},
+ /*II_0F_BA_04*/ {0x56, 1, 17, 8, 872},
+ /*II_0F_BA_05*/ {0x37, 1, 17, 8, 887},
+ /*II_0F_BA_06*/ {0x37, 1, 17, 8, 912},
+ /*II_0F_BA_07*/ {0x37, 1, 17, 8, 934},
+ /*II_0F_BC*/ {0x28, 17, 11, 8, 4346},
+ /*II_F3_0F_BC*/ {0x57, 17, 11, 112, 4351},
+ /*II_0F_BD*/ {0x28, 17, 11, 8, 4358},
+ /*II_F3_0F_BD*/ {0x58, 17, 11, 8, 4363},
+ /*II_0F_C7_07*/ {0x3c, 0, 46, 112, 6385},
+ /*II_66_0F_D0*/ {0x28, 73, 68, 56, 6394},
+ /*II_F2_0F_D0*/ {0x28, 73, 68, 56, 6404},
+ /*II_0F_D1*/ {0x28, 67, 64, 32, 6436},
+ /*II_66_0F_D1*/ {0x28, 73, 68, 48, 6436},
+ /*II_0F_D2*/ {0x28, 67, 64, 32, 6451},
+ /*II_66_0F_D2*/ {0x28, 73, 68, 48, 6451},
+ /*II_0F_D3*/ {0x28, 67, 64, 32, 6466},
+ /*II_66_0F_D3*/ {0x28, 73, 68, 48, 6466},
+ /*II_0F_D4*/ {0x28, 72, 68, 48, 6481},
+ /*II_66_0F_D4*/ {0x28, 73, 68, 48, 6481},
+ /*II_0F_D5*/ {0x28, 67, 64, 32, 6496},
+ /*II_66_0F_D5*/ {0x28, 73, 68, 48, 6496},
+ /*II_66_0F_D6*/ {0x29, 68, 72, 48, 3926},
+ /*II_F3_0F_D6*/ {0x49, 65, 68, 48, 6513},
+ /*II_F2_0F_D6*/ {0x49, 69, 64, 48, 6522},
+ /*II_0F_D7*/ {0x51, 65, 12, 40, 6531},
+ /*II_66_0F_D7*/ {0x51, 69, 12, 48, 6531},
+ /*II_0F_D8*/ {0x28, 67, 64, 32, 6552},
+ /*II_66_0F_D8*/ {0x28, 73, 68, 48, 6552},
+ /*II_0F_D9*/ {0x28, 67, 64, 32, 6571},
+ /*II_66_0F_D9*/ {0x28, 73, 68, 48, 6571},
+ /*II_0F_DA*/ {0x28, 67, 64, 40, 6590},
+ /*II_66_0F_DA*/ {0x28, 73, 68, 48, 6590},
+ /*II_0F_DB*/ {0x28, 67, 64, 32, 6607},
+ /*II_66_0F_DB*/ {0x28, 73, 68, 48, 6607},
+ /*II_0F_DC*/ {0x28, 67, 64, 32, 6620},
+ /*II_66_0F_DC*/ {0x28, 73, 68, 48, 6620},
+ /*II_0F_DD*/ {0x28, 67, 64, 32, 6639},
+ /*II_66_0F_DD*/ {0x28, 73, 68, 48, 6639},
+ /*II_0F_DE*/ {0x28, 67, 64, 40, 6648},
+ /*II_66_0F_DE*/ {0x28, 73, 68, 48, 6648},
+ /*II_0F_DF*/ {0x28, 67, 64, 32, 6665},
+ /*II_66_0F_DF*/ {0x28, 73, 68, 48, 6665},
+ /*II_0F_E0*/ {0x28, 67, 64, 40, 6680},
+ /*II_66_0F_E0*/ {0x28, 73, 68, 48, 6680},
+ /*II_0F_E1*/ {0x28, 67, 64, 32, 6695},
+ /*II_66_0F_E1*/ {0x28, 73, 68, 48, 6695},
+ /*II_0F_E2*/ {0x28, 67, 64, 32, 6710},
+ /*II_66_0F_E2*/ {0x28, 73, 68, 48, 6710},
+ /*II_0F_E3*/ {0x28, 67, 64, 40, 6725},
+ /*II_66_0F_E3*/ {0x28, 73, 68, 48, 6725},
+ /*II_0F_E4*/ {0x28, 67, 64, 40, 6740},
+ /*II_66_0F_E4*/ {0x28, 73, 68, 48, 6740},
+ /*II_0F_E5*/ {0x28, 67, 64, 32, 6759},
+ /*II_66_0F_E5*/ {0x28, 73, 68, 48, 6759},
+ /*II_66_0F_E6*/ {0x28, 73, 68, 48, 6776},
+ /*II_F3_0F_E6*/ {0x28, 72, 68, 48, 6787},
+ /*II_F2_0F_E6*/ {0x28, 73, 68, 48, 6797},
+ /*II_0F_E7*/ {0x29, 64, 46, 40, 6841},
+ /*II_66_0F_E7*/ {0x29, 68, 47, 48, 6849},
+ /*II_0F_E8*/ {0x28, 67, 64, 32, 6868},
+ /*II_66_0F_E8*/ {0x28, 73, 68, 48, 6868},
+ /*II_0F_E9*/ {0x28, 67, 64, 32, 6885},
+ /*II_66_0F_E9*/ {0x28, 73, 68, 48, 6885},
+ /*II_0F_EA*/ {0x28, 67, 64, 40, 6902},
+ /*II_66_0F_EA*/ {0x28, 73, 68, 48, 6902},
+ /*II_0F_EB*/ {0x28, 67, 64, 32, 6919},
+ /*II_66_0F_EB*/ {0x28, 73, 68, 48, 6919},
+ /*II_0F_EC*/ {0x28, 67, 64, 32, 6930},
+ /*II_66_0F_EC*/ {0x28, 73, 68, 48, 6930},
+ /*II_0F_ED*/ {0x28, 67, 64, 32, 6947},
+ /*II_66_0F_ED*/ {0x28, 73, 68, 48, 6947},
+ /*II_0F_EE*/ {0x28, 67, 64, 40, 6964},
+ /*II_66_0F_EE*/ {0x28, 73, 68, 48, 6964},
+ /*II_0F_EF*/ {0x28, 67, 64, 32, 6981},
+ /*II_66_0F_EF*/ {0x28, 73, 68, 48, 6981},
+ /*II_F2_0F_F0*/ {0x28, 42, 68, 56, 6994},
+ /*II_0F_F1*/ {0x28, 67, 64, 32, 7009},
+ /*II_66_0F_F1*/ {0x28, 73, 68, 48, 7009},
+ /*II_0F_F2*/ {0x28, 67, 64, 32, 7024},
+ /*II_66_0F_F2*/ {0x28, 73, 68, 48, 7024},
+ /*II_0F_F3*/ {0x28, 67, 64, 32, 7039},
+ /*II_66_0F_F3*/ {0x28, 73, 68, 48, 7039},
+ /*II_0F_F4*/ {0x28, 67, 64, 48, 7054},
+ /*II_66_0F_F4*/ {0x28, 73, 68, 48, 7054},
+ /*II_0F_F5*/ {0x28, 67, 64, 32, 7073},
+ /*II_66_0F_F5*/ {0x28, 73, 68, 48, 7073},
+ /*II_0F_F6*/ {0x28, 67, 64, 40, 7092},
+ /*II_66_0F_F6*/ {0x28, 73, 68, 48, 7092},
+ /*II_0F_F7*/ {0x51, 65, 64, 40, 7109},
+ /*II_66_0F_F7*/ {0x51, 69, 68, 48, 7119},
+ /*II_0F_F8*/ {0x28, 67, 64, 32, 7144},
+ /*II_66_0F_F8*/ {0x28, 73, 68, 48, 7144},
+ /*II_0F_F9*/ {0x28, 67, 64, 32, 7159},
+ /*II_66_0F_F9*/ {0x28, 73, 68, 48, 7159},
+ /*II_0F_FA*/ {0x28, 67, 64, 32, 7174},
+ /*II_66_0F_FA*/ {0x28, 73, 68, 48, 7174},
+ /*II_0F_FB*/ {0x28, 67, 64, 48, 7189},
+ /*II_66_0F_FB*/ {0x28, 73, 68, 48, 7189},
+ /*II_0F_FC*/ {0x28, 67, 64, 32, 7204},
+ /*II_66_0F_FC*/ {0x28, 73, 68, 48, 7204},
+ /*II_0F_FD*/ {0x28, 67, 64, 32, 7219},
+ /*II_66_0F_FD*/ {0x28, 73, 68, 48, 7219},
+ /*II_0F_FE*/ {0x28, 67, 64, 32, 7234},
+ /*II_66_0F_FE*/ {0x28, 73, 68, 48, 7234},
+ /*II_D9_06*/ {0x34, 0, 42, 16, 7249},
+ /*II_9B_D9_06*/ {0x60, 0, 42, 16, 7258},
+ /*II_D9_07*/ {0x34, 0, 42, 16, 7266},
+ /*II_9B_D9_07*/ {0x60, 0, 42, 16, 7274},
+ /*II_DB_E2*/ {0x3a, 0, 0, 16, 7281},
+ /*II_9B_DB_E2*/ {0x61, 0, 0, 16, 7289},
+ /*II_DB_E3*/ {0x3a, 0, 0, 16, 7296},
+ /*II_9B_DB_E3*/ {0x61, 0, 0, 16, 7304},
+ /*II_DD_06*/ {0x34, 0, 42, 16, 7311},
+ /*II_9B_DD_06*/ {0x60, 0, 42, 16, 7319},
+ /*II_DD_07*/ {0x34, 0, 42, 16, 7326},
+ /*II_9B_DD_07*/ {0x60, 0, 42, 16, 7334},
+ /*II_DF_E0*/ {0x3a, 0, 34, 16, 7326},
+ /*II_9B_DF_E0*/ {0x61, 0, 34, 16, 7334},
+ /*II_0F_38_00*/ {0x28, 67, 64, 64, 7341},
+ /*II_66_0F_38_00*/ {0x28, 73, 68, 64, 7341},
+ /*II_0F_38_01*/ {0x28, 67, 64, 64, 7358},
+ /*II_66_0F_38_01*/ {0x28, 73, 68, 64, 7358},
+ /*II_0F_38_02*/ {0x28, 67, 64, 64, 7375},
+ /*II_66_0F_38_02*/ {0x28, 73, 68, 64, 7375},
+ /*II_0F_38_03*/ {0x28, 67, 64, 64, 7392},
+ /*II_66_0F_38_03*/ {0x28, 73, 68, 64, 7392},
+ /*II_0F_38_04*/ {0x28, 67, 64, 64, 7411},
+ /*II_66_0F_38_04*/ {0x28, 73, 68, 64, 7411},
+ /*II_0F_38_05*/ {0x28, 67, 64, 64, 7434},
+ /*II_66_0F_38_05*/ {0x28, 73, 68, 64, 7434},
+ /*II_0F_38_06*/ {0x28, 67, 64, 64, 7451},
+ /*II_66_0F_38_06*/ {0x28, 73, 68, 64, 7451},
+ /*II_0F_38_07*/ {0x28, 67, 64, 64, 7468},
+ /*II_66_0F_38_07*/ {0x28, 73, 68, 64, 7468},
+ /*II_0F_38_08*/ {0x28, 67, 64, 64, 7487},
+ /*II_66_0F_38_08*/ {0x28, 73, 68, 64, 7487},
+ /*II_0F_38_09*/ {0x28, 67, 64, 64, 7504},
+ /*II_66_0F_38_09*/ {0x28, 73, 68, 64, 7504},
+ /*II_0F_38_0A*/ {0x28, 67, 64, 64, 7521},
+ /*II_66_0F_38_0A*/ {0x28, 73, 68, 64, 7521},
+ /*II_0F_38_0B*/ {0x28, 67, 64, 64, 7538},
+ /*II_66_0F_38_0B*/ {0x28, 73, 68, 64, 7538},
+ /*II_66_0F_38_17*/ {0x28, 73, 68, 80, 7629},
+ /*II_0F_38_1C*/ {0x28, 67, 64, 64, 7688},
+ /*II_66_0F_38_1C*/ {0x28, 73, 68, 64, 7688},
+ /*II_0F_38_1D*/ {0x28, 67, 64, 64, 7703},
+ /*II_66_0F_38_1D*/ {0x28, 73, 68, 64, 7703},
+ /*II_0F_38_1E*/ {0x28, 67, 64, 64, 7718},
+ /*II_66_0F_38_1E*/ {0x28, 73, 68, 64, 7718},
+ /*II_66_0F_38_20*/ {0x28, 72, 68, 72, 7733},
+ /*II_66_0F_38_21*/ {0x28, 71, 68, 72, 7754},
+ /*II_66_0F_38_22*/ {0x28, 70, 68, 72, 7775},
+ /*II_66_0F_38_23*/ {0x28, 72, 68, 72, 7796},
+ /*II_66_0F_38_24*/ {0x28, 71, 68, 72, 7817},
+ /*II_66_0F_38_25*/ {0x28, 72, 68, 72, 7838},
+ /*II_66_0F_38_28*/ {0x28, 73, 68, 72, 7859},
+ /*II_66_0F_38_29*/ {0x28, 73, 68, 72, 7876},
+ /*II_66_0F_38_2A*/ {0x29, 47, 68, 72, 7895},
+ /*II_66_0F_38_2B*/ {0x28, 73, 68, 72, 7916},
+ /*II_66_0F_38_30*/ {0x28, 72, 68, 72, 7961},
+ /*II_66_0F_38_31*/ {0x28, 71, 68, 72, 7982},
+ /*II_66_0F_38_32*/ {0x28, 70, 68, 72, 8003},
+ /*II_66_0F_38_33*/ {0x28, 72, 68, 72, 8024},
+ /*II_66_0F_38_34*/ {0x28, 71, 68, 72, 8045},
+ /*II_66_0F_38_35*/ {0x28, 72, 68, 72, 8066},
+ /*II_66_0F_38_37*/ {0x28, 73, 68, 80, 8087},
+ /*II_66_0F_38_38*/ {0x28, 73, 68, 72, 8106},
+ /*II_66_0F_38_39*/ {0x28, 73, 68, 72, 8123},
+ /*II_66_0F_38_3A*/ {0x28, 73, 68, 72, 8140},
+ /*II_66_0F_38_3B*/ {0x28, 73, 68, 72, 8157},
+ /*II_66_0F_38_3C*/ {0x28, 73, 68, 72, 8174},
+ /*II_66_0F_38_3D*/ {0x28, 73, 68, 72, 8191},
+ /*II_66_0F_38_3E*/ {0x28, 73, 68, 72, 8208},
+ /*II_66_0F_38_3F*/ {0x28, 73, 68, 72, 8225},
+ /*II_66_0F_38_40*/ {0x28, 73, 68, 72, 8242},
+ /*II_66_0F_38_41*/ {0x28, 73, 68, 72, 8259},
+ /*II_66_0F_38_80*/ {0x4e, 47, 13, 112, 8284},
+ /*II_66_0F_38_81*/ {0x4e, 47, 13, 112, 8292},
+ /*II_66_0F_38_82*/ {0x4e, 47, 13, 112, 8301},
+ /*II_66_0F_38_DB*/ {0x28, 73, 68, 152, 9150},
+ /*II_66_0F_38_DC*/ {0x28, 73, 68, 152, 9167},
+ /*II_66_0F_38_DD*/ {0x28, 73, 68, 152, 9184},
+ /*II_66_0F_38_DE*/ {0x28, 73, 68, 152, 9209},
+ /*II_66_0F_38_DF*/ {0x28, 73, 68, 152, 9226},
+ /*II_0F_38_F0*/ {0x29, 17, 11, 8, 9251},
+ /*II_F2_0F_38_F0*/ {0x29, 15, 13, 80, 9258},
+ /*II_0F_38_F1*/ {0x29, 11, 17, 8, 9251},
+ /*II_F2_0F_38_F1*/ {0x29, 17, 13, 80, 9258},
+ /*II_0F_71_02*/ {0x63, 1, 65, 32, 6436},
+ /*II_66_0F_71_02*/ {0x3c, 1, 69, 48, 6436},
+ /*II_0F_71_04*/ {0x63, 1, 65, 32, 6695},
+ /*II_66_0F_71_04*/ {0x3c, 1, 69, 48, 6695},
+ /*II_0F_71_06*/ {0x63, 1, 65, 32, 7009},
+ /*II_66_0F_71_06*/ {0x3c, 1, 69, 48, 7009},
+ /*II_0F_72_02*/ {0x63, 1, 65, 32, 6451},
+ /*II_66_0F_72_02*/ {0x3c, 1, 69, 48, 6451},
+ /*II_0F_72_04*/ {0x63, 1, 65, 32, 6710},
+ /*II_66_0F_72_04*/ {0x3c, 1, 69, 48, 6710},
+ /*II_0F_72_06*/ {0x63, 1, 65, 32, 7024},
+ /*II_66_0F_72_06*/ {0x3c, 1, 69, 48, 7024},
+ /*II_0F_73_02*/ {0x63, 1, 65, 32, 6466},
+ /*II_66_0F_73_02*/ {0x3c, 1, 69, 48, 6466},
+ /*II_66_0F_73_03*/ {0x3c, 1, 69, 48, 9830},
+ /*II_0F_73_06*/ {0x63, 1, 65, 32, 7039},
+ /*II_66_0F_73_06*/ {0x3c, 1, 69, 48, 7039},
+ /*II_66_0F_73_07*/ {0x3c, 1, 69, 48, 9847},
+ /*II_F3_0F_AE_00*/ {0x65, 0, 13, 112, 9882},
+ /*II_F3_0F_AE_01*/ {0x65, 0, 13, 112, 9912},
+ /*II_0F_AE_02*/ {0x3c, 0, 42, 8, 9922},
+ /*II_F3_0F_AE_02*/ {0x65, 0, 13, 112, 9931},
+ /*II_0F_AE_03*/ {0x3c, 0, 42, 8, 9951},
+ /*II_F3_0F_AE_03*/ {0x65, 0, 13, 112, 9960},
+ /*II_66_0F_C7_06*/ {0x3c, 0, 46, 112, 9997},
+ /*II_F3_0F_C7_06*/ {0x3c, 0, 46, 112, 10006}
+};
+
+_InstInfoEx InstInfosEx[] = {
+ /*II_69*/ {{0x17, 17, 11, 8, 117}, 0x0, 3, 0, 0, 0},
+ /*II_6B*/ {{0x17, 17, 11, 8, 117}, 0x0, 5, 0, 0, 0},
+ /*II_98*/ {{0x1c, 0, 0, 8, 228}, 0x0, 0, 0, 233, 239},
+ /*II_99*/ {{0x1c, 0, 0, 8, 245}, 0x0, 0, 0, 250, 255},
+ /*II_E3*/ {{0x25, 0, 40, 13, 427}, 0x0, 0, 0, 433, 440},
+ /*II_0F_A4*/ {{0x2c, 11, 17, 8, 876}, 0x0, 1, 0, 0, 0},
+ /*II_0F_A5*/ {{0x2c, 11, 17, 8, 876}, 0x0, 52, 0, 0, 0},
+ /*II_0F_AC*/ {{0x2c, 11, 17, 8, 892}, 0x0, 1, 0, 0, 0},
+ /*II_0F_AD*/ {{0x2c, 11, 17, 8, 892}, 0x0, 52, 0, 0, 0},
+ /*II_V_0F_10*/ {{0x43, 90, 83, 128, 2117}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_10*/ {{0x43, 90, 83, 128, 2126}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_10*/ {{0x44, 81, 68, 128, 2135}, 0x20, 69, 0, 0, 0},
+ /*II_V_F2_0F_10*/ {{0x44, 81, 68, 128, 2143}, 0x20, 69, 0, 0, 0},
+ /*II_VRR_F3_0F_10*/ {{0x45, 44, 68, 128, 2135}, 0x60, 0, 0, 0, 0},
+ /*II_VRR_F2_0F_10*/ {{0x45, 46, 68, 128, 2143}, 0x60, 0, 0, 0, 0},
+ /*II_V_0F_11*/ {{0x43, 83, 90, 128, 2117}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_11*/ {{0x43, 83, 90, 128, 2126}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_11*/ {{0x44, 81, 68, 128, 2135}, 0x20, 69, 0, 0, 0},
+ /*II_V_F2_0F_11*/ {{0x44, 81, 68, 128, 2143}, 0x20, 69, 0, 0, 0},
+ /*II_VRR_F3_0F_11*/ {{0x45, 68, 44, 128, 2135}, 0x60, 0, 0, 0, 0},
+ /*II_VRR_F2_0F_11*/ {{0x45, 68, 46, 128, 2143}, 0x60, 0, 0, 0, 0},
+ /*II_0F_12*/ {{0x46, 72, 68, 40, 2151}, 0x0, 0, 0, 2160, 0},
+ /*II_V_0F_12*/ {{0x47, 81, 68, 128, 2195}, 0x0, 72, 0, 2205, 0},
+ /*II_V_66_0F_12*/ {{0x48, 81, 68, 128, 2214}, 0x0, 46, 0, 0, 0},
+ /*II_V_F3_0F_12*/ {{0x43, 90, 83, 128, 2223}, 0x41, 0, 0, 0, 0},
+ /*II_V_F2_0F_12*/ {{0x43, 89, 83, 128, 2234}, 0x41, 0, 0, 0, 0},
+ /*II_V_0F_13*/ {{0x43, 68, 46, 128, 2205}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_13*/ {{0x43, 68, 46, 128, 2214}, 0x40, 0, 0, 0, 0},
+ /*II_V_0F_14*/ {{0x48, 88, 83, 128, 2264}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_14*/ {{0x48, 88, 83, 128, 2275}, 0x1, 90, 0, 0, 0},
+ /*II_V_0F_15*/ {{0x48, 88, 83, 128, 2306}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_15*/ {{0x48, 88, 83, 128, 2317}, 0x1, 90, 0, 0, 0},
+ /*II_0F_16*/ {{0x46, 72, 68, 40, 2328}, 0x0, 0, 0, 2337, 0},
+ /*II_V_0F_16*/ {{0x47, 81, 68, 128, 2363}, 0x0, 72, 0, 2373, 0},
+ /*II_V_66_0F_16*/ {{0x48, 81, 68, 128, 2382}, 0x0, 46, 0, 0, 0},
+ /*II_V_F3_0F_16*/ {{0x43, 90, 83, 128, 2391}, 0x41, 0, 0, 0, 0},
+ /*II_V_0F_17*/ {{0x43, 68, 46, 128, 2373}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_17*/ {{0x43, 68, 46, 128, 2382}, 0x40, 0, 0, 0, 0},
+ /*II_V_0F_28*/ {{0x43, 90, 83, 128, 2467}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_28*/ {{0x43, 90, 83, 128, 2476}, 0x41, 0, 0, 0, 0},
+ /*II_V_0F_29*/ {{0x43, 83, 90, 128, 2467}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_29*/ {{0x43, 83, 90, 128, 2476}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_2A*/ {{0x48, 81, 68, 128, 2525}, 0x2, 79, 0, 0, 0},
+ /*II_V_F2_0F_2A*/ {{0x48, 81, 68, 128, 2536}, 0x2, 79, 0, 0, 0},
+ /*II_V_0F_2B*/ {{0x43, 83, 92, 128, 2583}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_2B*/ {{0x43, 83, 92, 128, 2593}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_2C*/ {{0x43, 80, 78, 128, 2647}, 0x42, 0, 0, 0, 0},
+ /*II_V_F2_0F_2C*/ {{0x43, 80, 78, 128, 2659}, 0x42, 0, 0, 0, 0},
+ /*II_V_F3_0F_2D*/ {{0x43, 80, 78, 128, 2711}, 0x42, 0, 0, 0, 0},
+ /*II_V_F2_0F_2D*/ {{0x43, 80, 78, 128, 2722}, 0x42, 0, 0, 0, 0},
+ /*II_V_0F_2E*/ {{0x43, 71, 68, 128, 2751}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_2E*/ {{0x43, 72, 68, 128, 2761}, 0x40, 0, 0, 0, 0},
+ /*II_V_0F_2F*/ {{0x43, 71, 68, 128, 2787}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_2F*/ {{0x43, 72, 68, 128, 2796}, 0x40, 0, 0, 0, 0},
+ /*II_V_0F_50*/ {{0x4a, 83, 13, 128, 2825}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_50*/ {{0x4a, 83, 13, 128, 2836}, 0x41, 0, 0, 0, 0},
+ /*II_V_0F_51*/ {{0x43, 90, 83, 128, 2879}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_51*/ {{0x43, 90, 83, 128, 2888}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_51*/ {{0x48, 81, 68, 128, 2897}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_51*/ {{0x48, 81, 68, 128, 2906}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_52*/ {{0x43, 90, 83, 128, 2933}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_52*/ {{0x48, 81, 68, 128, 2943}, 0x0, 71, 0, 0, 0},
+ /*II_V_0F_53*/ {{0x43, 90, 83, 128, 2967}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_53*/ {{0x48, 81, 68, 128, 2975}, 0x0, 71, 0, 0, 0},
+ /*II_V_0F_54*/ {{0x48, 88, 83, 128, 2997}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_54*/ {{0x48, 88, 83, 128, 3005}, 0x1, 90, 0, 0, 0},
+ /*II_V_0F_55*/ {{0x48, 88, 83, 128, 3029}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_55*/ {{0x48, 88, 83, 128, 3038}, 0x1, 90, 0, 0, 0},
+ /*II_V_0F_56*/ {{0x48, 88, 83, 128, 3059}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_56*/ {{0x48, 88, 83, 128, 3066}, 0x1, 90, 0, 0, 0},
+ /*II_V_0F_57*/ {{0x48, 88, 83, 128, 3087}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_57*/ {{0x48, 88, 83, 128, 3095}, 0x1, 90, 0, 0, 0},
+ /*II_V_0F_58*/ {{0x48, 88, 83, 128, 3131}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_58*/ {{0x48, 88, 83, 128, 3139}, 0x1, 90, 0, 0, 0},
+ /*II_V_F3_0F_58*/ {{0x48, 81, 68, 128, 3147}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_58*/ {{0x48, 81, 68, 128, 3155}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_59*/ {{0x48, 88, 83, 128, 3191}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_59*/ {{0x48, 88, 83, 128, 3199}, 0x1, 90, 0, 0, 0},
+ /*II_V_F3_0F_59*/ {{0x48, 81, 68, 128, 3207}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_59*/ {{0x48, 81, 68, 128, 3215}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_5A*/ {{0x43, 91, 83, 128, 3263}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_5A*/ {{0x43, 90, 68, 128, 3274}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_5A*/ {{0x48, 81, 68, 128, 3285}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_5A*/ {{0x48, 81, 68, 128, 3296}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_5B*/ {{0x43, 90, 83, 128, 3338}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_5B*/ {{0x43, 90, 83, 128, 3349}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_5B*/ {{0x43, 90, 83, 128, 3360}, 0x41, 0, 0, 0, 0},
+ /*II_V_0F_5C*/ {{0x48, 88, 83, 128, 3400}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_5C*/ {{0x48, 88, 83, 128, 3408}, 0x1, 90, 0, 0, 0},
+ /*II_V_F3_0F_5C*/ {{0x48, 81, 68, 128, 3416}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_5C*/ {{0x48, 81, 68, 128, 3424}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_5D*/ {{0x48, 88, 83, 128, 3460}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_5D*/ {{0x48, 88, 83, 128, 3468}, 0x1, 90, 0, 0, 0},
+ /*II_V_F3_0F_5D*/ {{0x48, 81, 68, 128, 3476}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_5D*/ {{0x48, 81, 68, 128, 3484}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_5E*/ {{0x48, 88, 83, 128, 3520}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_5E*/ {{0x48, 88, 83, 128, 3528}, 0x1, 90, 0, 0, 0},
+ /*II_V_F3_0F_5E*/ {{0x48, 81, 68, 128, 3536}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_5E*/ {{0x48, 81, 68, 128, 3544}, 0x0, 72, 0, 0, 0},
+ /*II_V_0F_5F*/ {{0x48, 88, 83, 128, 3580}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_5F*/ {{0x48, 88, 83, 128, 3588}, 0x1, 90, 0, 0, 0},
+ /*II_V_F3_0F_5F*/ {{0x48, 81, 68, 128, 3596}, 0x0, 71, 0, 0, 0},
+ /*II_V_F2_0F_5F*/ {{0x48, 81, 68, 128, 3604}, 0x0, 72, 0, 0, 0},
+ /*II_V_66_0F_60*/ {{0x48, 81, 68, 128, 3623}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_61*/ {{0x48, 81, 68, 128, 3646}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_62*/ {{0x48, 81, 68, 128, 3669}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_63*/ {{0x48, 81, 68, 128, 3691}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_64*/ {{0x48, 81, 68, 128, 3711}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_65*/ {{0x48, 81, 68, 128, 3730}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_66*/ {{0x48, 81, 68, 128, 3749}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_67*/ {{0x48, 81, 68, 128, 3769}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_68*/ {{0x48, 81, 68, 128, 3791}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_69*/ {{0x48, 81, 68, 128, 3814}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_6A*/ {{0x48, 81, 68, 128, 3837}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_6B*/ {{0x48, 81, 68, 128, 3859}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_6C*/ {{0x48, 81, 68, 128, 3882}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_6D*/ {{0x48, 81, 68, 128, 3907}, 0x0, 73, 0, 0, 0},
+ /*II_0F_6E*/ {{0x4b, 18, 64, 32, 3920}, 0x0, 0, 0, 0, 3926},
+ /*II_66_0F_6E*/ {{0x4b, 18, 68, 48, 3920}, 0x0, 0, 0, 0, 3926},
+ /*II_V_66_0F_6E*/ {{0x43, 79, 68, 128, 3932}, 0x46, 0, 0, 3939, 0},
+ /*II_V_66_0F_6F*/ {{0x43, 90, 83, 128, 3962}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_6F*/ {{0x43, 90, 83, 128, 3971}, 0x41, 0, 0, 0, 0},
+ /*II_0F_70*/ {{0x4c, 67, 64, 40, 3980}, 0x0, 1, 0, 0, 0},
+ /*II_66_0F_70*/ {{0x4c, 73, 68, 48, 3988}, 0x0, 1, 0, 0, 0},
+ /*II_F3_0F_70*/ {{0x4c, 73, 68, 48, 3996}, 0x0, 1, 0, 0, 0},
+ /*II_F2_0F_70*/ {{0x4c, 73, 68, 48, 4005}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_70*/ {{0x48, 73, 68, 128, 4014}, 0x40, 1, 0, 0, 0},
+ /*II_V_F3_0F_70*/ {{0x48, 73, 68, 128, 4023}, 0x40, 1, 0, 0, 0},
+ /*II_V_F2_0F_70*/ {{0x48, 73, 68, 128, 4033}, 0x40, 1, 0, 0, 0},
+ /*II_V_66_0F_74*/ {{0x48, 81, 68, 128, 4052}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_75*/ {{0x48, 81, 68, 128, 4071}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_76*/ {{0x48, 81, 68, 128, 4090}, 0x0, 73, 0, 0, 0},
+ /*II_V_0F_77*/ {{0x4d, 0, 0, 128, 4106}, 0x49, 0, 0, 4118, 0},
+ /*II_66_0F_78*/ {{0x4f, 7, 69, 88, 4136}, 0x0, 8, 0, 0, 0},
+ /*II_F2_0F_78*/ {{0x50, 69, 68, 88, 4143}, 0x0, 7, 8, 0, 0},
+ /*II_V_66_0F_7C*/ {{0x48, 88, 83, 128, 4197}, 0x1, 90, 0, 0, 0},
+ /*II_V_F2_0F_7C*/ {{0x48, 88, 83, 128, 4206}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_7D*/ {{0x48, 88, 83, 128, 4231}, 0x1, 90, 0, 0, 0},
+ /*II_V_F2_0F_7D*/ {{0x48, 88, 83, 128, 4240}, 0x1, 90, 0, 0, 0},
+ /*II_0F_7E*/ {{0x4b, 64, 18, 32, 3920}, 0x0, 0, 0, 0, 3926},
+ /*II_66_0F_7E*/ {{0x4b, 68, 18, 48, 3920}, 0x0, 0, 0, 0, 3926},
+ /*II_V_66_0F_7E*/ {{0x43, 68, 79, 128, 3932}, 0x46, 0, 0, 3939, 0},
+ /*II_V_F3_0F_7E*/ {{0x43, 72, 68, 128, 3939}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_7F*/ {{0x43, 83, 90, 128, 3962}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_7F*/ {{0x43, 83, 90, 128, 3971}, 0x41, 0, 0, 0, 0},
+ /*II_0F_AE_04*/ {{0x52, 0, 42, 8, 4249}, 0x0, 0, 0, 0, 4256},
+ /*II_0F_AE_05*/ {{0x53, 0, 43, 8, 4265}, 0x0, 0, 0, 4273, 4281},
+ /*II_0F_AE_06*/ {{0x53, 0, 43, 8, 4291}, 0x0, 0, 0, 4299, 4309},
+ /*II_0F_AE_07*/ {{0x54, 0, 43, 8, 4321}, 0x0, 0, 0, 4329, 0},
+ /*II_0F_C2*/ {{0x59, 73, 68, 40, 4370}, 0x0, 0, 0, 4379, 4388},
+ /*II_66_0F_C2*/ {{0x59, 73, 68, 48, 4449}, 0x0, 0, 0, 4458, 4467},
+ /*II_F3_0F_C2*/ {{0x59, 71, 68, 40, 4528}, 0x0, 0, 0, 4537, 4546},
+ /*II_F2_0F_C2*/ {{0x59, 72, 68, 48, 4607}, 0x0, 0, 0, 4616, 4625},
+ /*II_V_0F_C2*/ {{0x5a, 88, 83, 128, 4686}, 0x1, 90, 0, 4696, 4706},
+ /*II_V_66_0F_C2*/ {{0x5a, 88, 83, 128, 5088}, 0x1, 90, 0, 5098, 5108},
+ /*II_V_F3_0F_C2*/ {{0x5a, 81, 68, 128, 5490}, 0x0, 71, 0, 5500, 5510},
+ /*II_V_F2_0F_C2*/ {{0x5a, 81, 68, 128, 5892}, 0x0, 72, 0, 5902, 5912},
+ /*II_0F_C4*/ {{0x4c, 25, 64, 40, 6294}, 0x0, 1, 0, 0, 0},
+ /*II_66_0F_C4*/ {{0x4c, 25, 68, 48, 6294}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_C4*/ {{0x5b, 81, 68, 128, 6302}, 0x0, 25, 1, 0, 0},
+ /*II_0F_C5*/ {{0x5c, 65, 12, 40, 6311}, 0x0, 1, 0, 0, 0},
+ /*II_66_0F_C5*/ {{0x4c, 69, 12, 48, 6311}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_C5*/ {{0x5d, 68, 13, 128, 6319}, 0x40, 1, 0, 0, 0},
+ /*II_0F_C6*/ {{0x4c, 73, 68, 40, 6328}, 0x0, 1, 0, 0, 0},
+ /*II_66_0F_C6*/ {{0x4c, 73, 68, 48, 6336}, 0x0, 1, 0, 0, 0},
+ /*II_V_0F_C6*/ {{0x5b, 88, 83, 128, 6344}, 0x1, 90, 1, 0, 0},
+ /*II_V_66_0F_C6*/ {{0x5b, 88, 83, 128, 6353}, 0x1, 90, 1, 0, 0},
+ /*II_0F_C7_01*/ {{0x5e, 0, 48, 8, 6362}, 0x0, 0, 0, 0, 6373},
+ /*II_V_66_0F_D0*/ {{0x48, 88, 83, 128, 6414}, 0x1, 90, 0, 0, 0},
+ /*II_V_F2_0F_D0*/ {{0x48, 88, 83, 128, 6425}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_D1*/ {{0x48, 81, 68, 128, 6443}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_D2*/ {{0x48, 81, 68, 128, 6458}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_D3*/ {{0x48, 81, 68, 128, 6473}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_D4*/ {{0x48, 81, 68, 128, 6488}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_D5*/ {{0x48, 81, 68, 128, 6504}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_D6*/ {{0x43, 68, 72, 128, 3939}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_D7*/ {{0x4a, 68, 13, 128, 6541}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_D8*/ {{0x48, 81, 68, 128, 6561}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_D9*/ {{0x48, 81, 68, 128, 6580}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_DA*/ {{0x48, 81, 68, 128, 6598}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_DB*/ {{0x48, 81, 68, 128, 6613}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_DC*/ {{0x48, 81, 68, 128, 6629}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_DD*/ {{0x48, 81, 68, 128, 6629}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_DE*/ {{0x48, 81, 68, 128, 6656}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_DF*/ {{0x48, 81, 68, 128, 6672}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E0*/ {{0x48, 81, 68, 128, 6687}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E1*/ {{0x48, 81, 68, 128, 6702}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E2*/ {{0x48, 81, 68, 128, 6717}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E3*/ {{0x48, 81, 68, 128, 6732}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E4*/ {{0x48, 81, 68, 128, 6749}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E5*/ {{0x48, 81, 68, 128, 6767}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E6*/ {{0x43, 90, 68, 128, 6807}, 0x41, 0, 0, 0, 0},
+ /*II_V_F3_0F_E6*/ {{0x43, 91, 83, 128, 6819}, 0x41, 0, 0, 0, 0},
+ /*II_V_F2_0F_E6*/ {{0x43, 90, 68, 128, 6830}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_E7*/ {{0x43, 83, 92, 128, 6858}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_E8*/ {{0x48, 81, 68, 128, 6876}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_E9*/ {{0x48, 81, 68, 128, 6893}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_EA*/ {{0x48, 81, 68, 128, 6910}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_EB*/ {{0x48, 81, 68, 128, 6924}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_EC*/ {{0x48, 81, 68, 128, 6938}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_ED*/ {{0x48, 81, 68, 128, 6955}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_EE*/ {{0x48, 81, 68, 128, 6972}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_EF*/ {{0x48, 81, 68, 128, 6987}, 0x0, 73, 0, 0, 0},
+ /*II_V_F2_0F_F0*/ {{0x43, 92, 83, 128, 7001}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_F1*/ {{0x48, 81, 68, 128, 7016}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F2*/ {{0x48, 81, 68, 128, 7031}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F3*/ {{0x48, 81, 68, 128, 7046}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F4*/ {{0x48, 81, 68, 128, 7063}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F5*/ {{0x48, 81, 68, 128, 7082}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F6*/ {{0x48, 81, 68, 128, 7100}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F7*/ {{0x5f, 69, 68, 128, 7131}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_F8*/ {{0x48, 81, 68, 128, 7151}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_F9*/ {{0x48, 81, 68, 128, 7166}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_FA*/ {{0x48, 81, 68, 128, 7181}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_FB*/ {{0x48, 81, 68, 128, 7196}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_FC*/ {{0x48, 81, 68, 128, 7211}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_FD*/ {{0x48, 81, 68, 128, 7226}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_FE*/ {{0x48, 81, 68, 128, 7241}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_00*/ {{0x48, 81, 68, 128, 7349}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_01*/ {{0x48, 81, 68, 128, 7366}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_02*/ {{0x48, 81, 68, 128, 7383}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_03*/ {{0x48, 81, 68, 128, 7401}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_04*/ {{0x48, 81, 68, 128, 7422}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_05*/ {{0x48, 81, 68, 128, 7442}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_06*/ {{0x48, 81, 68, 128, 7459}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_07*/ {{0x48, 81, 68, 128, 7477}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_08*/ {{0x48, 81, 68, 128, 7495}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_09*/ {{0x48, 81, 68, 128, 7512}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_0A*/ {{0x48, 81, 68, 128, 7529}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_0B*/ {{0x48, 81, 68, 128, 7548}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_0C*/ {{0x48, 88, 83, 128, 7559}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_38_0D*/ {{0x48, 88, 83, 128, 7570}, 0x1, 90, 0, 0, 0},
+ /*II_V_66_0F_38_0E*/ {{0x43, 90, 83, 128, 7581}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_38_0F*/ {{0x43, 90, 83, 128, 7590}, 0x41, 0, 0, 0, 0},
+ /*II_66_0F_38_10*/ {{0x4c, 73, 68, 72, 7599}, 0x0, 74, 0, 0, 0},
+ /*II_66_0F_38_14*/ {{0x4c, 73, 68, 72, 7609}, 0x0, 74, 0, 0, 0},
+ /*II_66_0F_38_15*/ {{0x4c, 73, 68, 72, 7619}, 0x0, 74, 0, 0, 0},
+ /*II_V_66_0F_38_17*/ {{0x43, 90, 83, 128, 7636}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_38_18*/ {{0x43, 44, 83, 128, 7644}, 0x41, 0, 0, 0, 0},
+ /*II_V_66_0F_38_19*/ {{0x43, 46, 85, 128, 7658}, 0x50, 0, 0, 0, 0},
+ /*II_V_66_0F_38_1A*/ {{0x43, 47, 85, 128, 7672}, 0x50, 0, 0, 0, 0},
+ /*II_V_66_0F_38_1C*/ {{0x43, 73, 68, 128, 7695}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_1D*/ {{0x43, 73, 68, 128, 7710}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_1E*/ {{0x43, 73, 68, 128, 7725}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_20*/ {{0x43, 72, 68, 128, 7743}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_21*/ {{0x43, 71, 68, 128, 7764}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_22*/ {{0x43, 70, 68, 128, 7785}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_23*/ {{0x43, 72, 68, 128, 7806}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_24*/ {{0x43, 71, 68, 128, 7827}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_25*/ {{0x43, 72, 68, 128, 7848}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_28*/ {{0x48, 81, 68, 128, 7867}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_29*/ {{0x48, 81, 68, 128, 7885}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_2A*/ {{0x43, 47, 68, 128, 7905}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_2B*/ {{0x48, 81, 68, 128, 7926}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_2C*/ {{0x48, 88, 83, 128, 7937}, 0x1, 92, 0, 0, 0},
+ /*II_V_66_0F_38_2D*/ {{0x48, 88, 83, 128, 7949}, 0x1, 92, 0, 0, 0},
+ /*II_V_66_0F_38_2E*/ {{0x48, 88, 92, 128, 7937}, 0x1, 83, 0, 0, 0},
+ /*II_V_66_0F_38_2F*/ {{0x48, 88, 92, 128, 7949}, 0x1, 83, 0, 0, 0},
+ /*II_V_66_0F_38_30*/ {{0x43, 72, 68, 128, 7971}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_31*/ {{0x43, 71, 68, 128, 7992}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_32*/ {{0x43, 70, 68, 128, 8013}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_33*/ {{0x43, 72, 68, 128, 8034}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_34*/ {{0x43, 71, 68, 128, 8055}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_35*/ {{0x43, 72, 68, 128, 8076}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_37*/ {{0x48, 81, 68, 128, 8096}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_38*/ {{0x48, 81, 68, 128, 8114}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_39*/ {{0x48, 81, 68, 128, 8131}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_3A*/ {{0x48, 81, 68, 128, 8148}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_3B*/ {{0x48, 81, 68, 128, 8165}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_3C*/ {{0x48, 81, 68, 128, 8182}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_3D*/ {{0x48, 81, 68, 128, 8199}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_3E*/ {{0x48, 81, 68, 128, 8216}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_3F*/ {{0x48, 81, 68, 128, 8233}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_40*/ {{0x48, 81, 68, 128, 8250}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_41*/ {{0x43, 73, 68, 128, 8271}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_96*/ {{0x48, 88, 83, 136, 8310}, 0x7, 90, 0, 8326, 0},
+ /*II_V_66_0F_38_97*/ {{0x48, 88, 83, 136, 8342}, 0x7, 90, 0, 8358, 0},
+ /*II_V_66_0F_38_98*/ {{0x48, 88, 83, 136, 8374}, 0x7, 90, 0, 8387, 0},
+ /*II_V_66_0F_38_99*/ {{0x48, 81, 68, 136, 8400}, 0x6, 80, 0, 8413, 0},
+ /*II_V_66_0F_38_9A*/ {{0x48, 88, 83, 136, 8426}, 0x7, 90, 0, 8439, 0},
+ /*II_V_66_0F_38_9B*/ {{0x48, 81, 68, 136, 8452}, 0x6, 80, 0, 8465, 0},
+ /*II_V_66_0F_38_9C*/ {{0x48, 88, 83, 136, 8478}, 0x7, 90, 0, 8492, 0},
+ /*II_V_66_0F_38_9D*/ {{0x48, 81, 68, 136, 8506}, 0x6, 80, 0, 8520, 0},
+ /*II_V_66_0F_38_9E*/ {{0x48, 88, 83, 136, 8534}, 0x7, 90, 0, 8548, 0},
+ /*II_V_66_0F_38_9F*/ {{0x48, 81, 68, 136, 8562}, 0x6, 80, 0, 8576, 0},
+ /*II_V_66_0F_38_A6*/ {{0x48, 88, 83, 136, 8590}, 0x7, 90, 0, 8606, 0},
+ /*II_V_66_0F_38_A7*/ {{0x48, 88, 83, 136, 8622}, 0x7, 90, 0, 8638, 0},
+ /*II_V_66_0F_38_A8*/ {{0x48, 88, 83, 136, 8654}, 0x7, 90, 0, 8667, 0},
+ /*II_V_66_0F_38_A9*/ {{0x48, 81, 68, 136, 8680}, 0x6, 80, 0, 8693, 0},
+ /*II_V_66_0F_38_AA*/ {{0x48, 88, 83, 136, 8706}, 0x7, 90, 0, 8719, 0},
+ /*II_V_66_0F_38_AB*/ {{0x48, 81, 68, 136, 8732}, 0x6, 80, 0, 8745, 0},
+ /*II_V_66_0F_38_AC*/ {{0x48, 88, 83, 136, 8758}, 0x7, 90, 0, 8772, 0},
+ /*II_V_66_0F_38_AD*/ {{0x48, 81, 68, 136, 8786}, 0x6, 80, 0, 8800, 0},
+ /*II_V_66_0F_38_AE*/ {{0x48, 88, 83, 136, 8814}, 0x7, 90, 0, 8828, 0},
+ /*II_V_66_0F_38_AF*/ {{0x48, 81, 68, 136, 8842}, 0x6, 80, 0, 8856, 0},
+ /*II_V_66_0F_38_B6*/ {{0x48, 88, 83, 136, 8870}, 0x7, 90, 0, 8886, 0},
+ /*II_V_66_0F_38_B7*/ {{0x48, 88, 83, 136, 8902}, 0x7, 90, 0, 8918, 0},
+ /*II_V_66_0F_38_B8*/ {{0x48, 88, 83, 136, 8934}, 0x7, 90, 0, 8947, 0},
+ /*II_V_66_0F_38_B9*/ {{0x48, 81, 68, 136, 8960}, 0x6, 80, 0, 8973, 0},
+ /*II_V_66_0F_38_BA*/ {{0x48, 88, 83, 136, 8986}, 0x7, 90, 0, 8999, 0},
+ /*II_V_66_0F_38_BB*/ {{0x48, 81, 68, 136, 9012}, 0x6, 80, 0, 9025, 0},
+ /*II_V_66_0F_38_BC*/ {{0x48, 88, 83, 136, 9038}, 0x7, 90, 0, 9052, 0},
+ /*II_V_66_0F_38_BD*/ {{0x48, 81, 68, 136, 9066}, 0x6, 80, 0, 9080, 0},
+ /*II_V_66_0F_38_BE*/ {{0x48, 88, 83, 136, 9094}, 0x7, 90, 0, 9108, 0},
+ /*II_V_66_0F_38_BF*/ {{0x48, 81, 68, 136, 9122}, 0x6, 80, 0, 9136, 0},
+ /*II_V_66_0F_38_DB*/ {{0x43, 73, 68, 152, 9158}, 0x40, 0, 0, 0, 0},
+ /*II_V_66_0F_38_DC*/ {{0x48, 81, 68, 152, 9175}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_DD*/ {{0x48, 81, 68, 152, 9196}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_DE*/ {{0x48, 81, 68, 152, 9217}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_38_DF*/ {{0x48, 81, 68, 152, 9238}, 0x0, 73, 0, 0, 0},
+ /*II_V_66_0F_3A_04*/ {{0x48, 90, 83, 128, 7559}, 0x41, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_05*/ {{0x48, 90, 83, 128, 7570}, 0x41, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_06*/ {{0x5b, 87, 85, 128, 9265}, 0x10, 86, 1, 0, 0},
+ /*II_66_0F_3A_08*/ {{0x4c, 73, 68, 72, 9277}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_08*/ {{0x48, 90, 83, 128, 9286}, 0x41, 1, 0, 0, 0},
+ /*II_66_0F_3A_09*/ {{0x4c, 73, 68, 72, 9296}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_09*/ {{0x48, 90, 83, 128, 9305}, 0x41, 1, 0, 0, 0},
+ /*II_66_0F_3A_0A*/ {{0x4c, 71, 68, 72, 9315}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_0A*/ {{0x5b, 81, 68, 128, 9324}, 0x0, 71, 1, 0, 0},
+ /*II_66_0F_3A_0B*/ {{0x4c, 72, 68, 72, 9334}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_0B*/ {{0x5b, 81, 68, 128, 9343}, 0x0, 72, 1, 0, 0},
+ /*II_66_0F_3A_0C*/ {{0x4c, 73, 68, 72, 9353}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_0C*/ {{0x5b, 88, 83, 128, 9362}, 0x1, 90, 1, 0, 0},
+ /*II_66_0F_3A_0D*/ {{0x4c, 73, 68, 72, 9372}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_0D*/ {{0x5b, 88, 83, 128, 9381}, 0x1, 90, 1, 0, 0},
+ /*II_66_0F_3A_0E*/ {{0x4c, 73, 68, 72, 9391}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_0E*/ {{0x5b, 81, 68, 128, 9400}, 0x0, 73, 1, 0, 0},
+ /*II_0F_3A_0F*/ {{0x4c, 67, 64, 64, 9410}, 0x0, 1, 0, 0, 0},
+ /*II_66_0F_3A_0F*/ {{0x4c, 73, 68, 64, 9410}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_0F*/ {{0x5b, 81, 68, 128, 9419}, 0x0, 73, 1, 0, 0},
+ /*II_66_0F_3A_14*/ {{0x4c, 68, 26, 72, 9429}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_14*/ {{0x5d, 68, 76, 128, 9437}, 0x40, 1, 0, 0, 0},
+ /*II_66_0F_3A_15*/ {{0x4c, 68, 27, 72, 6311}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_15*/ {{0x5d, 68, 77, 128, 6319}, 0x40, 1, 0, 0, 0},
+ /*II_66_0F_3A_16*/ {{0x62, 68, 18, 72, 9446}, 0x0, 1, 0, 0, 9454},
+ /*II_V_66_0F_3A_16*/ {{0x48, 68, 79, 128, 9462}, 0x46, 1, 0, 9471, 0},
+ /*II_66_0F_3A_17*/ {{0x4c, 68, 18, 72, 9480}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_17*/ {{0x48, 68, 75, 128, 9491}, 0x40, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_18*/ {{0x5b, 87, 85, 128, 9503}, 0x10, 73, 1, 0, 0},
+ /*II_V_66_0F_3A_19*/ {{0x48, 85, 73, 128, 9516}, 0x50, 1, 0, 0, 0},
+ /*II_66_0F_3A_20*/ {{0x4c, 24, 68, 72, 9530}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_20*/ {{0x5b, 81, 68, 128, 9538}, 0x0, 76, 1, 0, 0},
+ /*II_66_0F_3A_21*/ {{0x4c, 71, 68, 72, 9547}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_21*/ {{0x5b, 81, 68, 128, 9557}, 0x0, 71, 1, 0, 0},
+ /*II_66_0F_3A_22*/ {{0x62, 18, 68, 72, 9568}, 0x0, 1, 0, 0, 9576},
+ /*II_V_66_0F_3A_22*/ {{0x5b, 81, 68, 128, 9584}, 0x6, 79, 1, 9593, 0},
+ /*II_66_0F_3A_40*/ {{0x4c, 73, 68, 72, 9602}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_40*/ {{0x5b, 88, 83, 128, 9608}, 0x1, 90, 1, 0, 0},
+ /*II_66_0F_3A_41*/ {{0x4c, 73, 68, 72, 9615}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_41*/ {{0x5b, 81, 68, 128, 9621}, 0x0, 73, 1, 0, 0},
+ /*II_66_0F_3A_42*/ {{0x4c, 73, 68, 72, 9628}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_42*/ {{0x5b, 81, 68, 128, 9637}, 0x0, 73, 1, 0, 0},
+ /*II_66_0F_3A_44*/ {{0x4c, 73, 68, 144, 9647}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_44*/ {{0x5b, 81, 68, 144, 9658}, 0x0, 73, 1, 0, 0},
+ /*II_V_66_0F_3A_4A*/ {{0x5b, 88, 83, 128, 9670}, 0x1, 90, 84, 0, 0},
+ /*II_V_66_0F_3A_4B*/ {{0x5b, 88, 83, 128, 9681}, 0x1, 90, 84, 0, 0},
+ /*II_V_66_0F_3A_4C*/ {{0x5b, 81, 68, 128, 9692}, 0x0, 73, 82, 0, 0},
+ /*II_66_0F_3A_60*/ {{0x4c, 73, 68, 80, 9703}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_60*/ {{0x48, 73, 68, 128, 9714}, 0x40, 1, 0, 0, 0},
+ /*II_66_0F_3A_61*/ {{0x4c, 73, 68, 80, 9726}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_61*/ {{0x48, 73, 68, 128, 9737}, 0x40, 1, 0, 0, 0},
+ /*II_66_0F_3A_62*/ {{0x4c, 73, 68, 80, 9749}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_62*/ {{0x48, 73, 68, 128, 9760}, 0x40, 1, 0, 0, 0},
+ /*II_66_0F_3A_63*/ {{0x4c, 73, 68, 80, 9772}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_63*/ {{0x48, 73, 68, 128, 9783}, 0x40, 1, 0, 0, 0},
+ /*II_66_0F_3A_DF*/ {{0x4c, 73, 68, 152, 9795}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_3A_DF*/ {{0x48, 73, 68, 152, 9812}, 0x40, 1, 0, 0, 0},
+ /*II_V_66_0F_71_02*/ {{0x64, 69, 81, 128, 6443}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_71_04*/ {{0x64, 69, 81, 128, 6702}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_71_06*/ {{0x64, 69, 81, 128, 7016}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_72_02*/ {{0x64, 69, 81, 128, 6458}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_72_04*/ {{0x64, 69, 81, 128, 6717}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_72_06*/ {{0x64, 69, 81, 128, 7031}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_73_02*/ {{0x64, 69, 81, 128, 6473}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_73_03*/ {{0x64, 69, 81, 128, 9838}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_73_06*/ {{0x64, 69, 81, 128, 7046}, 0x0, 1, 0, 0, 0},
+ /*II_V_66_0F_73_07*/ {{0x64, 69, 81, 128, 9855}, 0x0, 1, 0, 0, 0},
+ /*II_0F_AE_00*/ {{0x52, 0, 42, 8, 9864}, 0x0, 0, 0, 0, 9872},
+ /*II_0F_AE_01*/ {{0x52, 0, 42, 8, 9892}, 0x0, 0, 0, 0, 9901},
+ /*II_V_0F_AE_02*/ {{0x45, 0, 44, 128, 9941}, 0x40, 0, 0, 0, 0},
+ /*II_V_0F_AE_03*/ {{0x45, 0, 44, 128, 9970}, 0x40, 0, 0, 0, 0},
+ /*II_0F_C7_06*/ {{0x54, 0, 43, 112, 9980}, 0x0, 0, 0, 9988, 0}
+};
+
+_InstNode InstructionsTree[] = {
+/* 0 - _00 */ 0x2000,
+/* 1 - _01 */ 0x2001,
+/* 2 - _02 */ 0x2002,
+/* 3 - _03 */ 0x2003,
+/* 4 - _04 */ 0x2004,
+/* 5 - _05 */ 0x2005,
+/* 6 - _06 */ 0x2006,
+/* 7 - _07 */ 0x2007,
+/* 8 - _08 */ 0x2008,
+/* 9 - _09 */ 0x2009,
+/* a - _0A */ 0x200a,
+/* b - _0B */ 0x200b,
+/* c - _0C */ 0x200c,
+/* d - _0D */ 0x200d,
+/* e - _0E */ 0x200e,
+/* f - _0F */ 0x8100,
+/* 10 - _10 */ 0x200f,
+/* 11 - _11 */ 0x2010,
+/* 12 - _12 */ 0x2011,
+/* 13 - _13 */ 0x2012,
+/* 14 - _14 */ 0x2013,
+/* 15 - _15 */ 0x2014,
+/* 16 - _16 */ 0x2015,
+/* 17 - _17 */ 0x2016,
+/* 18 - _18 */ 0x2017,
+/* 19 - _19 */ 0x2018,
+/* 1a - _1A */ 0x2019,
+/* 1b - _1B */ 0x201a,
+/* 1c - _1C */ 0x201b,
+/* 1d - _1D */ 0x201c,
+/* 1e - _1E */ 0x201d,
+/* 1f - _1F */ 0x201e,
+/* 20 - _20 */ 0x201f,
+/* 21 - _21 */ 0x2020,
+/* 22 - _22 */ 0x2021,
+/* 23 - _23 */ 0x2022,
+/* 24 - _24 */ 0x2023,
+/* 25 - _25 */ 0x2024,
+/* 26 - */ 0,
+/* 27 - _27 */ 0x2025,
+/* 28 - _28 */ 0x2026,
+/* 29 - _29 */ 0x2027,
+/* 2a - _2A */ 0x2028,
+/* 2b - _2B */ 0x2029,
+/* 2c - _2C */ 0x202a,
+/* 2d - _2D */ 0x202b,
+/* 2e - */ 0,
+/* 2f - _2F */ 0x202c,
+/* 30 - _30 */ 0x202d,
+/* 31 - _31 */ 0x202e,
+/* 32 - _32 */ 0x202f,
+/* 33 - _33 */ 0x2030,
+/* 34 - _34 */ 0x2031,
+/* 35 - _35 */ 0x2032,
+/* 36 - */ 0,
+/* 37 - _37 */ 0x2033,
+/* 38 - _38 */ 0x2034,
+/* 39 - _39 */ 0x2035,
+/* 3a - _3A */ 0x2036,
+/* 3b - _3B */ 0x2037,
+/* 3c - _3C */ 0x2038,
+/* 3d - _3D */ 0x2039,
+/* 3e - */ 0,
+/* 3f - _3F */ 0x203a,
+/* 40 - _40 */ 0x203b,
+/* 41 - _40 */ 0x203c,
+/* 42 - _40 */ 0x203d,
+/* 43 - _40 */ 0x203e,
+/* 44 - _40 */ 0x203f,
+/* 45 - _40 */ 0x2040,
+/* 46 - _40 */ 0x2041,
+/* 47 - _40 */ 0x2042,
+/* 48 - _48 */ 0x2043,
+/* 49 - _48 */ 0x2044,
+/* 4a - _48 */ 0x2045,
+/* 4b - _48 */ 0x2046,
+/* 4c - _48 */ 0x2047,
+/* 4d - _48 */ 0x2048,
+/* 4e - _48 */ 0x2049,
+/* 4f - _48 */ 0x204a,
+/* 50 - _50 */ 0x204b,
+/* 51 - _50 */ 0x204c,
+/* 52 - _50 */ 0x204d,
+/* 53 - _50 */ 0x204e,
+/* 54 - _50 */ 0x204f,
+/* 55 - _50 */ 0x2050,
+/* 56 - _50 */ 0x2051,
+/* 57 - _50 */ 0x2052,
+/* 58 - _58 */ 0x2053,
+/* 59 - _58 */ 0x2054,
+/* 5a - _58 */ 0x2055,
+/* 5b - _58 */ 0x2056,
+/* 5c - _58 */ 0x2057,
+/* 5d - _58 */ 0x2058,
+/* 5e - _58 */ 0x2059,
+/* 5f - _58 */ 0x205a,
+/* 60 - _60 */ 0x205b,
+/* 61 - _61 */ 0x205c,
+/* 62 - _62 */ 0x205d,
+/* 63 - _63 */ 0x205e,
+/* 64 - */ 0,
+/* 65 - */ 0,
+/* 66 - */ 0,
+/* 67 - */ 0,
+/* 68 - _68 */ 0x205f,
+/* 69 - _69 */ 0x4000,
+/* 6a - _6A */ 0x2060,
+/* 6b - _6B */ 0x4001,
+/* 6c - _6C */ 0x2061,
+/* 6d - _6D */ 0x2062,
+/* 6e - _6E */ 0x2063,
+/* 6f - _6F */ 0x2064,
+/* 70 - _70 */ 0x2065,
+/* 71 - _71 */ 0x2066,
+/* 72 - _72 */ 0x2067,
+/* 73 - _73 */ 0x2068,
+/* 74 - _74 */ 0x2069,
+/* 75 - _75 */ 0x206a,
+/* 76 - _76 */ 0x206b,
+/* 77 - _77 */ 0x206c,
+/* 78 - _78 */ 0x206d,
+/* 79 - _79 */ 0x206e,
+/* 7a - _7A */ 0x206f,
+/* 7b - _7B */ 0x2070,
+/* 7c - _7C */ 0x2071,
+/* 7d - _7D */ 0x2072,
+/* 7e - _7E */ 0x2073,
+/* 7f - _7F */ 0x2074,
+/* 80 - _80 */ 0x6200,
+/* 81 - _81 */ 0x6208,
+/* 82 - _82 */ 0x6210,
+/* 83 - _83 */ 0x6218,
+/* 84 - _84 */ 0x2075,
+/* 85 - _85 */ 0x2076,
+/* 86 - _86 */ 0x2077,
+/* 87 - _87 */ 0x2078,
+/* 88 - _88 */ 0x2079,
+/* 89 - _89 */ 0x207a,
+/* 8a - _8A */ 0x207b,
+/* 8b - _8B */ 0x207c,
+/* 8c - _8C */ 0x207d,
+/* 8d - _8D */ 0x207e,
+/* 8e - _8E */ 0x207f,
+/* 8f - _8F */ 0x6220,
+/* 90 - _90 */ 0x2080,
+/* 91 - _91 */ 0x2081,
+/* 92 - _92 */ 0x2082,
+/* 93 - _93 */ 0x2083,
+/* 94 - _94 */ 0x2084,
+/* 95 - _95 */ 0x2085,
+/* 96 - _96 */ 0x2086,
+/* 97 - _97 */ 0x2087,
+/* 98 - _98 */ 0x4002,
+/* 99 - _99 */ 0x4003,
+/* 9a - _9A */ 0x2088,
+/* 9b - */ 0,
+/* 9c - _9C */ 0x2089,
+/* 9d - _9D */ 0x208a,
+/* 9e - _9E */ 0x208b,
+/* 9f - _9F */ 0x208c,
+/* a0 - _A0 */ 0x208d,
+/* a1 - _A1 */ 0x208e,
+/* a2 - _A2 */ 0x208f,
+/* a3 - _A3 */ 0x2090,
+/* a4 - _A4 */ 0x2091,
+/* a5 - _A5 */ 0x2092,
+/* a6 - _A6 */ 0x2093,
+/* a7 - _A7 */ 0x2094,
+/* a8 - _A8 */ 0x2095,
+/* a9 - _A9 */ 0x2096,
+/* aa - _AA */ 0x2097,
+/* ab - _AB */ 0x2098,
+/* ac - _AC */ 0x2099,
+/* ad - _AD */ 0x209a,
+/* ae - _AE */ 0x209b,
+/* af - _AF */ 0x209c,
+/* b0 - _B0 */ 0x209d,
+/* b1 - _B0 */ 0x209e,
+/* b2 - _B0 */ 0x209f,
+/* b3 - _B0 */ 0x20a0,
+/* b4 - _B0 */ 0x20a1,
+/* b5 - _B0 */ 0x20a2,
+/* b6 - _B0 */ 0x20a3,
+/* b7 - _B0 */ 0x20a4,
+/* b8 - _B8 */ 0x20a5,
+/* b9 - _B8 */ 0x20a6,
+/* ba - _B8 */ 0x20a7,
+/* bb - _B8 */ 0x20a8,
+/* bc - _B8 */ 0x20a9,
+/* bd - _B8 */ 0x20aa,
+/* be - _B8 */ 0x20ab,
+/* bf - _B8 */ 0x20ac,
+/* c0 - _C0 */ 0x6228,
+/* c1 - _C1 */ 0x6230,
+/* c2 - _C2 */ 0x20ad,
+/* c3 - _C3 */ 0x20ae,
+/* c4 - _C4 */ 0x20af,
+/* c5 - _C5 */ 0x20b0,
+/* c6 - _C6 */ 0x6238,
+/* c7 - _C7 */ 0x6240,
+/* c8 - _C8 */ 0x20b1,
+/* c9 - _C9 */ 0x20b2,
+/* ca - _CA */ 0x20b3,
+/* cb - _CB */ 0x20b4,
+/* cc - _CC */ 0x20b5,
+/* cd - _CD */ 0x20b6,
+/* ce - _CE */ 0x20b7,
+/* cf - _CF */ 0x20b8,
+/* d0 - _D0 */ 0x6248,
+/* d1 - _D1 */ 0x6250,
+/* d2 - _D2 */ 0x6258,
+/* d3 - _D3 */ 0x6260,
+/* d4 - _D4 */ 0x20b9,
+/* d5 - _D5 */ 0x20ba,
+/* d6 - _D6 */ 0x20bb,
+/* d7 - _D7 */ 0x20bc,
+/* d8 - _D8 */ 0xa268,
+/* d9 - _D9 */ 0xa2b0,
+/* da - _DA */ 0xa2f8,
+/* db - _DB */ 0xa340,
+/* dc - _DC */ 0xa388,
+/* dd - _DD */ 0xa3d0,
+/* de - _DE */ 0xa418,
+/* df - _DF */ 0xa460,
+/* e0 - _E0 */ 0x20bd,
+/* e1 - _E1 */ 0x20be,
+/* e2 - _E2 */ 0x20bf,
+/* e3 - _E3 */ 0x4004,
+/* e4 - _E4 */ 0x20c0,
+/* e5 - _E5 */ 0x20c1,
+/* e6 - _E6 */ 0x20c2,
+/* e7 - _E7 */ 0x20c3,
+/* e8 - _E8 */ 0x20c4,
+/* e9 - _E9 */ 0x20c5,
+/* ea - _EA */ 0x20c6,
+/* eb - _EB */ 0x20c7,
+/* ec - _EC */ 0x20c8,
+/* ed - _ED */ 0x20c9,
+/* ee - _EE */ 0x20ca,
+/* ef - _EF */ 0x20cb,
+/* f0 - */ 0,
+/* f1 - _F1 */ 0x20cc,
+/* f2 - */ 0,
+/* f3 - */ 0,
+/* f4 - _F4 */ 0x20cd,
+/* f5 - _F5 */ 0x20ce,
+/* f6 - _F6 */ 0x64a8,
+/* f7 - _F7 */ 0x64b0,
+/* f8 - _F8 */ 0x20cf,
+/* f9 - _F9 */ 0x20d0,
+/* fa - _FA */ 0x20d1,
+/* fb - _FB */ 0x20d2,
+/* fc - _FC */ 0x20d3,
+/* fd - _FD */ 0x20d4,
+/* fe - _FE */ 0x64b8,
+/* ff - _FF */ 0x64c0,
+/* 100 - _0F_00 */ 0x64c8,
+/* 101 - _0F_01 */ 0xa4d0,
+/* 102 - _0F_02 */ 0x20d5,
+/* 103 - _0F_03 */ 0x20d6,
+/* 104 - */ 0,
+/* 105 - _0F_05 */ 0x20d7,
+/* 106 - _0F_06 */ 0x20d8,
+/* 107 - _0F_07 */ 0x20d9,
+/* 108 - _0F_08 */ 0x20da,
+/* 109 - _0F_09 */ 0x20db,
+/* 10a - */ 0,
+/* 10b - _0F_0B */ 0x20dc,
+/* 10c - */ 0,
+/* 10d - _0F_0D */ 0x6518,
+/* 10e - _0F_0E */ 0x20dd,
+/* 10f - _0F_0F */ 0x8520,
+/* 110 - _0F_10 */ 0xc620,
+/* 111 - _0F_11 */ 0xc62c,
+/* 112 - _0F_12 */ 0xc638,
+/* 113 - _0F_13 */ 0xc644,
+/* 114 - _0F_14 */ 0xc650,
+/* 115 - _0F_15 */ 0xc65c,
+/* 116 - _0F_16 */ 0xc668,
+/* 117 - _0F_17 */ 0xc674,
+/* 118 - _0F_18 */ 0x6680,
+/* 119 - */ 0,
+/* 11a - */ 0,
+/* 11b - */ 0,
+/* 11c - */ 0,
+/* 11d - */ 0,
+/* 11e - */ 0,
+/* 11f - _0F_1F */ 0x20de,
+/* 120 - _0F_20 */ 0x20df,
+/* 121 - _0F_21 */ 0x20e0,
+/* 122 - _0F_22 */ 0x20e1,
+/* 123 - _0F_23 */ 0x20e2,
+/* 124 - */ 0,
+/* 125 - */ 0,
+/* 126 - */ 0,
+/* 127 - */ 0,
+/* 128 - _0F_28 */ 0xc688,
+/* 129 - _0F_29 */ 0xc694,
+/* 12a - _0F_2A */ 0xc6a0,
+/* 12b - _0F_2B */ 0xc6ac,
+/* 12c - _0F_2C */ 0xc6b8,
+/* 12d - _0F_2D */ 0xc6c4,
+/* 12e - _0F_2E */ 0xc6d0,
+/* 12f - _0F_2F */ 0xc6dc,
+/* 130 - _0F_30 */ 0x20e3,
+/* 131 - _0F_31 */ 0x20e4,
+/* 132 - _0F_32 */ 0x20e5,
+/* 133 - _0F_33 */ 0x20e6,
+/* 134 - _0F_34 */ 0x20e7,
+/* 135 - _0F_35 */ 0x20e8,
+/* 136 - */ 0,
+/* 137 - _0F_37 */ 0x20e9,
+/* 138 - _0F_38 */ 0x86e8,
+/* 139 - */ 0,
+/* 13a - _0F_3A */ 0x87e8,
+/* 13b - */ 0,
+/* 13c - */ 0,
+/* 13d - */ 0,
+/* 13e - */ 0,
+/* 13f - */ 0,
+/* 140 - _0F_40 */ 0x20ea,
+/* 141 - _0F_41 */ 0x20eb,
+/* 142 - _0F_42 */ 0x20ec,
+/* 143 - _0F_43 */ 0x20ed,
+/* 144 - _0F_44 */ 0x20ee,
+/* 145 - _0F_45 */ 0x20ef,
+/* 146 - _0F_46 */ 0x20f0,
+/* 147 - _0F_47 */ 0x20f1,
+/* 148 - _0F_48 */ 0x20f2,
+/* 149 - _0F_49 */ 0x20f3,
+/* 14a - _0F_4A */ 0x20f4,
+/* 14b - _0F_4B */ 0x20f5,
+/* 14c - _0F_4C */ 0x20f6,
+/* 14d - _0F_4D */ 0x20f7,
+/* 14e - _0F_4E */ 0x20f8,
+/* 14f - _0F_4F */ 0x20f9,
+/* 150 - _0F_50 */ 0xc8e8,
+/* 151 - _0F_51 */ 0xc8f4,
+/* 152 - _0F_52 */ 0xc900,
+/* 153 - _0F_53 */ 0xc90c,
+/* 154 - _0F_54 */ 0xc918,
+/* 155 - _0F_55 */ 0xc924,
+/* 156 - _0F_56 */ 0xc930,
+/* 157 - _0F_57 */ 0xc93c,
+/* 158 - _0F_58 */ 0xc948,
+/* 159 - _0F_59 */ 0xc954,
+/* 15a - _0F_5A */ 0xc960,
+/* 15b - _0F_5B */ 0xc96c,
+/* 15c - _0F_5C */ 0xc978,
+/* 15d - _0F_5D */ 0xc984,
+/* 15e - _0F_5E */ 0xc990,
+/* 15f - _0F_5F */ 0xc99c,
+/* 160 - _0F_60 */ 0xc9a8,
+/* 161 - _0F_61 */ 0xc9b4,
+/* 162 - _0F_62 */ 0xc9c0,
+/* 163 - _0F_63 */ 0xc9cc,
+/* 164 - _0F_64 */ 0xc9d8,
+/* 165 - _0F_65 */ 0xc9e4,
+/* 166 - _0F_66 */ 0xc9f0,
+/* 167 - _0F_67 */ 0xc9fc,
+/* 168 - _0F_68 */ 0xca08,
+/* 169 - _0F_69 */ 0xca14,
+/* 16a - _0F_6A */ 0xca20,
+/* 16b - _0F_6B */ 0xca2c,
+/* 16c - _0F_6C */ 0xca38,
+/* 16d - _0F_6D */ 0xca44,
+/* 16e - _0F_6E */ 0xca50,
+/* 16f - _0F_6F */ 0xca5c,
+/* 170 - _0F_70 */ 0xca68,
+/* 171 - _0F_71 */ 0x6a74,
+/* 172 - _0F_72 */ 0x6a7c,
+/* 173 - _0F_73 */ 0x6a84,
+/* 174 - _0F_74 */ 0xca8c,
+/* 175 - _0F_75 */ 0xca98,
+/* 176 - _0F_76 */ 0xcaa4,
+/* 177 - _0F_77 */ 0xcab0,
+/* 178 - _0F_78 */ 0xcabc,
+/* 179 - _0F_79 */ 0xcac8,
+/* 17a - _0F_7A */ 0x8ad4,
+/* 17b - */ 0,
+/* 17c - _0F_7C */ 0xcbd4,
+/* 17d - _0F_7D */ 0xcbe0,
+/* 17e - _0F_7E */ 0xcbec,
+/* 17f - _0F_7F */ 0xcbf8,
+/* 180 - _0F_80 */ 0x20fa,
+/* 181 - _0F_81 */ 0x20fb,
+/* 182 - _0F_82 */ 0x20fc,
+/* 183 - _0F_83 */ 0x20fd,
+/* 184 - _0F_84 */ 0x20fe,
+/* 185 - _0F_85 */ 0x20ff,
+/* 186 - _0F_86 */ 0x2100,
+/* 187 - _0F_87 */ 0x2101,
+/* 188 - _0F_88 */ 0x2102,
+/* 189 - _0F_89 */ 0x2103,
+/* 18a - _0F_8A */ 0x2104,
+/* 18b - _0F_8B */ 0x2105,
+/* 18c - _0F_8C */ 0x2106,
+/* 18d - _0F_8D */ 0x2107,
+/* 18e - _0F_8E */ 0x2108,
+/* 18f - _0F_8F */ 0x2109,
+/* 190 - _0F_90 */ 0x210a,
+/* 191 - _0F_91 */ 0x210b,
+/* 192 - _0F_92 */ 0x210c,
+/* 193 - _0F_93 */ 0x210d,
+/* 194 - _0F_94 */ 0x210e,
+/* 195 - _0F_95 */ 0x210f,
+/* 196 - _0F_96 */ 0x2110,
+/* 197 - _0F_97 */ 0x2111,
+/* 198 - _0F_98 */ 0x2112,
+/* 199 - _0F_99 */ 0x2113,
+/* 19a - _0F_9A */ 0x2114,
+/* 19b - _0F_9B */ 0x2115,
+/* 19c - _0F_9C */ 0x2116,
+/* 19d - _0F_9D */ 0x2117,
+/* 19e - _0F_9E */ 0x2118,
+/* 19f - _0F_9F */ 0x2119,
+/* 1a0 - _0F_A0 */ 0x211a,
+/* 1a1 - _0F_A1 */ 0x211b,
+/* 1a2 - _0F_A2 */ 0x211c,
+/* 1a3 - _0F_A3 */ 0x211d,
+/* 1a4 - _0F_A4 */ 0x4005,
+/* 1a5 - _0F_A5 */ 0x4006,
+/* 1a6 - */ 0,
+/* 1a7 - */ 0,
+/* 1a8 - _0F_A8 */ 0x211e,
+/* 1a9 - _0F_A9 */ 0x211f,
+/* 1aa - _0F_AA */ 0x2120,
+/* 1ab - _0F_AB */ 0x2121,
+/* 1ac - _0F_AC */ 0x4007,
+/* 1ad - _0F_AD */ 0x4008,
+/* 1ae - _0F_AE */ 0x6c04,
+/* 1af - _0F_AF */ 0x2122,
+/* 1b0 - _0F_B0 */ 0x2123,
+/* 1b1 - _0F_B1 */ 0x2124,
+/* 1b2 - _0F_B2 */ 0x2125,
+/* 1b3 - _0F_B3 */ 0x2126,
+/* 1b4 - _0F_B4 */ 0x2127,
+/* 1b5 - _0F_B5 */ 0x2128,
+/* 1b6 - _0F_B6 */ 0x2129,
+/* 1b7 - _0F_B7 */ 0x212a,
+/* 1b8 - _0F_B8 */ 0xcc0c,
+/* 1b9 - _0F_B9 */ 0x212b,
+/* 1ba - _0F_BA */ 0x6c18,
+/* 1bb - _0F_BB */ 0x212c,
+/* 1bc - _0F_BC */ 0xcc20,
+/* 1bd - _0F_BD */ 0xcc2c,
+/* 1be - _0F_BE */ 0x212d,
+/* 1bf - _0F_BF */ 0x212e,
+/* 1c0 - _0F_C0 */ 0x212f,
+/* 1c1 - _0F_C1 */ 0x2130,
+/* 1c2 - _0F_C2 */ 0xcc38,
+/* 1c3 - _0F_C3 */ 0x2131,
+/* 1c4 - _0F_C4 */ 0xcc44,
+/* 1c5 - _0F_C5 */ 0xcc50,
+/* 1c6 - _0F_C6 */ 0xcc5c,
+/* 1c7 - _0F_C7 */ 0x6c68,
+/* 1c8 - _0F_C8 */ 0x2132,
+/* 1c9 - _0F_C8 */ 0x2133,
+/* 1ca - _0F_C8 */ 0x2134,
+/* 1cb - _0F_C8 */ 0x2135,
+/* 1cc - _0F_C8 */ 0x2136,
+/* 1cd - _0F_C8 */ 0x2137,
+/* 1ce - _0F_C8 */ 0x2138,
+/* 1cf - _0F_C8 */ 0x2139,
+/* 1d0 - _0F_D0 */ 0xcc70,
+/* 1d1 - _0F_D1 */ 0xcc7c,
+/* 1d2 - _0F_D2 */ 0xcc88,
+/* 1d3 - _0F_D3 */ 0xcc94,
+/* 1d4 - _0F_D4 */ 0xcca0,
+/* 1d5 - _0F_D5 */ 0xccac,
+/* 1d6 - _0F_D6 */ 0xccb8,
+/* 1d7 - _0F_D7 */ 0xccc4,
+/* 1d8 - _0F_D8 */ 0xccd0,
+/* 1d9 - _0F_D9 */ 0xccdc,
+/* 1da - _0F_DA */ 0xcce8,
+/* 1db - _0F_DB */ 0xccf4,
+/* 1dc - _0F_DC */ 0xcd00,
+/* 1dd - _0F_DD */ 0xcd0c,
+/* 1de - _0F_DE */ 0xcd18,
+/* 1df - _0F_DF */ 0xcd24,
+/* 1e0 - _0F_E0 */ 0xcd30,
+/* 1e1 - _0F_E1 */ 0xcd3c,
+/* 1e2 - _0F_E2 */ 0xcd48,
+/* 1e3 - _0F_E3 */ 0xcd54,
+/* 1e4 - _0F_E4 */ 0xcd60,
+/* 1e5 - _0F_E5 */ 0xcd6c,
+/* 1e6 - _0F_E6 */ 0xcd78,
+/* 1e7 - _0F_E7 */ 0xcd84,
+/* 1e8 - _0F_E8 */ 0xcd90,
+/* 1e9 - _0F_E9 */ 0xcd9c,
+/* 1ea - _0F_EA */ 0xcda8,
+/* 1eb - _0F_EB */ 0xcdb4,
+/* 1ec - _0F_EC */ 0xcdc0,
+/* 1ed - _0F_ED */ 0xcdcc,
+/* 1ee - _0F_EE */ 0xcdd8,
+/* 1ef - _0F_EF */ 0xcde4,
+/* 1f0 - _0F_F0 */ 0xcdf0,
+/* 1f1 - _0F_F1 */ 0xcdfc,
+/* 1f2 - _0F_F2 */ 0xce08,
+/* 1f3 - _0F_F3 */ 0xce14,
+/* 1f4 - _0F_F4 */ 0xce20,
+/* 1f5 - _0F_F5 */ 0xce2c,
+/* 1f6 - _0F_F6 */ 0xce38,
+/* 1f7 - _0F_F7 */ 0xce44,
+/* 1f8 - _0F_F8 */ 0xce50,
+/* 1f9 - _0F_F9 */ 0xce5c,
+/* 1fa - _0F_FA */ 0xce68,
+/* 1fb - _0F_FB */ 0xce74,
+/* 1fc - _0F_FC */ 0xce80,
+/* 1fd - _0F_FD */ 0xce8c,
+/* 1fe - _0F_FE */ 0xce98,
+/* 1ff - */ 0,
+/* 200 - _80_00 */ 0x213a,
+/* 201 - _80_01 */ 0x213b,
+/* 202 - _80_02 */ 0x213c,
+/* 203 - _80_03 */ 0x213d,
+/* 204 - _80_04 */ 0x213e,
+/* 205 - _80_05 */ 0x213f,
+/* 206 - _80_06 */ 0x2140,
+/* 207 - _80_07 */ 0x2141,
+/* 208 - _81_00 */ 0x2142,
+/* 209 - _81_01 */ 0x2143,
+/* 20a - _81_02 */ 0x2144,
+/* 20b - _81_03 */ 0x2145,
+/* 20c - _81_04 */ 0x2146,
+/* 20d - _81_05 */ 0x2147,
+/* 20e - _81_06 */ 0x2148,
+/* 20f - _81_07 */ 0x2149,
+/* 210 - _82_00 */ 0x214a,
+/* 211 - _82_01 */ 0x214b,
+/* 212 - _82_02 */ 0x214c,
+/* 213 - _82_03 */ 0x214d,
+/* 214 - _82_04 */ 0x214e,
+/* 215 - _82_05 */ 0x214f,
+/* 216 - _82_06 */ 0x2150,
+/* 217 - _82_07 */ 0x2151,
+/* 218 - _83_00 */ 0x2152,
+/* 219 - _83_01 */ 0x2153,
+/* 21a - _83_02 */ 0x2154,
+/* 21b - _83_03 */ 0x2155,
+/* 21c - _83_04 */ 0x2156,
+/* 21d - _83_05 */ 0x2157,
+/* 21e - _83_06 */ 0x2158,
+/* 21f - _83_07 */ 0x2159,
+/* 220 - _8F_00 */ 0x215a,
+/* 221 - */ 0,
+/* 222 - */ 0,
+/* 223 - */ 0,
+/* 224 - */ 0,
+/* 225 - */ 0,
+/* 226 - */ 0,
+/* 227 - */ 0,
+/* 228 - _C0_00 */ 0x215b,
+/* 229 - _C0_01 */ 0x215c,
+/* 22a - _C0_02 */ 0x215d,
+/* 22b - _C0_03 */ 0x215e,
+/* 22c - _C0_04 */ 0x215f,
+/* 22d - _C0_05 */ 0x2160,
+/* 22e - _C0_06 */ 0x2161,
+/* 22f - _C0_07 */ 0x2162,
+/* 230 - _C1_00 */ 0x2163,
+/* 231 - _C1_01 */ 0x2164,
+/* 232 - _C1_02 */ 0x2165,
+/* 233 - _C1_03 */ 0x2166,
+/* 234 - _C1_04 */ 0x2167,
+/* 235 - _C1_05 */ 0x2168,
+/* 236 - _C1_06 */ 0x2169,
+/* 237 - _C1_07 */ 0x216a,
+/* 238 - _C6_00 */ 0x216b,
+/* 239 - */ 0,
+/* 23a - */ 0,
+/* 23b - */ 0,
+/* 23c - */ 0,
+/* 23d - */ 0,
+/* 23e - */ 0,
+/* 23f - */ 0,
+/* 240 - _C7_00 */ 0x216c,
+/* 241 - */ 0,
+/* 242 - */ 0,
+/* 243 - */ 0,
+/* 244 - */ 0,
+/* 245 - */ 0,
+/* 246 - */ 0,
+/* 247 - */ 0,
+/* 248 - _D0_00 */ 0x216d,
+/* 249 - _D0_01 */ 0x216e,
+/* 24a - _D0_02 */ 0x216f,
+/* 24b - _D0_03 */ 0x2170,
+/* 24c - _D0_04 */ 0x2171,
+/* 24d - _D0_05 */ 0x2172,
+/* 24e - _D0_06 */ 0x2173,
+/* 24f - _D0_07 */ 0x2174,
+/* 250 - _D1_00 */ 0x2175,
+/* 251 - _D1_01 */ 0x2176,
+/* 252 - _D1_02 */ 0x2177,
+/* 253 - _D1_03 */ 0x2178,
+/* 254 - _D1_04 */ 0x2179,
+/* 255 - _D1_05 */ 0x217a,
+/* 256 - _D1_06 */ 0x217b,
+/* 257 - _D1_07 */ 0x217c,
+/* 258 - _D2_00 */ 0x217d,
+/* 259 - _D2_01 */ 0x217e,
+/* 25a - _D2_02 */ 0x217f,
+/* 25b - _D2_03 */ 0x2180,
+/* 25c - _D2_04 */ 0x2181,
+/* 25d - _D2_05 */ 0x2182,
+/* 25e - _D2_06 */ 0x2183,
+/* 25f - _D2_07 */ 0x2184,
+/* 260 - _D3_00 */ 0x2185,
+/* 261 - _D3_01 */ 0x2186,
+/* 262 - _D3_02 */ 0x2187,
+/* 263 - _D3_03 */ 0x2188,
+/* 264 - _D3_04 */ 0x2189,
+/* 265 - _D3_05 */ 0x218a,
+/* 266 - _D3_06 */ 0x218b,
+/* 267 - _D3_07 */ 0x218c,
+/* 268 - _D8_00 */ 0x218d,
+/* 269 - _D8_01 */ 0x218e,
+/* 26a - _D8_02 */ 0x218f,
+/* 26b - _D8_03 */ 0x2190,
+/* 26c - _D8_04 */ 0x2191,
+/* 26d - _D8_05 */ 0x2192,
+/* 26e - _D8_06 */ 0x2193,
+/* 26f - _D8_07 */ 0x2194,
+/* 270 - _D8_C0 */ 0x2195,
+/* 271 - _D8_C0 */ 0x2196,
+/* 272 - _D8_C0 */ 0x2197,
+/* 273 - _D8_C0 */ 0x2198,
+/* 274 - _D8_C0 */ 0x2199,
+/* 275 - _D8_C0 */ 0x219a,
+/* 276 - _D8_C0 */ 0x219b,
+/* 277 - _D8_C0 */ 0x219c,
+/* 278 - _D8_C8 */ 0x219d,
+/* 279 - _D8_C8 */ 0x219e,
+/* 27a - _D8_C8 */ 0x219f,
+/* 27b - _D8_C8 */ 0x21a0,
+/* 27c - _D8_C8 */ 0x21a1,
+/* 27d - _D8_C8 */ 0x21a2,
+/* 27e - _D8_C8 */ 0x21a3,
+/* 27f - _D8_C8 */ 0x21a4,
+/* 280 - _D8_D0 */ 0x21a5,
+/* 281 - _D8_D0 */ 0x21a6,
+/* 282 - _D8_D0 */ 0x21a7,
+/* 283 - _D8_D0 */ 0x21a8,
+/* 284 - _D8_D0 */ 0x21a9,
+/* 285 - _D8_D0 */ 0x21aa,
+/* 286 - _D8_D0 */ 0x21ab,
+/* 287 - _D8_D0 */ 0x21ac,
+/* 288 - _D8_D8 */ 0x21ad,
+/* 289 - _D8_D9 */ 0x21ae,
+/* 28a - _D8_D8 */ 0x21af,
+/* 28b - _D8_D8 */ 0x21b0,
+/* 28c - _D8_D8 */ 0x21b1,
+/* 28d - _D8_D8 */ 0x21b2,
+/* 28e - _D8_D8 */ 0x21b3,
+/* 28f - _D8_D8 */ 0x21b4,
+/* 290 - _D8_E0 */ 0x21b5,
+/* 291 - _D8_E0 */ 0x21b6,
+/* 292 - _D8_E0 */ 0x21b7,
+/* 293 - _D8_E0 */ 0x21b8,
+/* 294 - _D8_E0 */ 0x21b9,
+/* 295 - _D8_E0 */ 0x21ba,
+/* 296 - _D8_E0 */ 0x21bb,
+/* 297 - _D8_E0 */ 0x21bc,
+/* 298 - _D8_E8 */ 0x21bd,
+/* 299 - _D8_E8 */ 0x21be,
+/* 29a - _D8_E8 */ 0x21bf,
+/* 29b - _D8_E8 */ 0x21c0,
+/* 29c - _D8_E8 */ 0x21c1,
+/* 29d - _D8_E8 */ 0x21c2,
+/* 29e - _D8_E8 */ 0x21c3,
+/* 29f - _D8_E8 */ 0x21c4,
+/* 2a0 - _D8_F0 */ 0x21c5,
+/* 2a1 - _D8_F0 */ 0x21c6,
+/* 2a2 - _D8_F0 */ 0x21c7,
+/* 2a3 - _D8_F0 */ 0x21c8,
+/* 2a4 - _D8_F0 */ 0x21c9,
+/* 2a5 - _D8_F0 */ 0x21ca,
+/* 2a6 - _D8_F0 */ 0x21cb,
+/* 2a7 - _D8_F0 */ 0x21cc,
+/* 2a8 - _D8_F8 */ 0x21cd,
+/* 2a9 - _D8_F8 */ 0x21ce,
+/* 2aa - _D8_F8 */ 0x21cf,
+/* 2ab - _D8_F8 */ 0x21d0,
+/* 2ac - _D8_F8 */ 0x21d1,
+/* 2ad - _D8_F8 */ 0x21d2,
+/* 2ae - _D8_F8 */ 0x21d3,
+/* 2af - _D8_F8 */ 0x21d4,
+/* 2b0 - _D9_00 */ 0x21d5,
+/* 2b1 - */ 0,
+/* 2b2 - _D9_02 */ 0x21d6,
+/* 2b3 - _D9_03 */ 0x21d7,
+/* 2b4 - _D9_04 */ 0x21d8,
+/* 2b5 - _D9_05 */ 0x21d9,
+/* 2b6 - _D9_06 */ 0xcea4,
+/* 2b7 - _D9_07 */ 0xceb0,
+/* 2b8 - _D9_C0 */ 0x21da,
+/* 2b9 - _D9_C0 */ 0x21db,
+/* 2ba - _D9_C0 */ 0x21dc,
+/* 2bb - _D9_C0 */ 0x21dd,
+/* 2bc - _D9_C0 */ 0x21de,
+/* 2bd - _D9_C0 */ 0x21df,
+/* 2be - _D9_C0 */ 0x21e0,
+/* 2bf - _D9_C0 */ 0x21e1,
+/* 2c0 - _D9_C8 */ 0x21e2,
+/* 2c1 - _D9_C9 */ 0x21e3,
+/* 2c2 - _D9_C8 */ 0x21e4,
+/* 2c3 - _D9_C8 */ 0x21e5,
+/* 2c4 - _D9_C8 */ 0x21e6,
+/* 2c5 - _D9_C8 */ 0x21e7,
+/* 2c6 - _D9_C8 */ 0x21e8,
+/* 2c7 - _D9_C8 */ 0x21e9,
+/* 2c8 - _D9_D0 */ 0x21ea,
+/* 2c9 - */ 0,
+/* 2ca - */ 0,
+/* 2cb - */ 0,
+/* 2cc - */ 0,
+/* 2cd - */ 0,
+/* 2ce - */ 0,
+/* 2cf - */ 0,
+/* 2d0 - */ 0,
+/* 2d1 - */ 0,
+/* 2d2 - */ 0,
+/* 2d3 - */ 0,
+/* 2d4 - */ 0,
+/* 2d5 - */ 0,
+/* 2d6 - */ 0,
+/* 2d7 - */ 0,
+/* 2d8 - _D9_E0 */ 0x21eb,
+/* 2d9 - _D9_E1 */ 0x21ec,
+/* 2da - */ 0,
+/* 2db - */ 0,
+/* 2dc - _D9_E4 */ 0x21ed,
+/* 2dd - _D9_E5 */ 0x21ee,
+/* 2de - */ 0,
+/* 2df - */ 0,
+/* 2e0 - _D9_E8 */ 0x21ef,
+/* 2e1 - _D9_E9 */ 0x21f0,
+/* 2e2 - _D9_EA */ 0x21f1,
+/* 2e3 - _D9_EB */ 0x21f2,
+/* 2e4 - _D9_EC */ 0x21f3,
+/* 2e5 - _D9_ED */ 0x21f4,
+/* 2e6 - _D9_EE */ 0x21f5,
+/* 2e7 - */ 0,
+/* 2e8 - _D9_F0 */ 0x21f6,
+/* 2e9 - _D9_F1 */ 0x21f7,
+/* 2ea - _D9_F2 */ 0x21f8,
+/* 2eb - _D9_F3 */ 0x21f9,
+/* 2ec - _D9_F4 */ 0x21fa,
+/* 2ed - _D9_F5 */ 0x21fb,
+/* 2ee - _D9_F6 */ 0x21fc,
+/* 2ef - _D9_F7 */ 0x21fd,
+/* 2f0 - _D9_F8 */ 0x21fe,
+/* 2f1 - _D9_F9 */ 0x21ff,
+/* 2f2 - _D9_FA */ 0x2200,
+/* 2f3 - _D9_FB */ 0x2201,
+/* 2f4 - _D9_FC */ 0x2202,
+/* 2f5 - _D9_FD */ 0x2203,
+/* 2f6 - _D9_FE */ 0x2204,
+/* 2f7 - _D9_FF */ 0x2205,
+/* 2f8 - _DA_00 */ 0x2206,
+/* 2f9 - _DA_01 */ 0x2207,
+/* 2fa - _DA_02 */ 0x2208,
+/* 2fb - _DA_03 */ 0x2209,
+/* 2fc - _DA_04 */ 0x220a,
+/* 2fd - _DA_05 */ 0x220b,
+/* 2fe - _DA_06 */ 0x220c,
+/* 2ff - _DA_07 */ 0x220d,
+/* 300 - _DA_C0 */ 0x220e,
+/* 301 - _DA_C0 */ 0x220f,
+/* 302 - _DA_C0 */ 0x2210,
+/* 303 - _DA_C0 */ 0x2211,
+/* 304 - _DA_C0 */ 0x2212,
+/* 305 - _DA_C0 */ 0x2213,
+/* 306 - _DA_C0 */ 0x2214,
+/* 307 - _DA_C0 */ 0x2215,
+/* 308 - _DA_C8 */ 0x2216,
+/* 309 - _DA_C8 */ 0x2217,
+/* 30a - _DA_C8 */ 0x2218,
+/* 30b - _DA_C8 */ 0x2219,
+/* 30c - _DA_C8 */ 0x221a,
+/* 30d - _DA_C8 */ 0x221b,
+/* 30e - _DA_C8 */ 0x221c,
+/* 30f - _DA_C8 */ 0x221d,
+/* 310 - _DA_D0 */ 0x221e,
+/* 311 - _DA_D0 */ 0x221f,
+/* 312 - _DA_D0 */ 0x2220,
+/* 313 - _DA_D0 */ 0x2221,
+/* 314 - _DA_D0 */ 0x2222,
+/* 315 - _DA_D0 */ 0x2223,
+/* 316 - _DA_D0 */ 0x2224,
+/* 317 - _DA_D0 */ 0x2225,
+/* 318 - _DA_D8 */ 0x2226,
+/* 319 - _DA_D8 */ 0x2227,
+/* 31a - _DA_D8 */ 0x2228,
+/* 31b - _DA_D8 */ 0x2229,
+/* 31c - _DA_D8 */ 0x222a,
+/* 31d - _DA_D8 */ 0x222b,
+/* 31e - _DA_D8 */ 0x222c,
+/* 31f - _DA_D8 */ 0x222d,
+/* 320 - */ 0,
+/* 321 - */ 0,
+/* 322 - */ 0,
+/* 323 - */ 0,
+/* 324 - */ 0,
+/* 325 - */ 0,
+/* 326 - */ 0,
+/* 327 - */ 0,
+/* 328 - */ 0,
+/* 329 - _DA_E9 */ 0x222e,
+/* 32a - */ 0,
+/* 32b - */ 0,
+/* 32c - */ 0,
+/* 32d - */ 0,
+/* 32e - */ 0,
+/* 32f - */ 0,
+/* 330 - */ 0,
+/* 331 - */ 0,
+/* 332 - */ 0,
+/* 333 - */ 0,
+/* 334 - */ 0,
+/* 335 - */ 0,
+/* 336 - */ 0,
+/* 337 - */ 0,
+/* 338 - */ 0,
+/* 339 - */ 0,
+/* 33a - */ 0,
+/* 33b - */ 0,
+/* 33c - */ 0,
+/* 33d - */ 0,
+/* 33e - */ 0,
+/* 33f - */ 0,
+/* 340 - _DB_00 */ 0x222f,
+/* 341 - _DB_01 */ 0x2230,
+/* 342 - _DB_02 */ 0x2231,
+/* 343 - _DB_03 */ 0x2232,
+/* 344 - */ 0,
+/* 345 - _DB_05 */ 0x2233,
+/* 346 - */ 0,
+/* 347 - _DB_07 */ 0x2234,
+/* 348 - _DB_C0 */ 0x2235,
+/* 349 - _DB_C0 */ 0x2236,
+/* 34a - _DB_C0 */ 0x2237,
+/* 34b - _DB_C0 */ 0x2238,
+/* 34c - _DB_C0 */ 0x2239,
+/* 34d - _DB_C0 */ 0x223a,
+/* 34e - _DB_C0 */ 0x223b,
+/* 34f - _DB_C0 */ 0x223c,
+/* 350 - _DB_C8 */ 0x223d,
+/* 351 - _DB_C8 */ 0x223e,
+/* 352 - _DB_C8 */ 0x223f,
+/* 353 - _DB_C8 */ 0x2240,
+/* 354 - _DB_C8 */ 0x2241,
+/* 355 - _DB_C8 */ 0x2242,
+/* 356 - _DB_C8 */ 0x2243,
+/* 357 - _DB_C8 */ 0x2244,
+/* 358 - _DB_D0 */ 0x2245,
+/* 359 - _DB_D0 */ 0x2246,
+/* 35a - _DB_D0 */ 0x2247,
+/* 35b - _DB_D0 */ 0x2248,
+/* 35c - _DB_D0 */ 0x2249,
+/* 35d - _DB_D0 */ 0x224a,
+/* 35e - _DB_D0 */ 0x224b,
+/* 35f - _DB_D0 */ 0x224c,
+/* 360 - _DB_D8 */ 0x224d,
+/* 361 - _DB_D8 */ 0x224e,
+/* 362 - _DB_D8 */ 0x224f,
+/* 363 - _DB_D8 */ 0x2250,
+/* 364 - _DB_D8 */ 0x2251,
+/* 365 - _DB_D8 */ 0x2252,
+/* 366 - _DB_D8 */ 0x2253,
+/* 367 - _DB_D8 */ 0x2254,
+/* 368 - _DB_E0 */ 0x2255,
+/* 369 - _DB_E1 */ 0x2256,
+/* 36a - _DB_E2 */ 0xcebc,
+/* 36b - _DB_E3 */ 0xcec8,
+/* 36c - _DB_E4 */ 0x2257,
+/* 36d - */ 0,
+/* 36e - */ 0,
+/* 36f - */ 0,
+/* 370 - _DB_E8 */ 0x2258,
+/* 371 - _DB_E8 */ 0x2259,
+/* 372 - _DB_E8 */ 0x225a,
+/* 373 - _DB_E8 */ 0x225b,
+/* 374 - _DB_E8 */ 0x225c,
+/* 375 - _DB_E8 */ 0x225d,
+/* 376 - _DB_E8 */ 0x225e,
+/* 377 - _DB_E8 */ 0x225f,
+/* 378 - _DB_F0 */ 0x2260,
+/* 379 - _DB_F0 */ 0x2261,
+/* 37a - _DB_F0 */ 0x2262,
+/* 37b - _DB_F0 */ 0x2263,
+/* 37c - _DB_F0 */ 0x2264,
+/* 37d - _DB_F0 */ 0x2265,
+/* 37e - _DB_F0 */ 0x2266,
+/* 37f - _DB_F0 */ 0x2267,
+/* 380 - */ 0,
+/* 381 - */ 0,
+/* 382 - */ 0,
+/* 383 - */ 0,
+/* 384 - */ 0,
+/* 385 - */ 0,
+/* 386 - */ 0,
+/* 387 - */ 0,
+/* 388 - _DC_00 */ 0x2268,
+/* 389 - _DC_01 */ 0x2269,
+/* 38a - _DC_02 */ 0x226a,
+/* 38b - _DC_03 */ 0x226b,
+/* 38c - _DC_04 */ 0x226c,
+/* 38d - _DC_05 */ 0x226d,
+/* 38e - _DC_06 */ 0x226e,
+/* 38f - _DC_07 */ 0x226f,
+/* 390 - _DC_C0 */ 0x2270,
+/* 391 - _DC_C0 */ 0x2271,
+/* 392 - _DC_C0 */ 0x2272,
+/* 393 - _DC_C0 */ 0x2273,
+/* 394 - _DC_C0 */ 0x2274,
+/* 395 - _DC_C0 */ 0x2275,
+/* 396 - _DC_C0 */ 0x2276,
+/* 397 - _DC_C0 */ 0x2277,
+/* 398 - _DC_C8 */ 0x2278,
+/* 399 - _DC_C8 */ 0x2279,
+/* 39a - _DC_C8 */ 0x227a,
+/* 39b - _DC_C8 */ 0x227b,
+/* 39c - _DC_C8 */ 0x227c,
+/* 39d - _DC_C8 */ 0x227d,
+/* 39e - _DC_C8 */ 0x227e,
+/* 39f - _DC_C8 */ 0x227f,
+/* 3a0 - */ 0,
+/* 3a1 - */ 0,
+/* 3a2 - */ 0,
+/* 3a3 - */ 0,
+/* 3a4 - */ 0,
+/* 3a5 - */ 0,
+/* 3a6 - */ 0,
+/* 3a7 - */ 0,
+/* 3a8 - */ 0,
+/* 3a9 - */ 0,
+/* 3aa - */ 0,
+/* 3ab - */ 0,
+/* 3ac - */ 0,
+/* 3ad - */ 0,
+/* 3ae - */ 0,
+/* 3af - */ 0,
+/* 3b0 - _DC_E0 */ 0x2280,
+/* 3b1 - _DC_E0 */ 0x2281,
+/* 3b2 - _DC_E0 */ 0x2282,
+/* 3b3 - _DC_E0 */ 0x2283,
+/* 3b4 - _DC_E0 */ 0x2284,
+/* 3b5 - _DC_E0 */ 0x2285,
+/* 3b6 - _DC_E0 */ 0x2286,
+/* 3b7 - _DC_E0 */ 0x2287,
+/* 3b8 - _DC_E8 */ 0x2288,
+/* 3b9 - _DC_E8 */ 0x2289,
+/* 3ba - _DC_E8 */ 0x228a,
+/* 3bb - _DC_E8 */ 0x228b,
+/* 3bc - _DC_E8 */ 0x228c,
+/* 3bd - _DC_E8 */ 0x228d,
+/* 3be - _DC_E8 */ 0x228e,
+/* 3bf - _DC_E8 */ 0x228f,
+/* 3c0 - _DC_F0 */ 0x2290,
+/* 3c1 - _DC_F0 */ 0x2291,
+/* 3c2 - _DC_F0 */ 0x2292,
+/* 3c3 - _DC_F0 */ 0x2293,
+/* 3c4 - _DC_F0 */ 0x2294,
+/* 3c5 - _DC_F0 */ 0x2295,
+/* 3c6 - _DC_F0 */ 0x2296,
+/* 3c7 - _DC_F0 */ 0x2297,
+/* 3c8 - _DC_F8 */ 0x2298,
+/* 3c9 - _DC_F8 */ 0x2299,
+/* 3ca - _DC_F8 */ 0x229a,
+/* 3cb - _DC_F8 */ 0x229b,
+/* 3cc - _DC_F8 */ 0x229c,
+/* 3cd - _DC_F8 */ 0x229d,
+/* 3ce - _DC_F8 */ 0x229e,
+/* 3cf - _DC_F8 */ 0x229f,
+/* 3d0 - _DD_00 */ 0x22a0,
+/* 3d1 - _DD_01 */ 0x22a1,
+/* 3d2 - _DD_02 */ 0x22a2,
+/* 3d3 - _DD_03 */ 0x22a3,
+/* 3d4 - _DD_04 */ 0x22a4,
+/* 3d5 - */ 0,
+/* 3d6 - _DD_06 */ 0xced4,
+/* 3d7 - _DD_07 */ 0xcee0,
+/* 3d8 - _DD_C0 */ 0x22a5,
+/* 3d9 - _DD_C0 */ 0x22a6,
+/* 3da - _DD_C0 */ 0x22a7,
+/* 3db - _DD_C0 */ 0x22a8,
+/* 3dc - _DD_C0 */ 0x22a9,
+/* 3dd - _DD_C0 */ 0x22aa,
+/* 3de - _DD_C0 */ 0x22ab,
+/* 3df - _DD_C0 */ 0x22ac,
+/* 3e0 - */ 0,
+/* 3e1 - */ 0,
+/* 3e2 - */ 0,
+/* 3e3 - */ 0,
+/* 3e4 - */ 0,
+/* 3e5 - */ 0,
+/* 3e6 - */ 0,
+/* 3e7 - */ 0,
+/* 3e8 - _DD_D0 */ 0x22ad,
+/* 3e9 - _DD_D0 */ 0x22ae,
+/* 3ea - _DD_D0 */ 0x22af,
+/* 3eb - _DD_D0 */ 0x22b0,
+/* 3ec - _DD_D0 */ 0x22b1,
+/* 3ed - _DD_D0 */ 0x22b2,
+/* 3ee - _DD_D0 */ 0x22b3,
+/* 3ef - _DD_D0 */ 0x22b4,
+/* 3f0 - _DD_D8 */ 0x22b5,
+/* 3f1 - _DD_D8 */ 0x22b6,
+/* 3f2 - _DD_D8 */ 0x22b7,
+/* 3f3 - _DD_D8 */ 0x22b8,
+/* 3f4 - _DD_D8 */ 0x22b9,
+/* 3f5 - _DD_D8 */ 0x22ba,
+/* 3f6 - _DD_D8 */ 0x22bb,
+/* 3f7 - _DD_D8 */ 0x22bc,
+/* 3f8 - _DD_E0 */ 0x22bd,
+/* 3f9 - _DD_E1 */ 0x22be,
+/* 3fa - _DD_E0 */ 0x22bf,
+/* 3fb - _DD_E0 */ 0x22c0,
+/* 3fc - _DD_E0 */ 0x22c1,
+/* 3fd - _DD_E0 */ 0x22c2,
+/* 3fe - _DD_E0 */ 0x22c3,
+/* 3ff - _DD_E0 */ 0x22c4,
+/* 400 - _DD_E8 */ 0x22c5,
+/* 401 - _DD_E9 */ 0x22c6,
+/* 402 - _DD_E8 */ 0x22c7,
+/* 403 - _DD_E8 */ 0x22c8,
+/* 404 - _DD_E8 */ 0x22c9,
+/* 405 - _DD_E8 */ 0x22ca,
+/* 406 - _DD_E8 */ 0x22cb,
+/* 407 - _DD_E8 */ 0x22cc,
+/* 408 - */ 0,
+/* 409 - */ 0,
+/* 40a - */ 0,
+/* 40b - */ 0,
+/* 40c - */ 0,
+/* 40d - */ 0,
+/* 40e - */ 0,
+/* 40f - */ 0,
+/* 410 - */ 0,
+/* 411 - */ 0,
+/* 412 - */ 0,
+/* 413 - */ 0,
+/* 414 - */ 0,
+/* 415 - */ 0,
+/* 416 - */ 0,
+/* 417 - */ 0,
+/* 418 - _DE_00 */ 0x22cd,
+/* 419 - _DE_01 */ 0x22ce,
+/* 41a - _DE_02 */ 0x22cf,
+/* 41b - _DE_03 */ 0x22d0,
+/* 41c - _DE_04 */ 0x22d1,
+/* 41d - _DE_05 */ 0x22d2,
+/* 41e - _DE_06 */ 0x22d3,
+/* 41f - _DE_07 */ 0x22d4,
+/* 420 - _DE_C0 */ 0x22d5,
+/* 421 - _DE_C1 */ 0x22d6,
+/* 422 - _DE_C0 */ 0x22d7,
+/* 423 - _DE_C0 */ 0x22d8,
+/* 424 - _DE_C0 */ 0x22d9,
+/* 425 - _DE_C0 */ 0x22da,
+/* 426 - _DE_C0 */ 0x22db,
+/* 427 - _DE_C0 */ 0x22dc,
+/* 428 - _DE_C8 */ 0x22dd,
+/* 429 - _DE_C9 */ 0x22de,
+/* 42a - _DE_C8 */ 0x22df,
+/* 42b - _DE_C8 */ 0x22e0,
+/* 42c - _DE_C8 */ 0x22e1,
+/* 42d - _DE_C8 */ 0x22e2,
+/* 42e - _DE_C8 */ 0x22e3,
+/* 42f - _DE_C8 */ 0x22e4,
+/* 430 - */ 0,
+/* 431 - */ 0,
+/* 432 - */ 0,
+/* 433 - */ 0,
+/* 434 - */ 0,
+/* 435 - */ 0,
+/* 436 - */ 0,
+/* 437 - */ 0,
+/* 438 - */ 0,
+/* 439 - _DE_D9 */ 0x22e5,
+/* 43a - */ 0,
+/* 43b - */ 0,
+/* 43c - */ 0,
+/* 43d - */ 0,
+/* 43e - */ 0,
+/* 43f - */ 0,
+/* 440 - _DE_E0 */ 0x22e6,
+/* 441 - _DE_E1 */ 0x22e7,
+/* 442 - _DE_E0 */ 0x22e8,
+/* 443 - _DE_E0 */ 0x22e9,
+/* 444 - _DE_E0 */ 0x22ea,
+/* 445 - _DE_E0 */ 0x22eb,
+/* 446 - _DE_E0 */ 0x22ec,
+/* 447 - _DE_E0 */ 0x22ed,
+/* 448 - _DE_E8 */ 0x22ee,
+/* 449 - _DE_E9 */ 0x22ef,
+/* 44a - _DE_E8 */ 0x22f0,
+/* 44b - _DE_E8 */ 0x22f1,
+/* 44c - _DE_E8 */ 0x22f2,
+/* 44d - _DE_E8 */ 0x22f3,
+/* 44e - _DE_E8 */ 0x22f4,
+/* 44f - _DE_E8 */ 0x22f5,
+/* 450 - _DE_F0 */ 0x22f6,
+/* 451 - _DE_F1 */ 0x22f7,
+/* 452 - _DE_F0 */ 0x22f8,
+/* 453 - _DE_F0 */ 0x22f9,
+/* 454 - _DE_F0 */ 0x22fa,
+/* 455 - _DE_F0 */ 0x22fb,
+/* 456 - _DE_F0 */ 0x22fc,
+/* 457 - _DE_F0 */ 0x22fd,
+/* 458 - _DE_F8 */ 0x22fe,
+/* 459 - _DE_F9 */ 0x22ff,
+/* 45a - _DE_F8 */ 0x2300,
+/* 45b - _DE_F8 */ 0x2301,
+/* 45c - _DE_F8 */ 0x2302,
+/* 45d - _DE_F8 */ 0x2303,
+/* 45e - _DE_F8 */ 0x2304,
+/* 45f - _DE_F8 */ 0x2305,
+/* 460 - _DF_00 */ 0x2306,
+/* 461 - _DF_01 */ 0x2307,
+/* 462 - _DF_02 */ 0x2308,
+/* 463 - _DF_03 */ 0x2309,
+/* 464 - _DF_04 */ 0x230a,
+/* 465 - _DF_05 */ 0x230b,
+/* 466 - _DF_06 */ 0x230c,
+/* 467 - _DF_07 */ 0x230d,
+/* 468 - */ 0,
+/* 469 - */ 0,
+/* 46a - */ 0,
+/* 46b - */ 0,
+/* 46c - */ 0,
+/* 46d - */ 0,
+/* 46e - */ 0,
+/* 46f - */ 0,
+/* 470 - */ 0,
+/* 471 - */ 0,
+/* 472 - */ 0,
+/* 473 - */ 0,
+/* 474 - */ 0,
+/* 475 - */ 0,
+/* 476 - */ 0,
+/* 477 - */ 0,
+/* 478 - */ 0,
+/* 479 - */ 0,
+/* 47a - */ 0,
+/* 47b - */ 0,
+/* 47c - */ 0,
+/* 47d - */ 0,
+/* 47e - */ 0,
+/* 47f - */ 0,
+/* 480 - */ 0,
+/* 481 - */ 0,
+/* 482 - */ 0,
+/* 483 - */ 0,
+/* 484 - */ 0,
+/* 485 - */ 0,
+/* 486 - */ 0,
+/* 487 - */ 0,
+/* 488 - _DF_E0 */ 0xceec,
+/* 489 - */ 0,
+/* 48a - */ 0,
+/* 48b - */ 0,
+/* 48c - */ 0,
+/* 48d - */ 0,
+/* 48e - */ 0,
+/* 48f - */ 0,
+/* 490 - _DF_E8 */ 0x230e,
+/* 491 - _DF_E8 */ 0x230f,
+/* 492 - _DF_E8 */ 0x2310,
+/* 493 - _DF_E8 */ 0x2311,
+/* 494 - _DF_E8 */ 0x2312,
+/* 495 - _DF_E8 */ 0x2313,
+/* 496 - _DF_E8 */ 0x2314,
+/* 497 - _DF_E8 */ 0x2315,
+/* 498 - _DF_F0 */ 0x2316,
+/* 499 - _DF_F0 */ 0x2317,
+/* 49a - _DF_F0 */ 0x2318,
+/* 49b - _DF_F0 */ 0x2319,
+/* 49c - _DF_F0 */ 0x231a,
+/* 49d - _DF_F0 */ 0x231b,
+/* 49e - _DF_F0 */ 0x231c,
+/* 49f - _DF_F0 */ 0x231d,
+/* 4a0 - */ 0,
+/* 4a1 - */ 0,
+/* 4a2 - */ 0,
+/* 4a3 - */ 0,
+/* 4a4 - */ 0,
+/* 4a5 - */ 0,
+/* 4a6 - */ 0,
+/* 4a7 - */ 0,
+/* 4a8 - _F6_00 */ 0x231e,
+/* 4a9 - */ 0,
+/* 4aa - _F6_02 */ 0x231f,
+/* 4ab - _F6_03 */ 0x2320,
+/* 4ac - _F6_04 */ 0x2321,
+/* 4ad - _F6_05 */ 0x2322,
+/* 4ae - _F6_06 */ 0x2323,
+/* 4af - _F6_07 */ 0x2324,
+/* 4b0 - _F7_00 */ 0x2325,
+/* 4b1 - */ 0,
+/* 4b2 - _F7_02 */ 0x2326,
+/* 4b3 - _F7_03 */ 0x2327,
+/* 4b4 - _F7_04 */ 0x2328,
+/* 4b5 - _F7_05 */ 0x2329,
+/* 4b6 - _F7_06 */ 0x232a,
+/* 4b7 - _F7_07 */ 0x232b,
+/* 4b8 - _FE_00 */ 0x232c,
+/* 4b9 - _FE_01 */ 0x232d,
+/* 4ba - */ 0,
+/* 4bb - */ 0,
+/* 4bc - */ 0,
+/* 4bd - */ 0,
+/* 4be - */ 0,
+/* 4bf - */ 0,
+/* 4c0 - _FF_00 */ 0x232e,
+/* 4c1 - _FF_01 */ 0x232f,
+/* 4c2 - _FF_02 */ 0x2330,
+/* 4c3 - _FF_03 */ 0x2331,
+/* 4c4 - _FF_04 */ 0x2332,
+/* 4c5 - _FF_05 */ 0x2333,
+/* 4c6 - _FF_06 */ 0x2334,
+/* 4c7 - */ 0,
+/* 4c8 - _0F_00_00 */ 0x2335,
+/* 4c9 - _0F_00_01 */ 0x2336,
+/* 4ca - _0F_00_02 */ 0x2337,
+/* 4cb - _0F_00_03 */ 0x2338,
+/* 4cc - _0F_00_04 */ 0x2339,
+/* 4cd - _0F_00_05 */ 0x233a,
+/* 4ce - */ 0,
+/* 4cf - */ 0,
+/* 4d0 - _0F_01_00 */ 0x233b,
+/* 4d1 - _0F_01_01 */ 0x233c,
+/* 4d2 - _0F_01_02 */ 0x233d,
+/* 4d3 - _0F_01_03 */ 0x233e,
+/* 4d4 - _0F_01_04 */ 0x233f,
+/* 4d5 - */ 0,
+/* 4d6 - _0F_01_06 */ 0x2340,
+/* 4d7 - _0F_01_07 */ 0x2341,
+/* 4d8 - */ 0,
+/* 4d9 - _0F_01_C1 */ 0x2342,
+/* 4da - _0F_01_C2 */ 0x2343,
+/* 4db - _0F_01_C3 */ 0x2344,
+/* 4dc - _0F_01_C4 */ 0x2345,
+/* 4dd - */ 0,
+/* 4de - */ 0,
+/* 4df - */ 0,
+/* 4e0 - _0F_01_C8 */ 0x2346,
+/* 4e1 - _0F_01_C9 */ 0x2347,
+/* 4e2 - */ 0,
+/* 4e3 - */ 0,
+/* 4e4 - */ 0,
+/* 4e5 - */ 0,
+/* 4e6 - */ 0,
+/* 4e7 - */ 0,
+/* 4e8 - _0F_01_D0 */ 0x2348,
+/* 4e9 - _0F_01_D1 */ 0x2349,
+/* 4ea - */ 0,
+/* 4eb - */ 0,
+/* 4ec - _0F_01_D4 */ 0x234a,
+/* 4ed - */ 0,
+/* 4ee - */ 0,
+/* 4ef - */ 0,
+/* 4f0 - _0F_01_D8 */ 0x234b,
+/* 4f1 - _0F_01_D9 */ 0x234c,
+/* 4f2 - _0F_01_DA */ 0x234d,
+/* 4f3 - _0F_01_DB */ 0x234e,
+/* 4f4 - _0F_01_DC */ 0x234f,
+/* 4f5 - _0F_01_DD */ 0x2350,
+/* 4f6 - _0F_01_DE */ 0x2351,
+/* 4f7 - _0F_01_DF */ 0x2352,
+/* 4f8 - */ 0,
+/* 4f9 - */ 0,
+/* 4fa - */ 0,
+/* 4fb - */ 0,
+/* 4fc - */ 0,
+/* 4fd - */ 0,
+/* 4fe - */ 0,
+/* 4ff - */ 0,
+/* 500 - */ 0,
+/* 501 - */ 0,
+/* 502 - */ 0,
+/* 503 - */ 0,
+/* 504 - */ 0,
+/* 505 - */ 0,
+/* 506 - */ 0,
+/* 507 - */ 0,
+/* 508 - */ 0,
+/* 509 - */ 0,
+/* 50a - */ 0,
+/* 50b - */ 0,
+/* 50c - */ 0,
+/* 50d - */ 0,
+/* 50e - */ 0,
+/* 50f - */ 0,
+/* 510 - _0F_01_F8 */ 0x2353,
+/* 511 - _0F_01_F9 */ 0x2354,
+/* 512 - */ 0,
+/* 513 - */ 0,
+/* 514 - */ 0,
+/* 515 - */ 0,
+/* 516 - */ 0,
+/* 517 - */ 0,
+/* 518 - _0F_0D_00 */ 0x2355,
+/* 519 - _0F_0D_01 */ 0x2356,
+/* 51a - */ 0,
+/* 51b - */ 0,
+/* 51c - */ 0,
+/* 51d - */ 0,
+/* 51e - */ 0,
+/* 51f - */ 0,
+/* 520 - */ 0,
+/* 521 - */ 0,
+/* 522 - */ 0,
+/* 523 - */ 0,
+/* 524 - */ 0,
+/* 525 - */ 0,
+/* 526 - */ 0,
+/* 527 - */ 0,
+/* 528 - */ 0,
+/* 529 - */ 0,
+/* 52a - */ 0,
+/* 52b - */ 0,
+/* 52c - _0F_0F_0C */ 0x2357,
+/* 52d - _0F_0F_0D */ 0x2358,
+/* 52e - */ 0,
+/* 52f - */ 0,
+/* 530 - */ 0,
+/* 531 - */ 0,
+/* 532 - */ 0,
+/* 533 - */ 0,
+/* 534 - */ 0,
+/* 535 - */ 0,
+/* 536 - */ 0,
+/* 537 - */ 0,
+/* 538 - */ 0,
+/* 539 - */ 0,
+/* 53a - */ 0,
+/* 53b - */ 0,
+/* 53c - _0F_0F_1C */ 0x2359,
+/* 53d - _0F_0F_1D */ 0x235a,
+/* 53e - */ 0,
+/* 53f - */ 0,
+/* 540 - */ 0,
+/* 541 - */ 0,
+/* 542 - */ 0,
+/* 543 - */ 0,
+/* 544 - */ 0,
+/* 545 - */ 0,
+/* 546 - */ 0,
+/* 547 - */ 0,
+/* 548 - */ 0,
+/* 549 - */ 0,
+/* 54a - */ 0,
+/* 54b - */ 0,
+/* 54c - */ 0,
+/* 54d - */ 0,
+/* 54e - */ 0,
+/* 54f - */ 0,
+/* 550 - */ 0,
+/* 551 - */ 0,
+/* 552 - */ 0,
+/* 553 - */ 0,
+/* 554 - */ 0,
+/* 555 - */ 0,
+/* 556 - */ 0,
+/* 557 - */ 0,
+/* 558 - */ 0,
+/* 559 - */ 0,
+/* 55a - */ 0,
+/* 55b - */ 0,
+/* 55c - */ 0,
+/* 55d - */ 0,
+/* 55e - */ 0,
+/* 55f - */ 0,
+/* 560 - */ 0,
+/* 561 - */ 0,
+/* 562 - */ 0,
+/* 563 - */ 0,
+/* 564 - */ 0,
+/* 565 - */ 0,
+/* 566 - */ 0,
+/* 567 - */ 0,
+/* 568 - */ 0,
+/* 569 - */ 0,
+/* 56a - */ 0,
+/* 56b - */ 0,
+/* 56c - */ 0,
+/* 56d - */ 0,
+/* 56e - */ 0,
+/* 56f - */ 0,
+/* 570 - */ 0,
+/* 571 - */ 0,
+/* 572 - */ 0,
+/* 573 - */ 0,
+/* 574 - */ 0,
+/* 575 - */ 0,
+/* 576 - */ 0,
+/* 577 - */ 0,
+/* 578 - */ 0,
+/* 579 - */ 0,
+/* 57a - */ 0,
+/* 57b - */ 0,
+/* 57c - */ 0,
+/* 57d - */ 0,
+/* 57e - */ 0,
+/* 57f - */ 0,
+/* 580 - */ 0,
+/* 581 - */ 0,
+/* 582 - */ 0,
+/* 583 - */ 0,
+/* 584 - */ 0,
+/* 585 - */ 0,
+/* 586 - */ 0,
+/* 587 - */ 0,
+/* 588 - */ 0,
+/* 589 - */ 0,
+/* 58a - */ 0,
+/* 58b - */ 0,
+/* 58c - */ 0,
+/* 58d - */ 0,
+/* 58e - */ 0,
+/* 58f - */ 0,
+/* 590 - */ 0,
+/* 591 - */ 0,
+/* 592 - */ 0,
+/* 593 - */ 0,
+/* 594 - */ 0,
+/* 595 - */ 0,
+/* 596 - */ 0,
+/* 597 - */ 0,
+/* 598 - */ 0,
+/* 599 - */ 0,
+/* 59a - */ 0,
+/* 59b - */ 0,
+/* 59c - */ 0,
+/* 59d - */ 0,
+/* 59e - */ 0,
+/* 59f - */ 0,
+/* 5a0 - */ 0,
+/* 5a1 - */ 0,
+/* 5a2 - */ 0,
+/* 5a3 - */ 0,
+/* 5a4 - */ 0,
+/* 5a5 - */ 0,
+/* 5a6 - */ 0,
+/* 5a7 - */ 0,
+/* 5a8 - */ 0,
+/* 5a9 - */ 0,
+/* 5aa - _0F_0F_8A */ 0x235b,
+/* 5ab - */ 0,
+/* 5ac - */ 0,
+/* 5ad - */ 0,
+/* 5ae - _0F_0F_8E */ 0x235c,
+/* 5af - */ 0,
+/* 5b0 - _0F_0F_90 */ 0x235d,
+/* 5b1 - */ 0,
+/* 5b2 - */ 0,
+/* 5b3 - */ 0,
+/* 5b4 - _0F_0F_94 */ 0x235e,
+/* 5b5 - */ 0,
+/* 5b6 - _0F_0F_96 */ 0x235f,
+/* 5b7 - _0F_0F_97 */ 0x2360,
+/* 5b8 - */ 0,
+/* 5b9 - */ 0,
+/* 5ba - _0F_0F_9A */ 0x2361,
+/* 5bb - */ 0,
+/* 5bc - */ 0,
+/* 5bd - */ 0,
+/* 5be - _0F_0F_9E */ 0x2362,
+/* 5bf - */ 0,
+/* 5c0 - _0F_0F_A0 */ 0x2363,
+/* 5c1 - */ 0,
+/* 5c2 - */ 0,
+/* 5c3 - */ 0,
+/* 5c4 - _0F_0F_A4 */ 0x2364,
+/* 5c5 - */ 0,
+/* 5c6 - _0F_0F_A6 */ 0x2365,
+/* 5c7 - _0F_0F_A7 */ 0x2366,
+/* 5c8 - */ 0,
+/* 5c9 - */ 0,
+/* 5ca - _0F_0F_AA */ 0x2367,
+/* 5cb - */ 0,
+/* 5cc - */ 0,
+/* 5cd - */ 0,
+/* 5ce - _0F_0F_AE */ 0x2368,
+/* 5cf - */ 0,
+/* 5d0 - _0F_0F_B0 */ 0x2369,
+/* 5d1 - */ 0,
+/* 5d2 - */ 0,
+/* 5d3 - */ 0,
+/* 5d4 - _0F_0F_B4 */ 0x236a,
+/* 5d5 - */ 0,
+/* 5d6 - _0F_0F_B6 */ 0x236b,
+/* 5d7 - _0F_0F_B7 */ 0x236c,
+/* 5d8 - */ 0,
+/* 5d9 - */ 0,
+/* 5da - */ 0,
+/* 5db - _0F_0F_BB */ 0x236d,
+/* 5dc - */ 0,
+/* 5dd - */ 0,
+/* 5de - */ 0,
+/* 5df - _0F_0F_BF */ 0x236e,
+/* 5e0 - */ 0,
+/* 5e1 - */ 0,
+/* 5e2 - */ 0,
+/* 5e3 - */ 0,
+/* 5e4 - */ 0,
+/* 5e5 - */ 0,
+/* 5e6 - */ 0,
+/* 5e7 - */ 0,
+/* 5e8 - */ 0,
+/* 5e9 - */ 0,
+/* 5ea - */ 0,
+/* 5eb - */ 0,
+/* 5ec - */ 0,
+/* 5ed - */ 0,
+/* 5ee - */ 0,
+/* 5ef - */ 0,
+/* 5f0 - */ 0,
+/* 5f1 - */ 0,
+/* 5f2 - */ 0,
+/* 5f3 - */ 0,
+/* 5f4 - */ 0,
+/* 5f5 - */ 0,
+/* 5f6 - */ 0,
+/* 5f7 - */ 0,
+/* 5f8 - */ 0,
+/* 5f9 - */ 0,
+/* 5fa - */ 0,
+/* 5fb - */ 0,
+/* 5fc - */ 0,
+/* 5fd - */ 0,
+/* 5fe - */ 0,
+/* 5ff - */ 0,
+/* 600 - */ 0,
+/* 601 - */ 0,
+/* 602 - */ 0,
+/* 603 - */ 0,
+/* 604 - */ 0,
+/* 605 - */ 0,
+/* 606 - */ 0,
+/* 607 - */ 0,
+/* 608 - */ 0,
+/* 609 - */ 0,
+/* 60a - */ 0,
+/* 60b - */ 0,
+/* 60c - */ 0,
+/* 60d - */ 0,
+/* 60e - */ 0,
+/* 60f - */ 0,
+/* 610 - */ 0,
+/* 611 - */ 0,
+/* 612 - */ 0,
+/* 613 - */ 0,
+/* 614 - */ 0,
+/* 615 - */ 0,
+/* 616 - */ 0,
+/* 617 - */ 0,
+/* 618 - */ 0,
+/* 619 - */ 0,
+/* 61a - */ 0,
+/* 61b - */ 0,
+/* 61c - */ 0,
+/* 61d - */ 0,
+/* 61e - */ 0,
+/* 61f - */ 0,
+/* 620 - _0F_10 */ 0x236f,
+/* 621 - _66_0F_10 */ 0x2370,
+/* 622 - _F3_0F_10 */ 0x2371,
+/* 623 - _F2_0F_10 */ 0x2372,
+/* 624 - _V_0F_10 */ 0x4009,
+/* 625 - _V_66_0F_10 */ 0x400a,
+/* 626 - _V_F3_0F_10 */ 0x400b,
+/* 627 - _V_F2_0F_10 */ 0x400c,
+/* 628 - */ 0,
+/* 629 - */ 0,
+/* 62a - _VRR_F3_0F_10 */ 0x400d,
+/* 62b - _VRR_F2_0F_10 */ 0x400e,
+/* 62c - _0F_11 */ 0x2373,
+/* 62d - _66_0F_11 */ 0x2374,
+/* 62e - _F3_0F_11 */ 0x2375,
+/* 62f - _F2_0F_11 */ 0x2376,
+/* 630 - _V_0F_11 */ 0x400f,
+/* 631 - _V_66_0F_11 */ 0x4010,
+/* 632 - _V_F3_0F_11 */ 0x4011,
+/* 633 - _V_F2_0F_11 */ 0x4012,
+/* 634 - */ 0,
+/* 635 - */ 0,
+/* 636 - _VRR_F3_0F_11 */ 0x4013,
+/* 637 - _VRR_F2_0F_11 */ 0x4014,
+/* 638 - _0F_12 */ 0x4015,
+/* 639 - _66_0F_12 */ 0x2377,
+/* 63a - _F3_0F_12 */ 0x2378,
+/* 63b - _F2_0F_12 */ 0x2379,
+/* 63c - _V_0F_12 */ 0x4016,
+/* 63d - _V_66_0F_12 */ 0x4017,
+/* 63e - _V_F3_0F_12 */ 0x4018,
+/* 63f - _V_F2_0F_12 */ 0x4019,
+/* 640 - */ 0,
+/* 641 - */ 0,
+/* 642 - */ 0,
+/* 643 - */ 0,
+/* 644 - _0F_13 */ 0x237a,
+/* 645 - _66_0F_13 */ 0x237b,
+/* 646 - */ 0,
+/* 647 - */ 0,
+/* 648 - _V_0F_13 */ 0x401a,
+/* 649 - _V_66_0F_13 */ 0x401b,
+/* 64a - */ 0,
+/* 64b - */ 0,
+/* 64c - */ 0,
+/* 64d - */ 0,
+/* 64e - */ 0,
+/* 64f - */ 0,
+/* 650 - _0F_14 */ 0x237c,
+/* 651 - _66_0F_14 */ 0x237d,
+/* 652 - */ 0,
+/* 653 - */ 0,
+/* 654 - _V_0F_14 */ 0x401c,
+/* 655 - _V_66_0F_14 */ 0x401d,
+/* 656 - */ 0,
+/* 657 - */ 0,
+/* 658 - */ 0,
+/* 659 - */ 0,
+/* 65a - */ 0,
+/* 65b - */ 0,
+/* 65c - _0F_15 */ 0x237e,
+/* 65d - _66_0F_15 */ 0x237f,
+/* 65e - */ 0,
+/* 65f - */ 0,
+/* 660 - _V_0F_15 */ 0x401e,
+/* 661 - _V_66_0F_15 */ 0x401f,
+/* 662 - */ 0,
+/* 663 - */ 0,
+/* 664 - */ 0,
+/* 665 - */ 0,
+/* 666 - */ 0,
+/* 667 - */ 0,
+/* 668 - _0F_16 */ 0x4020,
+/* 669 - _66_0F_16 */ 0x2380,
+/* 66a - _F3_0F_16 */ 0x2381,
+/* 66b - */ 0,
+/* 66c - _V_0F_16 */ 0x4021,
+/* 66d - _V_66_0F_16 */ 0x4022,
+/* 66e - _V_F3_0F_16 */ 0x4023,
+/* 66f - */ 0,
+/* 670 - */ 0,
+/* 671 - */ 0,
+/* 672 - */ 0,
+/* 673 - */ 0,
+/* 674 - _0F_17 */ 0x2382,
+/* 675 - _66_0F_17 */ 0x2383,
+/* 676 - */ 0,
+/* 677 - */ 0,
+/* 678 - _V_0F_17 */ 0x4024,
+/* 679 - _V_66_0F_17 */ 0x4025,
+/* 67a - */ 0,
+/* 67b - */ 0,
+/* 67c - */ 0,
+/* 67d - */ 0,
+/* 67e - */ 0,
+/* 67f - */ 0,
+/* 680 - _0F_18_00 */ 0x2384,
+/* 681 - _0F_18_01 */ 0x2385,
+/* 682 - _0F_18_02 */ 0x2386,
+/* 683 - _0F_18_03 */ 0x2387,
+/* 684 - */ 0,
+/* 685 - */ 0,
+/* 686 - */ 0,
+/* 687 - */ 0,
+/* 688 - _0F_28 */ 0x2388,
+/* 689 - _66_0F_28 */ 0x2389,
+/* 68a - */ 0,
+/* 68b - */ 0,
+/* 68c - _V_0F_28 */ 0x4026,
+/* 68d - _V_66_0F_28 */ 0x4027,
+/* 68e - */ 0,
+/* 68f - */ 0,
+/* 690 - */ 0,
+/* 691 - */ 0,
+/* 692 - */ 0,
+/* 693 - */ 0,
+/* 694 - _0F_29 */ 0x238a,
+/* 695 - _66_0F_29 */ 0x238b,
+/* 696 - */ 0,
+/* 697 - */ 0,
+/* 698 - _V_0F_29 */ 0x4028,
+/* 699 - _V_66_0F_29 */ 0x4029,
+/* 69a - */ 0,
+/* 69b - */ 0,
+/* 69c - */ 0,
+/* 69d - */ 0,
+/* 69e - */ 0,
+/* 69f - */ 0,
+/* 6a0 - _0F_2A */ 0x238c,
+/* 6a1 - _66_0F_2A */ 0x238d,
+/* 6a2 - _F3_0F_2A */ 0x238e,
+/* 6a3 - _F2_0F_2A */ 0x238f,
+/* 6a4 - */ 0,
+/* 6a5 - */ 0,
+/* 6a6 - _V_F3_0F_2A */ 0x402a,
+/* 6a7 - _V_F2_0F_2A */ 0x402b,
+/* 6a8 - */ 0,
+/* 6a9 - */ 0,
+/* 6aa - */ 0,
+/* 6ab - */ 0,
+/* 6ac - _0F_2B */ 0x2390,
+/* 6ad - _66_0F_2B */ 0x2391,
+/* 6ae - _F3_0F_2B */ 0x2392,
+/* 6af - _F2_0F_2B */ 0x2393,
+/* 6b0 - _V_0F_2B */ 0x402c,
+/* 6b1 - _V_66_0F_2B */ 0x402d,
+/* 6b2 - */ 0,
+/* 6b3 - */ 0,
+/* 6b4 - */ 0,
+/* 6b5 - */ 0,
+/* 6b6 - */ 0,
+/* 6b7 - */ 0,
+/* 6b8 - _0F_2C */ 0x2394,
+/* 6b9 - _66_0F_2C */ 0x2395,
+/* 6ba - _F3_0F_2C */ 0x2396,
+/* 6bb - _F2_0F_2C */ 0x2397,
+/* 6bc - */ 0,
+/* 6bd - */ 0,
+/* 6be - _V_F3_0F_2C */ 0x402e,
+/* 6bf - _V_F2_0F_2C */ 0x402f,
+/* 6c0 - */ 0,
+/* 6c1 - */ 0,
+/* 6c2 - */ 0,
+/* 6c3 - */ 0,
+/* 6c4 - _0F_2D */ 0x2398,
+/* 6c5 - _66_0F_2D */ 0x2399,
+/* 6c6 - _F3_0F_2D */ 0x239a,
+/* 6c7 - _F2_0F_2D */ 0x239b,
+/* 6c8 - */ 0,
+/* 6c9 - */ 0,
+/* 6ca - _V_F3_0F_2D */ 0x4030,
+/* 6cb - _V_F2_0F_2D */ 0x4031,
+/* 6cc - */ 0,
+/* 6cd - */ 0,
+/* 6ce - */ 0,
+/* 6cf - */ 0,
+/* 6d0 - _0F_2E */ 0x239c,
+/* 6d1 - _66_0F_2E */ 0x239d,
+/* 6d2 - */ 0,
+/* 6d3 - */ 0,
+/* 6d4 - _V_0F_2E */ 0x4032,
+/* 6d5 - _V_66_0F_2E */ 0x4033,
+/* 6d6 - */ 0,
+/* 6d7 - */ 0,
+/* 6d8 - */ 0,
+/* 6d9 - */ 0,
+/* 6da - */ 0,
+/* 6db - */ 0,
+/* 6dc - _0F_2F */ 0x239e,
+/* 6dd - _66_0F_2F */ 0x239f,
+/* 6de - */ 0,
+/* 6df - */ 0,
+/* 6e0 - _V_0F_2F */ 0x4034,
+/* 6e1 - _V_66_0F_2F */ 0x4035,
+/* 6e2 - */ 0,
+/* 6e3 - */ 0,
+/* 6e4 - */ 0,
+/* 6e5 - */ 0,
+/* 6e6 - */ 0,
+/* 6e7 - */ 0,
+/* 6e8 - _0F_38_00 */ 0xcef8,
+/* 6e9 - _0F_38_01 */ 0xcf04,
+/* 6ea - _0F_38_02 */ 0xcf10,
+/* 6eb - _0F_38_03 */ 0xcf1c,
+/* 6ec - _0F_38_04 */ 0xcf28,
+/* 6ed - _0F_38_05 */ 0xcf34,
+/* 6ee - _0F_38_06 */ 0xcf40,
+/* 6ef - _0F_38_07 */ 0xcf4c,
+/* 6f0 - _0F_38_08 */ 0xcf58,
+/* 6f1 - _0F_38_09 */ 0xcf64,
+/* 6f2 - _0F_38_0A */ 0xcf70,
+/* 6f3 - _0F_38_0B */ 0xcf7c,
+/* 6f4 - _0F_38_0C */ 0xcf88,
+/* 6f5 - _0F_38_0D */ 0xcf94,
+/* 6f6 - _0F_38_0E */ 0xcfa0,
+/* 6f7 - _0F_38_0F */ 0xcfac,
+/* 6f8 - _0F_38_10 */ 0xcfb8,
+/* 6f9 - */ 0,
+/* 6fa - */ 0,
+/* 6fb - */ 0,
+/* 6fc - _0F_38_14 */ 0xcfc4,
+/* 6fd - _0F_38_15 */ 0xcfd0,
+/* 6fe - */ 0,
+/* 6ff - _0F_38_17 */ 0xcfdc,
+/* 700 - _0F_38_18 */ 0xcfe8,
+/* 701 - _0F_38_19 */ 0xcff4,
+/* 702 - _0F_38_1A */ 0xd000,
+/* 703 - */ 0,
+/* 704 - _0F_38_1C */ 0xd00c,
+/* 705 - _0F_38_1D */ 0xd018,
+/* 706 - _0F_38_1E */ 0xd024,
+/* 707 - */ 0,
+/* 708 - _0F_38_20 */ 0xd030,
+/* 709 - _0F_38_21 */ 0xd03c,
+/* 70a - _0F_38_22 */ 0xd048,
+/* 70b - _0F_38_23 */ 0xd054,
+/* 70c - _0F_38_24 */ 0xd060,
+/* 70d - _0F_38_25 */ 0xd06c,
+/* 70e - */ 0,
+/* 70f - */ 0,
+/* 710 - _0F_38_28 */ 0xd078,
+/* 711 - _0F_38_29 */ 0xd084,
+/* 712 - _0F_38_2A */ 0xd090,
+/* 713 - _0F_38_2B */ 0xd09c,
+/* 714 - _0F_38_2C */ 0xd0a8,
+/* 715 - _0F_38_2D */ 0xd0b4,
+/* 716 - _0F_38_2E */ 0xd0c0,
+/* 717 - _0F_38_2F */ 0xd0cc,
+/* 718 - _0F_38_30 */ 0xd0d8,
+/* 719 - _0F_38_31 */ 0xd0e4,
+/* 71a - _0F_38_32 */ 0xd0f0,
+/* 71b - _0F_38_33 */ 0xd0fc,
+/* 71c - _0F_38_34 */ 0xd108,
+/* 71d - _0F_38_35 */ 0xd114,
+/* 71e - */ 0,
+/* 71f - _0F_38_37 */ 0xd120,
+/* 720 - _0F_38_38 */ 0xd12c,
+/* 721 - _0F_38_39 */ 0xd138,
+/* 722 - _0F_38_3A */ 0xd144,
+/* 723 - _0F_38_3B */ 0xd150,
+/* 724 - _0F_38_3C */ 0xd15c,
+/* 725 - _0F_38_3D */ 0xd168,
+/* 726 - _0F_38_3E */ 0xd174,
+/* 727 - _0F_38_3F */ 0xd180,
+/* 728 - _0F_38_40 */ 0xd18c,
+/* 729 - _0F_38_41 */ 0xd198,
+/* 72a - */ 0,
+/* 72b - */ 0,
+/* 72c - */ 0,
+/* 72d - */ 0,
+/* 72e - */ 0,
+/* 72f - */ 0,
+/* 730 - */ 0,
+/* 731 - */ 0,
+/* 732 - */ 0,
+/* 733 - */ 0,
+/* 734 - */ 0,
+/* 735 - */ 0,
+/* 736 - */ 0,
+/* 737 - */ 0,
+/* 738 - */ 0,
+/* 739 - */ 0,
+/* 73a - */ 0,
+/* 73b - */ 0,
+/* 73c - */ 0,
+/* 73d - */ 0,
+/* 73e - */ 0,
+/* 73f - */ 0,
+/* 740 - */ 0,
+/* 741 - */ 0,
+/* 742 - */ 0,
+/* 743 - */ 0,
+/* 744 - */ 0,
+/* 745 - */ 0,
+/* 746 - */ 0,
+/* 747 - */ 0,
+/* 748 - */ 0,
+/* 749 - */ 0,
+/* 74a - */ 0,
+/* 74b - */ 0,
+/* 74c - */ 0,
+/* 74d - */ 0,
+/* 74e - */ 0,
+/* 74f - */ 0,
+/* 750 - */ 0,
+/* 751 - */ 0,
+/* 752 - */ 0,
+/* 753 - */ 0,
+/* 754 - */ 0,
+/* 755 - */ 0,
+/* 756 - */ 0,
+/* 757 - */ 0,
+/* 758 - */ 0,
+/* 759 - */ 0,
+/* 75a - */ 0,
+/* 75b - */ 0,
+/* 75c - */ 0,
+/* 75d - */ 0,
+/* 75e - */ 0,
+/* 75f - */ 0,
+/* 760 - */ 0,
+/* 761 - */ 0,
+/* 762 - */ 0,
+/* 763 - */ 0,
+/* 764 - */ 0,
+/* 765 - */ 0,
+/* 766 - */ 0,
+/* 767 - */ 0,
+/* 768 - _0F_38_80 */ 0xd1a4,
+/* 769 - _0F_38_81 */ 0xd1b0,
+/* 76a - _0F_38_82 */ 0xd1bc,
+/* 76b - */ 0,
+/* 76c - */ 0,
+/* 76d - */ 0,
+/* 76e - */ 0,
+/* 76f - */ 0,
+/* 770 - */ 0,
+/* 771 - */ 0,
+/* 772 - */ 0,
+/* 773 - */ 0,
+/* 774 - */ 0,
+/* 775 - */ 0,
+/* 776 - */ 0,
+/* 777 - */ 0,
+/* 778 - */ 0,
+/* 779 - */ 0,
+/* 77a - */ 0,
+/* 77b - */ 0,
+/* 77c - */ 0,
+/* 77d - */ 0,
+/* 77e - _0F_38_96 */ 0xd1c8,
+/* 77f - _0F_38_97 */ 0xd1d4,
+/* 780 - _0F_38_98 */ 0xd1e0,
+/* 781 - _0F_38_99 */ 0xd1ec,
+/* 782 - _0F_38_9A */ 0xd1f8,
+/* 783 - _0F_38_9B */ 0xd204,
+/* 784 - _0F_38_9C */ 0xd210,
+/* 785 - _0F_38_9D */ 0xd21c,
+/* 786 - _0F_38_9E */ 0xd228,
+/* 787 - _0F_38_9F */ 0xd234,
+/* 788 - */ 0,
+/* 789 - */ 0,
+/* 78a - */ 0,
+/* 78b - */ 0,
+/* 78c - */ 0,
+/* 78d - */ 0,
+/* 78e - _0F_38_A6 */ 0xd240,
+/* 78f - _0F_38_A7 */ 0xd24c,
+/* 790 - _0F_38_A8 */ 0xd258,
+/* 791 - _0F_38_A9 */ 0xd264,
+/* 792 - _0F_38_AA */ 0xd270,
+/* 793 - _0F_38_AB */ 0xd27c,
+/* 794 - _0F_38_AC */ 0xd288,
+/* 795 - _0F_38_AD */ 0xd294,
+/* 796 - _0F_38_AE */ 0xd2a0,
+/* 797 - _0F_38_AF */ 0xd2ac,
+/* 798 - */ 0,
+/* 799 - */ 0,
+/* 79a - */ 0,
+/* 79b - */ 0,
+/* 79c - */ 0,
+/* 79d - */ 0,
+/* 79e - _0F_38_B6 */ 0xd2b8,
+/* 79f - _0F_38_B7 */ 0xd2c4,
+/* 7a0 - _0F_38_B8 */ 0xd2d0,
+/* 7a1 - _0F_38_B9 */ 0xd2dc,
+/* 7a2 - _0F_38_BA */ 0xd2e8,
+/* 7a3 - _0F_38_BB */ 0xd2f4,
+/* 7a4 - _0F_38_BC */ 0xd300,
+/* 7a5 - _0F_38_BD */ 0xd30c,
+/* 7a6 - _0F_38_BE */ 0xd318,
+/* 7a7 - _0F_38_BF */ 0xd324,
+/* 7a8 - */ 0,
+/* 7a9 - */ 0,
+/* 7aa - */ 0,
+/* 7ab - */ 0,
+/* 7ac - */ 0,
+/* 7ad - */ 0,
+/* 7ae - */ 0,
+/* 7af - */ 0,
+/* 7b0 - */ 0,
+/* 7b1 - */ 0,
+/* 7b2 - */ 0,
+/* 7b3 - */ 0,
+/* 7b4 - */ 0,
+/* 7b5 - */ 0,
+/* 7b6 - */ 0,
+/* 7b7 - */ 0,
+/* 7b8 - */ 0,
+/* 7b9 - */ 0,
+/* 7ba - */ 0,
+/* 7bb - */ 0,
+/* 7bc - */ 0,
+/* 7bd - */ 0,
+/* 7be - */ 0,
+/* 7bf - */ 0,
+/* 7c0 - */ 0,
+/* 7c1 - */ 0,
+/* 7c2 - */ 0,
+/* 7c3 - _0F_38_DB */ 0xd330,
+/* 7c4 - _0F_38_DC */ 0xd33c,
+/* 7c5 - _0F_38_DD */ 0xd348,
+/* 7c6 - _0F_38_DE */ 0xd354,
+/* 7c7 - _0F_38_DF */ 0xd360,
+/* 7c8 - */ 0,
+/* 7c9 - */ 0,
+/* 7ca - */ 0,
+/* 7cb - */ 0,
+/* 7cc - */ 0,
+/* 7cd - */ 0,
+/* 7ce - */ 0,
+/* 7cf - */ 0,
+/* 7d0 - */ 0,
+/* 7d1 - */ 0,
+/* 7d2 - */ 0,
+/* 7d3 - */ 0,
+/* 7d4 - */ 0,
+/* 7d5 - */ 0,
+/* 7d6 - */ 0,
+/* 7d7 - */ 0,
+/* 7d8 - _0F_38_F0 */ 0xd36c,
+/* 7d9 - _0F_38_F1 */ 0xd378,
+/* 7da - */ 0,
+/* 7db - */ 0,
+/* 7dc - */ 0,
+/* 7dd - */ 0,
+/* 7de - */ 0,
+/* 7df - */ 0,
+/* 7e0 - */ 0,
+/* 7e1 - */ 0,
+/* 7e2 - */ 0,
+/* 7e3 - */ 0,
+/* 7e4 - */ 0,
+/* 7e5 - */ 0,
+/* 7e6 - */ 0,
+/* 7e7 - */ 0,
+/* 7e8 - */ 0,
+/* 7e9 - */ 0,
+/* 7ea - */ 0,
+/* 7eb - */ 0,
+/* 7ec - _0F_3A_04 */ 0xd384,
+/* 7ed - _0F_3A_05 */ 0xd390,
+/* 7ee - _0F_3A_06 */ 0xd39c,
+/* 7ef - */ 0,
+/* 7f0 - _0F_3A_08 */ 0xd3a8,
+/* 7f1 - _0F_3A_09 */ 0xd3b4,
+/* 7f2 - _0F_3A_0A */ 0xd3c0,
+/* 7f3 - _0F_3A_0B */ 0xd3cc,
+/* 7f4 - _0F_3A_0C */ 0xd3d8,
+/* 7f5 - _0F_3A_0D */ 0xd3e4,
+/* 7f6 - _0F_3A_0E */ 0xd3f0,
+/* 7f7 - _0F_3A_0F */ 0xd3fc,
+/* 7f8 - */ 0,
+/* 7f9 - */ 0,
+/* 7fa - */ 0,
+/* 7fb - */ 0,
+/* 7fc - _0F_3A_14 */ 0xd408,
+/* 7fd - _0F_3A_15 */ 0xd414,
+/* 7fe - _0F_3A_16 */ 0xd420,
+/* 7ff - _0F_3A_17 */ 0xd42c,
+/* 800 - _0F_3A_18 */ 0xd438,
+/* 801 - _0F_3A_19 */ 0xd444,
+/* 802 - */ 0,
+/* 803 - */ 0,
+/* 804 - */ 0,
+/* 805 - */ 0,
+/* 806 - */ 0,
+/* 807 - */ 0,
+/* 808 - _0F_3A_20 */ 0xd450,
+/* 809 - _0F_3A_21 */ 0xd45c,
+/* 80a - _0F_3A_22 */ 0xd468,
+/* 80b - */ 0,
+/* 80c - */ 0,
+/* 80d - */ 0,
+/* 80e - */ 0,
+/* 80f - */ 0,
+/* 810 - */ 0,
+/* 811 - */ 0,
+/* 812 - */ 0,
+/* 813 - */ 0,
+/* 814 - */ 0,
+/* 815 - */ 0,
+/* 816 - */ 0,
+/* 817 - */ 0,
+/* 818 - */ 0,
+/* 819 - */ 0,
+/* 81a - */ 0,
+/* 81b - */ 0,
+/* 81c - */ 0,
+/* 81d - */ 0,
+/* 81e - */ 0,
+/* 81f - */ 0,
+/* 820 - */ 0,
+/* 821 - */ 0,
+/* 822 - */ 0,
+/* 823 - */ 0,
+/* 824 - */ 0,
+/* 825 - */ 0,
+/* 826 - */ 0,
+/* 827 - */ 0,
+/* 828 - _0F_3A_40 */ 0xd474,
+/* 829 - _0F_3A_41 */ 0xd480,
+/* 82a - _0F_3A_42 */ 0xd48c,
+/* 82b - */ 0,
+/* 82c - _0F_3A_44 */ 0xd498,
+/* 82d - */ 0,
+/* 82e - */ 0,
+/* 82f - */ 0,
+/* 830 - */ 0,
+/* 831 - */ 0,
+/* 832 - _0F_3A_4A */ 0xd4a4,
+/* 833 - _0F_3A_4B */ 0xd4b0,
+/* 834 - _0F_3A_4C */ 0xd4bc,
+/* 835 - */ 0,
+/* 836 - */ 0,
+/* 837 - */ 0,
+/* 838 - */ 0,
+/* 839 - */ 0,
+/* 83a - */ 0,
+/* 83b - */ 0,
+/* 83c - */ 0,
+/* 83d - */ 0,
+/* 83e - */ 0,
+/* 83f - */ 0,
+/* 840 - */ 0,
+/* 841 - */ 0,
+/* 842 - */ 0,
+/* 843 - */ 0,
+/* 844 - */ 0,
+/* 845 - */ 0,
+/* 846 - */ 0,
+/* 847 - */ 0,
+/* 848 - _0F_3A_60 */ 0xd4c8,
+/* 849 - _0F_3A_61 */ 0xd4d4,
+/* 84a - _0F_3A_62 */ 0xd4e0,
+/* 84b - _0F_3A_63 */ 0xd4ec,
+/* 84c - */ 0,
+/* 84d - */ 0,
+/* 84e - */ 0,
+/* 84f - */ 0,
+/* 850 - */ 0,
+/* 851 - */ 0,
+/* 852 - */ 0,
+/* 853 - */ 0,
+/* 854 - */ 0,
+/* 855 - */ 0,
+/* 856 - */ 0,
+/* 857 - */ 0,
+/* 858 - */ 0,
+/* 859 - */ 0,
+/* 85a - */ 0,
+/* 85b - */ 0,
+/* 85c - */ 0,
+/* 85d - */ 0,
+/* 85e - */ 0,
+/* 85f - */ 0,
+/* 860 - */ 0,
+/* 861 - */ 0,
+/* 862 - */ 0,
+/* 863 - */ 0,
+/* 864 - */ 0,
+/* 865 - */ 0,
+/* 866 - */ 0,
+/* 867 - */ 0,
+/* 868 - */ 0,
+/* 869 - */ 0,
+/* 86a - */ 0,
+/* 86b - */ 0,
+/* 86c - */ 0,
+/* 86d - */ 0,
+/* 86e - */ 0,
+/* 86f - */ 0,
+/* 870 - */ 0,
+/* 871 - */ 0,
+/* 872 - */ 0,
+/* 873 - */ 0,
+/* 874 - */ 0,
+/* 875 - */ 0,
+/* 876 - */ 0,
+/* 877 - */ 0,
+/* 878 - */ 0,
+/* 879 - */ 0,
+/* 87a - */ 0,
+/* 87b - */ 0,
+/* 87c - */ 0,
+/* 87d - */ 0,
+/* 87e - */ 0,
+/* 87f - */ 0,
+/* 880 - */ 0,
+/* 881 - */ 0,
+/* 882 - */ 0,
+/* 883 - */ 0,
+/* 884 - */ 0,
+/* 885 - */ 0,
+/* 886 - */ 0,
+/* 887 - */ 0,
+/* 888 - */ 0,
+/* 889 - */ 0,
+/* 88a - */ 0,
+/* 88b - */ 0,
+/* 88c - */ 0,
+/* 88d - */ 0,
+/* 88e - */ 0,
+/* 88f - */ 0,
+/* 890 - */ 0,
+/* 891 - */ 0,
+/* 892 - */ 0,
+/* 893 - */ 0,
+/* 894 - */ 0,
+/* 895 - */ 0,
+/* 896 - */ 0,
+/* 897 - */ 0,
+/* 898 - */ 0,
+/* 899 - */ 0,
+/* 89a - */ 0,
+/* 89b - */ 0,
+/* 89c - */ 0,
+/* 89d - */ 0,
+/* 89e - */ 0,
+/* 89f - */ 0,
+/* 8a0 - */ 0,
+/* 8a1 - */ 0,
+/* 8a2 - */ 0,
+/* 8a3 - */ 0,
+/* 8a4 - */ 0,
+/* 8a5 - */ 0,
+/* 8a6 - */ 0,
+/* 8a7 - */ 0,
+/* 8a8 - */ 0,
+/* 8a9 - */ 0,
+/* 8aa - */ 0,
+/* 8ab - */ 0,
+/* 8ac - */ 0,
+/* 8ad - */ 0,
+/* 8ae - */ 0,
+/* 8af - */ 0,
+/* 8b0 - */ 0,
+/* 8b1 - */ 0,
+/* 8b2 - */ 0,
+/* 8b3 - */ 0,
+/* 8b4 - */ 0,
+/* 8b5 - */ 0,
+/* 8b6 - */ 0,
+/* 8b7 - */ 0,
+/* 8b8 - */ 0,
+/* 8b9 - */ 0,
+/* 8ba - */ 0,
+/* 8bb - */ 0,
+/* 8bc - */ 0,
+/* 8bd - */ 0,
+/* 8be - */ 0,
+/* 8bf - */ 0,
+/* 8c0 - */ 0,
+/* 8c1 - */ 0,
+/* 8c2 - */ 0,
+/* 8c3 - */ 0,
+/* 8c4 - */ 0,
+/* 8c5 - */ 0,
+/* 8c6 - */ 0,
+/* 8c7 - _0F_3A_DF */ 0xd4f8,
+/* 8c8 - */ 0,
+/* 8c9 - */ 0,
+/* 8ca - */ 0,
+/* 8cb - */ 0,
+/* 8cc - */ 0,
+/* 8cd - */ 0,
+/* 8ce - */ 0,
+/* 8cf - */ 0,
+/* 8d0 - */ 0,
+/* 8d1 - */ 0,
+/* 8d2 - */ 0,
+/* 8d3 - */ 0,
+/* 8d4 - */ 0,
+/* 8d5 - */ 0,
+/* 8d6 - */ 0,
+/* 8d7 - */ 0,
+/* 8d8 - */ 0,
+/* 8d9 - */ 0,
+/* 8da - */ 0,
+/* 8db - */ 0,
+/* 8dc - */ 0,
+/* 8dd - */ 0,
+/* 8de - */ 0,
+/* 8df - */ 0,
+/* 8e0 - */ 0,
+/* 8e1 - */ 0,
+/* 8e2 - */ 0,
+/* 8e3 - */ 0,
+/* 8e4 - */ 0,
+/* 8e5 - */ 0,
+/* 8e6 - */ 0,
+/* 8e7 - */ 0,
+/* 8e8 - _0F_50 */ 0x23a0,
+/* 8e9 - _66_0F_50 */ 0x23a1,
+/* 8ea - */ 0,
+/* 8eb - */ 0,
+/* 8ec - _V_0F_50 */ 0x4036,
+/* 8ed - _V_66_0F_50 */ 0x4037,
+/* 8ee - */ 0,
+/* 8ef - */ 0,
+/* 8f0 - */ 0,
+/* 8f1 - */ 0,
+/* 8f2 - */ 0,
+/* 8f3 - */ 0,
+/* 8f4 - _0F_51 */ 0x23a2,
+/* 8f5 - _66_0F_51 */ 0x23a3,
+/* 8f6 - _F3_0F_51 */ 0x23a4,
+/* 8f7 - _F2_0F_51 */ 0x23a5,
+/* 8f8 - _V_0F_51 */ 0x4038,
+/* 8f9 - _V_66_0F_51 */ 0x4039,
+/* 8fa - _V_F3_0F_51 */ 0x403a,
+/* 8fb - _V_F2_0F_51 */ 0x403b,
+/* 8fc - */ 0,
+/* 8fd - */ 0,
+/* 8fe - */ 0,
+/* 8ff - */ 0,
+/* 900 - _0F_52 */ 0x23a6,
+/* 901 - */ 0,
+/* 902 - _F3_0F_52 */ 0x23a7,
+/* 903 - */ 0,
+/* 904 - _V_0F_52 */ 0x403c,
+/* 905 - */ 0,
+/* 906 - _V_F3_0F_52 */ 0x403d,
+/* 907 - */ 0,
+/* 908 - */ 0,
+/* 909 - */ 0,
+/* 90a - */ 0,
+/* 90b - */ 0,
+/* 90c - _0F_53 */ 0x23a8,
+/* 90d - */ 0,
+/* 90e - _F3_0F_53 */ 0x23a9,
+/* 90f - */ 0,
+/* 910 - _V_0F_53 */ 0x403e,
+/* 911 - */ 0,
+/* 912 - _V_F3_0F_53 */ 0x403f,
+/* 913 - */ 0,
+/* 914 - */ 0,
+/* 915 - */ 0,
+/* 916 - */ 0,
+/* 917 - */ 0,
+/* 918 - _0F_54 */ 0x23aa,
+/* 919 - _66_0F_54 */ 0x23ab,
+/* 91a - */ 0,
+/* 91b - */ 0,
+/* 91c - _V_0F_54 */ 0x4040,
+/* 91d - _V_66_0F_54 */ 0x4041,
+/* 91e - */ 0,
+/* 91f - */ 0,
+/* 920 - */ 0,
+/* 921 - */ 0,
+/* 922 - */ 0,
+/* 923 - */ 0,
+/* 924 - _0F_55 */ 0x23ac,
+/* 925 - _66_0F_55 */ 0x23ad,
+/* 926 - */ 0,
+/* 927 - */ 0,
+/* 928 - _V_0F_55 */ 0x4042,
+/* 929 - _V_66_0F_55 */ 0x4043,
+/* 92a - */ 0,
+/* 92b - */ 0,
+/* 92c - */ 0,
+/* 92d - */ 0,
+/* 92e - */ 0,
+/* 92f - */ 0,
+/* 930 - _0F_56 */ 0x23ae,
+/* 931 - _66_0F_56 */ 0x23af,
+/* 932 - */ 0,
+/* 933 - */ 0,
+/* 934 - _V_0F_56 */ 0x4044,
+/* 935 - _V_66_0F_56 */ 0x4045,
+/* 936 - */ 0,
+/* 937 - */ 0,
+/* 938 - */ 0,
+/* 939 - */ 0,
+/* 93a - */ 0,
+/* 93b - */ 0,
+/* 93c - _0F_57 */ 0x23b0,
+/* 93d - _66_0F_57 */ 0x23b1,
+/* 93e - */ 0,
+/* 93f - */ 0,
+/* 940 - _V_0F_57 */ 0x4046,
+/* 941 - _V_66_0F_57 */ 0x4047,
+/* 942 - */ 0,
+/* 943 - */ 0,
+/* 944 - */ 0,
+/* 945 - */ 0,
+/* 946 - */ 0,
+/* 947 - */ 0,
+/* 948 - _0F_58 */ 0x23b2,
+/* 949 - _66_0F_58 */ 0x23b3,
+/* 94a - _F3_0F_58 */ 0x23b4,
+/* 94b - _F2_0F_58 */ 0x23b5,
+/* 94c - _V_0F_58 */ 0x4048,
+/* 94d - _V_66_0F_58 */ 0x4049,
+/* 94e - _V_F3_0F_58 */ 0x404a,
+/* 94f - _V_F2_0F_58 */ 0x404b,
+/* 950 - */ 0,
+/* 951 - */ 0,
+/* 952 - */ 0,
+/* 953 - */ 0,
+/* 954 - _0F_59 */ 0x23b6,
+/* 955 - _66_0F_59 */ 0x23b7,
+/* 956 - _F3_0F_59 */ 0x23b8,
+/* 957 - _F2_0F_59 */ 0x23b9,
+/* 958 - _V_0F_59 */ 0x404c,
+/* 959 - _V_66_0F_59 */ 0x404d,
+/* 95a - _V_F3_0F_59 */ 0x404e,
+/* 95b - _V_F2_0F_59 */ 0x404f,
+/* 95c - */ 0,
+/* 95d - */ 0,
+/* 95e - */ 0,
+/* 95f - */ 0,
+/* 960 - _0F_5A */ 0x23ba,
+/* 961 - _66_0F_5A */ 0x23bb,
+/* 962 - _F3_0F_5A */ 0x23bc,
+/* 963 - _F2_0F_5A */ 0x23bd,
+/* 964 - _V_0F_5A */ 0x4050,
+/* 965 - _V_66_0F_5A */ 0x4051,
+/* 966 - _V_F3_0F_5A */ 0x4052,
+/* 967 - _V_F2_0F_5A */ 0x4053,
+/* 968 - */ 0,
+/* 969 - */ 0,
+/* 96a - */ 0,
+/* 96b - */ 0,
+/* 96c - _0F_5B */ 0x23be,
+/* 96d - _66_0F_5B */ 0x23bf,
+/* 96e - _F3_0F_5B */ 0x23c0,
+/* 96f - */ 0,
+/* 970 - _V_0F_5B */ 0x4054,
+/* 971 - _V_66_0F_5B */ 0x4055,
+/* 972 - _V_F3_0F_5B */ 0x4056,
+/* 973 - */ 0,
+/* 974 - */ 0,
+/* 975 - */ 0,
+/* 976 - */ 0,
+/* 977 - */ 0,
+/* 978 - _0F_5C */ 0x23c1,
+/* 979 - _66_0F_5C */ 0x23c2,
+/* 97a - _F3_0F_5C */ 0x23c3,
+/* 97b - _F2_0F_5C */ 0x23c4,
+/* 97c - _V_0F_5C */ 0x4057,
+/* 97d - _V_66_0F_5C */ 0x4058,
+/* 97e - _V_F3_0F_5C */ 0x4059,
+/* 97f - _V_F2_0F_5C */ 0x405a,
+/* 980 - */ 0,
+/* 981 - */ 0,
+/* 982 - */ 0,
+/* 983 - */ 0,
+/* 984 - _0F_5D */ 0x23c5,
+/* 985 - _66_0F_5D */ 0x23c6,
+/* 986 - _F3_0F_5D */ 0x23c7,
+/* 987 - _F2_0F_5D */ 0x23c8,
+/* 988 - _V_0F_5D */ 0x405b,
+/* 989 - _V_66_0F_5D */ 0x405c,
+/* 98a - _V_F3_0F_5D */ 0x405d,
+/* 98b - _V_F2_0F_5D */ 0x405e,
+/* 98c - */ 0,
+/* 98d - */ 0,
+/* 98e - */ 0,
+/* 98f - */ 0,
+/* 990 - _0F_5E */ 0x23c9,
+/* 991 - _66_0F_5E */ 0x23ca,
+/* 992 - _F3_0F_5E */ 0x23cb,
+/* 993 - _F2_0F_5E */ 0x23cc,
+/* 994 - _V_0F_5E */ 0x405f,
+/* 995 - _V_66_0F_5E */ 0x4060,
+/* 996 - _V_F3_0F_5E */ 0x4061,
+/* 997 - _V_F2_0F_5E */ 0x4062,
+/* 998 - */ 0,
+/* 999 - */ 0,
+/* 99a - */ 0,
+/* 99b - */ 0,
+/* 99c - _0F_5F */ 0x23cd,
+/* 99d - _66_0F_5F */ 0x23ce,
+/* 99e - _F3_0F_5F */ 0x23cf,
+/* 99f - _F2_0F_5F */ 0x23d0,
+/* 9a0 - _V_0F_5F */ 0x4063,
+/* 9a1 - _V_66_0F_5F */ 0x4064,
+/* 9a2 - _V_F3_0F_5F */ 0x4065,
+/* 9a3 - _V_F2_0F_5F */ 0x4066,
+/* 9a4 - */ 0,
+/* 9a5 - */ 0,
+/* 9a6 - */ 0,
+/* 9a7 - */ 0,
+/* 9a8 - _0F_60 */ 0x23d1,
+/* 9a9 - _66_0F_60 */ 0x23d2,
+/* 9aa - */ 0,
+/* 9ab - */ 0,
+/* 9ac - */ 0,
+/* 9ad - _V_66_0F_60 */ 0x4067,
+/* 9ae - */ 0,
+/* 9af - */ 0,
+/* 9b0 - */ 0,
+/* 9b1 - */ 0,
+/* 9b2 - */ 0,
+/* 9b3 - */ 0,
+/* 9b4 - _0F_61 */ 0x23d3,
+/* 9b5 - _66_0F_61 */ 0x23d4,
+/* 9b6 - */ 0,
+/* 9b7 - */ 0,
+/* 9b8 - */ 0,
+/* 9b9 - _V_66_0F_61 */ 0x4068,
+/* 9ba - */ 0,
+/* 9bb - */ 0,
+/* 9bc - */ 0,
+/* 9bd - */ 0,
+/* 9be - */ 0,
+/* 9bf - */ 0,
+/* 9c0 - _0F_62 */ 0x23d5,
+/* 9c1 - _66_0F_62 */ 0x23d6,
+/* 9c2 - */ 0,
+/* 9c3 - */ 0,
+/* 9c4 - */ 0,
+/* 9c5 - _V_66_0F_62 */ 0x4069,
+/* 9c6 - */ 0,
+/* 9c7 - */ 0,
+/* 9c8 - */ 0,
+/* 9c9 - */ 0,
+/* 9ca - */ 0,
+/* 9cb - */ 0,
+/* 9cc - _0F_63 */ 0x23d7,
+/* 9cd - _66_0F_63 */ 0x23d8,
+/* 9ce - */ 0,
+/* 9cf - */ 0,
+/* 9d0 - */ 0,
+/* 9d1 - _V_66_0F_63 */ 0x406a,
+/* 9d2 - */ 0,
+/* 9d3 - */ 0,
+/* 9d4 - */ 0,
+/* 9d5 - */ 0,
+/* 9d6 - */ 0,
+/* 9d7 - */ 0,
+/* 9d8 - _0F_64 */ 0x23d9,
+/* 9d9 - _66_0F_64 */ 0x23da,
+/* 9da - */ 0,
+/* 9db - */ 0,
+/* 9dc - */ 0,
+/* 9dd - _V_66_0F_64 */ 0x406b,
+/* 9de - */ 0,
+/* 9df - */ 0,
+/* 9e0 - */ 0,
+/* 9e1 - */ 0,
+/* 9e2 - */ 0,
+/* 9e3 - */ 0,
+/* 9e4 - _0F_65 */ 0x23db,
+/* 9e5 - _66_0F_65 */ 0x23dc,
+/* 9e6 - */ 0,
+/* 9e7 - */ 0,
+/* 9e8 - */ 0,
+/* 9e9 - _V_66_0F_65 */ 0x406c,
+/* 9ea - */ 0,
+/* 9eb - */ 0,
+/* 9ec - */ 0,
+/* 9ed - */ 0,
+/* 9ee - */ 0,
+/* 9ef - */ 0,
+/* 9f0 - _0F_66 */ 0x23dd,
+/* 9f1 - _66_0F_66 */ 0x23de,
+/* 9f2 - */ 0,
+/* 9f3 - */ 0,
+/* 9f4 - */ 0,
+/* 9f5 - _V_66_0F_66 */ 0x406d,
+/* 9f6 - */ 0,
+/* 9f7 - */ 0,
+/* 9f8 - */ 0,
+/* 9f9 - */ 0,
+/* 9fa - */ 0,
+/* 9fb - */ 0,
+/* 9fc - _0F_67 */ 0x23df,
+/* 9fd - _66_0F_67 */ 0x23e0,
+/* 9fe - */ 0,
+/* 9ff - */ 0,
+/* a00 - */ 0,
+/* a01 - _V_66_0F_67 */ 0x406e,
+/* a02 - */ 0,
+/* a03 - */ 0,
+/* a04 - */ 0,
+/* a05 - */ 0,
+/* a06 - */ 0,
+/* a07 - */ 0,
+/* a08 - _0F_68 */ 0x23e1,
+/* a09 - _66_0F_68 */ 0x23e2,
+/* a0a - */ 0,
+/* a0b - */ 0,
+/* a0c - */ 0,
+/* a0d - _V_66_0F_68 */ 0x406f,
+/* a0e - */ 0,
+/* a0f - */ 0,
+/* a10 - */ 0,
+/* a11 - */ 0,
+/* a12 - */ 0,
+/* a13 - */ 0,
+/* a14 - _0F_69 */ 0x23e3,
+/* a15 - _66_0F_69 */ 0x23e4,
+/* a16 - */ 0,
+/* a17 - */ 0,
+/* a18 - */ 0,
+/* a19 - _V_66_0F_69 */ 0x4070,
+/* a1a - */ 0,
+/* a1b - */ 0,
+/* a1c - */ 0,
+/* a1d - */ 0,
+/* a1e - */ 0,
+/* a1f - */ 0,
+/* a20 - _0F_6A */ 0x23e5,
+/* a21 - _66_0F_6A */ 0x23e6,
+/* a22 - */ 0,
+/* a23 - */ 0,
+/* a24 - */ 0,
+/* a25 - _V_66_0F_6A */ 0x4071,
+/* a26 - */ 0,
+/* a27 - */ 0,
+/* a28 - */ 0,
+/* a29 - */ 0,
+/* a2a - */ 0,
+/* a2b - */ 0,
+/* a2c - _0F_6B */ 0x23e7,
+/* a2d - _66_0F_6B */ 0x23e8,
+/* a2e - */ 0,
+/* a2f - */ 0,
+/* a30 - */ 0,
+/* a31 - _V_66_0F_6B */ 0x4072,
+/* a32 - */ 0,
+/* a33 - */ 0,
+/* a34 - */ 0,
+/* a35 - */ 0,
+/* a36 - */ 0,
+/* a37 - */ 0,
+/* a38 - */ 0,
+/* a39 - _66_0F_6C */ 0x23e9,
+/* a3a - */ 0,
+/* a3b - */ 0,
+/* a3c - */ 0,
+/* a3d - _V_66_0F_6C */ 0x4073,
+/* a3e - */ 0,
+/* a3f - */ 0,
+/* a40 - */ 0,
+/* a41 - */ 0,
+/* a42 - */ 0,
+/* a43 - */ 0,
+/* a44 - */ 0,
+/* a45 - _66_0F_6D */ 0x23ea,
+/* a46 - */ 0,
+/* a47 - */ 0,
+/* a48 - */ 0,
+/* a49 - _V_66_0F_6D */ 0x4074,
+/* a4a - */ 0,
+/* a4b - */ 0,
+/* a4c - */ 0,
+/* a4d - */ 0,
+/* a4e - */ 0,
+/* a4f - */ 0,
+/* a50 - _0F_6E */ 0x4075,
+/* a51 - _66_0F_6E */ 0x4076,
+/* a52 - */ 0,
+/* a53 - */ 0,
+/* a54 - */ 0,
+/* a55 - _V_66_0F_6E */ 0x4077,
+/* a56 - */ 0,
+/* a57 - */ 0,
+/* a58 - */ 0,
+/* a59 - */ 0,
+/* a5a - */ 0,
+/* a5b - */ 0,
+/* a5c - _0F_6F */ 0x23eb,
+/* a5d - _66_0F_6F */ 0x23ec,
+/* a5e - _F3_0F_6F */ 0x23ed,
+/* a5f - */ 0,
+/* a60 - */ 0,
+/* a61 - _V_66_0F_6F */ 0x4078,
+/* a62 - _V_F3_0F_6F */ 0x4079,
+/* a63 - */ 0,
+/* a64 - */ 0,
+/* a65 - */ 0,
+/* a66 - */ 0,
+/* a67 - */ 0,
+/* a68 - _0F_70 */ 0x407a,
+/* a69 - _66_0F_70 */ 0x407b,
+/* a6a - _F3_0F_70 */ 0x407c,
+/* a6b - _F2_0F_70 */ 0x407d,
+/* a6c - */ 0,
+/* a6d - _V_66_0F_70 */ 0x407e,
+/* a6e - _V_F3_0F_70 */ 0x407f,
+/* a6f - _V_F2_0F_70 */ 0x4080,
+/* a70 - */ 0,
+/* a71 - */ 0,
+/* a72 - */ 0,
+/* a73 - */ 0,
+/* a74 - */ 0,
+/* a75 - */ 0,
+/* a76 - _0F_71_02 */ 0xd504,
+/* a77 - */ 0,
+/* a78 - _0F_71_04 */ 0xd510,
+/* a79 - */ 0,
+/* a7a - _0F_71_06 */ 0xd51c,
+/* a7b - */ 0,
+/* a7c - */ 0,
+/* a7d - */ 0,
+/* a7e - _0F_72_02 */ 0xd528,
+/* a7f - */ 0,
+/* a80 - _0F_72_04 */ 0xd534,
+/* a81 - */ 0,
+/* a82 - _0F_72_06 */ 0xd540,
+/* a83 - */ 0,
+/* a84 - */ 0,
+/* a85 - */ 0,
+/* a86 - _0F_73_02 */ 0xd54c,
+/* a87 - _0F_73_03 */ 0xd558,
+/* a88 - */ 0,
+/* a89 - */ 0,
+/* a8a - _0F_73_06 */ 0xd564,
+/* a8b - _0F_73_07 */ 0xd570,
+/* a8c - _0F_74 */ 0x23ee,
+/* a8d - _66_0F_74 */ 0x23ef,
+/* a8e - */ 0,
+/* a8f - */ 0,
+/* a90 - */ 0,
+/* a91 - _V_66_0F_74 */ 0x4081,
+/* a92 - */ 0,
+/* a93 - */ 0,
+/* a94 - */ 0,
+/* a95 - */ 0,
+/* a96 - */ 0,
+/* a97 - */ 0,
+/* a98 - _0F_75 */ 0x23f0,
+/* a99 - _66_0F_75 */ 0x23f1,
+/* a9a - */ 0,
+/* a9b - */ 0,
+/* a9c - */ 0,
+/* a9d - _V_66_0F_75 */ 0x4082,
+/* a9e - */ 0,
+/* a9f - */ 0,
+/* aa0 - */ 0,
+/* aa1 - */ 0,
+/* aa2 - */ 0,
+/* aa3 - */ 0,
+/* aa4 - _0F_76 */ 0x23f2,
+/* aa5 - _66_0F_76 */ 0x23f3,
+/* aa6 - */ 0,
+/* aa7 - */ 0,
+/* aa8 - */ 0,
+/* aa9 - _V_66_0F_76 */ 0x4083,
+/* aaa - */ 0,
+/* aab - */ 0,
+/* aac - */ 0,
+/* aad - */ 0,
+/* aae - */ 0,
+/* aaf - */ 0,
+/* ab0 - _0F_77 */ 0x23f4,
+/* ab1 - */ 0,
+/* ab2 - */ 0,
+/* ab3 - */ 0,
+/* ab4 - _V_0F_77 */ 0x4084,
+/* ab5 - */ 0,
+/* ab6 - */ 0,
+/* ab7 - */ 0,
+/* ab8 - */ 0,
+/* ab9 - */ 0,
+/* aba - */ 0,
+/* abb - */ 0,
+/* abc - _0F_78 */ 0x23f5,
+/* abd - _66_0F_78 */ 0x4085,
+/* abe - */ 0,
+/* abf - _F2_0F_78 */ 0x4086,
+/* ac0 - */ 0,
+/* ac1 - */ 0,
+/* ac2 - */ 0,
+/* ac3 - */ 0,
+/* ac4 - */ 0,
+/* ac5 - */ 0,
+/* ac6 - */ 0,
+/* ac7 - */ 0,
+/* ac8 - _0F_79 */ 0x23f6,
+/* ac9 - _66_0F_79 */ 0x23f7,
+/* aca - */ 0,
+/* acb - _F2_0F_79 */ 0x23f8,
+/* acc - */ 0,
+/* acd - */ 0,
+/* ace - */ 0,
+/* acf - */ 0,
+/* ad0 - */ 0,
+/* ad1 - */ 0,
+/* ad2 - */ 0,
+/* ad3 - */ 0,
+/* ad4 - */ 0,
+/* ad5 - */ 0,
+/* ad6 - */ 0,
+/* ad7 - */ 0,
+/* ad8 - */ 0,
+/* ad9 - */ 0,
+/* ada - */ 0,
+/* adb - */ 0,
+/* adc - */ 0,
+/* add - */ 0,
+/* ade - */ 0,
+/* adf - */ 0,
+/* ae0 - */ 0,
+/* ae1 - */ 0,
+/* ae2 - */ 0,
+/* ae3 - */ 0,
+/* ae4 - */ 0,
+/* ae5 - */ 0,
+/* ae6 - */ 0,
+/* ae7 - */ 0,
+/* ae8 - */ 0,
+/* ae9 - */ 0,
+/* aea - */ 0,
+/* aeb - */ 0,
+/* aec - */ 0,
+/* aed - */ 0,
+/* aee - */ 0,
+/* aef - */ 0,
+/* af0 - */ 0,
+/* af1 - */ 0,
+/* af2 - */ 0,
+/* af3 - */ 0,
+/* af4 - */ 0,
+/* af5 - */ 0,
+/* af6 - */ 0,
+/* af7 - */ 0,
+/* af8 - */ 0,
+/* af9 - */ 0,
+/* afa - */ 0,
+/* afb - */ 0,
+/* afc - */ 0,
+/* afd - */ 0,
+/* afe - */ 0,
+/* aff - */ 0,
+/* b00 - */ 0,
+/* b01 - */ 0,
+/* b02 - */ 0,
+/* b03 - */ 0,
+/* b04 - _0F_7A_30 */ 0x23f9,
+/* b05 - _0F_7A_31 */ 0x23fa,
+/* b06 - */ 0,
+/* b07 - */ 0,
+/* b08 - */ 0,
+/* b09 - */ 0,
+/* b0a - */ 0,
+/* b0b - */ 0,
+/* b0c - */ 0,
+/* b0d - */ 0,
+/* b0e - */ 0,
+/* b0f - */ 0,
+/* b10 - */ 0,
+/* b11 - */ 0,
+/* b12 - */ 0,
+/* b13 - */ 0,
+/* b14 - */ 0,
+/* b15 - */ 0,
+/* b16 - */ 0,
+/* b17 - */ 0,
+/* b18 - */ 0,
+/* b19 - */ 0,
+/* b1a - */ 0,
+/* b1b - */ 0,
+/* b1c - */ 0,
+/* b1d - */ 0,
+/* b1e - */ 0,
+/* b1f - */ 0,
+/* b20 - */ 0,
+/* b21 - */ 0,
+/* b22 - */ 0,
+/* b23 - */ 0,
+/* b24 - */ 0,
+/* b25 - */ 0,
+/* b26 - */ 0,
+/* b27 - */ 0,
+/* b28 - */ 0,
+/* b29 - */ 0,
+/* b2a - */ 0,
+/* b2b - */ 0,
+/* b2c - */ 0,
+/* b2d - */ 0,
+/* b2e - */ 0,
+/* b2f - */ 0,
+/* b30 - */ 0,
+/* b31 - */ 0,
+/* b32 - */ 0,
+/* b33 - */ 0,
+/* b34 - */ 0,
+/* b35 - */ 0,
+/* b36 - */ 0,
+/* b37 - */ 0,
+/* b38 - */ 0,
+/* b39 - */ 0,
+/* b3a - */ 0,
+/* b3b - */ 0,
+/* b3c - */ 0,
+/* b3d - */ 0,
+/* b3e - */ 0,
+/* b3f - */ 0,
+/* b40 - */ 0,
+/* b41 - */ 0,
+/* b42 - */ 0,
+/* b43 - */ 0,
+/* b44 - */ 0,
+/* b45 - */ 0,
+/* b46 - */ 0,
+/* b47 - */ 0,
+/* b48 - */ 0,
+/* b49 - */ 0,
+/* b4a - */ 0,
+/* b4b - */ 0,
+/* b4c - */ 0,
+/* b4d - */ 0,
+/* b4e - */ 0,
+/* b4f - */ 0,
+/* b50 - */ 0,
+/* b51 - */ 0,
+/* b52 - */ 0,
+/* b53 - */ 0,
+/* b54 - */ 0,
+/* b55 - */ 0,
+/* b56 - */ 0,
+/* b57 - */ 0,
+/* b58 - */ 0,
+/* b59 - */ 0,
+/* b5a - */ 0,
+/* b5b - */ 0,
+/* b5c - */ 0,
+/* b5d - */ 0,
+/* b5e - */ 0,
+/* b5f - */ 0,
+/* b60 - */ 0,
+/* b61 - */ 0,
+/* b62 - */ 0,
+/* b63 - */ 0,
+/* b64 - */ 0,
+/* b65 - */ 0,
+/* b66 - */ 0,
+/* b67 - */ 0,
+/* b68 - */ 0,
+/* b69 - */ 0,
+/* b6a - */ 0,
+/* b6b - */ 0,
+/* b6c - */ 0,
+/* b6d - */ 0,
+/* b6e - */ 0,
+/* b6f - */ 0,
+/* b70 - */ 0,
+/* b71 - */ 0,
+/* b72 - */ 0,
+/* b73 - */ 0,
+/* b74 - */ 0,
+/* b75 - */ 0,
+/* b76 - */ 0,
+/* b77 - */ 0,
+/* b78 - */ 0,
+/* b79 - */ 0,
+/* b7a - */ 0,
+/* b7b - */ 0,
+/* b7c - */ 0,
+/* b7d - */ 0,
+/* b7e - */ 0,
+/* b7f - */ 0,
+/* b80 - */ 0,
+/* b81 - */ 0,
+/* b82 - */ 0,
+/* b83 - */ 0,
+/* b84 - */ 0,
+/* b85 - */ 0,
+/* b86 - */ 0,
+/* b87 - */ 0,
+/* b88 - */ 0,
+/* b89 - */ 0,
+/* b8a - */ 0,
+/* b8b - */ 0,
+/* b8c - */ 0,
+/* b8d - */ 0,
+/* b8e - */ 0,
+/* b8f - */ 0,
+/* b90 - */ 0,
+/* b91 - */ 0,
+/* b92 - */ 0,
+/* b93 - */ 0,
+/* b94 - */ 0,
+/* b95 - */ 0,
+/* b96 - */ 0,
+/* b97 - */ 0,
+/* b98 - */ 0,
+/* b99 - */ 0,
+/* b9a - */ 0,
+/* b9b - */ 0,
+/* b9c - */ 0,
+/* b9d - */ 0,
+/* b9e - */ 0,
+/* b9f - */ 0,
+/* ba0 - */ 0,
+/* ba1 - */ 0,
+/* ba2 - */ 0,
+/* ba3 - */ 0,
+/* ba4 - */ 0,
+/* ba5 - */ 0,
+/* ba6 - */ 0,
+/* ba7 - */ 0,
+/* ba8 - */ 0,
+/* ba9 - */ 0,
+/* baa - */ 0,
+/* bab - */ 0,
+/* bac - */ 0,
+/* bad - */ 0,
+/* bae - */ 0,
+/* baf - */ 0,
+/* bb0 - */ 0,
+/* bb1 - */ 0,
+/* bb2 - */ 0,
+/* bb3 - */ 0,
+/* bb4 - */ 0,
+/* bb5 - */ 0,
+/* bb6 - */ 0,
+/* bb7 - */ 0,
+/* bb8 - */ 0,
+/* bb9 - */ 0,
+/* bba - */ 0,
+/* bbb - */ 0,
+/* bbc - */ 0,
+/* bbd - */ 0,
+/* bbe - */ 0,
+/* bbf - */ 0,
+/* bc0 - */ 0,
+/* bc1 - */ 0,
+/* bc2 - */ 0,
+/* bc3 - */ 0,
+/* bc4 - */ 0,
+/* bc5 - */ 0,
+/* bc6 - */ 0,
+/* bc7 - */ 0,
+/* bc8 - */ 0,
+/* bc9 - */ 0,
+/* bca - */ 0,
+/* bcb - */ 0,
+/* bcc - */ 0,
+/* bcd - */ 0,
+/* bce - */ 0,
+/* bcf - */ 0,
+/* bd0 - */ 0,
+/* bd1 - */ 0,
+/* bd2 - */ 0,
+/* bd3 - */ 0,
+/* bd4 - */ 0,
+/* bd5 - _66_0F_7C */ 0x23fb,
+/* bd6 - */ 0,
+/* bd7 - _F2_0F_7C */ 0x23fc,
+/* bd8 - */ 0,
+/* bd9 - _V_66_0F_7C */ 0x4087,
+/* bda - */ 0,
+/* bdb - _V_F2_0F_7C */ 0x4088,
+/* bdc - */ 0,
+/* bdd - */ 0,
+/* bde - */ 0,
+/* bdf - */ 0,
+/* be0 - */ 0,
+/* be1 - _66_0F_7D */ 0x23fd,
+/* be2 - */ 0,
+/* be3 - _F2_0F_7D */ 0x23fe,
+/* be4 - */ 0,
+/* be5 - _V_66_0F_7D */ 0x4089,
+/* be6 - */ 0,
+/* be7 - _V_F2_0F_7D */ 0x408a,
+/* be8 - */ 0,
+/* be9 - */ 0,
+/* bea - */ 0,
+/* beb - */ 0,
+/* bec - _0F_7E */ 0x408b,
+/* bed - _66_0F_7E */ 0x408c,
+/* bee - _F3_0F_7E */ 0x23ff,
+/* bef - */ 0,
+/* bf0 - */ 0,
+/* bf1 - _V_66_0F_7E */ 0x408d,
+/* bf2 - _V_F3_0F_7E */ 0x408e,
+/* bf3 - */ 0,
+/* bf4 - */ 0,
+/* bf5 - */ 0,
+/* bf6 - */ 0,
+/* bf7 - */ 0,
+/* bf8 - _0F_7F */ 0x2400,
+/* bf9 - _66_0F_7F */ 0x2401,
+/* bfa - _F3_0F_7F */ 0x2402,
+/* bfb - */ 0,
+/* bfc - */ 0,
+/* bfd - _V_66_0F_7F */ 0x408f,
+/* bfe - _V_F3_0F_7F */ 0x4090,
+/* bff - */ 0,
+/* c00 - */ 0,
+/* c01 - */ 0,
+/* c02 - */ 0,
+/* c03 - */ 0,
+/* c04 - _0F_AE_00 */ 0xd57c,
+/* c05 - _0F_AE_01 */ 0xd588,
+/* c06 - _0F_AE_02 */ 0xd594,
+/* c07 - _0F_AE_03 */ 0xd5a0,
+/* c08 - _0F_AE_04 */ 0x4091,
+/* c09 - _0F_AE_05 */ 0x4092,
+/* c0a - _0F_AE_06 */ 0x4093,
+/* c0b - _0F_AE_07 */ 0x4094,
+/* c0c - */ 0,
+/* c0d - */ 0,
+/* c0e - _F3_0F_B8 */ 0x2403,
+/* c0f - */ 0,
+/* c10 - */ 0,
+/* c11 - */ 0,
+/* c12 - */ 0,
+/* c13 - */ 0,
+/* c14 - */ 0,
+/* c15 - */ 0,
+/* c16 - */ 0,
+/* c17 - */ 0,
+/* c18 - */ 0,
+/* c19 - */ 0,
+/* c1a - */ 0,
+/* c1b - */ 0,
+/* c1c - _0F_BA_04 */ 0x2404,
+/* c1d - _0F_BA_05 */ 0x2405,
+/* c1e - _0F_BA_06 */ 0x2406,
+/* c1f - _0F_BA_07 */ 0x2407,
+/* c20 - _0F_BC */ 0x2408,
+/* c21 - */ 0,
+/* c22 - _F3_0F_BC */ 0x2409,
+/* c23 - */ 0,
+/* c24 - */ 0,
+/* c25 - */ 0,
+/* c26 - */ 0,
+/* c27 - */ 0,
+/* c28 - */ 0,
+/* c29 - */ 0,
+/* c2a - */ 0,
+/* c2b - */ 0,
+/* c2c - _0F_BD */ 0x240a,
+/* c2d - */ 0,
+/* c2e - _F3_0F_BD */ 0x240b,
+/* c2f - */ 0,
+/* c30 - */ 0,
+/* c31 - */ 0,
+/* c32 - */ 0,
+/* c33 - */ 0,
+/* c34 - */ 0,
+/* c35 - */ 0,
+/* c36 - */ 0,
+/* c37 - */ 0,
+/* c38 - _0F_C2 */ 0x4095,
+/* c39 - _66_0F_C2 */ 0x4096,
+/* c3a - _F3_0F_C2 */ 0x4097,
+/* c3b - _F2_0F_C2 */ 0x4098,
+/* c3c - _V_0F_C2 */ 0x4099,
+/* c3d - _V_66_0F_C2 */ 0x409a,
+/* c3e - _V_F3_0F_C2 */ 0x409b,
+/* c3f - _V_F2_0F_C2 */ 0x409c,
+/* c40 - */ 0,
+/* c41 - */ 0,
+/* c42 - */ 0,
+/* c43 - */ 0,
+/* c44 - _0F_C4 */ 0x409d,
+/* c45 - _66_0F_C4 */ 0x409e,
+/* c46 - */ 0,
+/* c47 - */ 0,
+/* c48 - */ 0,
+/* c49 - _V_66_0F_C4 */ 0x409f,
+/* c4a - */ 0,
+/* c4b - */ 0,
+/* c4c - */ 0,
+/* c4d - */ 0,
+/* c4e - */ 0,
+/* c4f - */ 0,
+/* c50 - _0F_C5 */ 0x40a0,
+/* c51 - _66_0F_C5 */ 0x40a1,
+/* c52 - */ 0,
+/* c53 - */ 0,
+/* c54 - */ 0,
+/* c55 - _V_66_0F_C5 */ 0x40a2,
+/* c56 - */ 0,
+/* c57 - */ 0,
+/* c58 - */ 0,
+/* c59 - */ 0,
+/* c5a - */ 0,
+/* c5b - */ 0,
+/* c5c - _0F_C6 */ 0x40a3,
+/* c5d - _66_0F_C6 */ 0x40a4,
+/* c5e - */ 0,
+/* c5f - */ 0,
+/* c60 - _V_0F_C6 */ 0x40a5,
+/* c61 - _V_66_0F_C6 */ 0x40a6,
+/* c62 - */ 0,
+/* c63 - */ 0,
+/* c64 - */ 0,
+/* c65 - */ 0,
+/* c66 - */ 0,
+/* c67 - */ 0,
+/* c68 - */ 0,
+/* c69 - _0F_C7_01 */ 0x40a7,
+/* c6a - */ 0,
+/* c6b - */ 0,
+/* c6c - */ 0,
+/* c6d - */ 0,
+/* c6e - _0F_C7_06 */ 0xd5ac,
+/* c6f - _0F_C7_07 */ 0x240c,
+/* c70 - */ 0,
+/* c71 - _66_0F_D0 */ 0x240d,
+/* c72 - */ 0,
+/* c73 - _F2_0F_D0 */ 0x240e,
+/* c74 - */ 0,
+/* c75 - _V_66_0F_D0 */ 0x40a8,
+/* c76 - */ 0,
+/* c77 - _V_F2_0F_D0 */ 0x40a9,
+/* c78 - */ 0,
+/* c79 - */ 0,
+/* c7a - */ 0,
+/* c7b - */ 0,
+/* c7c - _0F_D1 */ 0x240f,
+/* c7d - _66_0F_D1 */ 0x2410,
+/* c7e - */ 0,
+/* c7f - */ 0,
+/* c80 - */ 0,
+/* c81 - _V_66_0F_D1 */ 0x40aa,
+/* c82 - */ 0,
+/* c83 - */ 0,
+/* c84 - */ 0,
+/* c85 - */ 0,
+/* c86 - */ 0,
+/* c87 - */ 0,
+/* c88 - _0F_D2 */ 0x2411,
+/* c89 - _66_0F_D2 */ 0x2412,
+/* c8a - */ 0,
+/* c8b - */ 0,
+/* c8c - */ 0,
+/* c8d - _V_66_0F_D2 */ 0x40ab,
+/* c8e - */ 0,
+/* c8f - */ 0,
+/* c90 - */ 0,
+/* c91 - */ 0,
+/* c92 - */ 0,
+/* c93 - */ 0,
+/* c94 - _0F_D3 */ 0x2413,
+/* c95 - _66_0F_D3 */ 0x2414,
+/* c96 - */ 0,
+/* c97 - */ 0,
+/* c98 - */ 0,
+/* c99 - _V_66_0F_D3 */ 0x40ac,
+/* c9a - */ 0,
+/* c9b - */ 0,
+/* c9c - */ 0,
+/* c9d - */ 0,
+/* c9e - */ 0,
+/* c9f - */ 0,
+/* ca0 - _0F_D4 */ 0x2415,
+/* ca1 - _66_0F_D4 */ 0x2416,
+/* ca2 - */ 0,
+/* ca3 - */ 0,
+/* ca4 - */ 0,
+/* ca5 - _V_66_0F_D4 */ 0x40ad,
+/* ca6 - */ 0,
+/* ca7 - */ 0,
+/* ca8 - */ 0,
+/* ca9 - */ 0,
+/* caa - */ 0,
+/* cab - */ 0,
+/* cac - _0F_D5 */ 0x2417,
+/* cad - _66_0F_D5 */ 0x2418,
+/* cae - */ 0,
+/* caf - */ 0,
+/* cb0 - */ 0,
+/* cb1 - _V_66_0F_D5 */ 0x40ae,
+/* cb2 - */ 0,
+/* cb3 - */ 0,
+/* cb4 - */ 0,
+/* cb5 - */ 0,
+/* cb6 - */ 0,
+/* cb7 - */ 0,
+/* cb8 - */ 0,
+/* cb9 - _66_0F_D6 */ 0x2419,
+/* cba - _F3_0F_D6 */ 0x241a,
+/* cbb - _F2_0F_D6 */ 0x241b,
+/* cbc - */ 0,
+/* cbd - _V_66_0F_D6 */ 0x40af,
+/* cbe - */ 0,
+/* cbf - */ 0,
+/* cc0 - */ 0,
+/* cc1 - */ 0,
+/* cc2 - */ 0,
+/* cc3 - */ 0,
+/* cc4 - _0F_D7 */ 0x241c,
+/* cc5 - _66_0F_D7 */ 0x241d,
+/* cc6 - */ 0,
+/* cc7 - */ 0,
+/* cc8 - */ 0,
+/* cc9 - _V_66_0F_D7 */ 0x40b0,
+/* cca - */ 0,
+/* ccb - */ 0,
+/* ccc - */ 0,
+/* ccd - */ 0,
+/* cce - */ 0,
+/* ccf - */ 0,
+/* cd0 - _0F_D8 */ 0x241e,
+/* cd1 - _66_0F_D8 */ 0x241f,
+/* cd2 - */ 0,
+/* cd3 - */ 0,
+/* cd4 - */ 0,
+/* cd5 - _V_66_0F_D8 */ 0x40b1,
+/* cd6 - */ 0,
+/* cd7 - */ 0,
+/* cd8 - */ 0,
+/* cd9 - */ 0,
+/* cda - */ 0,
+/* cdb - */ 0,
+/* cdc - _0F_D9 */ 0x2420,
+/* cdd - _66_0F_D9 */ 0x2421,
+/* cde - */ 0,
+/* cdf - */ 0,
+/* ce0 - */ 0,
+/* ce1 - _V_66_0F_D9 */ 0x40b2,
+/* ce2 - */ 0,
+/* ce3 - */ 0,
+/* ce4 - */ 0,
+/* ce5 - */ 0,
+/* ce6 - */ 0,
+/* ce7 - */ 0,
+/* ce8 - _0F_DA */ 0x2422,
+/* ce9 - _66_0F_DA */ 0x2423,
+/* cea - */ 0,
+/* ceb - */ 0,
+/* cec - */ 0,
+/* ced - _V_66_0F_DA */ 0x40b3,
+/* cee - */ 0,
+/* cef - */ 0,
+/* cf0 - */ 0,
+/* cf1 - */ 0,
+/* cf2 - */ 0,
+/* cf3 - */ 0,
+/* cf4 - _0F_DB */ 0x2424,
+/* cf5 - _66_0F_DB */ 0x2425,
+/* cf6 - */ 0,
+/* cf7 - */ 0,
+/* cf8 - */ 0,
+/* cf9 - _V_66_0F_DB */ 0x40b4,
+/* cfa - */ 0,
+/* cfb - */ 0,
+/* cfc - */ 0,
+/* cfd - */ 0,
+/* cfe - */ 0,
+/* cff - */ 0,
+/* d00 - _0F_DC */ 0x2426,
+/* d01 - _66_0F_DC */ 0x2427,
+/* d02 - */ 0,
+/* d03 - */ 0,
+/* d04 - */ 0,
+/* d05 - _V_66_0F_DC */ 0x40b5,
+/* d06 - */ 0,
+/* d07 - */ 0,
+/* d08 - */ 0,
+/* d09 - */ 0,
+/* d0a - */ 0,
+/* d0b - */ 0,
+/* d0c - _0F_DD */ 0x2428,
+/* d0d - _66_0F_DD */ 0x2429,
+/* d0e - */ 0,
+/* d0f - */ 0,
+/* d10 - */ 0,
+/* d11 - _V_66_0F_DD */ 0x40b6,
+/* d12 - */ 0,
+/* d13 - */ 0,
+/* d14 - */ 0,
+/* d15 - */ 0,
+/* d16 - */ 0,
+/* d17 - */ 0,
+/* d18 - _0F_DE */ 0x242a,
+/* d19 - _66_0F_DE */ 0x242b,
+/* d1a - */ 0,
+/* d1b - */ 0,
+/* d1c - */ 0,
+/* d1d - _V_66_0F_DE */ 0x40b7,
+/* d1e - */ 0,
+/* d1f - */ 0,
+/* d20 - */ 0,
+/* d21 - */ 0,
+/* d22 - */ 0,
+/* d23 - */ 0,
+/* d24 - _0F_DF */ 0x242c,
+/* d25 - _66_0F_DF */ 0x242d,
+/* d26 - */ 0,
+/* d27 - */ 0,
+/* d28 - */ 0,
+/* d29 - _V_66_0F_DF */ 0x40b8,
+/* d2a - */ 0,
+/* d2b - */ 0,
+/* d2c - */ 0,
+/* d2d - */ 0,
+/* d2e - */ 0,
+/* d2f - */ 0,
+/* d30 - _0F_E0 */ 0x242e,
+/* d31 - _66_0F_E0 */ 0x242f,
+/* d32 - */ 0,
+/* d33 - */ 0,
+/* d34 - */ 0,
+/* d35 - _V_66_0F_E0 */ 0x40b9,
+/* d36 - */ 0,
+/* d37 - */ 0,
+/* d38 - */ 0,
+/* d39 - */ 0,
+/* d3a - */ 0,
+/* d3b - */ 0,
+/* d3c - _0F_E1 */ 0x2430,
+/* d3d - _66_0F_E1 */ 0x2431,
+/* d3e - */ 0,
+/* d3f - */ 0,
+/* d40 - */ 0,
+/* d41 - _V_66_0F_E1 */ 0x40ba,
+/* d42 - */ 0,
+/* d43 - */ 0,
+/* d44 - */ 0,
+/* d45 - */ 0,
+/* d46 - */ 0,
+/* d47 - */ 0,
+/* d48 - _0F_E2 */ 0x2432,
+/* d49 - _66_0F_E2 */ 0x2433,
+/* d4a - */ 0,
+/* d4b - */ 0,
+/* d4c - */ 0,
+/* d4d - _V_66_0F_E2 */ 0x40bb,
+/* d4e - */ 0,
+/* d4f - */ 0,
+/* d50 - */ 0,
+/* d51 - */ 0,
+/* d52 - */ 0,
+/* d53 - */ 0,
+/* d54 - _0F_E3 */ 0x2434,
+/* d55 - _66_0F_E3 */ 0x2435,
+/* d56 - */ 0,
+/* d57 - */ 0,
+/* d58 - */ 0,
+/* d59 - _V_66_0F_E3 */ 0x40bc,
+/* d5a - */ 0,
+/* d5b - */ 0,
+/* d5c - */ 0,
+/* d5d - */ 0,
+/* d5e - */ 0,
+/* d5f - */ 0,
+/* d60 - _0F_E4 */ 0x2436,
+/* d61 - _66_0F_E4 */ 0x2437,
+/* d62 - */ 0,
+/* d63 - */ 0,
+/* d64 - */ 0,
+/* d65 - _V_66_0F_E4 */ 0x40bd,
+/* d66 - */ 0,
+/* d67 - */ 0,
+/* d68 - */ 0,
+/* d69 - */ 0,
+/* d6a - */ 0,
+/* d6b - */ 0,
+/* d6c - _0F_E5 */ 0x2438,
+/* d6d - _66_0F_E5 */ 0x2439,
+/* d6e - */ 0,
+/* d6f - */ 0,
+/* d70 - */ 0,
+/* d71 - _V_66_0F_E5 */ 0x40be,
+/* d72 - */ 0,
+/* d73 - */ 0,
+/* d74 - */ 0,
+/* d75 - */ 0,
+/* d76 - */ 0,
+/* d77 - */ 0,
+/* d78 - */ 0,
+/* d79 - _66_0F_E6 */ 0x243a,
+/* d7a - _F3_0F_E6 */ 0x243b,
+/* d7b - _F2_0F_E6 */ 0x243c,
+/* d7c - */ 0,
+/* d7d - _V_66_0F_E6 */ 0x40bf,
+/* d7e - _V_F3_0F_E6 */ 0x40c0,
+/* d7f - _V_F2_0F_E6 */ 0x40c1,
+/* d80 - */ 0,
+/* d81 - */ 0,
+/* d82 - */ 0,
+/* d83 - */ 0,
+/* d84 - _0F_E7 */ 0x243d,
+/* d85 - _66_0F_E7 */ 0x243e,
+/* d86 - */ 0,
+/* d87 - */ 0,
+/* d88 - */ 0,
+/* d89 - _V_66_0F_E7 */ 0x40c2,
+/* d8a - */ 0,
+/* d8b - */ 0,
+/* d8c - */ 0,
+/* d8d - */ 0,
+/* d8e - */ 0,
+/* d8f - */ 0,
+/* d90 - _0F_E8 */ 0x243f,
+/* d91 - _66_0F_E8 */ 0x2440,
+/* d92 - */ 0,
+/* d93 - */ 0,
+/* d94 - */ 0,
+/* d95 - _V_66_0F_E8 */ 0x40c3,
+/* d96 - */ 0,
+/* d97 - */ 0,
+/* d98 - */ 0,
+/* d99 - */ 0,
+/* d9a - */ 0,
+/* d9b - */ 0,
+/* d9c - _0F_E9 */ 0x2441,
+/* d9d - _66_0F_E9 */ 0x2442,
+/* d9e - */ 0,
+/* d9f - */ 0,
+/* da0 - */ 0,
+/* da1 - _V_66_0F_E9 */ 0x40c4,
+/* da2 - */ 0,
+/* da3 - */ 0,
+/* da4 - */ 0,
+/* da5 - */ 0,
+/* da6 - */ 0,
+/* da7 - */ 0,
+/* da8 - _0F_EA */ 0x2443,
+/* da9 - _66_0F_EA */ 0x2444,
+/* daa - */ 0,
+/* dab - */ 0,
+/* dac - */ 0,
+/* dad - _V_66_0F_EA */ 0x40c5,
+/* dae - */ 0,
+/* daf - */ 0,
+/* db0 - */ 0,
+/* db1 - */ 0,
+/* db2 - */ 0,
+/* db3 - */ 0,
+/* db4 - _0F_EB */ 0x2445,
+/* db5 - _66_0F_EB */ 0x2446,
+/* db6 - */ 0,
+/* db7 - */ 0,
+/* db8 - */ 0,
+/* db9 - _V_66_0F_EB */ 0x40c6,
+/* dba - */ 0,
+/* dbb - */ 0,
+/* dbc - */ 0,
+/* dbd - */ 0,
+/* dbe - */ 0,
+/* dbf - */ 0,
+/* dc0 - _0F_EC */ 0x2447,
+/* dc1 - _66_0F_EC */ 0x2448,
+/* dc2 - */ 0,
+/* dc3 - */ 0,
+/* dc4 - */ 0,
+/* dc5 - _V_66_0F_EC */ 0x40c7,
+/* dc6 - */ 0,
+/* dc7 - */ 0,
+/* dc8 - */ 0,
+/* dc9 - */ 0,
+/* dca - */ 0,
+/* dcb - */ 0,
+/* dcc - _0F_ED */ 0x2449,
+/* dcd - _66_0F_ED */ 0x244a,
+/* dce - */ 0,
+/* dcf - */ 0,
+/* dd0 - */ 0,
+/* dd1 - _V_66_0F_ED */ 0x40c8,
+/* dd2 - */ 0,
+/* dd3 - */ 0,
+/* dd4 - */ 0,
+/* dd5 - */ 0,
+/* dd6 - */ 0,
+/* dd7 - */ 0,
+/* dd8 - _0F_EE */ 0x244b,
+/* dd9 - _66_0F_EE */ 0x244c,
+/* dda - */ 0,
+/* ddb - */ 0,
+/* ddc - */ 0,
+/* ddd - _V_66_0F_EE */ 0x40c9,
+/* dde - */ 0,
+/* ddf - */ 0,
+/* de0 - */ 0,
+/* de1 - */ 0,
+/* de2 - */ 0,
+/* de3 - */ 0,
+/* de4 - _0F_EF */ 0x244d,
+/* de5 - _66_0F_EF */ 0x244e,
+/* de6 - */ 0,
+/* de7 - */ 0,
+/* de8 - */ 0,
+/* de9 - _V_66_0F_EF */ 0x40ca,
+/* dea - */ 0,
+/* deb - */ 0,
+/* dec - */ 0,
+/* ded - */ 0,
+/* dee - */ 0,
+/* def - */ 0,
+/* df0 - */ 0,
+/* df1 - */ 0,
+/* df2 - */ 0,
+/* df3 - _F2_0F_F0 */ 0x244f,
+/* df4 - */ 0,
+/* df5 - */ 0,
+/* df6 - */ 0,
+/* df7 - _V_F2_0F_F0 */ 0x40cb,
+/* df8 - */ 0,
+/* df9 - */ 0,
+/* dfa - */ 0,
+/* dfb - */ 0,
+/* dfc - _0F_F1 */ 0x2450,
+/* dfd - _66_0F_F1 */ 0x2451,
+/* dfe - */ 0,
+/* dff - */ 0,
+/* e00 - */ 0,
+/* e01 - _V_66_0F_F1 */ 0x40cc,
+/* e02 - */ 0,
+/* e03 - */ 0,
+/* e04 - */ 0,
+/* e05 - */ 0,
+/* e06 - */ 0,
+/* e07 - */ 0,
+/* e08 - _0F_F2 */ 0x2452,
+/* e09 - _66_0F_F2 */ 0x2453,
+/* e0a - */ 0,
+/* e0b - */ 0,
+/* e0c - */ 0,
+/* e0d - _V_66_0F_F2 */ 0x40cd,
+/* e0e - */ 0,
+/* e0f - */ 0,
+/* e10 - */ 0,
+/* e11 - */ 0,
+/* e12 - */ 0,
+/* e13 - */ 0,
+/* e14 - _0F_F3 */ 0x2454,
+/* e15 - _66_0F_F3 */ 0x2455,
+/* e16 - */ 0,
+/* e17 - */ 0,
+/* e18 - */ 0,
+/* e19 - _V_66_0F_F3 */ 0x40ce,
+/* e1a - */ 0,
+/* e1b - */ 0,
+/* e1c - */ 0,
+/* e1d - */ 0,
+/* e1e - */ 0,
+/* e1f - */ 0,
+/* e20 - _0F_F4 */ 0x2456,
+/* e21 - _66_0F_F4 */ 0x2457,
+/* e22 - */ 0,
+/* e23 - */ 0,
+/* e24 - */ 0,
+/* e25 - _V_66_0F_F4 */ 0x40cf,
+/* e26 - */ 0,
+/* e27 - */ 0,
+/* e28 - */ 0,
+/* e29 - */ 0,
+/* e2a - */ 0,
+/* e2b - */ 0,
+/* e2c - _0F_F5 */ 0x2458,
+/* e2d - _66_0F_F5 */ 0x2459,
+/* e2e - */ 0,
+/* e2f - */ 0,
+/* e30 - */ 0,
+/* e31 - _V_66_0F_F5 */ 0x40d0,
+/* e32 - */ 0,
+/* e33 - */ 0,
+/* e34 - */ 0,
+/* e35 - */ 0,
+/* e36 - */ 0,
+/* e37 - */ 0,
+/* e38 - _0F_F6 */ 0x245a,
+/* e39 - _66_0F_F6 */ 0x245b,
+/* e3a - */ 0,
+/* e3b - */ 0,
+/* e3c - */ 0,
+/* e3d - _V_66_0F_F6 */ 0x40d1,
+/* e3e - */ 0,
+/* e3f - */ 0,
+/* e40 - */ 0,
+/* e41 - */ 0,
+/* e42 - */ 0,
+/* e43 - */ 0,
+/* e44 - _0F_F7 */ 0x245c,
+/* e45 - _66_0F_F7 */ 0x245d,
+/* e46 - */ 0,
+/* e47 - */ 0,
+/* e48 - */ 0,
+/* e49 - _V_66_0F_F7 */ 0x40d2,
+/* e4a - */ 0,
+/* e4b - */ 0,
+/* e4c - */ 0,
+/* e4d - */ 0,
+/* e4e - */ 0,
+/* e4f - */ 0,
+/* e50 - _0F_F8 */ 0x245e,
+/* e51 - _66_0F_F8 */ 0x245f,
+/* e52 - */ 0,
+/* e53 - */ 0,
+/* e54 - */ 0,
+/* e55 - _V_66_0F_F8 */ 0x40d3,
+/* e56 - */ 0,
+/* e57 - */ 0,
+/* e58 - */ 0,
+/* e59 - */ 0,
+/* e5a - */ 0,
+/* e5b - */ 0,
+/* e5c - _0F_F9 */ 0x2460,
+/* e5d - _66_0F_F9 */ 0x2461,
+/* e5e - */ 0,
+/* e5f - */ 0,
+/* e60 - */ 0,
+/* e61 - _V_66_0F_F9 */ 0x40d4,
+/* e62 - */ 0,
+/* e63 - */ 0,
+/* e64 - */ 0,
+/* e65 - */ 0,
+/* e66 - */ 0,
+/* e67 - */ 0,
+/* e68 - _0F_FA */ 0x2462,
+/* e69 - _66_0F_FA */ 0x2463,
+/* e6a - */ 0,
+/* e6b - */ 0,
+/* e6c - */ 0,
+/* e6d - _V_66_0F_FA */ 0x40d5,
+/* e6e - */ 0,
+/* e6f - */ 0,
+/* e70 - */ 0,
+/* e71 - */ 0,
+/* e72 - */ 0,
+/* e73 - */ 0,
+/* e74 - _0F_FB */ 0x2464,
+/* e75 - _66_0F_FB */ 0x2465,
+/* e76 - */ 0,
+/* e77 - */ 0,
+/* e78 - */ 0,
+/* e79 - _V_66_0F_FB */ 0x40d6,
+/* e7a - */ 0,
+/* e7b - */ 0,
+/* e7c - */ 0,
+/* e7d - */ 0,
+/* e7e - */ 0,
+/* e7f - */ 0,
+/* e80 - _0F_FC */ 0x2466,
+/* e81 - _66_0F_FC */ 0x2467,
+/* e82 - */ 0,
+/* e83 - */ 0,
+/* e84 - */ 0,
+/* e85 - _V_66_0F_FC */ 0x40d7,
+/* e86 - */ 0,
+/* e87 - */ 0,
+/* e88 - */ 0,
+/* e89 - */ 0,
+/* e8a - */ 0,
+/* e8b - */ 0,
+/* e8c - _0F_FD */ 0x2468,
+/* e8d - _66_0F_FD */ 0x2469,
+/* e8e - */ 0,
+/* e8f - */ 0,
+/* e90 - */ 0,
+/* e91 - _V_66_0F_FD */ 0x40d8,
+/* e92 - */ 0,
+/* e93 - */ 0,
+/* e94 - */ 0,
+/* e95 - */ 0,
+/* e96 - */ 0,
+/* e97 - */ 0,
+/* e98 - _0F_FE */ 0x246a,
+/* e99 - _66_0F_FE */ 0x246b,
+/* e9a - */ 0,
+/* e9b - */ 0,
+/* e9c - */ 0,
+/* e9d - _V_66_0F_FE */ 0x40d9,
+/* e9e - */ 0,
+/* e9f - */ 0,
+/* ea0 - */ 0,
+/* ea1 - */ 0,
+/* ea2 - */ 0,
+/* ea3 - */ 0,
+/* ea4 - _D9_06 */ 0x246c,
+/* ea5 - _9B_D9_06 */ 0x246d,
+/* ea6 - */ 0,
+/* ea7 - */ 0,
+/* ea8 - */ 0,
+/* ea9 - */ 0,
+/* eaa - */ 0,
+/* eab - */ 0,
+/* eac - */ 0,
+/* ead - */ 0,
+/* eae - */ 0,
+/* eaf - */ 0,
+/* eb0 - _D9_07 */ 0x246e,
+/* eb1 - _9B_D9_07 */ 0x246f,
+/* eb2 - */ 0,
+/* eb3 - */ 0,
+/* eb4 - */ 0,
+/* eb5 - */ 0,
+/* eb6 - */ 0,
+/* eb7 - */ 0,
+/* eb8 - */ 0,
+/* eb9 - */ 0,
+/* eba - */ 0,
+/* ebb - */ 0,
+/* ebc - _DB_E2 */ 0x2470,
+/* ebd - _9B_DB_E2 */ 0x2471,
+/* ebe - */ 0,
+/* ebf - */ 0,
+/* ec0 - */ 0,
+/* ec1 - */ 0,
+/* ec2 - */ 0,
+/* ec3 - */ 0,
+/* ec4 - */ 0,
+/* ec5 - */ 0,
+/* ec6 - */ 0,
+/* ec7 - */ 0,
+/* ec8 - _DB_E3 */ 0x2472,
+/* ec9 - _9B_DB_E3 */ 0x2473,
+/* eca - */ 0,
+/* ecb - */ 0,
+/* ecc - */ 0,
+/* ecd - */ 0,
+/* ece - */ 0,
+/* ecf - */ 0,
+/* ed0 - */ 0,
+/* ed1 - */ 0,
+/* ed2 - */ 0,
+/* ed3 - */ 0,
+/* ed4 - _DD_06 */ 0x2474,
+/* ed5 - _9B_DD_06 */ 0x2475,
+/* ed6 - */ 0,
+/* ed7 - */ 0,
+/* ed8 - */ 0,
+/* ed9 - */ 0,
+/* eda - */ 0,
+/* edb - */ 0,
+/* edc - */ 0,
+/* edd - */ 0,
+/* ede - */ 0,
+/* edf - */ 0,
+/* ee0 - _DD_07 */ 0x2476,
+/* ee1 - _9B_DD_07 */ 0x2477,
+/* ee2 - */ 0,
+/* ee3 - */ 0,
+/* ee4 - */ 0,
+/* ee5 - */ 0,
+/* ee6 - */ 0,
+/* ee7 - */ 0,
+/* ee8 - */ 0,
+/* ee9 - */ 0,
+/* eea - */ 0,
+/* eeb - */ 0,
+/* eec - _DF_E0 */ 0x2478,
+/* eed - _9B_DF_E0 */ 0x2479,
+/* eee - */ 0,
+/* eef - */ 0,
+/* ef0 - */ 0,
+/* ef1 - */ 0,
+/* ef2 - */ 0,
+/* ef3 - */ 0,
+/* ef4 - */ 0,
+/* ef5 - */ 0,
+/* ef6 - */ 0,
+/* ef7 - */ 0,
+/* ef8 - _0F_38_00 */ 0x247a,
+/* ef9 - _66_0F_38_00 */ 0x247b,
+/* efa - */ 0,
+/* efb - */ 0,
+/* efc - */ 0,
+/* efd - _V_66_0F_38_00 */ 0x40da,
+/* efe - */ 0,
+/* eff - */ 0,
+/* f00 - */ 0,
+/* f01 - */ 0,
+/* f02 - */ 0,
+/* f03 - */ 0,
+/* f04 - _0F_38_01 */ 0x247c,
+/* f05 - _66_0F_38_01 */ 0x247d,
+/* f06 - */ 0,
+/* f07 - */ 0,
+/* f08 - */ 0,
+/* f09 - _V_66_0F_38_01 */ 0x40db,
+/* f0a - */ 0,
+/* f0b - */ 0,
+/* f0c - */ 0,
+/* f0d - */ 0,
+/* f0e - */ 0,
+/* f0f - */ 0,
+/* f10 - _0F_38_02 */ 0x247e,
+/* f11 - _66_0F_38_02 */ 0x247f,
+/* f12 - */ 0,
+/* f13 - */ 0,
+/* f14 - */ 0,
+/* f15 - _V_66_0F_38_02 */ 0x40dc,
+/* f16 - */ 0,
+/* f17 - */ 0,
+/* f18 - */ 0,
+/* f19 - */ 0,
+/* f1a - */ 0,
+/* f1b - */ 0,
+/* f1c - _0F_38_03 */ 0x2480,
+/* f1d - _66_0F_38_03 */ 0x2481,
+/* f1e - */ 0,
+/* f1f - */ 0,
+/* f20 - */ 0,
+/* f21 - _V_66_0F_38_03 */ 0x40dd,
+/* f22 - */ 0,
+/* f23 - */ 0,
+/* f24 - */ 0,
+/* f25 - */ 0,
+/* f26 - */ 0,
+/* f27 - */ 0,
+/* f28 - _0F_38_04 */ 0x2482,
+/* f29 - _66_0F_38_04 */ 0x2483,
+/* f2a - */ 0,
+/* f2b - */ 0,
+/* f2c - */ 0,
+/* f2d - _V_66_0F_38_04 */ 0x40de,
+/* f2e - */ 0,
+/* f2f - */ 0,
+/* f30 - */ 0,
+/* f31 - */ 0,
+/* f32 - */ 0,
+/* f33 - */ 0,
+/* f34 - _0F_38_05 */ 0x2484,
+/* f35 - _66_0F_38_05 */ 0x2485,
+/* f36 - */ 0,
+/* f37 - */ 0,
+/* f38 - */ 0,
+/* f39 - _V_66_0F_38_05 */ 0x40df,
+/* f3a - */ 0,
+/* f3b - */ 0,
+/* f3c - */ 0,
+/* f3d - */ 0,
+/* f3e - */ 0,
+/* f3f - */ 0,
+/* f40 - _0F_38_06 */ 0x2486,
+/* f41 - _66_0F_38_06 */ 0x2487,
+/* f42 - */ 0,
+/* f43 - */ 0,
+/* f44 - */ 0,
+/* f45 - _V_66_0F_38_06 */ 0x40e0,
+/* f46 - */ 0,
+/* f47 - */ 0,
+/* f48 - */ 0,
+/* f49 - */ 0,
+/* f4a - */ 0,
+/* f4b - */ 0,
+/* f4c - _0F_38_07 */ 0x2488,
+/* f4d - _66_0F_38_07 */ 0x2489,
+/* f4e - */ 0,
+/* f4f - */ 0,
+/* f50 - */ 0,
+/* f51 - _V_66_0F_38_07 */ 0x40e1,
+/* f52 - */ 0,
+/* f53 - */ 0,
+/* f54 - */ 0,
+/* f55 - */ 0,
+/* f56 - */ 0,
+/* f57 - */ 0,
+/* f58 - _0F_38_08 */ 0x248a,
+/* f59 - _66_0F_38_08 */ 0x248b,
+/* f5a - */ 0,
+/* f5b - */ 0,
+/* f5c - */ 0,
+/* f5d - _V_66_0F_38_08 */ 0x40e2,
+/* f5e - */ 0,
+/* f5f - */ 0,
+/* f60 - */ 0,
+/* f61 - */ 0,
+/* f62 - */ 0,
+/* f63 - */ 0,
+/* f64 - _0F_38_09 */ 0x248c,
+/* f65 - _66_0F_38_09 */ 0x248d,
+/* f66 - */ 0,
+/* f67 - */ 0,
+/* f68 - */ 0,
+/* f69 - _V_66_0F_38_09 */ 0x40e3,
+/* f6a - */ 0,
+/* f6b - */ 0,
+/* f6c - */ 0,
+/* f6d - */ 0,
+/* f6e - */ 0,
+/* f6f - */ 0,
+/* f70 - _0F_38_0A */ 0x248e,
+/* f71 - _66_0F_38_0A */ 0x248f,
+/* f72 - */ 0,
+/* f73 - */ 0,
+/* f74 - */ 0,
+/* f75 - _V_66_0F_38_0A */ 0x40e4,
+/* f76 - */ 0,
+/* f77 - */ 0,
+/* f78 - */ 0,
+/* f79 - */ 0,
+/* f7a - */ 0,
+/* f7b - */ 0,
+/* f7c - _0F_38_0B */ 0x2490,
+/* f7d - _66_0F_38_0B */ 0x2491,
+/* f7e - */ 0,
+/* f7f - */ 0,
+/* f80 - */ 0,
+/* f81 - _V_66_0F_38_0B */ 0x40e5,
+/* f82 - */ 0,
+/* f83 - */ 0,
+/* f84 - */ 0,
+/* f85 - */ 0,
+/* f86 - */ 0,
+/* f87 - */ 0,
+/* f88 - */ 0,
+/* f89 - */ 0,
+/* f8a - */ 0,
+/* f8b - */ 0,
+/* f8c - */ 0,
+/* f8d - _V_66_0F_38_0C */ 0x40e6,
+/* f8e - */ 0,
+/* f8f - */ 0,
+/* f90 - */ 0,
+/* f91 - */ 0,
+/* f92 - */ 0,
+/* f93 - */ 0,
+/* f94 - */ 0,
+/* f95 - */ 0,
+/* f96 - */ 0,
+/* f97 - */ 0,
+/* f98 - */ 0,
+/* f99 - _V_66_0F_38_0D */ 0x40e7,
+/* f9a - */ 0,
+/* f9b - */ 0,
+/* f9c - */ 0,
+/* f9d - */ 0,
+/* f9e - */ 0,
+/* f9f - */ 0,
+/* fa0 - */ 0,
+/* fa1 - */ 0,
+/* fa2 - */ 0,
+/* fa3 - */ 0,
+/* fa4 - */ 0,
+/* fa5 - _V_66_0F_38_0E */ 0x40e8,
+/* fa6 - */ 0,
+/* fa7 - */ 0,
+/* fa8 - */ 0,
+/* fa9 - */ 0,
+/* faa - */ 0,
+/* fab - */ 0,
+/* fac - */ 0,
+/* fad - */ 0,
+/* fae - */ 0,
+/* faf - */ 0,
+/* fb0 - */ 0,
+/* fb1 - _V_66_0F_38_0F */ 0x40e9,
+/* fb2 - */ 0,
+/* fb3 - */ 0,
+/* fb4 - */ 0,
+/* fb5 - */ 0,
+/* fb6 - */ 0,
+/* fb7 - */ 0,
+/* fb8 - */ 0,
+/* fb9 - _66_0F_38_10 */ 0x40ea,
+/* fba - */ 0,
+/* fbb - */ 0,
+/* fbc - */ 0,
+/* fbd - */ 0,
+/* fbe - */ 0,
+/* fbf - */ 0,
+/* fc0 - */ 0,
+/* fc1 - */ 0,
+/* fc2 - */ 0,
+/* fc3 - */ 0,
+/* fc4 - */ 0,
+/* fc5 - _66_0F_38_14 */ 0x40eb,
+/* fc6 - */ 0,
+/* fc7 - */ 0,
+/* fc8 - */ 0,
+/* fc9 - */ 0,
+/* fca - */ 0,
+/* fcb - */ 0,
+/* fcc - */ 0,
+/* fcd - */ 0,
+/* fce - */ 0,
+/* fcf - */ 0,
+/* fd0 - */ 0,
+/* fd1 - _66_0F_38_15 */ 0x40ec,
+/* fd2 - */ 0,
+/* fd3 - */ 0,
+/* fd4 - */ 0,
+/* fd5 - */ 0,
+/* fd6 - */ 0,
+/* fd7 - */ 0,
+/* fd8 - */ 0,
+/* fd9 - */ 0,
+/* fda - */ 0,
+/* fdb - */ 0,
+/* fdc - */ 0,
+/* fdd - _66_0F_38_17 */ 0x2492,
+/* fde - */ 0,
+/* fdf - */ 0,
+/* fe0 - */ 0,
+/* fe1 - _V_66_0F_38_17 */ 0x40ed,
+/* fe2 - */ 0,
+/* fe3 - */ 0,
+/* fe4 - */ 0,
+/* fe5 - */ 0,
+/* fe6 - */ 0,
+/* fe7 - */ 0,
+/* fe8 - */ 0,
+/* fe9 - */ 0,
+/* fea - */ 0,
+/* feb - */ 0,
+/* fec - */ 0,
+/* fed - _V_66_0F_38_18 */ 0x40ee,
+/* fee - */ 0,
+/* fef - */ 0,
+/* ff0 - */ 0,
+/* ff1 - */ 0,
+/* ff2 - */ 0,
+/* ff3 - */ 0,
+/* ff4 - */ 0,
+/* ff5 - */ 0,
+/* ff6 - */ 0,
+/* ff7 - */ 0,
+/* ff8 - */ 0,
+/* ff9 - _V_66_0F_38_19 */ 0x40ef,
+/* ffa - */ 0,
+/* ffb - */ 0,
+/* ffc - */ 0,
+/* ffd - */ 0,
+/* ffe - */ 0,
+/* fff - */ 0,
+/* 1000 - */ 0,
+/* 1001 - */ 0,
+/* 1002 - */ 0,
+/* 1003 - */ 0,
+/* 1004 - */ 0,
+/* 1005 - _V_66_0F_38_1A */ 0x40f0,
+/* 1006 - */ 0,
+/* 1007 - */ 0,
+/* 1008 - */ 0,
+/* 1009 - */ 0,
+/* 100a - */ 0,
+/* 100b - */ 0,
+/* 100c - _0F_38_1C */ 0x2493,
+/* 100d - _66_0F_38_1C */ 0x2494,
+/* 100e - */ 0,
+/* 100f - */ 0,
+/* 1010 - */ 0,
+/* 1011 - _V_66_0F_38_1C */ 0x40f1,
+/* 1012 - */ 0,
+/* 1013 - */ 0,
+/* 1014 - */ 0,
+/* 1015 - */ 0,
+/* 1016 - */ 0,
+/* 1017 - */ 0,
+/* 1018 - _0F_38_1D */ 0x2495,
+/* 1019 - _66_0F_38_1D */ 0x2496,
+/* 101a - */ 0,
+/* 101b - */ 0,
+/* 101c - */ 0,
+/* 101d - _V_66_0F_38_1D */ 0x40f2,
+/* 101e - */ 0,
+/* 101f - */ 0,
+/* 1020 - */ 0,
+/* 1021 - */ 0,
+/* 1022 - */ 0,
+/* 1023 - */ 0,
+/* 1024 - _0F_38_1E */ 0x2497,
+/* 1025 - _66_0F_38_1E */ 0x2498,
+/* 1026 - */ 0,
+/* 1027 - */ 0,
+/* 1028 - */ 0,
+/* 1029 - _V_66_0F_38_1E */ 0x40f3,
+/* 102a - */ 0,
+/* 102b - */ 0,
+/* 102c - */ 0,
+/* 102d - */ 0,
+/* 102e - */ 0,
+/* 102f - */ 0,
+/* 1030 - */ 0,
+/* 1031 - _66_0F_38_20 */ 0x2499,
+/* 1032 - */ 0,
+/* 1033 - */ 0,
+/* 1034 - */ 0,
+/* 1035 - _V_66_0F_38_20 */ 0x40f4,
+/* 1036 - */ 0,
+/* 1037 - */ 0,
+/* 1038 - */ 0,
+/* 1039 - */ 0,
+/* 103a - */ 0,
+/* 103b - */ 0,
+/* 103c - */ 0,
+/* 103d - _66_0F_38_21 */ 0x249a,
+/* 103e - */ 0,
+/* 103f - */ 0,
+/* 1040 - */ 0,
+/* 1041 - _V_66_0F_38_21 */ 0x40f5,
+/* 1042 - */ 0,
+/* 1043 - */ 0,
+/* 1044 - */ 0,
+/* 1045 - */ 0,
+/* 1046 - */ 0,
+/* 1047 - */ 0,
+/* 1048 - */ 0,
+/* 1049 - _66_0F_38_22 */ 0x249b,
+/* 104a - */ 0,
+/* 104b - */ 0,
+/* 104c - */ 0,
+/* 104d - _V_66_0F_38_22 */ 0x40f6,
+/* 104e - */ 0,
+/* 104f - */ 0,
+/* 1050 - */ 0,
+/* 1051 - */ 0,
+/* 1052 - */ 0,
+/* 1053 - */ 0,
+/* 1054 - */ 0,
+/* 1055 - _66_0F_38_23 */ 0x249c,
+/* 1056 - */ 0,
+/* 1057 - */ 0,
+/* 1058 - */ 0,
+/* 1059 - _V_66_0F_38_23 */ 0x40f7,
+/* 105a - */ 0,
+/* 105b - */ 0,
+/* 105c - */ 0,
+/* 105d - */ 0,
+/* 105e - */ 0,
+/* 105f - */ 0,
+/* 1060 - */ 0,
+/* 1061 - _66_0F_38_24 */ 0x249d,
+/* 1062 - */ 0,
+/* 1063 - */ 0,
+/* 1064 - */ 0,
+/* 1065 - _V_66_0F_38_24 */ 0x40f8,
+/* 1066 - */ 0,
+/* 1067 - */ 0,
+/* 1068 - */ 0,
+/* 1069 - */ 0,
+/* 106a - */ 0,
+/* 106b - */ 0,
+/* 106c - */ 0,
+/* 106d - _66_0F_38_25 */ 0x249e,
+/* 106e - */ 0,
+/* 106f - */ 0,
+/* 1070 - */ 0,
+/* 1071 - _V_66_0F_38_25 */ 0x40f9,
+/* 1072 - */ 0,
+/* 1073 - */ 0,
+/* 1074 - */ 0,
+/* 1075 - */ 0,
+/* 1076 - */ 0,
+/* 1077 - */ 0,
+/* 1078 - */ 0,
+/* 1079 - _66_0F_38_28 */ 0x249f,
+/* 107a - */ 0,
+/* 107b - */ 0,
+/* 107c - */ 0,
+/* 107d - _V_66_0F_38_28 */ 0x40fa,
+/* 107e - */ 0,
+/* 107f - */ 0,
+/* 1080 - */ 0,
+/* 1081 - */ 0,
+/* 1082 - */ 0,
+/* 1083 - */ 0,
+/* 1084 - */ 0,
+/* 1085 - _66_0F_38_29 */ 0x24a0,
+/* 1086 - */ 0,
+/* 1087 - */ 0,
+/* 1088 - */ 0,
+/* 1089 - _V_66_0F_38_29 */ 0x40fb,
+/* 108a - */ 0,
+/* 108b - */ 0,
+/* 108c - */ 0,
+/* 108d - */ 0,
+/* 108e - */ 0,
+/* 108f - */ 0,
+/* 1090 - */ 0,
+/* 1091 - _66_0F_38_2A */ 0x24a1,
+/* 1092 - */ 0,
+/* 1093 - */ 0,
+/* 1094 - */ 0,
+/* 1095 - _V_66_0F_38_2A */ 0x40fc,
+/* 1096 - */ 0,
+/* 1097 - */ 0,
+/* 1098 - */ 0,
+/* 1099 - */ 0,
+/* 109a - */ 0,
+/* 109b - */ 0,
+/* 109c - */ 0,
+/* 109d - _66_0F_38_2B */ 0x24a2,
+/* 109e - */ 0,
+/* 109f - */ 0,
+/* 10a0 - */ 0,
+/* 10a1 - _V_66_0F_38_2B */ 0x40fd,
+/* 10a2 - */ 0,
+/* 10a3 - */ 0,
+/* 10a4 - */ 0,
+/* 10a5 - */ 0,
+/* 10a6 - */ 0,
+/* 10a7 - */ 0,
+/* 10a8 - */ 0,
+/* 10a9 - */ 0,
+/* 10aa - */ 0,
+/* 10ab - */ 0,
+/* 10ac - */ 0,
+/* 10ad - _V_66_0F_38_2C */ 0x40fe,
+/* 10ae - */ 0,
+/* 10af - */ 0,
+/* 10b0 - */ 0,
+/* 10b1 - */ 0,
+/* 10b2 - */ 0,
+/* 10b3 - */ 0,
+/* 10b4 - */ 0,
+/* 10b5 - */ 0,
+/* 10b6 - */ 0,
+/* 10b7 - */ 0,
+/* 10b8 - */ 0,
+/* 10b9 - _V_66_0F_38_2D */ 0x40ff,
+/* 10ba - */ 0,
+/* 10bb - */ 0,
+/* 10bc - */ 0,
+/* 10bd - */ 0,
+/* 10be - */ 0,
+/* 10bf - */ 0,
+/* 10c0 - */ 0,
+/* 10c1 - */ 0,
+/* 10c2 - */ 0,
+/* 10c3 - */ 0,
+/* 10c4 - */ 0,
+/* 10c5 - _V_66_0F_38_2E */ 0x4100,
+/* 10c6 - */ 0,
+/* 10c7 - */ 0,
+/* 10c8 - */ 0,
+/* 10c9 - */ 0,
+/* 10ca - */ 0,
+/* 10cb - */ 0,
+/* 10cc - */ 0,
+/* 10cd - */ 0,
+/* 10ce - */ 0,
+/* 10cf - */ 0,
+/* 10d0 - */ 0,
+/* 10d1 - _V_66_0F_38_2F */ 0x4101,
+/* 10d2 - */ 0,
+/* 10d3 - */ 0,
+/* 10d4 - */ 0,
+/* 10d5 - */ 0,
+/* 10d6 - */ 0,
+/* 10d7 - */ 0,
+/* 10d8 - */ 0,
+/* 10d9 - _66_0F_38_30 */ 0x24a3,
+/* 10da - */ 0,
+/* 10db - */ 0,
+/* 10dc - */ 0,
+/* 10dd - _V_66_0F_38_30 */ 0x4102,
+/* 10de - */ 0,
+/* 10df - */ 0,
+/* 10e0 - */ 0,
+/* 10e1 - */ 0,
+/* 10e2 - */ 0,
+/* 10e3 - */ 0,
+/* 10e4 - */ 0,
+/* 10e5 - _66_0F_38_31 */ 0x24a4,
+/* 10e6 - */ 0,
+/* 10e7 - */ 0,
+/* 10e8 - */ 0,
+/* 10e9 - _V_66_0F_38_31 */ 0x4103,
+/* 10ea - */ 0,
+/* 10eb - */ 0,
+/* 10ec - */ 0,
+/* 10ed - */ 0,
+/* 10ee - */ 0,
+/* 10ef - */ 0,
+/* 10f0 - */ 0,
+/* 10f1 - _66_0F_38_32 */ 0x24a5,
+/* 10f2 - */ 0,
+/* 10f3 - */ 0,
+/* 10f4 - */ 0,
+/* 10f5 - _V_66_0F_38_32 */ 0x4104,
+/* 10f6 - */ 0,
+/* 10f7 - */ 0,
+/* 10f8 - */ 0,
+/* 10f9 - */ 0,
+/* 10fa - */ 0,
+/* 10fb - */ 0,
+/* 10fc - */ 0,
+/* 10fd - _66_0F_38_33 */ 0x24a6,
+/* 10fe - */ 0,
+/* 10ff - */ 0,
+/* 1100 - */ 0,
+/* 1101 - _V_66_0F_38_33 */ 0x4105,
+/* 1102 - */ 0,
+/* 1103 - */ 0,
+/* 1104 - */ 0,
+/* 1105 - */ 0,
+/* 1106 - */ 0,
+/* 1107 - */ 0,
+/* 1108 - */ 0,
+/* 1109 - _66_0F_38_34 */ 0x24a7,
+/* 110a - */ 0,
+/* 110b - */ 0,
+/* 110c - */ 0,
+/* 110d - _V_66_0F_38_34 */ 0x4106,
+/* 110e - */ 0,
+/* 110f - */ 0,
+/* 1110 - */ 0,
+/* 1111 - */ 0,
+/* 1112 - */ 0,
+/* 1113 - */ 0,
+/* 1114 - */ 0,
+/* 1115 - _66_0F_38_35 */ 0x24a8,
+/* 1116 - */ 0,
+/* 1117 - */ 0,
+/* 1118 - */ 0,
+/* 1119 - _V_66_0F_38_35 */ 0x4107,
+/* 111a - */ 0,
+/* 111b - */ 0,
+/* 111c - */ 0,
+/* 111d - */ 0,
+/* 111e - */ 0,
+/* 111f - */ 0,
+/* 1120 - */ 0,
+/* 1121 - _66_0F_38_37 */ 0x24a9,
+/* 1122 - */ 0,
+/* 1123 - */ 0,
+/* 1124 - */ 0,
+/* 1125 - _V_66_0F_38_37 */ 0x4108,
+/* 1126 - */ 0,
+/* 1127 - */ 0,
+/* 1128 - */ 0,
+/* 1129 - */ 0,
+/* 112a - */ 0,
+/* 112b - */ 0,
+/* 112c - */ 0,
+/* 112d - _66_0F_38_38 */ 0x24aa,
+/* 112e - */ 0,
+/* 112f - */ 0,
+/* 1130 - */ 0,
+/* 1131 - _V_66_0F_38_38 */ 0x4109,
+/* 1132 - */ 0,
+/* 1133 - */ 0,
+/* 1134 - */ 0,
+/* 1135 - */ 0,
+/* 1136 - */ 0,
+/* 1137 - */ 0,
+/* 1138 - */ 0,
+/* 1139 - _66_0F_38_39 */ 0x24ab,
+/* 113a - */ 0,
+/* 113b - */ 0,
+/* 113c - */ 0,
+/* 113d - _V_66_0F_38_39 */ 0x410a,
+/* 113e - */ 0,
+/* 113f - */ 0,
+/* 1140 - */ 0,
+/* 1141 - */ 0,
+/* 1142 - */ 0,
+/* 1143 - */ 0,
+/* 1144 - */ 0,
+/* 1145 - _66_0F_38_3A */ 0x24ac,
+/* 1146 - */ 0,
+/* 1147 - */ 0,
+/* 1148 - */ 0,
+/* 1149 - _V_66_0F_38_3A */ 0x410b,
+/* 114a - */ 0,
+/* 114b - */ 0,
+/* 114c - */ 0,
+/* 114d - */ 0,
+/* 114e - */ 0,
+/* 114f - */ 0,
+/* 1150 - */ 0,
+/* 1151 - _66_0F_38_3B */ 0x24ad,
+/* 1152 - */ 0,
+/* 1153 - */ 0,
+/* 1154 - */ 0,
+/* 1155 - _V_66_0F_38_3B */ 0x410c,
+/* 1156 - */ 0,
+/* 1157 - */ 0,
+/* 1158 - */ 0,
+/* 1159 - */ 0,
+/* 115a - */ 0,
+/* 115b - */ 0,
+/* 115c - */ 0,
+/* 115d - _66_0F_38_3C */ 0x24ae,
+/* 115e - */ 0,
+/* 115f - */ 0,
+/* 1160 - */ 0,
+/* 1161 - _V_66_0F_38_3C */ 0x410d,
+/* 1162 - */ 0,
+/* 1163 - */ 0,
+/* 1164 - */ 0,
+/* 1165 - */ 0,
+/* 1166 - */ 0,
+/* 1167 - */ 0,
+/* 1168 - */ 0,
+/* 1169 - _66_0F_38_3D */ 0x24af,
+/* 116a - */ 0,
+/* 116b - */ 0,
+/* 116c - */ 0,
+/* 116d - _V_66_0F_38_3D */ 0x410e,
+/* 116e - */ 0,
+/* 116f - */ 0,
+/* 1170 - */ 0,
+/* 1171 - */ 0,
+/* 1172 - */ 0,
+/* 1173 - */ 0,
+/* 1174 - */ 0,
+/* 1175 - _66_0F_38_3E */ 0x24b0,
+/* 1176 - */ 0,
+/* 1177 - */ 0,
+/* 1178 - */ 0,
+/* 1179 - _V_66_0F_38_3E */ 0x410f,
+/* 117a - */ 0,
+/* 117b - */ 0,
+/* 117c - */ 0,
+/* 117d - */ 0,
+/* 117e - */ 0,
+/* 117f - */ 0,
+/* 1180 - */ 0,
+/* 1181 - _66_0F_38_3F */ 0x24b1,
+/* 1182 - */ 0,
+/* 1183 - */ 0,
+/* 1184 - */ 0,
+/* 1185 - _V_66_0F_38_3F */ 0x4110,
+/* 1186 - */ 0,
+/* 1187 - */ 0,
+/* 1188 - */ 0,
+/* 1189 - */ 0,
+/* 118a - */ 0,
+/* 118b - */ 0,
+/* 118c - */ 0,
+/* 118d - _66_0F_38_40 */ 0x24b2,
+/* 118e - */ 0,
+/* 118f - */ 0,
+/* 1190 - */ 0,
+/* 1191 - _V_66_0F_38_40 */ 0x4111,
+/* 1192 - */ 0,
+/* 1193 - */ 0,
+/* 1194 - */ 0,
+/* 1195 - */ 0,
+/* 1196 - */ 0,
+/* 1197 - */ 0,
+/* 1198 - */ 0,
+/* 1199 - _66_0F_38_41 */ 0x24b3,
+/* 119a - */ 0,
+/* 119b - */ 0,
+/* 119c - */ 0,
+/* 119d - _V_66_0F_38_41 */ 0x4112,
+/* 119e - */ 0,
+/* 119f - */ 0,
+/* 11a0 - */ 0,
+/* 11a1 - */ 0,
+/* 11a2 - */ 0,
+/* 11a3 - */ 0,
+/* 11a4 - */ 0,
+/* 11a5 - _66_0F_38_80 */ 0x24b4,
+/* 11a6 - */ 0,
+/* 11a7 - */ 0,
+/* 11a8 - */ 0,
+/* 11a9 - */ 0,
+/* 11aa - */ 0,
+/* 11ab - */ 0,
+/* 11ac - */ 0,
+/* 11ad - */ 0,
+/* 11ae - */ 0,
+/* 11af - */ 0,
+/* 11b0 - */ 0,
+/* 11b1 - _66_0F_38_81 */ 0x24b5,
+/* 11b2 - */ 0,
+/* 11b3 - */ 0,
+/* 11b4 - */ 0,
+/* 11b5 - */ 0,
+/* 11b6 - */ 0,
+/* 11b7 - */ 0,
+/* 11b8 - */ 0,
+/* 11b9 - */ 0,
+/* 11ba - */ 0,
+/* 11bb - */ 0,
+/* 11bc - */ 0,
+/* 11bd - _66_0F_38_82 */ 0x24b6,
+/* 11be - */ 0,
+/* 11bf - */ 0,
+/* 11c0 - */ 0,
+/* 11c1 - */ 0,
+/* 11c2 - */ 0,
+/* 11c3 - */ 0,
+/* 11c4 - */ 0,
+/* 11c5 - */ 0,
+/* 11c6 - */ 0,
+/* 11c7 - */ 0,
+/* 11c8 - */ 0,
+/* 11c9 - */ 0,
+/* 11ca - */ 0,
+/* 11cb - */ 0,
+/* 11cc - */ 0,
+/* 11cd - _V_66_0F_38_96 */ 0x4113,
+/* 11ce - */ 0,
+/* 11cf - */ 0,
+/* 11d0 - */ 0,
+/* 11d1 - */ 0,
+/* 11d2 - */ 0,
+/* 11d3 - */ 0,
+/* 11d4 - */ 0,
+/* 11d5 - */ 0,
+/* 11d6 - */ 0,
+/* 11d7 - */ 0,
+/* 11d8 - */ 0,
+/* 11d9 - _V_66_0F_38_97 */ 0x4114,
+/* 11da - */ 0,
+/* 11db - */ 0,
+/* 11dc - */ 0,
+/* 11dd - */ 0,
+/* 11de - */ 0,
+/* 11df - */ 0,
+/* 11e0 - */ 0,
+/* 11e1 - */ 0,
+/* 11e2 - */ 0,
+/* 11e3 - */ 0,
+/* 11e4 - */ 0,
+/* 11e5 - _V_66_0F_38_98 */ 0x4115,
+/* 11e6 - */ 0,
+/* 11e7 - */ 0,
+/* 11e8 - */ 0,
+/* 11e9 - */ 0,
+/* 11ea - */ 0,
+/* 11eb - */ 0,
+/* 11ec - */ 0,
+/* 11ed - */ 0,
+/* 11ee - */ 0,
+/* 11ef - */ 0,
+/* 11f0 - */ 0,
+/* 11f1 - _V_66_0F_38_99 */ 0x4116,
+/* 11f2 - */ 0,
+/* 11f3 - */ 0,
+/* 11f4 - */ 0,
+/* 11f5 - */ 0,
+/* 11f6 - */ 0,
+/* 11f7 - */ 0,
+/* 11f8 - */ 0,
+/* 11f9 - */ 0,
+/* 11fa - */ 0,
+/* 11fb - */ 0,
+/* 11fc - */ 0,
+/* 11fd - _V_66_0F_38_9A */ 0x4117,
+/* 11fe - */ 0,
+/* 11ff - */ 0,
+/* 1200 - */ 0,
+/* 1201 - */ 0,
+/* 1202 - */ 0,
+/* 1203 - */ 0,
+/* 1204 - */ 0,
+/* 1205 - */ 0,
+/* 1206 - */ 0,
+/* 1207 - */ 0,
+/* 1208 - */ 0,
+/* 1209 - _V_66_0F_38_9B */ 0x4118,
+/* 120a - */ 0,
+/* 120b - */ 0,
+/* 120c - */ 0,
+/* 120d - */ 0,
+/* 120e - */ 0,
+/* 120f - */ 0,
+/* 1210 - */ 0,
+/* 1211 - */ 0,
+/* 1212 - */ 0,
+/* 1213 - */ 0,
+/* 1214 - */ 0,
+/* 1215 - _V_66_0F_38_9C */ 0x4119,
+/* 1216 - */ 0,
+/* 1217 - */ 0,
+/* 1218 - */ 0,
+/* 1219 - */ 0,
+/* 121a - */ 0,
+/* 121b - */ 0,
+/* 121c - */ 0,
+/* 121d - */ 0,
+/* 121e - */ 0,
+/* 121f - */ 0,
+/* 1220 - */ 0,
+/* 1221 - _V_66_0F_38_9D */ 0x411a,
+/* 1222 - */ 0,
+/* 1223 - */ 0,
+/* 1224 - */ 0,
+/* 1225 - */ 0,
+/* 1226 - */ 0,
+/* 1227 - */ 0,
+/* 1228 - */ 0,
+/* 1229 - */ 0,
+/* 122a - */ 0,
+/* 122b - */ 0,
+/* 122c - */ 0,
+/* 122d - _V_66_0F_38_9E */ 0x411b,
+/* 122e - */ 0,
+/* 122f - */ 0,
+/* 1230 - */ 0,
+/* 1231 - */ 0,
+/* 1232 - */ 0,
+/* 1233 - */ 0,
+/* 1234 - */ 0,
+/* 1235 - */ 0,
+/* 1236 - */ 0,
+/* 1237 - */ 0,
+/* 1238 - */ 0,
+/* 1239 - _V_66_0F_38_9F */ 0x411c,
+/* 123a - */ 0,
+/* 123b - */ 0,
+/* 123c - */ 0,
+/* 123d - */ 0,
+/* 123e - */ 0,
+/* 123f - */ 0,
+/* 1240 - */ 0,
+/* 1241 - */ 0,
+/* 1242 - */ 0,
+/* 1243 - */ 0,
+/* 1244 - */ 0,
+/* 1245 - _V_66_0F_38_A6 */ 0x411d,
+/* 1246 - */ 0,
+/* 1247 - */ 0,
+/* 1248 - */ 0,
+/* 1249 - */ 0,
+/* 124a - */ 0,
+/* 124b - */ 0,
+/* 124c - */ 0,
+/* 124d - */ 0,
+/* 124e - */ 0,
+/* 124f - */ 0,
+/* 1250 - */ 0,
+/* 1251 - _V_66_0F_38_A7 */ 0x411e,
+/* 1252 - */ 0,
+/* 1253 - */ 0,
+/* 1254 - */ 0,
+/* 1255 - */ 0,
+/* 1256 - */ 0,
+/* 1257 - */ 0,
+/* 1258 - */ 0,
+/* 1259 - */ 0,
+/* 125a - */ 0,
+/* 125b - */ 0,
+/* 125c - */ 0,
+/* 125d - _V_66_0F_38_A8 */ 0x411f,
+/* 125e - */ 0,
+/* 125f - */ 0,
+/* 1260 - */ 0,
+/* 1261 - */ 0,
+/* 1262 - */ 0,
+/* 1263 - */ 0,
+/* 1264 - */ 0,
+/* 1265 - */ 0,
+/* 1266 - */ 0,
+/* 1267 - */ 0,
+/* 1268 - */ 0,
+/* 1269 - _V_66_0F_38_A9 */ 0x4120,
+/* 126a - */ 0,
+/* 126b - */ 0,
+/* 126c - */ 0,
+/* 126d - */ 0,
+/* 126e - */ 0,
+/* 126f - */ 0,
+/* 1270 - */ 0,
+/* 1271 - */ 0,
+/* 1272 - */ 0,
+/* 1273 - */ 0,
+/* 1274 - */ 0,
+/* 1275 - _V_66_0F_38_AA */ 0x4121,
+/* 1276 - */ 0,
+/* 1277 - */ 0,
+/* 1278 - */ 0,
+/* 1279 - */ 0,
+/* 127a - */ 0,
+/* 127b - */ 0,
+/* 127c - */ 0,
+/* 127d - */ 0,
+/* 127e - */ 0,
+/* 127f - */ 0,
+/* 1280 - */ 0,
+/* 1281 - _V_66_0F_38_AB */ 0x4122,
+/* 1282 - */ 0,
+/* 1283 - */ 0,
+/* 1284 - */ 0,
+/* 1285 - */ 0,
+/* 1286 - */ 0,
+/* 1287 - */ 0,
+/* 1288 - */ 0,
+/* 1289 - */ 0,
+/* 128a - */ 0,
+/* 128b - */ 0,
+/* 128c - */ 0,
+/* 128d - _V_66_0F_38_AC */ 0x4123,
+/* 128e - */ 0,
+/* 128f - */ 0,
+/* 1290 - */ 0,
+/* 1291 - */ 0,
+/* 1292 - */ 0,
+/* 1293 - */ 0,
+/* 1294 - */ 0,
+/* 1295 - */ 0,
+/* 1296 - */ 0,
+/* 1297 - */ 0,
+/* 1298 - */ 0,
+/* 1299 - _V_66_0F_38_AD */ 0x4124,
+/* 129a - */ 0,
+/* 129b - */ 0,
+/* 129c - */ 0,
+/* 129d - */ 0,
+/* 129e - */ 0,
+/* 129f - */ 0,
+/* 12a0 - */ 0,
+/* 12a1 - */ 0,
+/* 12a2 - */ 0,
+/* 12a3 - */ 0,
+/* 12a4 - */ 0,
+/* 12a5 - _V_66_0F_38_AE */ 0x4125,
+/* 12a6 - */ 0,
+/* 12a7 - */ 0,
+/* 12a8 - */ 0,
+/* 12a9 - */ 0,
+/* 12aa - */ 0,
+/* 12ab - */ 0,
+/* 12ac - */ 0,
+/* 12ad - */ 0,
+/* 12ae - */ 0,
+/* 12af - */ 0,
+/* 12b0 - */ 0,
+/* 12b1 - _V_66_0F_38_AF */ 0x4126,
+/* 12b2 - */ 0,
+/* 12b3 - */ 0,
+/* 12b4 - */ 0,
+/* 12b5 - */ 0,
+/* 12b6 - */ 0,
+/* 12b7 - */ 0,
+/* 12b8 - */ 0,
+/* 12b9 - */ 0,
+/* 12ba - */ 0,
+/* 12bb - */ 0,
+/* 12bc - */ 0,
+/* 12bd - _V_66_0F_38_B6 */ 0x4127,
+/* 12be - */ 0,
+/* 12bf - */ 0,
+/* 12c0 - */ 0,
+/* 12c1 - */ 0,
+/* 12c2 - */ 0,
+/* 12c3 - */ 0,
+/* 12c4 - */ 0,
+/* 12c5 - */ 0,
+/* 12c6 - */ 0,
+/* 12c7 - */ 0,
+/* 12c8 - */ 0,
+/* 12c9 - _V_66_0F_38_B7 */ 0x4128,
+/* 12ca - */ 0,
+/* 12cb - */ 0,
+/* 12cc - */ 0,
+/* 12cd - */ 0,
+/* 12ce - */ 0,
+/* 12cf - */ 0,
+/* 12d0 - */ 0,
+/* 12d1 - */ 0,
+/* 12d2 - */ 0,
+/* 12d3 - */ 0,
+/* 12d4 - */ 0,
+/* 12d5 - _V_66_0F_38_B8 */ 0x4129,
+/* 12d6 - */ 0,
+/* 12d7 - */ 0,
+/* 12d8 - */ 0,
+/* 12d9 - */ 0,
+/* 12da - */ 0,
+/* 12db - */ 0,
+/* 12dc - */ 0,
+/* 12dd - */ 0,
+/* 12de - */ 0,
+/* 12df - */ 0,
+/* 12e0 - */ 0,
+/* 12e1 - _V_66_0F_38_B9 */ 0x412a,
+/* 12e2 - */ 0,
+/* 12e3 - */ 0,
+/* 12e4 - */ 0,
+/* 12e5 - */ 0,
+/* 12e6 - */ 0,
+/* 12e7 - */ 0,
+/* 12e8 - */ 0,
+/* 12e9 - */ 0,
+/* 12ea - */ 0,
+/* 12eb - */ 0,
+/* 12ec - */ 0,
+/* 12ed - _V_66_0F_38_BA */ 0x412b,
+/* 12ee - */ 0,
+/* 12ef - */ 0,
+/* 12f0 - */ 0,
+/* 12f1 - */ 0,
+/* 12f2 - */ 0,
+/* 12f3 - */ 0,
+/* 12f4 - */ 0,
+/* 12f5 - */ 0,
+/* 12f6 - */ 0,
+/* 12f7 - */ 0,
+/* 12f8 - */ 0,
+/* 12f9 - _V_66_0F_38_BB */ 0x412c,
+/* 12fa - */ 0,
+/* 12fb - */ 0,
+/* 12fc - */ 0,
+/* 12fd - */ 0,
+/* 12fe - */ 0,
+/* 12ff - */ 0,
+/* 1300 - */ 0,
+/* 1301 - */ 0,
+/* 1302 - */ 0,
+/* 1303 - */ 0,
+/* 1304 - */ 0,
+/* 1305 - _V_66_0F_38_BC */ 0x412d,
+/* 1306 - */ 0,
+/* 1307 - */ 0,
+/* 1308 - */ 0,
+/* 1309 - */ 0,
+/* 130a - */ 0,
+/* 130b - */ 0,
+/* 130c - */ 0,
+/* 130d - */ 0,
+/* 130e - */ 0,
+/* 130f - */ 0,
+/* 1310 - */ 0,
+/* 1311 - _V_66_0F_38_BD */ 0x412e,
+/* 1312 - */ 0,
+/* 1313 - */ 0,
+/* 1314 - */ 0,
+/* 1315 - */ 0,
+/* 1316 - */ 0,
+/* 1317 - */ 0,
+/* 1318 - */ 0,
+/* 1319 - */ 0,
+/* 131a - */ 0,
+/* 131b - */ 0,
+/* 131c - */ 0,
+/* 131d - _V_66_0F_38_BE */ 0x412f,
+/* 131e - */ 0,
+/* 131f - */ 0,
+/* 1320 - */ 0,
+/* 1321 - */ 0,
+/* 1322 - */ 0,
+/* 1323 - */ 0,
+/* 1324 - */ 0,
+/* 1325 - */ 0,
+/* 1326 - */ 0,
+/* 1327 - */ 0,
+/* 1328 - */ 0,
+/* 1329 - _V_66_0F_38_BF */ 0x4130,
+/* 132a - */ 0,
+/* 132b - */ 0,
+/* 132c - */ 0,
+/* 132d - */ 0,
+/* 132e - */ 0,
+/* 132f - */ 0,
+/* 1330 - */ 0,
+/* 1331 - _66_0F_38_DB */ 0x24b7,
+/* 1332 - */ 0,
+/* 1333 - */ 0,
+/* 1334 - */ 0,
+/* 1335 - _V_66_0F_38_DB */ 0x4131,
+/* 1336 - */ 0,
+/* 1337 - */ 0,
+/* 1338 - */ 0,
+/* 1339 - */ 0,
+/* 133a - */ 0,
+/* 133b - */ 0,
+/* 133c - */ 0,
+/* 133d - _66_0F_38_DC */ 0x24b8,
+/* 133e - */ 0,
+/* 133f - */ 0,
+/* 1340 - */ 0,
+/* 1341 - _V_66_0F_38_DC */ 0x4132,
+/* 1342 - */ 0,
+/* 1343 - */ 0,
+/* 1344 - */ 0,
+/* 1345 - */ 0,
+/* 1346 - */ 0,
+/* 1347 - */ 0,
+/* 1348 - */ 0,
+/* 1349 - _66_0F_38_DD */ 0x24b9,
+/* 134a - */ 0,
+/* 134b - */ 0,
+/* 134c - */ 0,
+/* 134d - _V_66_0F_38_DD */ 0x4133,
+/* 134e - */ 0,
+/* 134f - */ 0,
+/* 1350 - */ 0,
+/* 1351 - */ 0,
+/* 1352 - */ 0,
+/* 1353 - */ 0,
+/* 1354 - */ 0,
+/* 1355 - _66_0F_38_DE */ 0x24ba,
+/* 1356 - */ 0,
+/* 1357 - */ 0,
+/* 1358 - */ 0,
+/* 1359 - _V_66_0F_38_DE */ 0x4134,
+/* 135a - */ 0,
+/* 135b - */ 0,
+/* 135c - */ 0,
+/* 135d - */ 0,
+/* 135e - */ 0,
+/* 135f - */ 0,
+/* 1360 - */ 0,
+/* 1361 - _66_0F_38_DF */ 0x24bb,
+/* 1362 - */ 0,
+/* 1363 - */ 0,
+/* 1364 - */ 0,
+/* 1365 - _V_66_0F_38_DF */ 0x4135,
+/* 1366 - */ 0,
+/* 1367 - */ 0,
+/* 1368 - */ 0,
+/* 1369 - */ 0,
+/* 136a - */ 0,
+/* 136b - */ 0,
+/* 136c - _0F_38_F0 */ 0x24bc,
+/* 136d - */ 0,
+/* 136e - */ 0,
+/* 136f - _F2_0F_38_F0 */ 0x24bd,
+/* 1370 - */ 0,
+/* 1371 - */ 0,
+/* 1372 - */ 0,
+/* 1373 - */ 0,
+/* 1374 - */ 0,
+/* 1375 - */ 0,
+/* 1376 - */ 0,
+/* 1377 - */ 0,
+/* 1378 - _0F_38_F1 */ 0x24be,
+/* 1379 - */ 0,
+/* 137a - */ 0,
+/* 137b - _F2_0F_38_F1 */ 0x24bf,
+/* 137c - */ 0,
+/* 137d - */ 0,
+/* 137e - */ 0,
+/* 137f - */ 0,
+/* 1380 - */ 0,
+/* 1381 - */ 0,
+/* 1382 - */ 0,
+/* 1383 - */ 0,
+/* 1384 - */ 0,
+/* 1385 - */ 0,
+/* 1386 - */ 0,
+/* 1387 - */ 0,
+/* 1388 - */ 0,
+/* 1389 - _V_66_0F_3A_04 */ 0x4136,
+/* 138a - */ 0,
+/* 138b - */ 0,
+/* 138c - */ 0,
+/* 138d - */ 0,
+/* 138e - */ 0,
+/* 138f - */ 0,
+/* 1390 - */ 0,
+/* 1391 - */ 0,
+/* 1392 - */ 0,
+/* 1393 - */ 0,
+/* 1394 - */ 0,
+/* 1395 - _V_66_0F_3A_05 */ 0x4137,
+/* 1396 - */ 0,
+/* 1397 - */ 0,
+/* 1398 - */ 0,
+/* 1399 - */ 0,
+/* 139a - */ 0,
+/* 139b - */ 0,
+/* 139c - */ 0,
+/* 139d - */ 0,
+/* 139e - */ 0,
+/* 139f - */ 0,
+/* 13a0 - */ 0,
+/* 13a1 - _V_66_0F_3A_06 */ 0x4138,
+/* 13a2 - */ 0,
+/* 13a3 - */ 0,
+/* 13a4 - */ 0,
+/* 13a5 - */ 0,
+/* 13a6 - */ 0,
+/* 13a7 - */ 0,
+/* 13a8 - */ 0,
+/* 13a9 - _66_0F_3A_08 */ 0x4139,
+/* 13aa - */ 0,
+/* 13ab - */ 0,
+/* 13ac - */ 0,
+/* 13ad - _V_66_0F_3A_08 */ 0x413a,
+/* 13ae - */ 0,
+/* 13af - */ 0,
+/* 13b0 - */ 0,
+/* 13b1 - */ 0,
+/* 13b2 - */ 0,
+/* 13b3 - */ 0,
+/* 13b4 - */ 0,
+/* 13b5 - _66_0F_3A_09 */ 0x413b,
+/* 13b6 - */ 0,
+/* 13b7 - */ 0,
+/* 13b8 - */ 0,
+/* 13b9 - _V_66_0F_3A_09 */ 0x413c,
+/* 13ba - */ 0,
+/* 13bb - */ 0,
+/* 13bc - */ 0,
+/* 13bd - */ 0,
+/* 13be - */ 0,
+/* 13bf - */ 0,
+/* 13c0 - */ 0,
+/* 13c1 - _66_0F_3A_0A */ 0x413d,
+/* 13c2 - */ 0,
+/* 13c3 - */ 0,
+/* 13c4 - */ 0,
+/* 13c5 - _V_66_0F_3A_0A */ 0x413e,
+/* 13c6 - */ 0,
+/* 13c7 - */ 0,
+/* 13c8 - */ 0,
+/* 13c9 - */ 0,
+/* 13ca - */ 0,
+/* 13cb - */ 0,
+/* 13cc - */ 0,
+/* 13cd - _66_0F_3A_0B */ 0x413f,
+/* 13ce - */ 0,
+/* 13cf - */ 0,
+/* 13d0 - */ 0,
+/* 13d1 - _V_66_0F_3A_0B */ 0x4140,
+/* 13d2 - */ 0,
+/* 13d3 - */ 0,
+/* 13d4 - */ 0,
+/* 13d5 - */ 0,
+/* 13d6 - */ 0,
+/* 13d7 - */ 0,
+/* 13d8 - */ 0,
+/* 13d9 - _66_0F_3A_0C */ 0x4141,
+/* 13da - */ 0,
+/* 13db - */ 0,
+/* 13dc - */ 0,
+/* 13dd - _V_66_0F_3A_0C */ 0x4142,
+/* 13de - */ 0,
+/* 13df - */ 0,
+/* 13e0 - */ 0,
+/* 13e1 - */ 0,
+/* 13e2 - */ 0,
+/* 13e3 - */ 0,
+/* 13e4 - */ 0,
+/* 13e5 - _66_0F_3A_0D */ 0x4143,
+/* 13e6 - */ 0,
+/* 13e7 - */ 0,
+/* 13e8 - */ 0,
+/* 13e9 - _V_66_0F_3A_0D */ 0x4144,
+/* 13ea - */ 0,
+/* 13eb - */ 0,
+/* 13ec - */ 0,
+/* 13ed - */ 0,
+/* 13ee - */ 0,
+/* 13ef - */ 0,
+/* 13f0 - */ 0,
+/* 13f1 - _66_0F_3A_0E */ 0x4145,
+/* 13f2 - */ 0,
+/* 13f3 - */ 0,
+/* 13f4 - */ 0,
+/* 13f5 - _V_66_0F_3A_0E */ 0x4146,
+/* 13f6 - */ 0,
+/* 13f7 - */ 0,
+/* 13f8 - */ 0,
+/* 13f9 - */ 0,
+/* 13fa - */ 0,
+/* 13fb - */ 0,
+/* 13fc - _0F_3A_0F */ 0x4147,
+/* 13fd - _66_0F_3A_0F */ 0x4148,
+/* 13fe - */ 0,
+/* 13ff - */ 0,
+/* 1400 - */ 0,
+/* 1401 - _V_66_0F_3A_0F */ 0x4149,
+/* 1402 - */ 0,
+/* 1403 - */ 0,
+/* 1404 - */ 0,
+/* 1405 - */ 0,
+/* 1406 - */ 0,
+/* 1407 - */ 0,
+/* 1408 - */ 0,
+/* 1409 - _66_0F_3A_14 */ 0x414a,
+/* 140a - */ 0,
+/* 140b - */ 0,
+/* 140c - */ 0,
+/* 140d - _V_66_0F_3A_14 */ 0x414b,
+/* 140e - */ 0,
+/* 140f - */ 0,
+/* 1410 - */ 0,
+/* 1411 - */ 0,
+/* 1412 - */ 0,
+/* 1413 - */ 0,
+/* 1414 - */ 0,
+/* 1415 - _66_0F_3A_15 */ 0x414c,
+/* 1416 - */ 0,
+/* 1417 - */ 0,
+/* 1418 - */ 0,
+/* 1419 - _V_66_0F_3A_15 */ 0x414d,
+/* 141a - */ 0,
+/* 141b - */ 0,
+/* 141c - */ 0,
+/* 141d - */ 0,
+/* 141e - */ 0,
+/* 141f - */ 0,
+/* 1420 - */ 0,
+/* 1421 - _66_0F_3A_16 */ 0x414e,
+/* 1422 - */ 0,
+/* 1423 - */ 0,
+/* 1424 - */ 0,
+/* 1425 - _V_66_0F_3A_16 */ 0x414f,
+/* 1426 - */ 0,
+/* 1427 - */ 0,
+/* 1428 - */ 0,
+/* 1429 - */ 0,
+/* 142a - */ 0,
+/* 142b - */ 0,
+/* 142c - */ 0,
+/* 142d - _66_0F_3A_17 */ 0x4150,
+/* 142e - */ 0,
+/* 142f - */ 0,
+/* 1430 - */ 0,
+/* 1431 - _V_66_0F_3A_17 */ 0x4151,
+/* 1432 - */ 0,
+/* 1433 - */ 0,
+/* 1434 - */ 0,
+/* 1435 - */ 0,
+/* 1436 - */ 0,
+/* 1437 - */ 0,
+/* 1438 - */ 0,
+/* 1439 - */ 0,
+/* 143a - */ 0,
+/* 143b - */ 0,
+/* 143c - */ 0,
+/* 143d - _V_66_0F_3A_18 */ 0x4152,
+/* 143e - */ 0,
+/* 143f - */ 0,
+/* 1440 - */ 0,
+/* 1441 - */ 0,
+/* 1442 - */ 0,
+/* 1443 - */ 0,
+/* 1444 - */ 0,
+/* 1445 - */ 0,
+/* 1446 - */ 0,
+/* 1447 - */ 0,
+/* 1448 - */ 0,
+/* 1449 - _V_66_0F_3A_19 */ 0x4153,
+/* 144a - */ 0,
+/* 144b - */ 0,
+/* 144c - */ 0,
+/* 144d - */ 0,
+/* 144e - */ 0,
+/* 144f - */ 0,
+/* 1450 - */ 0,
+/* 1451 - _66_0F_3A_20 */ 0x4154,
+/* 1452 - */ 0,
+/* 1453 - */ 0,
+/* 1454 - */ 0,
+/* 1455 - _V_66_0F_3A_20 */ 0x4155,
+/* 1456 - */ 0,
+/* 1457 - */ 0,
+/* 1458 - */ 0,
+/* 1459 - */ 0,
+/* 145a - */ 0,
+/* 145b - */ 0,
+/* 145c - */ 0,
+/* 145d - _66_0F_3A_21 */ 0x4156,
+/* 145e - */ 0,
+/* 145f - */ 0,
+/* 1460 - */ 0,
+/* 1461 - _V_66_0F_3A_21 */ 0x4157,
+/* 1462 - */ 0,
+/* 1463 - */ 0,
+/* 1464 - */ 0,
+/* 1465 - */ 0,
+/* 1466 - */ 0,
+/* 1467 - */ 0,
+/* 1468 - */ 0,
+/* 1469 - _66_0F_3A_22 */ 0x4158,
+/* 146a - */ 0,
+/* 146b - */ 0,
+/* 146c - */ 0,
+/* 146d - _V_66_0F_3A_22 */ 0x4159,
+/* 146e - */ 0,
+/* 146f - */ 0,
+/* 1470 - */ 0,
+/* 1471 - */ 0,
+/* 1472 - */ 0,
+/* 1473 - */ 0,
+/* 1474 - */ 0,
+/* 1475 - _66_0F_3A_40 */ 0x415a,
+/* 1476 - */ 0,
+/* 1477 - */ 0,
+/* 1478 - */ 0,
+/* 1479 - _V_66_0F_3A_40 */ 0x415b,
+/* 147a - */ 0,
+/* 147b - */ 0,
+/* 147c - */ 0,
+/* 147d - */ 0,
+/* 147e - */ 0,
+/* 147f - */ 0,
+/* 1480 - */ 0,
+/* 1481 - _66_0F_3A_41 */ 0x415c,
+/* 1482 - */ 0,
+/* 1483 - */ 0,
+/* 1484 - */ 0,
+/* 1485 - _V_66_0F_3A_41 */ 0x415d,
+/* 1486 - */ 0,
+/* 1487 - */ 0,
+/* 1488 - */ 0,
+/* 1489 - */ 0,
+/* 148a - */ 0,
+/* 148b - */ 0,
+/* 148c - */ 0,
+/* 148d - _66_0F_3A_42 */ 0x415e,
+/* 148e - */ 0,
+/* 148f - */ 0,
+/* 1490 - */ 0,
+/* 1491 - _V_66_0F_3A_42 */ 0x415f,
+/* 1492 - */ 0,
+/* 1493 - */ 0,
+/* 1494 - */ 0,
+/* 1495 - */ 0,
+/* 1496 - */ 0,
+/* 1497 - */ 0,
+/* 1498 - */ 0,
+/* 1499 - _66_0F_3A_44 */ 0x4160,
+/* 149a - */ 0,
+/* 149b - */ 0,
+/* 149c - */ 0,
+/* 149d - _V_66_0F_3A_44 */ 0x4161,
+/* 149e - */ 0,
+/* 149f - */ 0,
+/* 14a0 - */ 0,
+/* 14a1 - */ 0,
+/* 14a2 - */ 0,
+/* 14a3 - */ 0,
+/* 14a4 - */ 0,
+/* 14a5 - */ 0,
+/* 14a6 - */ 0,
+/* 14a7 - */ 0,
+/* 14a8 - */ 0,
+/* 14a9 - _V_66_0F_3A_4A */ 0x4162,
+/* 14aa - */ 0,
+/* 14ab - */ 0,
+/* 14ac - */ 0,
+/* 14ad - */ 0,
+/* 14ae - */ 0,
+/* 14af - */ 0,
+/* 14b0 - */ 0,
+/* 14b1 - */ 0,
+/* 14b2 - */ 0,
+/* 14b3 - */ 0,
+/* 14b4 - */ 0,
+/* 14b5 - _V_66_0F_3A_4B */ 0x4163,
+/* 14b6 - */ 0,
+/* 14b7 - */ 0,
+/* 14b8 - */ 0,
+/* 14b9 - */ 0,
+/* 14ba - */ 0,
+/* 14bb - */ 0,
+/* 14bc - */ 0,
+/* 14bd - */ 0,
+/* 14be - */ 0,
+/* 14bf - */ 0,
+/* 14c0 - */ 0,
+/* 14c1 - _V_66_0F_3A_4C */ 0x4164,
+/* 14c2 - */ 0,
+/* 14c3 - */ 0,
+/* 14c4 - */ 0,
+/* 14c5 - */ 0,
+/* 14c6 - */ 0,
+/* 14c7 - */ 0,
+/* 14c8 - */ 0,
+/* 14c9 - _66_0F_3A_60 */ 0x4165,
+/* 14ca - */ 0,
+/* 14cb - */ 0,
+/* 14cc - */ 0,
+/* 14cd - _V_66_0F_3A_60 */ 0x4166,
+/* 14ce - */ 0,
+/* 14cf - */ 0,
+/* 14d0 - */ 0,
+/* 14d1 - */ 0,
+/* 14d2 - */ 0,
+/* 14d3 - */ 0,
+/* 14d4 - */ 0,
+/* 14d5 - _66_0F_3A_61 */ 0x4167,
+/* 14d6 - */ 0,
+/* 14d7 - */ 0,
+/* 14d8 - */ 0,
+/* 14d9 - _V_66_0F_3A_61 */ 0x4168,
+/* 14da - */ 0,
+/* 14db - */ 0,
+/* 14dc - */ 0,
+/* 14dd - */ 0,
+/* 14de - */ 0,
+/* 14df - */ 0,
+/* 14e0 - */ 0,
+/* 14e1 - _66_0F_3A_62 */ 0x4169,
+/* 14e2 - */ 0,
+/* 14e3 - */ 0,
+/* 14e4 - */ 0,
+/* 14e5 - _V_66_0F_3A_62 */ 0x416a,
+/* 14e6 - */ 0,
+/* 14e7 - */ 0,
+/* 14e8 - */ 0,
+/* 14e9 - */ 0,
+/* 14ea - */ 0,
+/* 14eb - */ 0,
+/* 14ec - */ 0,
+/* 14ed - _66_0F_3A_63 */ 0x416b,
+/* 14ee - */ 0,
+/* 14ef - */ 0,
+/* 14f0 - */ 0,
+/* 14f1 - _V_66_0F_3A_63 */ 0x416c,
+/* 14f2 - */ 0,
+/* 14f3 - */ 0,
+/* 14f4 - */ 0,
+/* 14f5 - */ 0,
+/* 14f6 - */ 0,
+/* 14f7 - */ 0,
+/* 14f8 - */ 0,
+/* 14f9 - _66_0F_3A_DF */ 0x416d,
+/* 14fa - */ 0,
+/* 14fb - */ 0,
+/* 14fc - */ 0,
+/* 14fd - _V_66_0F_3A_DF */ 0x416e,
+/* 14fe - */ 0,
+/* 14ff - */ 0,
+/* 1500 - */ 0,
+/* 1501 - */ 0,
+/* 1502 - */ 0,
+/* 1503 - */ 0,
+/* 1504 - _0F_71_02 */ 0x24c0,
+/* 1505 - _66_0F_71_02 */ 0x24c1,
+/* 1506 - */ 0,
+/* 1507 - */ 0,
+/* 1508 - */ 0,
+/* 1509 - _V_66_0F_71_02 */ 0x416f,
+/* 150a - */ 0,
+/* 150b - */ 0,
+/* 150c - */ 0,
+/* 150d - */ 0,
+/* 150e - */ 0,
+/* 150f - */ 0,
+/* 1510 - _0F_71_04 */ 0x24c2,
+/* 1511 - _66_0F_71_04 */ 0x24c3,
+/* 1512 - */ 0,
+/* 1513 - */ 0,
+/* 1514 - */ 0,
+/* 1515 - _V_66_0F_71_04 */ 0x4170,
+/* 1516 - */ 0,
+/* 1517 - */ 0,
+/* 1518 - */ 0,
+/* 1519 - */ 0,
+/* 151a - */ 0,
+/* 151b - */ 0,
+/* 151c - _0F_71_06 */ 0x24c4,
+/* 151d - _66_0F_71_06 */ 0x24c5,
+/* 151e - */ 0,
+/* 151f - */ 0,
+/* 1520 - */ 0,
+/* 1521 - _V_66_0F_71_06 */ 0x4171,
+/* 1522 - */ 0,
+/* 1523 - */ 0,
+/* 1524 - */ 0,
+/* 1525 - */ 0,
+/* 1526 - */ 0,
+/* 1527 - */ 0,
+/* 1528 - _0F_72_02 */ 0x24c6,
+/* 1529 - _66_0F_72_02 */ 0x24c7,
+/* 152a - */ 0,
+/* 152b - */ 0,
+/* 152c - */ 0,
+/* 152d - _V_66_0F_72_02 */ 0x4172,
+/* 152e - */ 0,
+/* 152f - */ 0,
+/* 1530 - */ 0,
+/* 1531 - */ 0,
+/* 1532 - */ 0,
+/* 1533 - */ 0,
+/* 1534 - _0F_72_04 */ 0x24c8,
+/* 1535 - _66_0F_72_04 */ 0x24c9,
+/* 1536 - */ 0,
+/* 1537 - */ 0,
+/* 1538 - */ 0,
+/* 1539 - _V_66_0F_72_04 */ 0x4173,
+/* 153a - */ 0,
+/* 153b - */ 0,
+/* 153c - */ 0,
+/* 153d - */ 0,
+/* 153e - */ 0,
+/* 153f - */ 0,
+/* 1540 - _0F_72_06 */ 0x24ca,
+/* 1541 - _66_0F_72_06 */ 0x24cb,
+/* 1542 - */ 0,
+/* 1543 - */ 0,
+/* 1544 - */ 0,
+/* 1545 - _V_66_0F_72_06 */ 0x4174,
+/* 1546 - */ 0,
+/* 1547 - */ 0,
+/* 1548 - */ 0,
+/* 1549 - */ 0,
+/* 154a - */ 0,
+/* 154b - */ 0,
+/* 154c - _0F_73_02 */ 0x24cc,
+/* 154d - _66_0F_73_02 */ 0x24cd,
+/* 154e - */ 0,
+/* 154f - */ 0,
+/* 1550 - */ 0,
+/* 1551 - _V_66_0F_73_02 */ 0x4175,
+/* 1552 - */ 0,
+/* 1553 - */ 0,
+/* 1554 - */ 0,
+/* 1555 - */ 0,
+/* 1556 - */ 0,
+/* 1557 - */ 0,
+/* 1558 - */ 0,
+/* 1559 - _66_0F_73_03 */ 0x24ce,
+/* 155a - */ 0,
+/* 155b - */ 0,
+/* 155c - */ 0,
+/* 155d - _V_66_0F_73_03 */ 0x4176,
+/* 155e - */ 0,
+/* 155f - */ 0,
+/* 1560 - */ 0,
+/* 1561 - */ 0,
+/* 1562 - */ 0,
+/* 1563 - */ 0,
+/* 1564 - _0F_73_06 */ 0x24cf,
+/* 1565 - _66_0F_73_06 */ 0x24d0,
+/* 1566 - */ 0,
+/* 1567 - */ 0,
+/* 1568 - */ 0,
+/* 1569 - _V_66_0F_73_06 */ 0x4177,
+/* 156a - */ 0,
+/* 156b - */ 0,
+/* 156c - */ 0,
+/* 156d - */ 0,
+/* 156e - */ 0,
+/* 156f - */ 0,
+/* 1570 - */ 0,
+/* 1571 - _66_0F_73_07 */ 0x24d1,
+/* 1572 - */ 0,
+/* 1573 - */ 0,
+/* 1574 - */ 0,
+/* 1575 - _V_66_0F_73_07 */ 0x4178,
+/* 1576 - */ 0,
+/* 1577 - */ 0,
+/* 1578 - */ 0,
+/* 1579 - */ 0,
+/* 157a - */ 0,
+/* 157b - */ 0,
+/* 157c - _0F_AE_00 */ 0x4179,
+/* 157d - */ 0,
+/* 157e - _F3_0F_AE_00 */ 0x24d2,
+/* 157f - */ 0,
+/* 1580 - */ 0,
+/* 1581 - */ 0,
+/* 1582 - */ 0,
+/* 1583 - */ 0,
+/* 1584 - */ 0,
+/* 1585 - */ 0,
+/* 1586 - */ 0,
+/* 1587 - */ 0,
+/* 1588 - _0F_AE_01 */ 0x417a,
+/* 1589 - */ 0,
+/* 158a - _F3_0F_AE_01 */ 0x24d3,
+/* 158b - */ 0,
+/* 158c - */ 0,
+/* 158d - */ 0,
+/* 158e - */ 0,
+/* 158f - */ 0,
+/* 1590 - */ 0,
+/* 1591 - */ 0,
+/* 1592 - */ 0,
+/* 1593 - */ 0,
+/* 1594 - _0F_AE_02 */ 0x24d4,
+/* 1595 - */ 0,
+/* 1596 - _F3_0F_AE_02 */ 0x24d5,
+/* 1597 - */ 0,
+/* 1598 - _V_0F_AE_02 */ 0x417b,
+/* 1599 - */ 0,
+/* 159a - */ 0,
+/* 159b - */ 0,
+/* 159c - */ 0,
+/* 159d - */ 0,
+/* 159e - */ 0,
+/* 159f - */ 0,
+/* 15a0 - _0F_AE_03 */ 0x24d6,
+/* 15a1 - */ 0,
+/* 15a2 - _F3_0F_AE_03 */ 0x24d7,
+/* 15a3 - */ 0,
+/* 15a4 - _V_0F_AE_03 */ 0x417c,
+/* 15a5 - */ 0,
+/* 15a6 - */ 0,
+/* 15a7 - */ 0,
+/* 15a8 - */ 0,
+/* 15a9 - */ 0,
+/* 15aa - */ 0,
+/* 15ab - */ 0,
+/* 15ac - _0F_C7_06 */ 0x417d,
+/* 15ad - _66_0F_C7_06 */ 0x24d8,
+/* 15ae - _F3_0F_C7_06 */ 0x24d9,
+/* 15af - */ 0,
+/* 15b0 - */ 0,
+/* 15b1 - */ 0,
+/* 15b2 - */ 0,
+/* 15b3 - */ 0,
+/* 15b4 - */ 0,
+/* 15b5 - */ 0,
+/* 15b6 - */ 0,
+/* 15b7 - */ 0
+};
+
+uint16_t CmpMnemonicOffsets[8] = {
+0, 9, 18, 27, 39, 49, 59, 69
+};
+uint16_t VCmpMnemonicOffsets[32] = {
+0, 10, 20, 30, 43, 54, 65, 76, 87, 100, 111, 122, 135, 149, 159, 169, 181,
+194, 207, 220, 235, 249, 263, 277, 290, 303, 317, 331, 347, 361, 374, 387
+};
diff --git a/distorm3.2-package/src/insts.h b/distorm3.2-package/src/insts.h
new file mode 100644
index 0000000..0cdf2ef
--- /dev/null
+++ b/distorm3.2-package/src/insts.h
@@ -0,0 +1,47 @@
+/*
+insts.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef INSTS_H
+#define INSTS_H
+
+#include "instructions.h"
+
+
+/* Flags Table */
+extern _iflags FlagsTable[];
+
+/* Root Trie DB */
+extern _InstInfo InstInfos[];
+extern _InstInfoEx InstInfosEx[];
+extern _InstNode InstructionsTree[];
+
+/* 3DNow! Trie DB */
+extern _InstNode Table_0F_0F;
+/* AVX related: */
+extern _InstNode Table_0F, Table_0F_38, Table_0F_3A;
+
+/* Helper tables for pesudo compare mnemonics. */
+extern uint16_t CmpMnemonicOffsets[8]; /* SSE */
+extern uint16_t VCmpMnemonicOffsets[32]; /* AVX */
+
+#endif /* INSTS_H */
diff --git a/distorm3.2-package/src/mnemonics.c b/distorm3.2-package/src/mnemonics.c
new file mode 100644
index 0000000..0c39a21
--- /dev/null
+++ b/distorm3.2-package/src/mnemonics.c
@@ -0,0 +1,294 @@
+/*
+mnemonics.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "../include/mnemonics.h"
+
+#ifndef DISTORM_LIGHT
+
+const unsigned char _MNEMONICS[] =
+"\x09" "UNDEFINED\0" "\x03" "ADD\0" "\x04" "PUSH\0" "\x03" "POP\0" "\x02" "OR\0" \
+"\x03" "ADC\0" "\x03" "SBB\0" "\x03" "AND\0" "\x03" "DAA\0" "\x03" "SUB\0" \
+"\x03" "DAS\0" "\x03" "XOR\0" "\x03" "AAA\0" "\x03" "CMP\0" "\x03" "AAS\0" \
+"\x03" "INC\0" "\x03" "DEC\0" "\x05" "PUSHA\0" "\x04" "POPA\0" "\x05" "BOUND\0" \
+"\x04" "ARPL\0" "\x04" "IMUL\0" "\x03" "INS\0" "\x04" "OUTS\0" "\x02" "JO\0" \
+"\x03" "JNO\0" "\x02" "JB\0" "\x03" "JAE\0" "\x02" "JZ\0" "\x03" "JNZ\0" "\x03" "JBE\0" \
+"\x02" "JA\0" "\x02" "JS\0" "\x03" "JNS\0" "\x02" "JP\0" "\x03" "JNP\0" "\x02" "JL\0" \
+"\x03" "JGE\0" "\x03" "JLE\0" "\x02" "JG\0" "\x04" "TEST\0" "\x04" "XCHG\0" \
+"\x03" "MOV\0" "\x03" "LEA\0" "\x03" "CBW\0" "\x04" "CWDE\0" "\x04" "CDQE\0" \
+"\x03" "CWD\0" "\x03" "CDQ\0" "\x03" "CQO\0" "\x08" "CALL FAR\0" "\x05" "PUSHF\0" \
+"\x04" "POPF\0" "\x04" "SAHF\0" "\x04" "LAHF\0" "\x04" "MOVS\0" "\x04" "CMPS\0" \
+"\x04" "STOS\0" "\x04" "LODS\0" "\x04" "SCAS\0" "\x03" "RET\0" "\x03" "LES\0" \
+"\x03" "LDS\0" "\x05" "ENTER\0" "\x05" "LEAVE\0" "\x04" "RETF\0" "\x05" "INT 3\0" \
+"\x03" "INT\0" "\x04" "INTO\0" "\x04" "IRET\0" "\x03" "AAM\0" "\x03" "AAD\0" \
+"\x04" "SALC\0" "\x04" "XLAT\0" "\x06" "LOOPNZ\0" "\x05" "LOOPZ\0" "\x04" "LOOP\0" \
+"\x04" "JCXZ\0" "\x05" "JECXZ\0" "\x05" "JRCXZ\0" "\x02" "IN\0" "\x03" "OUT\0" \
+"\x04" "CALL\0" "\x03" "JMP\0" "\x07" "JMP FAR\0" "\x04" "INT1\0" "\x03" "HLT\0" \
+"\x03" "CMC\0" "\x03" "CLC\0" "\x03" "STC\0" "\x03" "CLI\0" "\x03" "STI\0" \
+"\x03" "CLD\0" "\x03" "STD\0" "\x03" "LAR\0" "\x03" "LSL\0" "\x07" "SYSCALL\0" \
+"\x04" "CLTS\0" "\x06" "SYSRET\0" "\x04" "INVD\0" "\x06" "WBINVD\0" "\x03" "UD2\0" \
+"\x05" "FEMMS\0" "\x03" "NOP\0" "\x05" "WRMSR\0" "\x05" "RDTSC\0" "\x05" "RDMSR\0" \
+"\x05" "RDPMC\0" "\x08" "SYSENTER\0" "\x07" "SYSEXIT\0" "\x06" "GETSEC\0" "\x05" "CMOVO\0" \
+"\x06" "CMOVNO\0" "\x05" "CMOVB\0" "\x06" "CMOVAE\0" "\x05" "CMOVZ\0" "\x06" "CMOVNZ\0" \
+"\x06" "CMOVBE\0" "\x05" "CMOVA\0" "\x05" "CMOVS\0" "\x06" "CMOVNS\0" "\x05" "CMOVP\0" \
+"\x06" "CMOVNP\0" "\x05" "CMOVL\0" "\x06" "CMOVGE\0" "\x06" "CMOVLE\0" "\x05" "CMOVG\0" \
+"\x04" "SETO\0" "\x05" "SETNO\0" "\x04" "SETB\0" "\x05" "SETAE\0" "\x04" "SETZ\0" \
+"\x05" "SETNZ\0" "\x05" "SETBE\0" "\x04" "SETA\0" "\x04" "SETS\0" "\x05" "SETNS\0" \
+"\x04" "SETP\0" "\x05" "SETNP\0" "\x04" "SETL\0" "\x05" "SETGE\0" "\x05" "SETLE\0" \
+"\x04" "SETG\0" "\x05" "CPUID\0" "\x02" "BT\0" "\x04" "SHLD\0" "\x03" "RSM\0" \
+"\x03" "BTS\0" "\x04" "SHRD\0" "\x07" "CMPXCHG\0" "\x03" "LSS\0" "\x03" "BTR\0" \
+"\x03" "LFS\0" "\x03" "LGS\0" "\x05" "MOVZX\0" "\x03" "BTC\0" "\x05" "MOVSX\0" \
+"\x04" "XADD\0" "\x06" "MOVNTI\0" "\x05" "BSWAP\0" "\x03" "ROL\0" "\x03" "ROR\0" \
+"\x03" "RCL\0" "\x03" "RCR\0" "\x03" "SHL\0" "\x03" "SHR\0" "\x03" "SAL\0" \
+"\x03" "SAR\0" "\x04" "FADD\0" "\x04" "FMUL\0" "\x04" "FCOM\0" "\x05" "FCOMP\0" \
+"\x04" "FSUB\0" "\x05" "FSUBR\0" "\x04" "FDIV\0" "\x05" "FDIVR\0" "\x03" "FLD\0" \
+"\x03" "FST\0" "\x04" "FSTP\0" "\x06" "FLDENV\0" "\x05" "FLDCW\0" "\x04" "FXCH\0" \
+"\x04" "FNOP\0" "\x04" "FCHS\0" "\x04" "FABS\0" "\x04" "FTST\0" "\x04" "FXAM\0" \
+"\x04" "FLD1\0" "\x06" "FLDL2T\0" "\x06" "FLDL2E\0" "\x05" "FLDPI\0" "\x06" "FLDLG2\0" \
+"\x06" "FLDLN2\0" "\x04" "FLDZ\0" "\x05" "F2XM1\0" "\x05" "FYL2X\0" "\x05" "FPTAN\0" \
+"\x06" "FPATAN\0" "\x07" "FXTRACT\0" "\x06" "FPREM1\0" "\x07" "FDECSTP\0" "\x07" "FINCSTP\0" \
+"\x05" "FPREM\0" "\x07" "FYL2XP1\0" "\x05" "FSQRT\0" "\x07" "FSINCOS\0" "\x07" "FRNDINT\0" \
+"\x06" "FSCALE\0" "\x04" "FSIN\0" "\x04" "FCOS\0" "\x05" "FIADD\0" "\x05" "FIMUL\0" \
+"\x05" "FICOM\0" "\x06" "FICOMP\0" "\x05" "FISUB\0" "\x06" "FISUBR\0" "\x05" "FIDIV\0" \
+"\x06" "FIDIVR\0" "\x06" "FCMOVB\0" "\x06" "FCMOVE\0" "\x07" "FCMOVBE\0" "\x06" "FCMOVU\0" \
+"\x07" "FUCOMPP\0" "\x04" "FILD\0" "\x06" "FISTTP\0" "\x04" "FIST\0" "\x05" "FISTP\0" \
+"\x07" "FCMOVNB\0" "\x07" "FCMOVNE\0" "\x08" "FCMOVNBE\0" "\x07" "FCMOVNU\0" \
+"\x04" "FENI\0" "\x06" "FEDISI\0" "\x06" "FSETPM\0" "\x06" "FUCOMI\0" "\x05" "FCOMI\0" \
+"\x06" "FRSTOR\0" "\x05" "FFREE\0" "\x05" "FUCOM\0" "\x06" "FUCOMP\0" "\x05" "FADDP\0" \
+"\x05" "FMULP\0" "\x06" "FCOMPP\0" "\x06" "FSUBRP\0" "\x05" "FSUBP\0" "\x06" "FDIVRP\0" \
+"\x05" "FDIVP\0" "\x04" "FBLD\0" "\x05" "FBSTP\0" "\x07" "FUCOMIP\0" "\x06" "FCOMIP\0" \
+"\x03" "NOT\0" "\x03" "NEG\0" "\x03" "MUL\0" "\x03" "DIV\0" "\x04" "IDIV\0" \
+"\x04" "SLDT\0" "\x03" "STR\0" "\x04" "LLDT\0" "\x03" "LTR\0" "\x04" "VERR\0" \
+"\x04" "VERW\0" "\x04" "SGDT\0" "\x04" "SIDT\0" "\x04" "LGDT\0" "\x04" "LIDT\0" \
+"\x04" "SMSW\0" "\x04" "LMSW\0" "\x06" "INVLPG\0" "\x06" "VMCALL\0" "\x08" "VMLAUNCH\0" \
+"\x08" "VMRESUME\0" "\x06" "VMXOFF\0" "\x07" "MONITOR\0" "\x05" "MWAIT\0" "\x06" "XGETBV\0" \
+"\x06" "XSETBV\0" "\x06" "VMFUNC\0" "\x05" "VMRUN\0" "\x07" "VMMCALL\0" "\x06" "VMLOAD\0" \
+"\x06" "VMSAVE\0" "\x04" "STGI\0" "\x04" "CLGI\0" "\x06" "SKINIT\0" "\x07" "INVLPGA\0" \
+"\x06" "SWAPGS\0" "\x06" "RDTSCP\0" "\x08" "PREFETCH\0" "\x09" "PREFETCHW\0" \
+"\x05" "PI2FW\0" "\x05" "PI2FD\0" "\x05" "PF2IW\0" "\x05" "PF2ID\0" "\x06" "PFNACC\0" \
+"\x07" "PFPNACC\0" "\x07" "PFCMPGE\0" "\x05" "PFMIN\0" "\x05" "PFRCP\0" "\x07" "PFRSQRT\0" \
+"\x05" "PFSUB\0" "\x05" "PFADD\0" "\x07" "PFCMPGT\0" "\x05" "PFMAX\0" "\x08" "PFRCPIT1\0" \
+"\x08" "PFRSQIT1\0" "\x06" "PFSUBR\0" "\x05" "PFACC\0" "\x07" "PFCMPEQ\0" "\x05" "PFMUL\0" \
+"\x08" "PFRCPIT2\0" "\x07" "PMULHRW\0" "\x06" "PSWAPD\0" "\x07" "PAVGUSB\0" \
+"\x06" "MOVUPS\0" "\x06" "MOVUPD\0" "\x05" "MOVSS\0" "\x05" "MOVSD\0" "\x07" "VMOVUPS\0" \
+"\x07" "VMOVUPD\0" "\x06" "VMOVSS\0" "\x06" "VMOVSD\0" "\x07" "MOVHLPS\0" "\x06" "MOVLPS\0" \
+"\x06" "MOVLPD\0" "\x08" "MOVSLDUP\0" "\x07" "MOVDDUP\0" "\x08" "VMOVHLPS\0" \
+"\x07" "VMOVLPS\0" "\x07" "VMOVLPD\0" "\x09" "VMOVSLDUP\0" "\x08" "VMOVDDUP\0" \
+"\x08" "UNPCKLPS\0" "\x08" "UNPCKLPD\0" "\x09" "VUNPCKLPS\0" "\x09" "VUNPCKLPD\0" \
+"\x08" "UNPCKHPS\0" "\x08" "UNPCKHPD\0" "\x09" "VUNPCKHPS\0" "\x09" "VUNPCKHPD\0" \
+"\x07" "MOVLHPS\0" "\x06" "MOVHPS\0" "\x06" "MOVHPD\0" "\x08" "MOVSHDUP\0" \
+"\x08" "VMOVLHPS\0" "\x07" "VMOVHPS\0" "\x07" "VMOVHPD\0" "\x09" "VMOVSHDUP\0" \
+"\x0b" "PREFETCHNTA\0" "\x0a" "PREFETCHT0\0" "\x0a" "PREFETCHT1\0" "\x0a" "PREFETCHT2\0" \
+"\x06" "MOVAPS\0" "\x06" "MOVAPD\0" "\x07" "VMOVAPS\0" "\x07" "VMOVAPD\0" "\x08" "CVTPI2PS\0" \
+"\x08" "CVTPI2PD\0" "\x08" "CVTSI2SS\0" "\x08" "CVTSI2SD\0" "\x09" "VCVTSI2SS\0" \
+"\x09" "VCVTSI2SD\0" "\x07" "MOVNTPS\0" "\x07" "MOVNTPD\0" "\x07" "MOVNTSS\0" \
+"\x07" "MOVNTSD\0" "\x08" "VMOVNTPS\0" "\x08" "VMOVNTPD\0" "\x09" "CVTTPS2PI\0" \
+"\x09" "CVTTPD2PI\0" "\x09" "CVTTSS2SI\0" "\x09" "CVTTSD2SI\0" "\x0a" "VCVTTSS2SI\0" \
+"\x0a" "VCVTTSD2SI\0" "\x08" "CVTPS2PI\0" "\x08" "CVTPD2PI\0" "\x08" "CVTSS2SI\0" \
+"\x08" "CVTSD2SI\0" "\x09" "VCVTSS2SI\0" "\x09" "VCVTSD2SI\0" "\x07" "UCOMISS\0" \
+"\x07" "UCOMISD\0" "\x08" "VUCOMISS\0" "\x08" "VUCOMISD\0" "\x06" "COMISS\0" \
+"\x06" "COMISD\0" "\x07" "VCOMISS\0" "\x07" "VCOMISD\0" "\x08" "MOVMSKPS\0" \
+"\x08" "MOVMSKPD\0" "\x09" "VMOVMSKPS\0" "\x09" "VMOVMSKPD\0" "\x06" "SQRTPS\0" \
+"\x06" "SQRTPD\0" "\x06" "SQRTSS\0" "\x06" "SQRTSD\0" "\x07" "VSQRTPS\0" "\x07" "VSQRTPD\0" \
+"\x07" "VSQRTSS\0" "\x07" "VSQRTSD\0" "\x07" "RSQRTPS\0" "\x07" "RSQRTSS\0" \
+"\x08" "VRSQRTPS\0" "\x08" "VRSQRTSS\0" "\x05" "RCPPS\0" "\x05" "RCPSS\0" "\x06" "VRCPPS\0" \
+"\x06" "VRCPSS\0" "\x05" "ANDPS\0" "\x05" "ANDPD\0" "\x06" "VANDPS\0" "\x06" "VANDPD\0" \
+"\x06" "ANDNPS\0" "\x06" "ANDNPD\0" "\x07" "VANDNPS\0" "\x07" "VANDNPD\0" "\x04" "ORPS\0" \
+"\x04" "ORPD\0" "\x05" "VORPS\0" "\x05" "VORPD\0" "\x05" "XORPS\0" "\x05" "XORPD\0" \
+"\x06" "VXORPS\0" "\x06" "VXORPD\0" "\x05" "ADDPS\0" "\x05" "ADDPD\0" "\x05" "ADDSS\0" \
+"\x05" "ADDSD\0" "\x06" "VADDPS\0" "\x06" "VADDPD\0" "\x06" "VADDSS\0" "\x06" "VADDSD\0" \
+"\x05" "MULPS\0" "\x05" "MULPD\0" "\x05" "MULSS\0" "\x05" "MULSD\0" "\x06" "VMULPS\0" \
+"\x06" "VMULPD\0" "\x06" "VMULSS\0" "\x06" "VMULSD\0" "\x08" "CVTPS2PD\0" "\x08" "CVTPD2PS\0" \
+"\x08" "CVTSS2SD\0" "\x08" "CVTSD2SS\0" "\x09" "VCVTPS2PD\0" "\x09" "VCVTPD2PS\0" \
+"\x09" "VCVTSS2SD\0" "\x09" "VCVTSD2SS\0" "\x08" "CVTDQ2PS\0" "\x08" "CVTPS2DQ\0" \
+"\x09" "CVTTPS2DQ\0" "\x09" "VCVTDQ2PS\0" "\x09" "VCVTPS2DQ\0" "\x0a" "VCVTTPS2DQ\0" \
+"\x05" "SUBPS\0" "\x05" "SUBPD\0" "\x05" "SUBSS\0" "\x05" "SUBSD\0" "\x06" "VSUBPS\0" \
+"\x06" "VSUBPD\0" "\x06" "VSUBSS\0" "\x06" "VSUBSD\0" "\x05" "MINPS\0" "\x05" "MINPD\0" \
+"\x05" "MINSS\0" "\x05" "MINSD\0" "\x06" "VMINPS\0" "\x06" "VMINPD\0" "\x06" "VMINSS\0" \
+"\x06" "VMINSD\0" "\x05" "DIVPS\0" "\x05" "DIVPD\0" "\x05" "DIVSS\0" "\x05" "DIVSD\0" \
+"\x06" "VDIVPS\0" "\x06" "VDIVPD\0" "\x06" "VDIVSS\0" "\x06" "VDIVSD\0" "\x05" "MAXPS\0" \
+"\x05" "MAXPD\0" "\x05" "MAXSS\0" "\x05" "MAXSD\0" "\x06" "VMAXPS\0" "\x06" "VMAXPD\0" \
+"\x06" "VMAXSS\0" "\x06" "VMAXSD\0" "\x09" "PUNPCKLBW\0" "\x0a" "VPUNPCKLBW\0" \
+"\x09" "PUNPCKLWD\0" "\x0a" "VPUNPCKLWD\0" "\x09" "PUNPCKLDQ\0" "\x0a" "VPUNPCKLDQ\0" \
+"\x08" "PACKSSWB\0" "\x09" "VPACKSSWB\0" "\x07" "PCMPGTB\0" "\x08" "VPCMPGTB\0" \
+"\x07" "PCMPGTW\0" "\x08" "VPCMPGTW\0" "\x07" "PCMPGTD\0" "\x08" "VPCMPGTD\0" \
+"\x08" "PACKUSWB\0" "\x09" "VPACKUSWB\0" "\x09" "PUNPCKHBW\0" "\x0a" "VPUNPCKHBW\0" \
+"\x09" "PUNPCKHWD\0" "\x0a" "VPUNPCKHWD\0" "\x09" "PUNPCKHDQ\0" "\x0a" "VPUNPCKHDQ\0" \
+"\x08" "PACKSSDW\0" "\x09" "VPACKSSDW\0" "\x0a" "PUNPCKLQDQ\0" "\x0b" "VPUNPCKLQDQ\0" \
+"\x0a" "PUNPCKHQDQ\0" "\x0b" "VPUNPCKHQDQ\0" "\x04" "MOVD\0" "\x04" "MOVQ\0" \
+"\x05" "VMOVD\0" "\x05" "VMOVQ\0" "\x06" "MOVDQA\0" "\x06" "MOVDQU\0" "\x07" "VMOVDQA\0" \
+"\x07" "VMOVDQU\0" "\x06" "PSHUFW\0" "\x06" "PSHUFD\0" "\x07" "PSHUFHW\0" "\x07" "PSHUFLW\0" \
+"\x07" "VPSHUFD\0" "\x08" "VPSHUFHW\0" "\x08" "VPSHUFLW\0" "\x07" "PCMPEQB\0" \
+"\x08" "VPCMPEQB\0" "\x07" "PCMPEQW\0" "\x08" "VPCMPEQW\0" "\x07" "PCMPEQD\0" \
+"\x08" "VPCMPEQD\0" "\x04" "EMMS\0" "\x0a" "VZEROUPPER\0" "\x08" "VZEROALL\0" \
+"\x06" "VMREAD\0" "\x05" "EXTRQ\0" "\x07" "INSERTQ\0" "\x07" "VMWRITE\0" "\x08" "CVTPH2PS\0" \
+"\x08" "CVTPS2PH\0" "\x06" "HADDPD\0" "\x06" "HADDPS\0" "\x07" "VHADDPD\0" \
+"\x07" "VHADDPS\0" "\x06" "HSUBPD\0" "\x06" "HSUBPS\0" "\x07" "VHSUBPD\0" "\x07" "VHSUBPS\0" \
+"\x05" "XSAVE\0" "\x07" "XSAVE64\0" "\x06" "LFENCE\0" "\x06" "XRSTOR\0" "\x08" "XRSTOR64\0" \
+"\x06" "MFENCE\0" "\x08" "XSAVEOPT\0" "\x0a" "XSAVEOPT64\0" "\x06" "SFENCE\0" \
+"\x07" "CLFLUSH\0" "\x06" "POPCNT\0" "\x03" "BSF\0" "\x05" "TZCNT\0" "\x03" "BSR\0" \
+"\x05" "LZCNT\0" "\x07" "CMPEQPS\0" "\x07" "CMPLTPS\0" "\x07" "CMPLEPS\0" "\x0a" "CMPUNORDPS\0" \
+"\x08" "CMPNEQPS\0" "\x08" "CMPNLTPS\0" "\x08" "CMPNLEPS\0" "\x08" "CMPORDPS\0" \
+"\x07" "CMPEQPD\0" "\x07" "CMPLTPD\0" "\x07" "CMPLEPD\0" "\x0a" "CMPUNORDPD\0" \
+"\x08" "CMPNEQPD\0" "\x08" "CMPNLTPD\0" "\x08" "CMPNLEPD\0" "\x08" "CMPORDPD\0" \
+"\x07" "CMPEQSS\0" "\x07" "CMPLTSS\0" "\x07" "CMPLESS\0" "\x0a" "CMPUNORDSS\0" \
+"\x08" "CMPNEQSS\0" "\x08" "CMPNLTSS\0" "\x08" "CMPNLESS\0" "\x08" "CMPORDSS\0" \
+"\x07" "CMPEQSD\0" "\x07" "CMPLTSD\0" "\x07" "CMPLESD\0" "\x0a" "CMPUNORDSD\0" \
+"\x08" "CMPNEQSD\0" "\x08" "CMPNLTSD\0" "\x08" "CMPNLESD\0" "\x08" "CMPORDSD\0" \
+"\x08" "VCMPEQPS\0" "\x08" "VCMPLTPS\0" "\x08" "VCMPLEPS\0" "\x0b" "VCMPUNORDPS\0" \
+"\x09" "VCMPNEQPS\0" "\x09" "VCMPNLTPS\0" "\x09" "VCMPNLEPS\0" "\x09" "VCMPORDPS\0" \
+"\x0b" "VCMPEQ_UQPS\0" "\x09" "VCMPNGEPS\0" "\x09" "VCMPNGTPS\0" "\x0b" "VCMPFALSEPS\0" \
+"\x0c" "VCMPNEQ_OQPS\0" "\x08" "VCMPGEPS\0" "\x08" "VCMPGTPS\0" "\x0a" "VCMPTRUEPS\0" \
+"\x0b" "VCMPEQ_OSPS\0" "\x0b" "VCMPLT_OQPS\0" "\x0b" "VCMPLE_OQPS\0" "\x0d" "VCMPUNORD_SPS\0" \
+"\x0c" "VCMPNEQ_USPS\0" "\x0c" "VCMPNLT_UQPS\0" "\x0c" "VCMPNLE_UQPS\0" "\x0b" "VCMPORD_SPS\0" \
+"\x0b" "VCMPEQ_USPS\0" "\x0c" "VCMPNGE_UQPS\0" "\x0c" "VCMPNGT_UQPS\0" "\x0e" "VCMPFALSE_OSPS\0" \
+"\x0c" "VCMPNEQ_OSPS\0" "\x0b" "VCMPGE_OQPS\0" "\x0b" "VCMPGT_OQPS\0" "\x0d" "VCMPTRUE_USPS\0" \
+"\x08" "VCMPEQPD\0" "\x08" "VCMPLTPD\0" "\x08" "VCMPLEPD\0" "\x0b" "VCMPUNORDPD\0" \
+"\x09" "VCMPNEQPD\0" "\x09" "VCMPNLTPD\0" "\x09" "VCMPNLEPD\0" "\x09" "VCMPORDPD\0" \
+"\x0b" "VCMPEQ_UQPD\0" "\x09" "VCMPNGEPD\0" "\x09" "VCMPNGTPD\0" "\x0b" "VCMPFALSEPD\0" \
+"\x0c" "VCMPNEQ_OQPD\0" "\x08" "VCMPGEPD\0" "\x08" "VCMPGTPD\0" "\x0a" "VCMPTRUEPD\0" \
+"\x0b" "VCMPEQ_OSPD\0" "\x0b" "VCMPLT_OQPD\0" "\x0b" "VCMPLE_OQPD\0" "\x0d" "VCMPUNORD_SPD\0" \
+"\x0c" "VCMPNEQ_USPD\0" "\x0c" "VCMPNLT_UQPD\0" "\x0c" "VCMPNLE_UQPD\0" "\x0b" "VCMPORD_SPD\0" \
+"\x0b" "VCMPEQ_USPD\0" "\x0c" "VCMPNGE_UQPD\0" "\x0c" "VCMPNGT_UQPD\0" "\x0e" "VCMPFALSE_OSPD\0" \
+"\x0c" "VCMPNEQ_OSPD\0" "\x0b" "VCMPGE_OQPD\0" "\x0b" "VCMPGT_OQPD\0" "\x0d" "VCMPTRUE_USPD\0" \
+"\x08" "VCMPEQSS\0" "\x08" "VCMPLTSS\0" "\x08" "VCMPLESS\0" "\x0b" "VCMPUNORDSS\0" \
+"\x09" "VCMPNEQSS\0" "\x09" "VCMPNLTSS\0" "\x09" "VCMPNLESS\0" "\x09" "VCMPORDSS\0" \
+"\x0b" "VCMPEQ_UQSS\0" "\x09" "VCMPNGESS\0" "\x09" "VCMPNGTSS\0" "\x0b" "VCMPFALSESS\0" \
+"\x0c" "VCMPNEQ_OQSS\0" "\x08" "VCMPGESS\0" "\x08" "VCMPGTSS\0" "\x0a" "VCMPTRUESS\0" \
+"\x0b" "VCMPEQ_OSSS\0" "\x0b" "VCMPLT_OQSS\0" "\x0b" "VCMPLE_OQSS\0" "\x0d" "VCMPUNORD_SSS\0" \
+"\x0c" "VCMPNEQ_USSS\0" "\x0c" "VCMPNLT_UQSS\0" "\x0c" "VCMPNLE_UQSS\0" "\x0b" "VCMPORD_SSS\0" \
+"\x0b" "VCMPEQ_USSS\0" "\x0c" "VCMPNGE_UQSS\0" "\x0c" "VCMPNGT_UQSS\0" "\x0e" "VCMPFALSE_OSSS\0" \
+"\x0c" "VCMPNEQ_OSSS\0" "\x0b" "VCMPGE_OQSS\0" "\x0b" "VCMPGT_OQSS\0" "\x0d" "VCMPTRUE_USSS\0" \
+"\x08" "VCMPEQSD\0" "\x08" "VCMPLTSD\0" "\x08" "VCMPLESD\0" "\x0b" "VCMPUNORDSD\0" \
+"\x09" "VCMPNEQSD\0" "\x09" "VCMPNLTSD\0" "\x09" "VCMPNLESD\0" "\x09" "VCMPORDSD\0" \
+"\x0b" "VCMPEQ_UQSD\0" "\x09" "VCMPNGESD\0" "\x09" "VCMPNGTSD\0" "\x0b" "VCMPFALSESD\0" \
+"\x0c" "VCMPNEQ_OQSD\0" "\x08" "VCMPGESD\0" "\x08" "VCMPGTSD\0" "\x0a" "VCMPTRUESD\0" \
+"\x0b" "VCMPEQ_OSSD\0" "\x0b" "VCMPLT_OQSD\0" "\x0b" "VCMPLE_OQSD\0" "\x0d" "VCMPUNORD_SSD\0" \
+"\x0c" "VCMPNEQ_USSD\0" "\x0c" "VCMPNLT_UQSD\0" "\x0c" "VCMPNLE_UQSD\0" "\x0b" "VCMPORD_SSD\0" \
+"\x0b" "VCMPEQ_USSD\0" "\x0c" "VCMPNGE_UQSD\0" "\x0c" "VCMPNGT_UQSD\0" "\x0e" "VCMPFALSE_OSSD\0" \
+"\x0c" "VCMPNEQ_OSSD\0" "\x0b" "VCMPGE_OQSD\0" "\x0b" "VCMPGT_OQSD\0" "\x0d" "VCMPTRUE_USSD\0" \
+"\x06" "PINSRW\0" "\x07" "VPINSRW\0" "\x06" "PEXTRW\0" "\x07" "VPEXTRW\0" "\x06" "SHUFPS\0" \
+"\x06" "SHUFPD\0" "\x07" "VSHUFPS\0" "\x07" "VSHUFPD\0" "\x09" "CMPXCHG8B\0" \
+"\x0a" "CMPXCHG16B\0" "\x07" "VMPTRST\0" "\x08" "ADDSUBPD\0" "\x08" "ADDSUBPS\0" \
+"\x09" "VADDSUBPD\0" "\x09" "VADDSUBPS\0" "\x05" "PSRLW\0" "\x06" "VPSRLW\0" \
+"\x05" "PSRLD\0" "\x06" "VPSRLD\0" "\x05" "PSRLQ\0" "\x06" "VPSRLQ\0" "\x05" "PADDQ\0" \
+"\x06" "VPADDQ\0" "\x06" "PMULLW\0" "\x07" "VPMULLW\0" "\x07" "MOVQ2DQ\0" "\x07" "MOVDQ2Q\0" \
+"\x08" "PMOVMSKB\0" "\x09" "VPMOVMSKB\0" "\x07" "PSUBUSB\0" "\x08" "VPSUBUSB\0" \
+"\x07" "PSUBUSW\0" "\x08" "VPSUBUSW\0" "\x06" "PMINUB\0" "\x07" "VPMINUB\0" \
+"\x04" "PAND\0" "\x05" "VPAND\0" "\x07" "PADDUSB\0" "\x08" "VPADDUSW\0" "\x07" "PADDUSW\0" \
+"\x06" "PMAXUB\0" "\x07" "VPMAXUB\0" "\x05" "PANDN\0" "\x06" "VPANDN\0" "\x05" "PAVGB\0" \
+"\x06" "VPAVGB\0" "\x05" "PSRAW\0" "\x06" "VPSRAW\0" "\x05" "PSRAD\0" "\x06" "VPSRAD\0" \
+"\x05" "PAVGW\0" "\x06" "VPAVGW\0" "\x07" "PMULHUW\0" "\x08" "VPMULHUW\0" "\x06" "PMULHW\0" \
+"\x07" "VPMULHW\0" "\x09" "CVTTPD2DQ\0" "\x08" "CVTDQ2PD\0" "\x08" "CVTPD2DQ\0" \
+"\x0a" "VCVTTPD2DQ\0" "\x09" "VCVTDQ2PD\0" "\x09" "VCVTPD2DQ\0" "\x06" "MOVNTQ\0" \
+"\x07" "MOVNTDQ\0" "\x08" "VMOVNTDQ\0" "\x06" "PSUBSB\0" "\x07" "VPSUBSB\0" \
+"\x06" "PSUBSW\0" "\x07" "VPSUBSW\0" "\x06" "PMINSW\0" "\x07" "VPMINSW\0" "\x03" "POR\0" \
+"\x04" "VPOR\0" "\x06" "PADDSB\0" "\x07" "VPADDSB\0" "\x06" "PADDSW\0" "\x07" "VPADDSW\0" \
+"\x06" "PMAXSW\0" "\x07" "VPMAXSW\0" "\x04" "PXOR\0" "\x05" "VPXOR\0" "\x05" "LDDQU\0" \
+"\x06" "VLDDQU\0" "\x05" "PSLLW\0" "\x06" "VPSLLW\0" "\x05" "PSLLD\0" "\x06" "VPSLLD\0" \
+"\x05" "PSLLQ\0" "\x06" "VPSLLQ\0" "\x07" "PMULUDQ\0" "\x08" "VPMULUDQ\0" "\x07" "PMADDWD\0" \
+"\x08" "VPMADDWD\0" "\x06" "PSADBW\0" "\x07" "VPSADBW\0" "\x08" "MASKMOVQ\0" \
+"\x0a" "MASKMOVDQU\0" "\x0b" "VMASKMOVDQU\0" "\x05" "PSUBB\0" "\x06" "VPSUBB\0" \
+"\x05" "PSUBW\0" "\x06" "VPSUBW\0" "\x05" "PSUBD\0" "\x06" "VPSUBD\0" "\x05" "PSUBQ\0" \
+"\x06" "VPSUBQ\0" "\x05" "PADDB\0" "\x06" "VPADDB\0" "\x05" "PADDW\0" "\x06" "VPADDW\0" \
+"\x05" "PADDD\0" "\x06" "VPADDD\0" "\x07" "FNSTENV\0" "\x06" "FSTENV\0" "\x06" "FNSTCW\0" \
+"\x05" "FSTCW\0" "\x06" "FNCLEX\0" "\x05" "FCLEX\0" "\x06" "FNINIT\0" "\x05" "FINIT\0" \
+"\x06" "FNSAVE\0" "\x05" "FSAVE\0" "\x06" "FNSTSW\0" "\x05" "FSTSW\0" "\x06" "PSHUFB\0" \
+"\x07" "VPSHUFB\0" "\x06" "PHADDW\0" "\x07" "VPHADDW\0" "\x06" "PHADDD\0" "\x07" "VPHADDD\0" \
+"\x07" "PHADDSW\0" "\x08" "VPHADDSW\0" "\x09" "PMADDUBSW\0" "\x0a" "VPMADDUBSW\0" \
+"\x06" "PHSUBW\0" "\x07" "VPHSUBW\0" "\x06" "PHSUBD\0" "\x07" "VPHSUBD\0" "\x07" "PHSUBSW\0" \
+"\x08" "VPHSUBSW\0" "\x06" "PSIGNB\0" "\x07" "VPSIGNB\0" "\x06" "PSIGNW\0" \
+"\x07" "VPSIGNW\0" "\x06" "PSIGND\0" "\x07" "VPSIGND\0" "\x08" "PMULHRSW\0" \
+"\x09" "VPMULHRSW\0" "\x09" "VPERMILPS\0" "\x09" "VPERMILPD\0" "\x07" "VTESTPS\0" \
+"\x07" "VTESTPD\0" "\x08" "PBLENDVB\0" "\x08" "BLENDVPS\0" "\x08" "BLENDVPD\0" \
+"\x05" "PTEST\0" "\x06" "VPTEST\0" "\x0c" "VBROADCASTSS\0" "\x0c" "VBROADCASTSD\0" \
+"\x0e" "VBROADCASTF128\0" "\x05" "PABSB\0" "\x06" "VPABSB\0" "\x05" "PABSW\0" \
+"\x06" "VPABSW\0" "\x05" "PABSD\0" "\x06" "VPABSD\0" "\x08" "PMOVSXBW\0" "\x09" "VPMOVSXBW\0" \
+"\x08" "PMOVSXBD\0" "\x09" "VPMOVSXBD\0" "\x08" "PMOVSXBQ\0" "\x09" "VPMOVSXBQ\0" \
+"\x08" "PMOVSXWD\0" "\x09" "VPMOVSXWD\0" "\x08" "PMOVSXWQ\0" "\x09" "VPMOVSXWQ\0" \
+"\x08" "PMOVSXDQ\0" "\x09" "VPMOVSXDQ\0" "\x06" "PMULDQ\0" "\x07" "VPMULDQ\0" \
+"\x07" "PCMPEQQ\0" "\x08" "VPCMPEQQ\0" "\x08" "MOVNTDQA\0" "\x09" "VMOVNTDQA\0" \
+"\x08" "PACKUSDW\0" "\x09" "VPACKUSDW\0" "\x0a" "VMASKMOVPS\0" "\x0a" "VMASKMOVPD\0" \
+"\x08" "PMOVZXBW\0" "\x09" "VPMOVZXBW\0" "\x08" "PMOVZXBD\0" "\x09" "VPMOVZXBD\0" \
+"\x08" "PMOVZXBQ\0" "\x09" "VPMOVZXBQ\0" "\x08" "PMOVZXWD\0" "\x09" "VPMOVZXWD\0" \
+"\x08" "PMOVZXWQ\0" "\x09" "VPMOVZXWQ\0" "\x08" "PMOVZXDQ\0" "\x09" "VPMOVZXDQ\0" \
+"\x07" "PCMPGTQ\0" "\x08" "VPCMPGTQ\0" "\x06" "PMINSB\0" "\x07" "VPMINSB\0" \
+"\x06" "PMINSD\0" "\x07" "VPMINSD\0" "\x06" "PMINUW\0" "\x07" "VPMINUW\0" "\x06" "PMINUD\0" \
+"\x07" "VPMINUD\0" "\x06" "PMAXSB\0" "\x07" "VPMAXSB\0" "\x06" "PMAXSD\0" "\x07" "VPMAXSD\0" \
+"\x06" "PMAXUW\0" "\x07" "VPMAXUW\0" "\x06" "PMAXUD\0" "\x07" "VPMAXUD\0" "\x06" "PMULLD\0" \
+"\x07" "VPMULLD\0" "\x0a" "PHMINPOSUW\0" "\x0b" "VPHMINPOSUW\0" "\x06" "INVEPT\0" \
+"\x07" "INVVPID\0" "\x07" "INVPCID\0" "\x0e" "VFMADDSUB132PS\0" "\x0e" "VFMADDSUB132PD\0" \
+"\x0e" "VFMSUBADD132PS\0" "\x0e" "VFMSUBADD132PD\0" "\x0b" "VFMADD132PS\0" \
+"\x0b" "VFMADD132PD\0" "\x0b" "VFMADD132SS\0" "\x0b" "VFMADD132SD\0" "\x0b" "VFMSUB132PS\0" \
+"\x0b" "VFMSUB132PD\0" "\x0b" "VFMSUB132SS\0" "\x0b" "VFMSUB132SD\0" "\x0c" "VFNMADD132PS\0" \
+"\x0c" "VFNMADD132PD\0" "\x0c" "VFNMADD132SS\0" "\x0c" "VFNMADD132SD\0" "\x0c" "VFNMSUB132PS\0" \
+"\x0c" "VFNMSUB132PD\0" "\x0c" "VFNMSUB132SS\0" "\x0c" "VFNMSUB132SD\0" "\x0e" "VFMADDSUB213PS\0" \
+"\x0e" "VFMADDSUB213PD\0" "\x0e" "VFMSUBADD213PS\0" "\x0e" "VFMSUBADD213PD\0" \
+"\x0b" "VFMADD213PS\0" "\x0b" "VFMADD213PD\0" "\x0b" "VFMADD213SS\0" "\x0b" "VFMADD213SD\0" \
+"\x0b" "VFMSUB213PS\0" "\x0b" "VFMSUB213PD\0" "\x0b" "VFMSUB213SS\0" "\x0b" "VFMSUB213SD\0" \
+"\x0c" "VFNMADD213PS\0" "\x0c" "VFNMADD213PD\0" "\x0c" "VFNMADD213SS\0" "\x0c" "VFNMADD213SD\0" \
+"\x0c" "VFNMSUB213PS\0" "\x0c" "VFNMSUB213PD\0" "\x0c" "VFNMSUB213SS\0" "\x0c" "VFNMSUB213SD\0" \
+"\x0e" "VFMADDSUB231PS\0" "\x0e" "VFMADDSUB231PD\0" "\x0e" "VFMSUBADD231PS\0" \
+"\x0e" "VFMSUBADD231PD\0" "\x0b" "VFMADD231PS\0" "\x0b" "VFMADD231PD\0" "\x0b" "VFMADD231SS\0" \
+"\x0b" "VFMADD231SD\0" "\x0b" "VFMSUB231PS\0" "\x0b" "VFMSUB231PD\0" "\x0b" "VFMSUB231SS\0" \
+"\x0b" "VFMSUB231SD\0" "\x0c" "VFNMADD231PS\0" "\x0c" "VFNMADD231PD\0" "\x0c" "VFNMADD231SS\0" \
+"\x0c" "VFNMADD231SD\0" "\x0c" "VFNMSUB231PS\0" "\x0c" "VFNMSUB231PD\0" "\x0c" "VFNMSUB231SS\0" \
+"\x0c" "VFNMSUB231SD\0" "\x06" "AESIMC\0" "\x07" "VAESIMC\0" "\x06" "AESENC\0" \
+"\x07" "VAESENC\0" "\x0a" "AESENCLAST\0" "\x0b" "VAESENCLAST\0" "\x06" "AESDEC\0" \
+"\x07" "VAESDEC\0" "\x0a" "AESDECLAST\0" "\x0b" "VAESDECLAST\0" "\x05" "MOVBE\0" \
+"\x05" "CRC32\0" "\x0a" "VPERM2F128\0" "\x07" "ROUNDPS\0" "\x08" "VROUNDPS\0" \
+"\x07" "ROUNDPD\0" "\x08" "VROUNDPD\0" "\x07" "ROUNDSS\0" "\x08" "VROUNDSS\0" \
+"\x07" "ROUNDSD\0" "\x08" "VROUNDSD\0" "\x07" "BLENDPS\0" "\x08" "VBLENDPS\0" \
+"\x07" "BLENDPD\0" "\x08" "VBLENDPD\0" "\x07" "PBLENDW\0" "\x08" "VPBLENDW\0" \
+"\x07" "PALIGNR\0" "\x08" "VPALIGNR\0" "\x06" "PEXTRB\0" "\x07" "VPEXTRB\0" \
+"\x06" "PEXTRD\0" "\x06" "PEXTRQ\0" "\x07" "VPEXTRD\0" "\x07" "VPEXTRQ\0" "\x09" "EXTRACTPS\0" \
+"\x0a" "VEXTRACTPS\0" "\x0b" "VINSERTF128\0" "\x0c" "VEXTRACTF128\0" "\x06" "PINSRB\0" \
+"\x07" "VPINSRB\0" "\x08" "INSERTPS\0" "\x09" "VINSERTPS\0" "\x06" "PINSRD\0" \
+"\x06" "PINSRQ\0" "\x07" "VPINSRD\0" "\x07" "VPINSRQ\0" "\x04" "DPPS\0" "\x05" "VDPPS\0" \
+"\x04" "DPPD\0" "\x05" "VDPPD\0" "\x07" "MPSADBW\0" "\x08" "VMPSADBW\0" "\x09" "PCLMULQDQ\0" \
+"\x0a" "VPCLMULQDQ\0" "\x09" "VBLENDVPS\0" "\x09" "VBLENDVPD\0" "\x09" "VPBLENDVB\0" \
+"\x09" "PCMPESTRM\0" "\x0a" "VPCMPESTRM\0" "\x09" "PCMPESTRI\0" "\x0a" "VPCMPESTRI\0" \
+"\x09" "PCMPISTRM\0" "\x0a" "VPCMPISTRM\0" "\x09" "PCMPISTRI\0" "\x0a" "VPCMPISTRI\0" \
+"\x0f" "AESKEYGENASSIST\0" "\x10" "VAESKEYGENASSIST\0" "\x06" "PSRLDQ\0" "\x07" "VPSRLDQ\0" \
+"\x06" "PSLLDQ\0" "\x07" "VPSLLDQ\0" "\x06" "FXSAVE\0" "\x08" "FXSAVE64\0" \
+"\x08" "RDFSBASE\0" "\x07" "FXRSTOR\0" "\x09" "FXRSTOR64\0" "\x08" "RDGSBASE\0" \
+"\x07" "LDMXCSR\0" "\x08" "WRFSBASE\0" "\x08" "VLDMXCSR\0" "\x07" "STMXCSR\0" \
+"\x08" "WRGSBASE\0" "\x08" "VSTMXCSR\0" "\x06" "RDRAND\0" "\x07" "VMPTRLD\0" \
+"\x07" "VMCLEAR\0" "\x05" "VMXON\0" "\x04" "WAIT\0" "\x06" "MOVSXD\0" "\x05" "PAUSE\0";
+
+const _WRegister _REGISTERS[] = {
+ {3, "RAX"}, {3, "RCX"}, {3, "RDX"}, {3, "RBX"}, {3, "RSP"}, {3, "RBP"}, {3, "RSI"}, {3, "RDI"}, {2, "R8"}, {2, "R9"}, {3, "R10"}, {3, "R11"}, {3, "R12"}, {3, "R13"}, {3, "R14"}, {3, "R15"},
+ {3, "EAX"}, {3, "ECX"}, {3, "EDX"}, {3, "EBX"}, {3, "ESP"}, {3, "EBP"}, {3, "ESI"}, {3, "EDI"}, {3, "R8D"}, {3, "R9D"}, {4, "R10D"}, {4, "R11D"}, {4, "R12D"}, {4, "R13D"}, {4, "R14D"}, {4, "R15D"},
+ {2, "AX"}, {2, "CX"}, {2, "DX"}, {2, "BX"}, {2, "SP"}, {2, "BP"}, {2, "SI"}, {2, "DI"}, {3, "R8W"}, {3, "R9W"}, {4, "R10W"}, {4, "R11W"}, {4, "R12W"}, {4, "R13W"}, {4, "R14W"}, {4, "R15W"},
+ {2, "AL"}, {2, "CL"}, {2, "DL"}, {2, "BL"}, {2, "AH"}, {2, "CH"}, {2, "DH"}, {2, "BH"}, {3, "R8B"}, {3, "R9B"}, {4, "R10B"}, {4, "R11B"}, {4, "R12B"}, {4, "R13B"}, {4, "R14B"}, {4, "R15B"},
+ {3, "SPL"}, {3, "BPL"}, {3, "SIL"}, {3, "DIL"},
+ {2, "ES"}, {2, "CS"}, {2, "SS"}, {2, "DS"}, {2, "FS"}, {2, "GS"},
+ {3, "RIP"},
+ {3, "ST0"}, {3, "ST1"}, {3, "ST2"}, {3, "ST3"}, {3, "ST4"}, {3, "ST5"}, {3, "ST6"}, {3, "ST7"},
+ {3, "MM0"}, {3, "MM1"}, {3, "MM2"}, {3, "MM3"}, {3, "MM4"}, {3, "MM5"}, {3, "MM6"}, {3, "MM7"},
+ {4, "XMM0"}, {4, "XMM1"}, {4, "XMM2"}, {4, "XMM3"}, {4, "XMM4"}, {4, "XMM5"}, {4, "XMM6"}, {4, "XMM7"}, {4, "XMM8"}, {4, "XMM9"}, {5, "XMM10"}, {5, "XMM11"}, {5, "XMM12"}, {5, "XMM13"}, {5, "XMM14"}, {5, "XMM15"},
+ {4, "YMM0"}, {4, "YMM1"}, {4, "YMM2"}, {4, "YMM3"}, {4, "YMM4"}, {4, "YMM5"}, {4, "YMM6"}, {4, "YMM7"}, {4, "YMM8"}, {4, "YMM9"}, {5, "YMM10"}, {5, "YMM11"}, {5, "YMM12"}, {5, "YMM13"}, {5, "YMM14"}, {5, "YMM15"},
+ {3, "CR0"}, {0, ""}, {3, "CR2"}, {3, "CR3"}, {3, "CR4"}, {0, ""}, {0, ""}, {0, ""}, {3, "CR8"},
+ {3, "DR0"}, {3, "DR1"}, {3, "DR2"}, {3, "DR3"}, {0, ""}, {0, ""}, {3, "DR6"}, {3, "DR7"}
+};
+
+#endif /* DISTORM_LIGHT */
diff --git a/distorm3.2-package/src/operands.c b/distorm3.2-package/src/operands.c
new file mode 100644
index 0000000..7260623
--- /dev/null
+++ b/distorm3.2-package/src/operands.c
@@ -0,0 +1,1299 @@
+/*
+operands.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "config.h"
+#include "operands.h"
+#include "x86defs.h"
+#include "insts.h"
+#include "../include/mnemonics.h"
+
+
+/* Maps a register to its register-class mask. */
+uint16_t _REGISTERTORCLASS[] = /* Based on _RegisterType enumeration! */
+{RM_AX, RM_CX, RM_DX, RM_BX, RM_SP, RM_BP, RM_SI, RM_DI, 0, 0, 0, 0, 0, 0, 0, 0,
+ RM_AX, RM_CX, RM_DX, RM_BX, RM_SP, RM_BP, RM_SI, RM_DI, 0, 0, 0, 0, 0, 0, 0, 0,
+ RM_AX, RM_CX, RM_DX, RM_BX, RM_SP, RM_BP, RM_SI, RM_DI, 0, 0, 0, 0, 0, 0, 0, 0,
+ RM_AX, RM_CX, RM_DX, RM_BX, RM_AX, RM_CX, RM_DX, RM_BX, 0, 0, 0, 0, 0, 0, 0, 0,
+ RM_SP, RM_BP, RM_SI, RM_DI,
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU,
+ RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX,
+ RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE,
+ RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX,
+ RM_CR, 0, RM_CR, RM_CR, RM_CR, 0, 0, 0, RM_CR,
+ RM_DR, RM_DR, RM_DR, RM_DR, 0, 0, RM_DR, RM_DR
+};
+
+typedef enum {OPERAND_SIZE_NONE = 0, OPERAND_SIZE8, OPERAND_SIZE16, OPERAND_SIZE32, OPERAND_SIZE64, OPERAND_SIZE80, OPERAND_SIZE128, OPERAND_SIZE256} _OperandSizeType;
+static uint16_t _OPSIZETOINT[] = {0, 8, 16, 32, 64, 80, 128, 256};
+
+/* A helper function to fix the 8 bits register if REX is used (to support SIL, DIL, etc). */
+static unsigned int _FASTCALL_ operands_fix_8bit_rex_base(unsigned int reg)
+{
+ if ((reg >= 4) && (reg < 8)) return reg + REGS8_REX_BASE - 4;
+ return reg + REGS8_BASE;
+}
+
+/* A helper function to set operand's type and size. */
+static void _FASTCALL_ operands_set_ts(_Operand* op, _OperandType type, uint16_t size)
+{
+ op->type = type;
+ op->size = size;
+}
+
+/* A helper function to set operand's type, size and index. */
+static void _FASTCALL_ operands_set_tsi(_Operand* op, _OperandType type, uint16_t size, unsigned int index)
+{
+ op->type = type;
+ op->index = (uint8_t)index;
+ op->size = size;
+}
+
+/* A helper function to read an unsigned integer from the stream safely. */
+static int _FASTCALL_ read_stream_safe_uint(_CodeInfo* ci, void* result, unsigned int size)
+{
+ ci->codeLen -= size;
+ if (ci->codeLen < 0) return FALSE;
+ switch (size)
+ {
+ case 1: *(uint8_t*)result = *(uint8_t*)ci->code; break;
+ case 2: *(uint16_t*)result = RUSHORT(ci->code); break;
+ case 4: *(uint32_t*)result = RULONG(ci->code); break;
+ case 8: *(uint64_t*)result = RULLONG(ci->code); break;
+ }
+ ci->code += size;
+ return TRUE;
+}
+
+/* A helper function to read a signed integer from the stream safely. */
+static int _FASTCALL_ read_stream_safe_sint(_CodeInfo* ci, int64_t* result, unsigned int size)
+{
+ ci->codeLen -= size;
+ if (ci->codeLen < 0) return FALSE;
+ switch (size)
+ {
+ case 1: *result = *(int8_t*)ci->code; break;
+ case 2: *result = RSHORT(ci->code); break;
+ case 4: *result = RLONG(ci->code); break;
+ case 8: *result = RLLONG(ci->code); break;
+ }
+ ci->code += size;
+ return TRUE;
+}
+
+/*
+ * SIB decoding is the most confusing part when decoding IA-32 instructions.
+ * This explanation should clear up some stuff.
+ *
+ * ! When base == 5, use EBP as the base register !
+ * if (rm == 4) {
+ * if mod == 01, decode SIB byte and ALSO read a 8 bits displacement.
+ * if mod == 10, decode SIB byte and ALSO read a 32 bits displacement.
+ * if mod == 11 <-- EXCEPTION, this is a general-purpose register and mustn't lead to SIB decoding!
+ * ; So far so good, now the confusing part comes in with mod == 0 and base=5, but no worry.
+ * if (mod == 00) {
+ * decode SIB byte WITHOUT any displacement.
+ * EXCEPTION!!! when base == 5, read a 32 bits displacement, but this time DO NOT use (EBP) BASE at all!
+ * }
+ *
+ * NOTE: base could specify None (no base register) if base==5 and mod==0, but then you also need DISP32.
+ * }
+ */
+static void operands_extract_sib(_DInst* di, _OperandNumberType opNum,
+ _PrefixState* ps, _DecodeType effAdrSz,
+ unsigned int sib, unsigned int mod)
+{
+ unsigned int scale = 0, index = 0, base = 0;
+ unsigned int vrex = ps->vrex;
+ uint8_t* pIndex = NULL;
+
+ _Operand* op = &di->ops[opNum];
+
+ /*
+ * SIB bits:
+ * |7---6-5----3-2---0|
+ * |SCALE| INDEX| BASE|
+ * |------------------|
+ */
+ scale = (sib >> 6) & 3;
+ index = (sib >> 3) & 7;
+ base = sib & 7;
+
+ /*
+ * The following fields: base/index/scale/disp8/32 are ALL optional by specific rules!
+ * The idea here is to keep the indirection as a simple-memory type.
+ * Because the base is optional, and we might be left with only one index.
+ * So even if there's a base but no index, or vice versa, we end up with one index register.
+ */
+
+ /* In 64 bits the REX prefix might affect the index of the SIB byte. */
+ if (vrex & PREFIX_EX_X) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ index += EX_GPR_BASE;
+ }
+
+ if (index == 4) { /* No index is used. Use SMEM. */
+ op->type = O_SMEM;
+ pIndex = &op->index;
+ } else {
+ op->type = O_MEM;
+ pIndex = &di->base;
+ /* No base, unless it is updated below. E.G: [EAX*4] has no base reg. */
+ }
+
+ if (base != 5) {
+ if (vrex & PREFIX_EX_B) ps->usedPrefixes |= INST_PRE_REX;
+ *pIndex = effAdrSz == Decode64Bits ? REGS64_BASE : REGS32_BASE;
+ *pIndex += (uint8_t)(base + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0));
+ } else if (mod != 0) {
+ /*
+ * if base == 5 then you have to decode according to MOD.
+ * mod(00) - disp32.
+ * mod(01) - disp8 + rBP
+ * mod(10) - disp32 + rBP
+ * mod(11) - not possible, it's a general-purpose register.
+ */
+
+ if (vrex & PREFIX_EX_B) ps->usedPrefixes |= INST_PRE_REX;
+ if (effAdrSz == Decode64Bits) *pIndex = REGS64_BASE + 5 + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0);
+ else *pIndex = REGS32_BASE + 5 + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0);
+ } else if (index == 4) {
+ /* 32bits displacement only. */
+ op->type = O_DISP;
+ return;
+ }
+
+ if (index != 4) { /* In 64 bits decoding mode, if index == R12, it's valid! */
+ if (effAdrSz == Decode64Bits) op->index = (uint8_t)(REGS64_BASE + index);
+ else op->index = (uint8_t)(REGS32_BASE + index);
+ di->scale = scale != 0 ? (1 << scale) : 0;
+ }
+}
+
+/*
+ * This seems to be the hardest part in decoding the operands.
+ * If you take a look carefully at Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte,
+ * you will understand it's easy to decode the operands.
+
+ * First we check the DT, so we can decide according to which Table in the documentation we are supposed to decode.
+ * Then we follow the specific table whether it's 16 bits or 32/64 bits.
+
+ * Don't forget that Operand Size AND Address Size prefixes may change the decoding!
+
+ * Some instructions force the use of RM16 or other specific types, so take it into account.
+ */
+static int operands_extract_modrm(_CodeInfo* ci,
+ _DInst* di, _OpType type,
+ _OperandNumberType opNum, _PrefixState* ps,
+ _DecodeType effOpSz, _DecodeType effAdrSz,
+ int* lockableInstruction, unsigned int mod, unsigned int rm,
+ _iflags instFlags)
+{
+ unsigned int vrex = ps->vrex, sib = 0, base = 0;
+ _Operand* op = &di->ops[opNum];
+ uint16_t size = 0;
+
+ if (mod == 3) {
+ /*
+ * General-purpose register is handled the same way in 16/32/64 bits decoding modes.
+ * NOTE!! that we have to override the size of the register, since it was set earlier as Memory and not Register!
+ */
+ op->type = O_REG;
+ /* Start with original size which was set earlier, some registers have same size of memory and depend on it. */
+ size = op->size;
+ switch(type)
+ {
+ case OT_RFULL_M16:
+ case OT_RM_FULL:
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 16;
+ rm += REGS16_BASE;
+ break;
+ case Decode32Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 32;
+ rm += REGS32_BASE;
+ break;
+ case Decode64Bits:
+ /* A fix for SMSW RAX which use the REX prefix. */
+ if (type == OT_RFULL_M16) ps->usedPrefixes |= INST_PRE_REX;
+ /* CALL NEAR/PUSH/POP defaults to 64 bits. --> INST_64BITS, REX isn't required, thus ignored anyways. */
+ if (instFlags & INST_PRE_REX) ps->usedPrefixes |= INST_PRE_REX;
+ /* Include REX if used for REX.B. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 64;
+ rm += REGS64_BASE;
+ break;
+ }
+ break;
+ case OT_R32_64_M8:
+ /* FALL THROUGH, decode 32 or 64 bits register. */
+ case OT_R32_64_M16:
+ /* FALL THROUGH, decode 32 or 64 bits register. */
+ case OT_RM32_64: /* Take care specifically in MOVNTI/MOVD/CVT's instructions, making it _REG64 with REX or if they are promoted. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ /* Is it a promoted instruction? (only INST_64BITS is set and REX isn't required.) */
+ if ((ci->dt == Decode64Bits) && ((instFlags & (INST_64BITS | INST_PRE_REX)) == INST_64BITS)) {
+ size = 64;
+ rm += REGS64_BASE;
+ break;
+ }
+ /* Give a chance to REX.W. Because if it was a promoted instruction we don't care about REX.W anyways. */
+ if (vrex & PREFIX_EX_W) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ size = 64;
+ rm += REGS64_BASE;
+ } else {
+ size = 32;
+ rm += REGS32_BASE;
+ }
+ break;
+ case OT_RM16_32: /* Used only with MOVZXD instruction to support 16 bits operand. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ /* Is it 16 bits operand size? */
+ if (ps->decodedPrefixes & INST_PRE_OP_SIZE) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ size = 16;
+ rm += REGS16_BASE;
+ } else {
+ size = 32;
+ rm += REGS32_BASE;
+ }
+ break;
+ case OT_RM16:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ rm += REGS16_BASE;
+ break;
+ case OT_RM8:
+ if (ps->prefixExtType == PET_REX) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm = operands_fix_8bit_rex_base(rm + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0));
+ } else rm += REGS8_BASE;
+ break;
+ case OT_MM32:
+ case OT_MM64:
+ /* MMX doesn't support extended registers. */
+ size = 64;
+ rm += MMXREGS_BASE;
+ break;
+
+ case OT_XMM16:
+ case OT_XMM32:
+ case OT_XMM64:
+ case OT_XMM128:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 128;
+ rm += SSEREGS_BASE;
+ break;
+
+ case OT_RM32:
+ case OT_R32_M8:
+ case OT_R32_M16:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 32;
+ rm += REGS32_BASE;
+ break;
+
+ case OT_YMM256:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ rm += AVXREGS_BASE;
+ break;
+ case OT_YXMM64_256:
+ case OT_YXMM128_256:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ if (vrex & PREFIX_EX_L) {
+ size = 256;
+ rm += AVXREGS_BASE;
+ } else {
+ size = 128;
+ rm += SSEREGS_BASE;
+ }
+ break;
+ case OT_WXMM32_64:
+ case OT_LXMM64_128:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ size = 128;
+ rm += SSEREGS_BASE;
+ break;
+
+ case OT_WRM32_64:
+ case OT_REG32_64_M8:
+ case OT_REG32_64_M16:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ if (vrex & PREFIX_EX_W) {
+ size = 64;
+ rm += REGS64_BASE;
+ } else {
+ size = 32;
+ rm += REGS32_BASE;
+ }
+ break;
+
+ default: return FALSE;
+ }
+ op->size = size;
+ op->index = (uint8_t)rm;
+ return TRUE;
+ }
+
+ /* Memory indirection decoding ahead:) */
+
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ if (lockableInstruction && (ps->decodedPrefixes & INST_PRE_LOCK)) *lockableInstruction = TRUE;
+
+ if (effAdrSz == Decode16Bits) {
+ /* Decoding according to Table 2-1. (16 bits) */
+ if ((mod == 0) && (rm == 6)) {
+ /* 6 is a special case - only 16 bits displacement. */
+ op->type = O_DISP;
+ di->dispSize = 16;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int16_t))) return FALSE;
+ } else {
+ /*
+ * Create the O_MEM for 16 bits indirection that requires 2 registers, E.G: [BS+SI].
+ * or create O_SMEM for a single register indirection, E.G: [BP].
+ */
+ static uint8_t MODS[] = {R_BX, R_BX, R_BP, R_BP, R_SI, R_DI, R_BP, R_BX};
+ static uint8_t MODS2[] = {R_SI, R_DI, R_SI, R_DI};
+ if (rm < 4) {
+ op->type = O_MEM;
+ di->base = MODS[rm];
+ op->index = MODS2[rm];
+ } else {
+ op->type = O_SMEM;
+ op->index = MODS[rm];
+ }
+
+ if (mod == 1) { /* 8 bits displacement + indirection */
+ di->dispSize = 8;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int8_t))) return FALSE;
+ } else if (mod == 2) { /* 16 bits displacement + indirection */
+ di->dispSize = 16;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int16_t))) return FALSE;
+ }
+ }
+
+ if ((rm == 2) || (rm == 3) || ((rm == 6) && (mod != 0))) {
+ /* BP's default segment is SS, so ignore it. */
+ prefixes_use_segment(INST_PRE_SS, ps, ci->dt, di);
+ } else {
+ /* Ignore default DS segment. */
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+ }
+ } else { /* Decode32Bits or Decode64Bits! */
+ /* Remember that from a 32/64 bits ModR/M byte a SIB byte could follow! */
+ if ((mod == 0) && (rm == 5)) {
+
+ /* 5 is a special case - only 32 bits displacement, or RIP relative. */
+ di->dispSize = 32;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int32_t))) return FALSE;
+
+ if (ci->dt == Decode64Bits) {
+ /* In 64 bits decoding mode depsite of the address size, a RIP-relative address it is. */
+ op->type = O_SMEM;
+ op->index = R_RIP;
+ di->flags |= FLAG_RIP_RELATIVE;
+ } else {
+ /* Absolute address: */
+ op->type = O_DISP;
+ }
+ } else {
+ if (rm == 4) {
+ /* 4 is a special case - SIB byte + disp8/32 follows! */
+ /* Read SIB byte. */
+ if (!read_stream_safe_uint(ci, &sib, sizeof(int8_t))) return FALSE;
+ operands_extract_sib(di, opNum, ps, effAdrSz, sib, mod);
+ } else {
+ op->type = O_SMEM;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+
+ if (effAdrSz == Decode64Bits) op->index = (uint8_t)(REGS64_BASE + rm);
+ else op->index = (uint8_t)(REGS32_BASE + rm);
+ }
+
+ if (mod == 1) {
+ di->dispSize = 8;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int8_t))) return FALSE;
+ } else if ((mod == 2) || ((sib & 7) == 5)) { /* If there is no BASE, read DISP32! */
+ di->dispSize = 32;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int32_t))) return FALSE;
+ }
+ }
+
+ /* Get the base register. */
+ base = op->index;
+ if (di->base != R_NONE) base = di->base;
+ else if (di->scale >= 2) base = 0; /* If it's only an index but got scale, it's still DS. */
+ /* Default for EBP/ESP is SS segment. 64 bits mode ignores DS anyway. */
+ if ((base == R_EBP) || (base == R_ESP)) prefixes_use_segment(INST_PRE_SS, ps, ci->dt, di);
+ else prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This function is reponsible to textually format a required operand according to its type.
+ * It is vital to understand that there are other operands than what the ModR/M byte specifies.
+
+ * Only by decoding the operands of an instruction which got a LOCK prefix, we could tell whether it may use the LOCK prefix.
+ * According to Intel, LOCK prefix must precede some specific instructions AND in their memory destination operand form (which means first operand).
+ * LOCK INC EAX, would generate an exception, but LOCK INC [EAX] is alright.
+ * Also LOCK ADD BX, [BP] would generate an exception.
+
+ * Return code:
+ * TRUE - continue parsing the instruction and its operands, everything went right 'till now.
+ * FALSE - not enough bytes, or invalid operands.
+ */
+
+int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii,
+ _OpType type, _OperandNumberType opNum,
+ unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz,
+ _DecodeType effAdrSz, int* lockableInstruction)
+{
+ int ret = 0;
+ unsigned int mod = 0, reg = 0, rm = 0, vexV = ps->vexV;
+ unsigned int vrex = ps->vrex, typeHandled = TRUE;
+ _iflags instFlags = INST_INFO_FLAGS(ii);
+ _Operand* op = &di->ops[opNum];
+
+ /* Used to indicate the size of the MEMORY INDIRECTION only. */
+ _OperandSizeType opSize = OPERAND_SIZE_NONE;
+
+ /*
+ * ModRM bits:
+ * |7-6-5--------3-2-0|
+ * |MOD|REG/OPCODE|RM |
+ * |------------------|
+ */
+ mod = (modrm >> 6) & 3; /* Mode(register-indirection, disp8+reg+indirection, disp16+reg+indirection, general-purpose register) */
+ reg = (modrm >> 3) & 7; /* Register(could be part of the opcode itself or general-purpose register) */
+ rm = modrm & 7; /* Specifies which general-purpose register or disp+reg to use. */
+
+ /* -- Memory Indirection Operands (that cannot be a general purpose register) -- */
+ switch (type)
+ {
+ case OT_MEM64_128: /* Used only by CMPXCHG8/16B. */
+ /* Make a specific check when the type is OT_MEM64_128 since the lockable CMPXCHG8B uses this one... */
+ if (lockableInstruction && (ps->decodedPrefixes & INST_PRE_LOCK)) *lockableInstruction = TRUE;
+ if (effOpSz == Decode64Bits) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE128;
+ } else opSize = OPERAND_SIZE64;
+ break;
+ case OT_MEM32: opSize = OPERAND_SIZE32; break;
+ case OT_MEM32_64:
+ /* Used by MOVNTI. Default size is 32bits, 64bits with REX. */
+ if (effOpSz == Decode64Bits) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE64;
+ } else opSize = OPERAND_SIZE32;
+ break;
+ case OT_MEM64: opSize = OPERAND_SIZE64; break;
+ case OT_MEM128: opSize = OPERAND_SIZE128; break;
+ case OT_MEM16_FULL: /* The size indicates about the second item of the pair. */
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE16;
+ break;
+ case Decode32Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE32;
+ break;
+ case Decode64Bits:
+ /* Mark usage of REX only if it was required. */
+ if ((instFlags & (INST_64BITS | INST_PRE_REX)) == (INST_64BITS | INST_PRE_REX)) ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE64;
+ break;
+ }
+ break;
+ case OT_MEM16_3264: /* The size indicates about the second item of the pair. */
+ if (ci->dt == Decode64Bits) opSize = OPERAND_SIZE64;
+ else opSize = OPERAND_SIZE32;
+ break;
+ case OT_MEM_OPT:
+ /* Since the MEM is optional, only when mod != 3, then return true as if the operand was alright. */
+ if (mod == 0x3) return TRUE;
+ break;
+ case OT_FPUM16: opSize = OPERAND_SIZE16; break;
+ case OT_FPUM32: opSize = OPERAND_SIZE32; break;
+ case OT_FPUM64: opSize = OPERAND_SIZE64; break;
+ case OT_FPUM80: opSize = OPERAND_SIZE80; break;
+ case OT_LMEM128_256:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE256;
+ else opSize = OPERAND_SIZE128;
+ break;
+ case OT_MEM: /* Size is unknown, but still handled. */ break;
+ default: typeHandled = FALSE; break;
+ }
+ if (typeHandled) {
+ /* All of the above types can't use a general-purpose register (a MOD of 3)!. */
+ if (mod == 0x3) {
+ if (lockableInstruction) *lockableInstruction = FALSE;
+ return FALSE;
+ }
+ op->size = _OPSIZETOINT[opSize];
+ ret = operands_extract_modrm(ci, di, type, opNum, ps, effOpSz, effAdrSz, lockableInstruction, mod, rm, instFlags);
+ if ((op->type == O_REG) || (op->type == O_SMEM) || (op->type == O_MEM)) {
+ di->usedRegistersMask |= _REGISTERTORCLASS[op->index];
+ }
+ return ret;
+ }
+
+ /* -- Memory Indirection Operands (that can be a register) -- */
+ typeHandled = TRUE;
+ switch (type)
+ {
+ case OT_RM_FULL:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* PUSH/JMP/CALL are automatically promoted to 64 bits! */
+ if (effOpSz == Decode32Bits) {
+ opSize = OPERAND_SIZE32;
+ break;
+ } else if (effOpSz == Decode64Bits) {
+ /* Mark usage of REX only if it was required. */
+ if ((instFlags & INST_64BITS) == 0) ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE64;
+ break;
+ }
+ /* FALL THROUGH BECAUSE dt==Decoded16Bits @-<----*/
+ case OT_RM16:
+ /* If we got here not from OT_RM16, then the prefix was used. */
+ if (type != OT_RM16) ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE16;
+ break;
+ case OT_RM32_64:
+ /* The default size is 32, which can be 64 with a REX only. */
+ if (effOpSz == Decode64Bits) {
+ opSize = OPERAND_SIZE64;
+ /* Mark REX prefix as used if non-promoted instruction. */
+ if ((instFlags & (INST_64BITS | INST_PRE_REX)) == (INST_64BITS | INST_PRE_REX)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ }
+ } else opSize = OPERAND_SIZE32;
+ break;
+ case OT_RM16_32:
+ /* Ignore REX, it's either 32 or 16 bits RM. */
+ if (ps->decodedPrefixes & INST_PRE_OP_SIZE) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* Assume: We are in 64bits when we have this operand used. */
+ opSize = OPERAND_SIZE16;
+ } else opSize = OPERAND_SIZE32;
+ break;
+ case OT_WXMM32_64:
+ case OT_WRM32_64:
+ if (vrex & PREFIX_EX_W) opSize = OPERAND_SIZE64;
+ else opSize = OPERAND_SIZE32;
+ break;
+ case OT_YXMM64_256:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE256;
+ else opSize = OPERAND_SIZE64;
+ break;
+ case OT_YXMM128_256:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE256;
+ else opSize = OPERAND_SIZE128;
+ break;
+ case OT_LXMM64_128:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE128;
+ else opSize = OPERAND_SIZE64;
+ break;
+ case OT_RFULL_M16:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE16;
+ break;
+
+ case OT_RM8:
+ case OT_R32_M8:
+ case OT_R32_64_M8:
+ case OT_REG32_64_M8:
+ opSize = OPERAND_SIZE8;
+ break;
+
+ case OT_XMM16:
+ case OT_R32_M16:
+ case OT_R32_64_M16:
+ case OT_REG32_64_M16:
+ opSize = OPERAND_SIZE16;
+ break;
+
+ case OT_RM32:
+ case OT_MM32:
+ case OT_XMM32:
+ opSize = OPERAND_SIZE32;
+ break;
+
+ case OT_MM64:
+ case OT_XMM64:
+ opSize = OPERAND_SIZE64;
+ break;
+
+ case OT_XMM128: opSize = OPERAND_SIZE128; break;
+ case OT_YMM256: opSize = OPERAND_SIZE256; break;
+ default: typeHandled = FALSE; break;
+ }
+ if (typeHandled) {
+ /* Fill size of memory dereference for operand. */
+ op->size = _OPSIZETOINT[opSize];
+ ret = operands_extract_modrm(ci, di, type, opNum, ps, effOpSz, effAdrSz, lockableInstruction, mod, rm, instFlags);
+ if ((op->type == O_REG) || (op->type == O_SMEM) || (op->type == O_MEM)) {
+ di->usedRegistersMask |= _REGISTERTORCLASS[op->index];
+ }
+ return ret;
+ }
+
+ /* Simple operand type (no ModRM byte). */
+ switch (type)
+ {
+ case OT_IMM8:
+ operands_set_ts(op, O_IMM, 8);
+ if (!read_stream_safe_uint(ci, &di->imm.byte, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_IMM_FULL: /* 16, 32 or 64, depends on prefixes. */
+ if (effOpSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* FALL THROUGH */
+ case OT_IMM16: /* Force 16 bits imm. */
+ operands_set_ts(op, O_IMM, 16);
+ if (!read_stream_safe_uint(ci, &di->imm.word, sizeof(int16_t))) return FALSE;
+ break;
+ /*
+ * Extension: MOV imm64, requires REX.
+ * Make sure it needs the REX.
+ * REX must be present because op size function takes it into consideration.
+ */
+ } else if ((effOpSz == Decode64Bits) &&
+ ((instFlags & (INST_64BITS | INST_PRE_REX)) == (INST_64BITS | INST_PRE_REX))) {
+ ps->usedPrefixes |= INST_PRE_REX;
+
+ operands_set_ts(op, O_IMM, 64);
+ if (!read_stream_safe_uint(ci, &di->imm.qword, sizeof(int64_t))) return FALSE;
+ break;
+ } else ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* FALL THROUGH BECAUSE dt==Decoded32Bits @-<----*/
+ case OT_IMM32:
+ op->type = O_IMM;
+ if (ci->dt == Decode64Bits) {
+ /* Imm32 is sign extended to 64 bits! */
+ op->size = 64;
+ di->flags |= FLAG_IMM_SIGNED;
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int32_t))) return FALSE;
+ } else {
+ op->size = 32;
+ if (!read_stream_safe_uint(ci, &di->imm.dword, sizeof(int32_t))) return FALSE;
+ }
+ break;
+ case OT_SEIMM8: /* Sign extended immediate. */
+ /*
+ * PUSH SEIMM8 can be prefixed by operand size:
+ * Input stream: 66, 6a, 55
+ * 64bits DT: push small 55
+ * 32bits DT: push small 55
+ * 16bits DT: push large 55
+ * small/large indicates the size of the eSP pointer advancement.
+ * Check the instFlags (ii->flags) if it can be operand-size-prefixed and if the prefix exists.
+ */
+ op->type = O_IMM;
+ if ((instFlags & INST_PRE_OP_SIZE) && (ps->decodedPrefixes & INST_PRE_OP_SIZE)) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ switch (ci->dt)
+ {
+ case Decode16Bits: op->size = 32; break;
+ case Decode32Bits:
+ case Decode64Bits:
+ op->size = 16;
+ break;
+ }
+ } else op->size = 8;
+ di->flags |= FLAG_IMM_SIGNED;
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_IMM16_1:
+ operands_set_ts(op, O_IMM1, 16);
+ if (!read_stream_safe_uint(ci, &di->imm.ex.i1, sizeof(int16_t))) return FALSE;
+ break;
+ case OT_IMM8_1:
+ operands_set_ts(op, O_IMM1, 8);
+ if (!read_stream_safe_uint(ci, &di->imm.ex.i1, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_IMM8_2:
+ operands_set_ts(op, O_IMM2, 8);
+ if (!read_stream_safe_uint(ci, &di->imm.ex.i2, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_REG8:
+ operands_set_ts(op, O_REG, 8);
+ if (ps->prefixExtType) {
+ /*
+ * If REX prefix is valid then we will have to use low bytes.
+ * This is a PASSIVE behaviour changer of REX prefix, it affects operands even if its value is 0x40 !
+ */
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->index = (uint8_t)operands_fix_8bit_rex_base(reg + ((vrex & PREFIX_EX_R) ? EX_GPR_BASE : 0));
+ } else op->index = (uint8_t)(REGS8_BASE + reg);
+ break;
+ case OT_REG16:
+ operands_set_tsi(op, O_REG, 16, REGS16_BASE + reg);
+ break;
+ case OT_REG_FULL:
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 16, REGS16_BASE + reg);
+ break;
+ case Decode32Bits:
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ } else ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case Decode64Bits: /* rex must be presented. */
+ ps->usedPrefixes |= INST_PRE_REX;
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg + ((vrex & PREFIX_EX_R) ? EX_GPR_BASE : 0));
+ break;
+ }
+ break;
+ case OT_REG32:
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case OT_REG32_64: /* Handle CVT's, MOVxX and MOVNTI instructions which could be extended to 64 bits registers with REX. */
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+
+ /* Is it a promoted instruction? (only INST_64BITS is set and REX isn't required.) */
+ if ((ci->dt == Decode64Bits) && ((instFlags & (INST_64BITS | INST_PRE_REX)) == INST_64BITS)) {
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ break;
+ }
+ /* Give a chance to REX.W. Because if it was a promoted instruction we don't care about REX.W anyways. */
+ if (vrex & PREFIX_EX_W) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ } else operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case OT_FREG32_64_RM: /* Force decoding mode. Used for MOV CR(n)/DR(n) which defaults to 64 bits operand size in 64 bits. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+
+ if (ci->dt == Decode64Bits) operands_set_tsi(op, O_REG, 64, REGS64_BASE + rm);
+ else operands_set_tsi(op, O_REG, 32, REGS32_BASE + rm);
+ break;
+ case OT_MM: /* MMX register */
+ operands_set_tsi(op, O_REG, 64, MMXREGS_BASE + reg);
+ break;
+ case OT_MM_RM: /* MMX register, this time from the RM field */
+ operands_set_tsi(op, O_REG, 64, MMXREGS_BASE + rm);
+ break;
+ case OT_REGXMM0: /* Implicit XMM0 operand. */
+ reg = 0;
+ vrex = 0;
+ /* FALL THROUGH */
+ case OT_XMM: /* SSE register */
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+ break;
+ case OT_XMM_RM: /* SSE register, this time from the RM field */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + rm);
+ break;
+ case OT_CREG:
+ /*
+ * Don't parse if the reg exceeds the bounds of the array.
+ * Most of the CR's are not implemented, so if there's no matching string, the operand is invalid.
+ */
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ } else if ((ci->dt == Decode32Bits) && (ps->decodedPrefixes & INST_PRE_LOCK)) {
+ /*
+ * NOTE: In 32 bits decoding mode,
+ * if the lock prefix is set before MOV CR(n) it will become the 4th bit of the REG field like REX.R in 64 bits.
+ */
+ reg += EX_GPR_BASE;
+ ps->usedPrefixes |= INST_PRE_LOCK;
+ }
+ /* Ignore some registers which do not exist. */
+ if ((reg >= CREGS_MAX) || (reg == 1) || ((reg >= 5) && (reg <= 7))) return FALSE;
+
+ op->type = O_REG;
+ if (ci->dt == Decode64Bits) op->size = 64;
+ else op->size = 32;
+ op->index = (uint8_t)(CREGS_BASE + reg);
+ break;
+ case OT_DREG:
+ /*
+ * In 64 bits there are 16 debug registers.
+ * but accessing any of dr8-15 which aren't implemented will cause an #ud.
+ */
+ if ((reg == 4) || (reg == 5) || (vrex & PREFIX_EX_R)) return FALSE;
+
+ op->type = O_REG;
+ if (ci->dt == Decode64Bits) op->size = 64;
+ else op->size = 32;
+ op->index = (uint8_t)(DREGS_BASE + reg);
+ break;
+ case OT_SREG: /* Works with REG16 only! */
+ /* If lockableInstruction pointer is non-null we know it's the first operand. */
+ if (lockableInstruction && (reg == 1)) return FALSE; /* Can't MOV CS, . */
+ /*Don't parse if the reg exceeds the bounds of the array. */
+ if (reg <= SEG_REGS_MAX - 1) operands_set_tsi(op, O_REG, 16, SREGS_BASE + reg);
+ else return FALSE;
+ break;
+ case OT_SEG:
+ op->type = O_REG;
+ /* Size of reg is always 16, it's up to caller to zero extend it to operand size. */
+ op->size = 16;
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /*
+ * Extract the SEG from ii->flags this time!!!
+ * Check whether an operand size prefix is used.
+ */
+ switch (instFlags & INST_PRE_SEGOVRD_MASK)
+ {
+ case INST_PRE_ES: op->index = R_ES; break;
+ case INST_PRE_CS: op->index = R_CS; break;
+ case INST_PRE_SS: op->index = R_SS; break;
+ case INST_PRE_DS: op->index = R_DS; break;
+ case INST_PRE_FS: op->index = R_FS; break;
+ case INST_PRE_GS: op->index = R_GS; break;
+ }
+ break;
+ case OT_ACC8:
+ operands_set_tsi(op, O_REG, 8, R_AL);
+ break;
+ case OT_ACC16:
+ operands_set_tsi(op, O_REG, 16, R_AX);
+ break;
+ case OT_ACC_FULL_NOT64: /* No REX.W support for IN/OUT. */
+ vrex &= ~PREFIX_EX_W;
+ case OT_ACC_FULL:
+ if (effOpSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 16, R_AX);
+ } else if (effOpSz == Decode32Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 32, R_EAX);
+ } else { /* Decode64Bits */
+ /* Only non-promoted instructions need REX in order to decode in 64 bits. */
+ /* MEM-OFFSET MOV's are NOT automatically promoted to 64 bits. */
+ if (~instFlags & INST_64BITS) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ }
+ operands_set_tsi(op, O_REG, 64, R_RAX);
+ }
+ break;
+ case OT_PTR16_FULL:
+ /* ptr16:full - full is size of operand size to read, therefore Operand Size Prefix affects this. So we need to handle it. */
+ if (effOpSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ ci->codeLen -= sizeof(int16_t)*2;
+ if (ci->codeLen < 0) return FALSE;
+
+ operands_set_ts(op, O_PTR, 16);
+ di->imm.ptr.off = RUSHORT(ci->code); /* Read offset first. */
+ di->imm.ptr.seg = RUSHORT((ci->code + sizeof(int16_t))); /* And read segment. */
+
+ ci->code += sizeof(int16_t)*2;
+ } else { /* Decode32Bits, for Decode64Bits this instruction is invalid. */
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ ci->codeLen -= sizeof(int32_t) + sizeof(int16_t);
+ if (ci->codeLen < 0) return FALSE;
+
+ operands_set_ts(op, O_PTR, 32);
+ di->imm.ptr.off = RULONG(ci->code); /* Read 32bits offset this time. */
+ di->imm.ptr.seg = RUSHORT((ci->code + sizeof(int32_t))); /* And read segment, 16 bits. */
+
+ ci->code += sizeof(int32_t) + sizeof(int16_t);
+ }
+ break;
+ case OT_RELCB:
+ case OT_RELC_FULL:
+
+ if (type == OT_RELCB) {
+ operands_set_ts(op, O_PC, 8);
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int8_t))) return FALSE;
+ } else { /* OT_RELC_FULL */
+
+ /* Yep, operand size prefix affects relc also. */
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (effOpSz == Decode16Bits) {
+ operands_set_ts(op, O_PC, 16);
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int16_t))) return FALSE;
+ } else { /* Decode32Bits or Decode64Bits = for now they are the same */
+ operands_set_ts(op, O_PC, 32);
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int32_t))) return FALSE;
+ }
+ }
+
+ /* Support for hint, see if there's a segment override. */
+ if ((ii->opcodeId >= I_JO) && (ii->opcodeId <= I_JG)) {
+ if (ps->decodedPrefixes & INST_PRE_CS) {
+ ps->usedPrefixes |= INST_PRE_CS;
+ di->flags |= FLAG_HINT_NOT_TAKEN;
+ } else if (ps->decodedPrefixes & INST_PRE_DS) {
+ ps->usedPrefixes |= INST_PRE_DS;
+ di->flags |= FLAG_HINT_TAKEN;
+ }
+ }
+ break;
+ case OT_MOFFS8:
+ op->size = 8;
+ /* FALL THROUGH, size won't be changed. */
+ case OT_MOFFS_FULL:
+ op->type = O_DISP;
+ if (op->size == 0) {
+ /* Calculate size of operand (same as ACC size). */
+ switch (effOpSz)
+ {
+ case Decode16Bits: op->size = 16; break;
+ case Decode32Bits: op->size = 32; break;
+ case Decode64Bits: op->size = 64; break;
+ }
+ }
+
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+
+ /*
+ * Just a pointer to a BYTE, WORD, DWORD, QWORD. Works only with ACC8/16/32/64 respectively.
+ * MOV [0x1234], AL ; MOV AX, [0x1234] ; MOV EAX, [0x1234], note that R/E/AX will be chosen by OT_ACC_FULL.
+ */
+ if (effAdrSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ di->dispSize = 16;
+ if (!read_stream_safe_uint(ci, &di->disp, sizeof(int16_t))) return FALSE;
+ } else if (effAdrSz == Decode32Bits) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ di->dispSize = 32;
+ if (!read_stream_safe_uint(ci, &di->disp, sizeof(int32_t))) return FALSE;
+ } else { /* Decode64Bits */
+ di->dispSize = 64;
+ if (!read_stream_safe_uint(ci, &di->disp, sizeof(int64_t))) return FALSE;
+ }
+ break;
+ case OT_CONST1:
+ operands_set_ts(op, O_IMM, 8);
+ di->imm.byte = 1;
+ break;
+ case OT_REGCL:
+ operands_set_tsi(op, O_REG, 8, R_CL);
+ break;
+
+ case OT_FPU_SI:
+ /* Low 3 bits specify the REG, similar to the MODR/M byte reg. */
+ operands_set_tsi(op, O_REG, 32, FPUREGS_BASE + (*(ci->code-1) & 7));
+ break;
+ case OT_FPU_SSI:
+ operands_set_tsi(op, O_REG, 32, R_ST0);
+ operands_set_tsi(op + 1, O_REG, 32, FPUREGS_BASE + (*(ci->code-1) & 7));
+ break;
+ case OT_FPU_SIS:
+ operands_set_tsi(op, O_REG, 32, FPUREGS_BASE + (*(ci->code-1) & 7));
+ operands_set_tsi(op + 1, O_REG, 32, R_ST0);
+ break;
+
+ /*
+ * Special treatment for Instructions-Block:
+ * INC/DEC (only 16/32 bits) /PUSH/POP/XCHG instructions, which get their REG from their own binary code.
+
+ * Notice these instructions are 1 or 2 byte long,
+ * code points after the byte which represents the instruction itself,
+ * thus, even if the instructions are 2 bytes long it will read its last byte which contains the REG info.
+ */
+ case OT_IB_RB:
+ /* Low 3 bits specify the REG, similar to the MODR/M byte reg. */
+ operands_set_ts(op, O_REG, 8);
+ reg = *(ci->code-1) & 7;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->index = (uint8_t)operands_fix_8bit_rex_base(reg + EX_GPR_BASE);
+ } else if (ps->prefixExtType == PET_REX) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->index = (uint8_t)operands_fix_8bit_rex_base(reg);
+ } else op->index = (uint8_t)(REGS8_BASE + reg);
+ break;
+ case OT_IB_R_FULL:
+ reg = *(ci->code-1) & 7;
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 16, REGS16_BASE + reg);
+ break;
+ case Decode32Bits:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ } else ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case Decode64Bits:
+ /*
+ * Automatically promoted instruction can drop REX prefix if not required.
+ * PUSH/POP defaults to 64 bits. --> INST_64BITS
+ * MOV imm64 / BSWAP requires REX.W to be 64 bits --> INST_64BITS | INST_PRE_REX
+ */
+ if ((instFlags & INST_64BITS) && ((instFlags & INST_PRE_REX) == 0)) {
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ } else {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += (vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0;
+ }
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ break;
+ }
+ break;
+
+ /*
+ * Special treatment for repeatable instructions.
+
+ * We want the following output:
+ * If there's only the REP/NZ prefix, we won't output anything (All operands are implicit).
+ * If there's an operand size prefix, we will change the suffix letter of the mnemonic, which specifies the size of operand to the required one.
+ * If there's a segment override prefix, we will output the segment and the used index register (EDI/ESI).
+ * If there's an address size prefix, we will output the (segment if needed and) the used and inverted index register (DI/SI).
+
+ * Example:
+ * :: Decoding in 16 bits mode! ::
+ * AD ~ LODSW
+ * 66 AD ~ LODSD
+ * F3 AC ~ REP LODSB
+ * F3 66 AD ~ REP LODSD
+ * F3 3E AC ~ REP LODS BYTE DS:[SI]
+ * F3 67 AD ~ REP LODS WORD [ESI]
+
+ * The basic form of a repeatable instruction has its operands hidden and has a suffix letter
+ * which implies on the size of operation being done.
+ * Therefore, we cannot change the mnemonic here when we encounter another prefix and its not the decoder's responsibility to do so.
+ * That's why the caller is responsible to add the suffix letter if no other prefixes are used.
+ * And all we are doing here is formatting the operand correctly.
+ */
+ case OT_REGI_ESI:
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ op->type = O_SMEM;
+
+ /* This might be a 16, 32 or 64 bits instruction, depends on the decoding mode. */
+ if (instFlags & INST_16BITS) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+
+ if (effOpSz == Decode16Bits) op->size = 16;
+ else if ((effOpSz == Decode64Bits) && (instFlags & INST_64BITS)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->size = 64;
+ } else op->size = 32;
+ } else op->size = 8;
+
+ /*
+ * Clear segment in case OT_REGI_EDI was parsed earlier,
+ * DS can be overridden and therefore has precedence.
+ */
+ di->segment = 0;
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+
+ if (effAdrSz == Decode16Bits) op->index = R_SI;
+ else if (effAdrSz == Decode32Bits) op->index = R_ESI;
+ else op->index = R_RSI;
+ break;
+ case OT_REGI_EDI:
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ op->type = O_SMEM;
+
+ /* This might be a 16 or 32 bits instruction, depends on the decoding mode. */
+ if (instFlags & INST_16BITS) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+
+ if (effOpSz == Decode16Bits) op->size = 16;
+ else if ((effOpSz == Decode64Bits) && (instFlags & INST_64BITS)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->size = 64;
+ } else op->size = 32;
+ } else op->size = 8;
+
+ /* Note: The [rDI] operand can't be prefixed by a segment override, therefore we don't set usedPrefixes. */
+ if ((opNum == ONT_1) && (ci->dt != Decode64Bits)) di->segment = R_ES | SEGMENT_DEFAULT; /* No ES in 64 bits mode. */
+
+ if (effAdrSz == Decode16Bits) op->index = R_DI;
+ else if (effAdrSz == Decode32Bits) op->index = R_EDI;
+ else op->index = R_RDI;
+ break;
+
+ /* Used for In/Out instructions varying forms. */
+ case OT_REGDX:
+ /* Simple single IN/OUT instruction. */
+ operands_set_tsi(op, O_REG, 16, R_DX);
+ break;
+
+ /* Used for INVLPGA instruction. */
+ case OT_REGECX:
+ operands_set_tsi(op, O_REG, 32, R_ECX);
+ break;
+ case OT_REGI_EBXAL:
+ /* XLAT BYTE [rBX + AL] */
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+
+ /* Size of deref is always 8 for xlat. */
+ operands_set_tsi(op, O_MEM, 8, R_AL);
+
+ if (effAdrSz == Decode16Bits) di->base = R_BX;
+ else if (effAdrSz == Decode32Bits) di->base = R_EBX;
+ else {
+ ps->usedPrefixes |= INST_PRE_REX;
+ di->base = R_RBX;
+ }
+ break;
+ case OT_REGI_EAX:
+ /*
+ * Implicit rAX as memory indirection operand. Used by AMD's SVM instructions.
+ * Since this is a memory indirection, the default address size in 64bits decoding mode is 64.
+ */
+
+ if (effAdrSz == Decode64Bits) operands_set_tsi(op, O_SMEM, 64, R_RAX);
+ else if (effAdrSz == Decode32Bits) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ operands_set_tsi(op, O_SMEM, 32, R_EAX);
+ } else {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ operands_set_tsi(op, O_SMEM, 16, R_AX);
+ }
+ break;
+ case OT_VXMM:
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + vexV);
+ break;
+ case OT_XMM_IMM:
+ ci->codeLen -= sizeof(int8_t);
+ if (ci->codeLen < 0) return FALSE;
+
+ if (ci->dt == Decode32Bits) reg = (*ci->code >> 4) & 0x7;
+ else reg = (*ci->code >> 4) & 0xf;
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+
+ ci->code += sizeof(int8_t);
+ break;
+ case OT_YXMM:
+ if (vrex & PREFIX_EX_R) reg += EX_GPR_BASE;
+ if (ps->vrex & PREFIX_EX_L) operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + reg);
+ else operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+ break;
+ case OT_YXMM_IMM:
+ ci->codeLen -= sizeof(int8_t);
+ if (ci->codeLen < 0) return FALSE;
+
+ if (ci->dt == Decode32Bits) reg = (*ci->code >> 4) & 0x7;
+ else reg = (*ci->code >> 4) & 0xf;
+
+ if (ps->vrex & PREFIX_EX_L) operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + reg);
+ else operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+
+ ci->code += sizeof(int8_t);
+ break;
+ case OT_YMM:
+ if (vrex & PREFIX_EX_R) reg += EX_GPR_BASE;
+ operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + reg);
+ break;
+ case OT_VYMM:
+ operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + vexV);
+ break;
+ case OT_VYXMM:
+ if (ps->vrex & PREFIX_EX_L) operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + vexV);
+ else operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + vexV);
+ break;
+ case OT_WREG32_64:
+ if (vrex & PREFIX_EX_R) reg += EX_GPR_BASE;
+ if (ps->vrex & PREFIX_EX_W) operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ else operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ default: return FALSE;
+ }
+
+ if ((op->type == O_REG) || (op->type == O_SMEM) || (op->type == O_MEM)) {
+ di->usedRegistersMask |= _REGISTERTORCLASS[op->index];
+ }
+
+ return TRUE;
+}
diff --git a/distorm3.2-package/src/operands.h b/distorm3.2-package/src/operands.h
new file mode 100644
index 0000000..e1beb6f
--- /dev/null
+++ b/distorm3.2-package/src/operands.h
@@ -0,0 +1,40 @@
+/*
+operands.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef OPERANDS_H
+#define OPERANDS_H
+
+#include "config.h"
+#include "decoder.h"
+#include "prefix.h"
+#include "instructions.h"
+
+
+extern uint16_t _REGISTERTORCLASS[];
+
+int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii,
+ _OpType type, _OperandNumberType opNum,
+ unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz,
+ _DecodeType effAdrSz, int* lockableInstruction);
+
+#endif /* OPERANDS_H */
diff --git a/distorm3.2-package/src/prefix.c b/distorm3.2-package/src/prefix.c
new file mode 100644
index 0000000..53f09b6
--- /dev/null
+++ b/distorm3.2-package/src/prefix.c
@@ -0,0 +1,380 @@
+/*
+prefix.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "prefix.h"
+
+#include "x86defs.h"
+#include "instructions.h"
+#include "../include/mnemonics.h"
+
+
+/*
+ * The main purpose of this module is to keep track of all kind of prefixes a single instruction may have.
+ * The problem is that a single instruction may have up to six different prefix-types.
+ * That's why I have to detect such cases and drop those excess prefixes.
+ */
+
+int prefixes_is_valid(unsigned int ch, _DecodeType dt)
+{
+ switch (ch) {
+ /* for i in xrange(0x40, 0x50): print "case 0x%2x:" % i */
+ case 0x40: /* REX: */
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f: return (dt == Decode64Bits);
+ case PREFIX_LOCK: return TRUE;
+ case PREFIX_REPNZ: return TRUE;
+ case PREFIX_REP: return TRUE;
+ case PREFIX_CS: return TRUE;
+ case PREFIX_SS: return TRUE;
+ case PREFIX_DS: return TRUE;
+ case PREFIX_ES: return TRUE;
+ case PREFIX_FS: return TRUE;
+ case PREFIX_GS: return TRUE;
+ case PREFIX_OP_SIZE: return TRUE;
+ case PREFIX_ADDR_SIZE: return TRUE;
+ /* The VEXs might be false positives, the decode_perfixes will determine for sure. */
+ case PREFIX_VEX2b: /* VEX is supported for all modes, because 16 bits Pmode is included. */
+ case PREFIX_VEX3b: return TRUE;
+ }
+ return FALSE;
+}
+
+/* Ignore a specific prefix type. */
+void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi)
+{
+ /*
+ * If that type of prefix appeared already, set the bit of that *former* prefix.
+ * Anyway, set the new index of that prefix type to the current index, so next time we know its position.
+ */
+ if (ps->pfxIndexer[pi] != PFXIDX_NONE) ps->unusedPrefixesMask |= (1 << ps->pfxIndexer[pi]);
+}
+
+/* Ignore all prefix. */
+void prefixes_ignore_all(_PrefixState* ps)
+{
+ int i;
+ for (i = 0; i < PFXIDX_MAX; i++)
+ prefixes_ignore(ps, i);
+}
+
+/* Calculates which prefixes weren't used and accordingly sets the bits in the unusedPrefixesMask. */
+uint16_t prefixes_set_unused_mask(_PrefixState* ps)
+{
+ /*
+ * The decodedPrefixes represents the prefixes that were *read* from the binary stream for the instruction.
+ * The usedPrefixes represents the prefixes that were actually used by the instruction in the *decode* phase.
+ * Xoring between the two will result in a 'diff' which returns the prefixes that were read
+ * from the stream *and* that were never used in the actual decoding.
+ *
+ * Only one prefix per type can be set in decodedPrefixes from the stream.
+ * Therefore it's enough to check each type once and set the flag accordingly.
+ * That's why we had to book-keep each prefix type and its position.
+ * So now we know which bits we need to set exactly in the mask.
+ */
+ _iflags unusedPrefixesDiff = ps->decodedPrefixes ^ ps->usedPrefixes;
+
+ /* Examine unused prefixes by type: */
+ /*
+ * About REX: it might be set in the diff although it was never in the stream itself.
+ * This is because the vrex is shared between VEX and REX and some places flag it as REX usage, while
+ * we were really decoding an AVX instruction.
+ * It's not a big problem, because the prefixes_ignore func will ignore it anyway,
+ * since it wasn't seen earlier. But it's important to know this.
+ */
+ if (unusedPrefixesDiff & INST_PRE_REX) prefixes_ignore(ps, PFXIDX_REX);
+ if (unusedPrefixesDiff & INST_PRE_SEGOVRD_MASK) prefixes_ignore(ps, PFXIDX_SEG);
+ if (unusedPrefixesDiff & INST_PRE_LOKREP_MASK) prefixes_ignore(ps, PFXIDX_LOREP);
+ if (unusedPrefixesDiff & INST_PRE_OP_SIZE) prefixes_ignore(ps, PFXIDX_OP_SIZE);
+ if (unusedPrefixesDiff & INST_PRE_ADDR_SIZE) prefixes_ignore(ps, PFXIDX_ADRS);
+ /* If a VEX instruction was found, its prefix is considered as used, therefore no point for checking for it. */
+
+ return ps->unusedPrefixesMask;
+}
+
+/*
+ * Mark a prefix as unused, and bookkeep where we last saw this same type,
+ * because in the future we might want to disable it too.
+ */
+_INLINE_ void prefixes_track_unused(_PrefixState* ps, int index, _PrefixIndexer pi)
+{
+ prefixes_ignore(ps, pi);
+ /* Book-keep the current index for this type. */
+ ps->pfxIndexer[pi] = index;
+}
+
+/*
+ * Read as many prefixes as possible, up to 15 bytes, and halt when we encounter non-prefix byte.
+ * This algorithm tries to imitate a real processor, where the same prefix can appear a few times, etc.
+ * The tiny complexity is that we want to know when a prefix was superfluous and mark any copy of it as unused.
+ * Note that the last prefix of its type will be considered as used, and all the others (of same type) before it as unused.
+ */
+void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt)
+{
+ int index, done;
+ uint8_t vex;
+
+ /*
+ * First thing to do, scan for prefixes, there are six types of prefixes.
+ * There may be up to six prefixes before a single instruction, not the same type, no special order,
+ * except REX/VEX must precede immediately the first opcode byte.
+ * BTW - This is the reason why I didn't make the REP prefixes part of the instructions (STOS/SCAS/etc).
+ *
+ * Another thing, the instruction maximum size is 15 bytes, thus if we read more than 15 bytes, we will halt.
+ *
+ * We attach all prefixes to the next instruction, there might be two or more occurrences from the same prefix.
+ * Also, since VEX can be allowed only once we will test it separately.
+ */
+ for (index = 0, done = FALSE;
+ (codeLen > 0) && (code - ps->start < INST_MAXIMUM_SIZE);
+ code++, codeLen--, index++) {
+ /*
+ NOTE: AMD treat lock/rep as two different groups... But I am based on Intel.
+
+ - Lock and Repeat:
+ - 0xF0 — LOCK
+ - 0xF2 — REPNE/REPNZ
+ - 0xF3 - REP/REPE/REPZ
+ - Segment Override:
+ - 0x2E - CS
+ - 0x36 - SS
+ - 0x3E - DS
+ - 0x26 - ES
+ - 0x64 - FS
+ - 0x65 - GS
+ - Operand-Size Override: 0x66, switching default size.
+ - Address-Size Override: 0x67, switching default size.
+
+ 64 Bits:
+ - REX: 0x40 - 0x4f, extends register access.
+ - 2 Bytes VEX: 0xc4
+ - 3 Bytes VEX: 0xc5
+ 32 Bits:
+ - 2 Bytes VEX: 0xc4 11xx-xxxx
+ - 3 Bytes VEX: 0xc5 11xx-xxxx
+ */
+
+ /* Examine what type of prefix we got. */
+ switch (*code)
+ {
+ /* REX type, 64 bits decoding mode only: */
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (dt == Decode64Bits) {
+ ps->decodedPrefixes |= INST_PRE_REX;
+ ps->vrex = *code & 0xf; /* Keep only BXRW. */
+ ps->rexPos = code;
+ ps->prefixExtType = PET_REX;
+ prefixes_track_unused(ps, index, PFXIDX_REX);
+ } else done = TRUE; /* If we are not in 64 bits mode, it's an instruction, then halt. */
+ break;
+
+ /* LOCK and REPx type: */
+ case PREFIX_LOCK:
+ ps->decodedPrefixes |= INST_PRE_LOCK;
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
+ break;
+ case PREFIX_REPNZ:
+ ps->decodedPrefixes |= INST_PRE_REPNZ;
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
+ break;
+ case PREFIX_REP:
+ ps->decodedPrefixes |= INST_PRE_REP;
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
+ break;
+
+ /* Seg Overide type: */
+ case PREFIX_CS:
+ ps->decodedPrefixes |= INST_PRE_CS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_SS:
+ ps->decodedPrefixes |= INST_PRE_SS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_DS:
+ ps->decodedPrefixes |= INST_PRE_DS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_ES:
+ ps->decodedPrefixes |= INST_PRE_ES;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_FS:
+ ps->decodedPrefixes |= INST_PRE_FS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_GS:
+ ps->decodedPrefixes |= INST_PRE_GS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+
+ /* Op Size type: */
+ case PREFIX_OP_SIZE:
+ ps->decodedPrefixes |= INST_PRE_OP_SIZE;
+ prefixes_track_unused(ps, index, PFXIDX_OP_SIZE);
+ break;
+
+ /* Addr Size type: */
+ case PREFIX_ADDR_SIZE:
+ ps->decodedPrefixes |= INST_PRE_ADDR_SIZE;
+ prefixes_track_unused(ps, index, PFXIDX_ADRS);
+ break;
+
+ /* Non-prefix byte now, so break 2. */
+ default: done = TRUE; break;
+ }
+ if (done) break;
+ }
+
+ /* 2 Bytes VEX: */
+ if ((codeLen >= 2) &&
+ (*code == PREFIX_VEX2b) &&
+ ((code - ps->start) <= INST_MAXIMUM_SIZE - 2)) {
+ /*
+ * In 32 bits the second byte has to be in the special range of Mod=11.
+ * Otherwise it might be a normal LDS instruction.
+ */
+ if ((dt == Decode64Bits) || (*(code + 1) >= INST_DIVIDED_MODRM)) {
+ ps->vexPos = code + 1;
+ ps->decodedPrefixes |= INST_PRE_VEX;
+ ps->prefixExtType = PET_VEX2BYTES;
+
+ /*
+ * VEX 1 byte bits:
+ * |7-6--3-2-10|
+ * |R|vvvv|L|pp|
+ * |-----------|
+ */
+
+ /* -- Convert from VEX prefix to VREX flags -- */
+ vex = *ps->vexPos;
+ if (~vex & 0x80 && dt == Decode64Bits) ps->vrex |= PREFIX_EX_R; /* Convert VEX.R. */
+ if (vex & 4) ps->vrex |= PREFIX_EX_L; /* Convert VEX.L. */
+
+ code += 2;
+ }
+ }
+
+ /* 3 Bytes VEX: */
+ if ((codeLen >= 3) &&
+ (*code == PREFIX_VEX3b) &&
+ ((code - ps->start) <= INST_MAXIMUM_SIZE - 3) &&
+ (~ps->decodedPrefixes & INST_PRE_VEX)) {
+ /*
+ * In 32 bits the second byte has to be in the special range of Mod=11.
+ * Otherwise it might be a normal LES instruction.
+ * And we don't care now about the 3rd byte.
+ */
+ if ((dt == Decode64Bits) || (*(code + 1) >= INST_DIVIDED_MODRM)) {
+ ps->vexPos = code + 1;
+ ps->decodedPrefixes |= INST_PRE_VEX;
+ ps->prefixExtType = PET_VEX3BYTES;
+
+ /*
+ * VEX first and second bytes:
+ * |7-6-5-4----0| |7-6--3-2-10|
+ * |R|X|B|m-mmmm| |W|vvvv|L|pp|
+ * |------------| |-----------|
+ */
+
+ /* -- Convert from VEX prefix to VREX flags -- */
+ vex = *ps->vexPos;
+ ps->vrex |= ((~vex >> 5) & 0x7); /* Shift and invert VEX.R/X/B to their place */
+ vex = *(ps->vexPos + 1);
+ if (vex & 4) ps->vrex |= PREFIX_EX_L; /* Convert VEX.L. */
+ if (vex & 0x80) ps->vrex |= PREFIX_EX_W; /* Convert VEX.W. */
+
+ /* Clear some flags if the mode isn't 64 bits. */
+ if (dt != Decode64Bits) ps->vrex &= ~(PREFIX_EX_B | PREFIX_EX_X | PREFIX_EX_R | PREFIX_EX_W);
+
+ code += 3;
+ }
+ }
+
+ /*
+ * Save last byte scanned address, so the decoder could keep on scanning from this point and on and on and on.
+ * In addition the decoder is able to know that the last byte could lead to MMX/SSE instructions (preceding REX if exists).
+ */
+ ps->last = code; /* ps->last points to an opcode byte. */
+}
+
+/*
+ * For every memory-indirection operand we want to set its corresponding default segment.
+ * If the segment is being overrided, we need to see whether we use it or not.
+ * We will use it only if it's not the default one already.
+ */
+void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di)
+{
+ _iflags flags = 0;
+ if (dt == Decode64Bits) flags = ps->decodedPrefixes & INST_PRE_SEGOVRD_MASK64;
+ else flags = ps->decodedPrefixes & INST_PRE_SEGOVRD_MASK;
+
+ if ((flags == 0) || (flags == defaultSeg)) {
+ flags = defaultSeg;
+ di->segment |= SEGMENT_DEFAULT;
+ } else if (flags != defaultSeg) {
+ /* Use it only if it's non-default segment. */
+ ps->usedPrefixes |= flags;
+ }
+
+ /* ASSERT: R_XX must be below 128. */
+ switch (flags)
+ {
+ case INST_PRE_ES: di->segment |= R_ES; break;
+ case INST_PRE_CS: di->segment |= R_CS; break;
+ case INST_PRE_SS: di->segment |= R_SS; break;
+ case INST_PRE_DS: di->segment |= R_DS; break;
+ case INST_PRE_FS: di->segment |= R_FS; break;
+ case INST_PRE_GS: di->segment |= R_GS; break;
+ }
+
+ /* If it's one of the CS,SS,DS,ES and the mode is 64 bits, set segment it to none, since it's ignored. */
+ if ((dt == Decode64Bits) && (flags & INST_PRE_SEGOVRD_MASK32)) di->segment = R_NONE;
+}
diff --git a/distorm3.2-package/src/prefix.h b/distorm3.2-package/src/prefix.h
new file mode 100644
index 0000000..673aa50
--- /dev/null
+++ b/distorm3.2-package/src/prefix.h
@@ -0,0 +1,76 @@
+/*
+prefix.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef PREFIX_H
+#define PREFIX_H
+
+#include "config.h"
+#include "decoder.h"
+
+
+/* Specifies the type of the extension prefix, such as: REX, 2 bytes VEX, 3 bytes VEX. */
+typedef enum {PET_NONE = 0, PET_REX, PET_VEX2BYTES, PET_VEX3BYTES} _PrefixExtType;
+
+/* Specifies an index into a table of prefixes by their type. */
+typedef enum {PFXIDX_NONE = -1, PFXIDX_REX, PFXIDX_LOREP, PFXIDX_SEG, PFXIDX_OP_SIZE, PFXIDX_ADRS, PFXIDX_MAX} _PrefixIndexer;
+
+/*
+* This holds the prefixes state for the current instruction we decode.
+* decodedPrefixes includes all specific prefixes that the instruction got.
+* start is a pointer to the first prefix to take into account.
+* last is a pointer to the last byte we scanned.
+* Other pointers are used to keep track of prefixes positions and help us know if they appeared already and where.
+*/
+typedef struct {
+ _iflags decodedPrefixes, usedPrefixes;
+ const uint8_t *start, *last, *vexPos, *rexPos;
+ _PrefixExtType prefixExtType;
+ uint16_t unusedPrefixesMask;
+ /* Indicates whether the operand size prefix (0x66) was used as a mandatory prefix. */
+ int isOpSizeMandatory;
+ /* If VEX prefix is used, store the VEX.vvvv field. */
+ unsigned int vexV;
+ /* The fields B/X/R/W/L of REX and VEX are stored together in this byte. */
+ unsigned int vrex;
+
+ /* !! Make sure pfxIndexer is LAST! Otherwise memset won't work well with it. !! */
+
+ /* Holds the offset to the prefix byte by its type. */
+ int pfxIndexer[PFXIDX_MAX];
+} _PrefixState;
+
+/*
+* Intel supports 6 types of prefixes, whereas AMD supports 5 types (lock is seperated from rep/nz).
+* REX is the fifth prefix type, this time I'm based on AMD64.
+* VEX is the 6th, though it can't be repeated.
+*/
+#define MAX_PREFIXES (5)
+
+int prefixes_is_valid(unsigned int ch, _DecodeType dt);
+void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi);
+void prefixes_ignore_all(_PrefixState* ps);
+uint16_t prefixes_set_unused_mask(_PrefixState* ps);
+void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt);
+void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di);
+
+#endif /* PREFIX_H */
diff --git a/distorm3.2-package/src/textdefs.c b/distorm3.2-package/src/textdefs.c
new file mode 100644
index 0000000..eec26f1
--- /dev/null
+++ b/distorm3.2-package/src/textdefs.c
@@ -0,0 +1,184 @@
+/*
+textdefs.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "textdefs.h"
+
+#ifndef DISTORM_LIGHT
+
+static uint8_t Nibble2ChrTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+#define NIBBLE_TO_CHR Nibble2ChrTable[t]
+
+void _FASTCALL_ str_hex_b(_WString* s, unsigned int x)
+{
+ /*
+ * def prebuilt():
+ * s = ""
+ * for i in xrange(256):
+ * if ((i % 0x10) == 0):
+ * s += "\r\n"
+ * s += "\"%02x\", " % (i)
+ * return s
+ */
+ static int8_t TextBTable[256][3] = {
+ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
+ "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
+ "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
+ "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
+ "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
+ "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
+ "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
+ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
+ "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
+ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"
+ };
+
+ /*
+ * Fixed length of 3 including null terminate character.
+ */
+ memcpy(&s->p[s->length], TextBTable[x & 255], 3);
+ s->length += 2;
+}
+
+void _FASTCALL_ str_code_hb(_WString* s, unsigned int x)
+{
+ static int8_t TextHBTable[256][5] = {
+ /*
+ * def prebuilt():
+ * s = ""
+ * for i in xrange(256):
+ * if ((i % 0x10) == 0):
+ * s += "\r\n"
+ * s += "\"0x%x\", " % (i)
+ * return s
+ */
+ "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf",
+ "0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f",
+ "0x20", "0x21", "0x22", "0x23", "0x24", "0x25", "0x26", "0x27", "0x28", "0x29", "0x2a", "0x2b", "0x2c", "0x2d", "0x2e", "0x2f",
+ "0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37", "0x38", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "0x3f",
+ "0x40", "0x41", "0x42", "0x43", "0x44", "0x45", "0x46", "0x47", "0x48", "0x49", "0x4a", "0x4b", "0x4c", "0x4d", "0x4e", "0x4f",
+ "0x50", "0x51", "0x52", "0x53", "0x54", "0x55", "0x56", "0x57", "0x58", "0x59", "0x5a", "0x5b", "0x5c", "0x5d", "0x5e", "0x5f",
+ "0x60", "0x61", "0x62", "0x63", "0x64", "0x65", "0x66", "0x67", "0x68", "0x69", "0x6a", "0x6b", "0x6c", "0x6d", "0x6e", "0x6f",
+ "0x70", "0x71", "0x72", "0x73", "0x74", "0x75", "0x76", "0x77", "0x78", "0x79", "0x7a", "0x7b", "0x7c", "0x7d", "0x7e", "0x7f",
+ "0x80", "0x81", "0x82", "0x83", "0x84", "0x85", "0x86", "0x87", "0x88", "0x89", "0x8a", "0x8b", "0x8c", "0x8d", "0x8e", "0x8f",
+ "0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97", "0x98", "0x99", "0x9a", "0x9b", "0x9c", "0x9d", "0x9e", "0x9f",
+ "0xa0", "0xa1", "0xa2", "0xa3", "0xa4", "0xa5", "0xa6", "0xa7", "0xa8", "0xa9", "0xaa", "0xab", "0xac", "0xad", "0xae", "0xaf",
+ "0xb0", "0xb1", "0xb2", "0xb3", "0xb4", "0xb5", "0xb6", "0xb7", "0xb8", "0xb9", "0xba", "0xbb", "0xbc", "0xbd", "0xbe", "0xbf",
+ "0xc0", "0xc1", "0xc2", "0xc3", "0xc4", "0xc5", "0xc6", "0xc7", "0xc8", "0xc9", "0xca", "0xcb", "0xcc", "0xcd", "0xce", "0xcf",
+ "0xd0", "0xd1", "0xd2", "0xd3", "0xd4", "0xd5", "0xd6", "0xd7", "0xd8", "0xd9", "0xda", "0xdb", "0xdc", "0xdd", "0xde", "0xdf",
+ "0xe0", "0xe1", "0xe2", "0xe3", "0xe4", "0xe5", "0xe6", "0xe7", "0xe8", "0xe9", "0xea", "0xeb", "0xec", "0xed", "0xee", "0xef",
+ "0xf0", "0xf1", "0xf2", "0xf3", "0xf4", "0xf5", "0xf6", "0xf7", "0xf8", "0xf9", "0xfa", "0xfb", "0xfc", "0xfd", "0xfe", "0xff"
+ };
+
+ if (x < 0x10) { /* < 0x10 has a fixed length of 4 including null terminate. */
+ memcpy(&s->p[s->length], TextHBTable[x & 255], 4);
+ s->length += 3;
+ } else { /* >= 0x10 has a fixed length of 5 including null terminate. */
+ memcpy(&s->p[s->length], TextHBTable[x & 255], 5);
+ s->length += 4;
+ }
+}
+
+void _FASTCALL_ str_code_hdw(_WString* s, uint32_t x)
+{
+ int8_t* buf;
+ int i = 0, shift = 0;
+ unsigned int t = 0;
+
+ buf = (int8_t*)&s->p[s->length];
+
+ buf[0] = '0';
+ buf[1] = 'x';
+ buf += 2;
+
+ for (shift = 28; shift != 0; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+ t = x & 0xf;
+ buf[i++] = NIBBLE_TO_CHR;
+
+ s->length += i + 2;
+ buf[i] = '\0';
+}
+
+void _FASTCALL_ str_code_hqw(_WString* s, uint8_t src[8])
+{
+ int8_t* buf;
+ int i = 0, shift = 0;
+ uint32_t x = RULONG(&src[sizeof(int32_t)]);
+ int t;
+
+ buf = (int8_t*)&s->p[s->length];
+ buf[0] = '0';
+ buf[1] = 'x';
+ buf += 2;
+
+ for (shift = 28; shift != -4; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+
+ x = RULONG(src);
+ for (shift = 28; shift != 0; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+ t = x & 0xf;
+ buf[i++] = NIBBLE_TO_CHR;
+
+ s->length += i + 2;
+ buf[i] = '\0';
+}
+
+#ifdef SUPPORT_64BIT_OFFSET
+void _FASTCALL_ str_off64(_WString* s, OFFSET_INTEGER x)
+{
+ int8_t* buf;
+ int i = 0, shift = 0;
+ OFFSET_INTEGER t = 0;
+
+ buf = (int8_t*)&s->p[s->length];
+
+ buf[0] = '0';
+ buf[1] = 'x';
+ buf += 2;
+
+ for (shift = 60; shift != 0; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+ t = x & 0xf;
+ buf[i++] = NIBBLE_TO_CHR;
+
+ s->length += i + 2;
+ buf[i] = '\0';
+}
+#endif /* SUPPORT_64BIT_OFFSET */
+
+#endif /* DISTORM_LIGHT */
diff --git a/distorm3.2-package/src/textdefs.h b/distorm3.2-package/src/textdefs.h
new file mode 100644
index 0000000..275cf88
--- /dev/null
+++ b/distorm3.2-package/src/textdefs.h
@@ -0,0 +1,71 @@
+/*
+textdefs.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef TEXTDEFS_H
+#define TEXTDEFS_H
+
+#include "config.h"
+#include "wstring.h"
+
+#ifndef DISTORM_LIGHT
+
+#define PLUS_DISP_CHR '+'
+#define MINUS_DISP_CHR '-'
+#define OPEN_CHR '['
+#define CLOSE_CHR ']'
+#define SP_CHR ' '
+#define SEG_OFF_CHR ':'
+
+/*
+Naming Convention:
+
+* get - returns a pointer to a string.
+* str - concatenates to string.
+
+* hex - means the function is used for hex dump (number is padded to required size) - Little Endian output.
+* code - means the function is used for disassembled instruction - Big Endian output.
+* off - means the function is used for 64bit offset - Big Endian output.
+
+* h - '0x' in front of the string.
+
+* b - byte
+* dw - double word (can be used for word also)
+* qw - quad word
+
+* all numbers are in HEX.
+*/
+
+extern int8_t TextBTable[256][4];
+
+void _FASTCALL_ str_hex_b(_WString* s, unsigned int x);
+void _FASTCALL_ str_code_hb(_WString* s, unsigned int x);
+void _FASTCALL_ str_code_hdw(_WString* s, uint32_t x);
+void _FASTCALL_ str_code_hqw(_WString* s, uint8_t src[8]);
+
+#ifdef SUPPORT_64BIT_OFFSET
+void _FASTCALL_ str_off64(_WString* s, OFFSET_INTEGER x);
+#endif
+
+#endif /* DISTORM_LIGHT */
+
+#endif /* TEXTDEFS_H */
diff --git a/distorm3.2-package/src/wstring.c b/distorm3.2-package/src/wstring.c
new file mode 100644
index 0000000..26b2260
--- /dev/null
+++ b/distorm3.2-package/src/wstring.c
@@ -0,0 +1,59 @@
+/*
+wstring.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "wstring.h"
+
+#ifndef DISTORM_LIGHT
+
+void strclear_WS(_WString* s)
+{
+ s->p[0] = '\0';
+ s->length = 0;
+}
+
+void chrcat_WS(_WString* s, uint8_t ch)
+{
+ s->p[s->length] = ch;
+ s->p[s->length + 1] = '\0';
+ s->length += 1;
+}
+
+void strcpylen_WS(_WString* s, const int8_t* buf, unsigned int len)
+{
+ s->length = len;
+ memcpy((int8_t*)s->p, buf, len + 1);
+}
+
+void strcatlen_WS(_WString* s, const int8_t* buf, unsigned int len)
+{
+ memcpy((int8_t*)&s->p[s->length], buf, len + 1);
+ s->length += len;
+}
+
+void strcat_WS(_WString* s, const _WString* s2)
+{
+ memcpy((int8_t*)&s->p[s->length], s2->p, s2->length + 1);
+ s->length += s2->length;
+}
+
+#endif /* DISTORM_LIGHT */
diff --git a/distorm3.2-package/src/wstring.h b/distorm3.2-package/src/wstring.h
new file mode 100644
index 0000000..6ff9ccf
--- /dev/null
+++ b/distorm3.2-package/src/wstring.h
@@ -0,0 +1,47 @@
+/*
+wstring.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef WSTRING_H
+#define WSTRING_H
+
+#include "config.h"
+
+#ifndef DISTORM_LIGHT
+
+void strclear_WS(_WString* s);
+void chrcat_WS(_WString* s, uint8_t ch);
+void strcpylen_WS(_WString* s, const int8_t* buf, unsigned int len);
+void strcatlen_WS(_WString* s, const int8_t* buf, unsigned int len);
+void strcat_WS(_WString* s, const _WString* s2);
+
+/*
+* Warning, this macro should be used only when the compiler knows the size of string in advance!
+* This macro is used in order to spare the call to strlen when the strings are known already.
+* Note: sizeof includes NULL terminated character.
+*/
+#define strcat_WSN(s, t) strcatlen_WS((s), ((const int8_t*)t), sizeof((t))-1)
+#define strcpy_WSN(s, t) strcpylen_WS((s), ((const int8_t*)t), sizeof((t))-1)
+
+#endif /* DISTORM_LIGHT */
+
+#endif /* WSTRING_H */
diff --git a/distorm3.2-package/src/x86defs.c b/distorm3.2-package/src/x86defs.c
new file mode 100644
index 0000000..4ee7e42
--- /dev/null
+++ b/distorm3.2-package/src/x86defs.c
@@ -0,0 +1,50 @@
+/*
+x86defs.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#include "x86defs.h"
+#include "instructions.h"
+#include "../include/mnemonics.h"
+
+
+/*
+ * The first field of an _InstInfo is the flagsInex, which goes into FlagsTable in insts.c
+ * Since this table is auto generated in disOps, we have to make sure that the first 5 entries
+ * are reserved for our use here.
+ * The following defined inst-infos have to be synced manually every time you change insts.c.
+ */
+
+_InstInfo II_arpl = {0 /* INST_MODRM_REQUIRED */, OT_REG16, OT_RM16, ISC_INTEGER << 3, I_ARPL};
+/*
+ * MOVSXD:
+ * This is the worst defined instruction ever. It has so many variations.
+ * I decided after a third review, to make it like MOVSXD RAX, EAX when there IS a REX.W.
+ * Otherwise it will be MOVSXD EAX, EAX, which really zero extends to RAX.
+ * Completely ignoring DB 0x66, which is possible by the docs, BTW.
+ */
+_InstInfo II_movsxd = {1 /* INST_MODRM_REQUIRED | INST_PRE_REX | INST_64BITS */, OT_RM32, OT_REG32_64, ISC_INTEGER << 3, I_MOVSXD};
+
+_InstInfo II_nop = {2 /* INST_FLAGS_NONE */, OT_NONE, OT_NONE, ISC_INTEGER << 3, I_NOP};
+
+_InstInfo II_pause = {3 /* INST_FLAGS_NONE */, OT_NONE, OT_NONE, ISC_INTEGER << 3, I_PAUSE};
+
+_InstInfo II_3dnow = {4 /* INST_32BITS | INST_MODRM_REQUIRED | INST_3DNOW_FETCH */, OT_MM64, OT_MM, ISC_3DNOW << 3, I_UNDEFINED};
diff --git a/distorm3.2-package/src/x86defs.h b/distorm3.2-package/src/x86defs.h
new file mode 100644
index 0000000..f35ff42
--- /dev/null
+++ b/distorm3.2-package/src/x86defs.h
@@ -0,0 +1,115 @@
+/*
+x86defs.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2012 Gil Dabah
+
+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
+*/
+
+
+#ifndef X86DEFS_H
+#define X86DEFS_H
+
+#include "config.h"
+#include "instructions.h"
+
+
+#define SEG_REGS_MAX (6)
+#define CREGS_MAX (9)
+#define DREGS_MAX (8)
+
+/* Maximum instruction size, including prefixes */
+#define INST_MAXIMUM_SIZE (15)
+
+/* Maximum range of imm8 (comparison type) of special SSE CMP instructions. */
+#define INST_CMP_MAX_RANGE (8)
+
+/* Maximum range of imm8 (comparison type) of special AVX VCMP instructions. */
+#define INST_VCMP_MAX_RANGE (32)
+
+/* Wait instruction byte code. */
+#define INST_WAIT_INDEX (0x9b)
+
+/* Lea instruction byte code. */
+#define INST_LEA_INDEX (0x8d)
+
+/*
+ * Minimal MODR/M value of divided instructions.
+ * It's 0xc0, two MSBs set, which indicates a general purpose register is used too.
+ */
+#define INST_DIVIDED_MODRM (0xc0)
+
+/* This is the escape byte value used for 3DNow! instructions. */
+#define _3DNOW_ESCAPE_BYTE (0x0f)
+
+#define PREFIX_LOCK (0xf0)
+#define PREFIX_REPNZ (0xf2)
+#define PREFIX_REP (0xf3)
+#define PREFIX_CS (0x2e)
+#define PREFIX_SS (0x36)
+#define PREFIX_DS (0x3e)
+#define PREFIX_ES (0x26)
+#define PREFIX_FS (0x64)
+#define PREFIX_GS (0x65)
+#define PREFIX_OP_SIZE (0x66)
+#define PREFIX_ADDR_SIZE (0x67)
+#define PREFIX_VEX2b (0xc5)
+#define PREFIX_VEX3b (0xc4)
+
+/* REX prefix value range, 64 bits mode decoding only. */
+#define PREFIX_REX_LOW (0x40)
+#define PREFIX_REX_HI (0x4f)
+/* In order to use the extended GPR's we have to add 8 to the Modr/M info values. */
+#define EX_GPR_BASE (8)
+
+/* Mask for REX and VEX features: */
+/* Base */
+#define PREFIX_EX_B (1)
+/* Index */
+#define PREFIX_EX_X (2)
+/* Register */
+#define PREFIX_EX_R (4)
+/* Operand Width */
+#define PREFIX_EX_W (8)
+/* Vector Lengh */
+#define PREFIX_EX_L (0x10)
+
+/*
+ * The inst_lookup will return on of these two instructions according to the specified decoding mode.
+ * ARPL or MOVSXD on 64 bits is one byte instruction at index 0x63.
+ */
+#define INST_ARPL_INDEX (0x63)
+extern _InstInfo II_arpl;
+extern _InstInfo II_movsxd;
+
+/*
+ * The NOP instruction can be prefixed by REX in 64bits, therefore we have to decide in runtime whether it's an XCHG or NOP instruction.
+ * If 0x90 is prefixed by a useable REX it will become XCHG, otherwise it will become a NOP.
+ * Also note that if it's prefixed by 0xf3, it becomes a Pause.
+ */
+#define INST_NOP_INDEX (0x90)
+extern _InstInfo II_nop;
+extern _InstInfo II_pause;
+
+/*
+ * Used for letting the extract operand know the type of operands without knowing the
+ * instruction itself yet, because of the way those instructions work.
+ * See function instructions.c!inst_lookup_3dnow.
+ */
+extern _InstInfo II_3dnow;
+
+#endif /* X86DEFS_H */
diff --git a/hook_file.c b/hook_file.c
new file mode 100644
index 0000000..94bb075
--- /dev/null
+++ b/hook_file.c
@@ -0,0 +1,505 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+#include "misc.h"
+#include "ignore.h"
+#include "lookup.h"
+
+static IS_SUCCESS_NTSTATUS();
+
+#define DUMP_FILE_MASK (GENERIC_WRITE | FILE_GENERIC_WRITE | \
+ FILE_WRITE_DATA | FILE_APPEND_DATA | STANDARD_RIGHTS_WRITE | \
+ STANDARD_RIGHTS_ALL)
+
+#define HDDVOL1 L"\\Device\\HarddiskVolume1"
+
+// length of a hardcoded unicode string
+#define UNILEN(x) (sizeof(x) / sizeof(wchar_t) - 1)
+
+typedef struct _file_record_t {
+ unsigned int attributes;
+ size_t length;
+ wchar_t filename[0];
+} file_record_t;
+
+static lookup_t g_files;
+
+void file_init()
+{
+ lookup_init(&g_files);
+}
+
+static void new_file(const UNICODE_STRING *obj)
+{
+ const wchar_t *str = obj->Buffer;
+ unsigned int len = obj->Length / sizeof(wchar_t);
+
+ // if it's a path including \??\ then we can send it straight away,
+ // but we strip the \??\ part
+ if(len > 4 && !wcsncmp(str, L"\\??\\", 4)) {
+ pipe("FILE_NEW:%S", len - 4, str + 4);
+ }
+ // maybe it's an absolute path (or a relative path with a harddisk,
+ // such as C:abc.txt)
+ else if(isalpha(str[0]) != 0 && str[1] == ':') {
+ pipe("FILE_NEW:%S", len, str);
+ }
+ // the filename starts with \Device\HarddiskVolume1, which is
+ // basically just C:
+ else if(!wcsnicmp(str, HDDVOL1, UNILEN(HDDVOL1))) {
+ str += UNILEN(HDDVOL1), len -= UNILEN(HDDVOL1);
+ pipe("FILE_NEW:C:%S", len, str);
+ }
+}
+
+static void cache_file(HANDLE file_handle, const wchar_t *path,
+ unsigned int length, unsigned int attributes)
+{
+ file_record_t *r = lookup_add(&g_files, (unsigned int) file_handle,
+ sizeof(file_record_t) + length * sizeof(wchar_t) + sizeof(wchar_t));
+
+ *r = (file_record_t) {
+ .attributes = attributes,
+ .length = length,
+ };
+
+ wcsncpy(r->filename, path, r->length + 1);
+}
+
+static void file_write(HANDLE file_handle)
+{
+ file_record_t *r = lookup_get(&g_files, (unsigned int) file_handle, NULL);
+ if(r != NULL) {
+ UNICODE_STRING str = {
+ // microsoft actually meant "size"
+ .Length = r->length * sizeof(wchar_t),
+ .MaximumLength = (r->length + 1) * sizeof(wchar_t) ,
+ .Buffer = r->filename,
+ };
+
+ // we do in fact want to dump this file because it was written to
+ new_file(&str);
+
+ // delete the file record from the list
+ lookup_del(&g_files, (unsigned int) file_handle);
+ }
+}
+
+static void handle_new_file(HANDLE file_handle, const OBJECT_ATTRIBUTES *obj)
+{
+ if(is_directory_objattr(obj) == 0 && is_ignored_file_objattr(obj) == 0) {
+
+ wchar_t fname[MAX_PATH_PLUS_TOLERANCE]; uint32_t length;
+
+ length = path_from_object_attributes(obj,
+ fname, MAX_PATH_PLUS_TOLERANCE);
+
+ length = ensure_absolute_path(fname, fname, length);
+
+ // cache this file
+ cache_file(file_handle, fname, length, obj->Attributes);
+ }
+}
+
+void file_close(HANDLE file_handle)
+{
+ lookup_del(&g_files, (unsigned int) file_handle);
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateFile,
+ __out PHANDLE FileHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in_opt PLARGE_INTEGER AllocationSize,
+ __in ULONG FileAttributes,
+ __in ULONG ShareAccess,
+ __in ULONG CreateDisposition,
+ __in ULONG CreateOptions,
+ __in PVOID EaBuffer,
+ __in ULONG EaLength
+) {
+ NTSTATUS ret = Old_NtCreateFile(FileHandle, DesiredAccess,
+ ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes,
+ ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
+ LOQ("PpOll", "FileHandle", FileHandle, "DesiredAccess", DesiredAccess,
+ "FileName", ObjectAttributes, "CreateDisposition", CreateDisposition,
+ "ShareAccess", ShareAccess);
+ if(NT_SUCCESS(ret) && DesiredAccess & DUMP_FILE_MASK) {
+ handle_new_file(*FileHandle, ObjectAttributes);
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenFile,
+ __out PHANDLE FileHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in ULONG ShareAccess,
+ __in ULONG OpenOptions
+) {
+ NTSTATUS ret = Old_NtOpenFile(FileHandle, DesiredAccess, ObjectAttributes,
+ IoStatusBlock, ShareAccess, OpenOptions);
+ LOQ("PpOl", "FileHandle", FileHandle, "DesiredAccess", DesiredAccess,
+ "FileName", ObjectAttributes, "ShareAccess", ShareAccess);
+ if(NT_SUCCESS(ret) && DesiredAccess & DUMP_FILE_MASK) {
+ handle_new_file(*FileHandle, ObjectAttributes);
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtReadFile,
+ __in HANDLE FileHandle,
+ __in_opt HANDLE Event,
+ __in_opt PIO_APC_ROUTINE ApcRoutine,
+ __in_opt PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __out PVOID Buffer,
+ __in ULONG Length,
+ __in_opt PLARGE_INTEGER ByteOffset,
+ __in_opt PULONG Key
+) {
+ NTSTATUS ret = Old_NtReadFile(FileHandle, Event, ApcRoutine, ApcContext,
+ IoStatusBlock, Buffer, Length, ByteOffset, Key);
+ LOQ("pb", "FileHandle", FileHandle,
+ "Buffer", IoStatusBlock->Information, Buffer);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtWriteFile,
+ __in HANDLE FileHandle,
+ __in_opt HANDLE Event,
+ __in_opt PIO_APC_ROUTINE ApcRoutine,
+ __in_opt PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in PVOID Buffer,
+ __in ULONG Length,
+ __in_opt PLARGE_INTEGER ByteOffset,
+ __in_opt PULONG Key
+) {
+ NTSTATUS ret = Old_NtWriteFile(FileHandle, Event, ApcRoutine, ApcContext,
+ IoStatusBlock, Buffer, Length, ByteOffset, Key);
+ LOQ("pb", "FileHandle", FileHandle,
+ "Buffer", IoStatusBlock->Information, Buffer);
+ if(NT_SUCCESS(ret)) {
+ file_write(FileHandle);
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtDeleteFile,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+) {
+ pipe("FILE_DEL:%O", ObjectAttributes);
+
+ NTSTATUS ret = Old_NtDeleteFile(ObjectAttributes);
+ LOQ("O", "FileName", ObjectAttributes);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtDeviceIoControlFile,
+ __in HANDLE FileHandle,
+ __in HANDLE Event,
+ __in PIO_APC_ROUTINE ApcRoutine,
+ __in PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in ULONG IoControlCode,
+ __in PVOID InputBuffer,
+ __in ULONG InputBufferLength,
+ __out PVOID OutputBuffer,
+ __in ULONG OutputBufferLength
+) {
+ NTSTATUS ret = Old_NtDeviceIoControlFile(FileHandle, Event,
+ ApcRoutine, ApcContext, IoStatusBlock, IoControlCode,
+ InputBuffer, InputBufferLength, OutputBuffer,
+ OutputBufferLength);
+ LOQ("pbb", "FileHandle", FileHandle,
+ "InputBuffer", InputBufferLength, InputBuffer,
+ "OutputBuffer", IoStatusBlock->Information, OutputBuffer);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtQueryDirectoryFile,
+ __in HANDLE FileHandle,
+ __in_opt HANDLE Event,
+ __in_opt PIO_APC_ROUTINE ApcRoutine,
+ __in_opt PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __out PVOID FileInformation,
+ __in ULONG Length,
+ __in FILE_INFORMATION_CLASS FileInformationClass,
+ __in BOOLEAN ReturnSingleEntry,
+ __in_opt PUNICODE_STRING FileName,
+ __in BOOLEAN RestartScan
+) {
+ NTSTATUS ret = Old_NtQueryDirectoryFile(FileHandle, Event,
+ ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
+ Length, FileInformationClass, ReturnSingleEntry,
+ FileName, RestartScan);
+ LOQ("pbo", "FileHandle", FileHandle,
+ "FileInformation", IoStatusBlock->Information, FileInformation,
+ "FileName", FileName);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtQueryInformationFile,
+ __in HANDLE FileHandle,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __out PVOID FileInformation,
+ __in ULONG Length,
+ __in FILE_INFORMATION_CLASS FileInformationClass
+) {
+ NTSTATUS ret = Old_NtQueryInformationFile(FileHandle, IoStatusBlock,
+ FileInformation, Length, FileInformationClass);
+ LOQ("pb", "FileHandle", FileHandle,
+ "FileInformation", IoStatusBlock->Information, FileInformation);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtSetInformationFile,
+ __in HANDLE FileHandle,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in PVOID FileInformation,
+ __in ULONG Length,
+ __in FILE_INFORMATION_CLASS FileInformationClass
+) {
+ if(FileInformation != NULL && Length == sizeof(BOOLEAN) &&
+ FileInformationClass == FileDispositionInformation &&
+ *(BOOLEAN *) FileInformation != FALSE) {
+
+ wchar_t path[MAX_PATH_PLUS_TOLERANCE];
+ path_from_handle(FileHandle, path, (unsigned int) MAX_PATH_PLUS_TOLERANCE);
+ pipe("FILE_DEL:%Z", path);
+ }
+
+ NTSTATUS ret = Old_NtSetInformationFile(FileHandle, IoStatusBlock,
+ FileInformation, Length, FileInformationClass);
+ LOQ("pb", "FileHandle", FileHandle,
+ "FileInformation", IoStatusBlock->Information, FileInformation);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenDirectoryObject,
+ __out PHANDLE DirectoryHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+) {
+ NTSTATUS ret = Old_NtOpenDirectoryObject(DirectoryHandle, DesiredAccess,
+ ObjectAttributes);
+ LOQ("PlO", "DirectoryHandle", DirectoryHandle,
+ "DesiredAccess", DesiredAccess, "ObjectAttributes", ObjectAttributes);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateDirectoryObject,
+ __out PHANDLE DirectoryHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+) {
+ NTSTATUS ret = Old_NtCreateDirectoryObject(DirectoryHandle, DesiredAccess,
+ ObjectAttributes);
+ LOQ("PlO", "DirectoryHandle", DirectoryHandle,
+ "DesiredAccess", DesiredAccess, "ObjectAttributes", ObjectAttributes);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, CreateDirectoryW,
+ __in LPWSTR lpPathName,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_CreateDirectoryW(lpPathName, lpSecurityAttributes);
+ LOQ("u", "DirectoryName", lpPathName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, CreateDirectoryExW,
+ __in LPWSTR lpTemplateDirectory,
+ __in LPWSTR lpNewDirectory,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_CreateDirectoryExW(lpTemplateDirectory, lpNewDirectory,
+ lpSecurityAttributes);
+ LOQ("u", "DirectoryName", lpNewDirectory);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, RemoveDirectoryA,
+ __in LPCTSTR lpPathName
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_RemoveDirectoryA(lpPathName);
+ LOQ("s", "DirectoryName", lpPathName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, RemoveDirectoryW,
+ __in LPWSTR lpPathName
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_RemoveDirectoryW(lpPathName);
+ LOQ("u", "DirectoryName", lpPathName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, MoveFileWithProgressW,
+ __in LPWSTR lpExistingFileName,
+ __in_opt LPWSTR lpNewFileName,
+ __in_opt LPPROGRESS_ROUTINE lpProgressRoutine,
+ __in_opt LPVOID lpData,
+ __in DWORD dwFlags
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_MoveFileWithProgressW(lpExistingFileName, lpNewFileName,
+ lpProgressRoutine, lpData, dwFlags);
+ LOQ("uu", "ExistingFileName", lpExistingFileName,
+ "NewFileName", lpNewFileName);
+ if(ret != FALSE) {
+ pipe("FILE_MOVE:%Z::%Z", lpExistingFileName, lpNewFileName);
+ }
+ return ret;
+}
+
+HOOKDEF(HANDLE, WINAPI, FindFirstFileExA,
+ __in LPCTSTR lpFileName,
+ __in FINDEX_INFO_LEVELS fInfoLevelId,
+ __out LPVOID lpFindFileData,
+ __in FINDEX_SEARCH_OPS fSearchOp,
+ __reserved LPVOID lpSearchFilter,
+ __in DWORD dwAdditionalFlags
+) {
+ IS_SUCCESS_HANDLE();
+
+ HANDLE ret = Old_FindFirstFileExA(lpFileName, fInfoLevelId,
+ lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
+ LOQ("s", "FileName", lpFileName);
+ return ret;
+}
+
+HOOKDEF(HANDLE, WINAPI, FindFirstFileExW,
+ __in LPWSTR lpFileName,
+ __in FINDEX_INFO_LEVELS fInfoLevelId,
+ __out LPVOID lpFindFileData,
+ __in FINDEX_SEARCH_OPS fSearchOp,
+ __reserved LPVOID lpSearchFilter,
+ __in DWORD dwAdditionalFlags
+) {
+ IS_SUCCESS_HANDLE();
+
+ HANDLE ret = Old_FindFirstFileExW(lpFileName, fInfoLevelId,
+ lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
+ LOQ("u", "FileName", lpFileName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, CopyFileA,
+ __in LPCTSTR lpExistingFileName,
+ __in LPCTSTR lpNewFileName,
+ __in BOOL bFailIfExists
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_CopyFileA(lpExistingFileName, lpNewFileName,
+ bFailIfExists);
+ LOQ("ss", "ExistingFileName", lpExistingFileName,
+ "NewFileName", lpNewFileName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, CopyFileW,
+ __in LPWSTR lpExistingFileName,
+ __in LPWSTR lpNewFileName,
+ __in BOOL bFailIfExists
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_CopyFileW(lpExistingFileName, lpNewFileName,
+ bFailIfExists);
+ LOQ("uu", "ExistingFileName", lpExistingFileName,
+ "NewFileName", lpNewFileName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, CopyFileExW,
+ _In_ LPWSTR lpExistingFileName,
+ _In_ LPWSTR lpNewFileName,
+ _In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine,
+ _In_opt_ LPVOID lpData,
+ _In_opt_ LPBOOL pbCancel,
+ _In_ DWORD dwCopyFlags
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_CopyFileExW(lpExistingFileName, lpNewFileName,
+ lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
+ LOQ("uul", "ExistingFileName", lpExistingFileName,
+ "NewFileName", lpNewFileName, "CopyFlags", dwCopyFlags);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, DeleteFileA,
+ __in LPCSTR lpFileName
+) {
+ IS_SUCCESS_BOOL();
+
+ wchar_t path[MAX_PATH];
+
+ // copy ascii to unicode string
+ for (int i = 0; lpFileName[i] != 0 && i < MAX_PATH; i++) {
+ path[i] = lpFileName[i];
+ }
+
+ ensure_absolute_path(path, path, strlen(lpFileName));
+
+ pipe("FILE_DEL:%Z", path);
+
+ BOOL ret = Old_DeleteFileA(lpFileName);
+ LOQ("s", "FileName", lpFileName);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, DeleteFileW,
+ __in LPWSTR lpFileName
+) {
+ IS_SUCCESS_BOOL();
+
+ wchar_t path[MAX_PATH];
+
+ ensure_absolute_path(path, lpFileName, lstrlenW(lpFileName));
+
+ pipe("FILE_DEL:%Z", path);
+
+ BOOL ret = Old_DeleteFileW(lpFileName);
+ LOQ("u", "FileName", lpFileName);
+ return ret;
+}
diff --git a/hook_file.h b/hook_file.h
new file mode 100644
index 0000000..1307e99
--- /dev/null
+++ b/hook_file.h
@@ -0,0 +1,20 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+void file_init();
+void file_close(HANDLE file_handle);
diff --git a/hook_misc.c b/hook_misc.c
new file mode 100644
index 0000000..02d0884
--- /dev/null
+++ b/hook_misc.c
@@ -0,0 +1,246 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+#include "misc.h"
+#include "hook_file.h"
+#include "hook_sleep.h"
+
+static IS_SUCCESS_NTSTATUS();
+
+HOOKDEF(HHOOK, WINAPI, SetWindowsHookExA,
+ __in int idHook,
+ __in HOOKPROC lpfn,
+ __in HINSTANCE hMod,
+ __in DWORD dwThreadId
+) {
+ IS_SUCCESS_HHOOK();
+
+ HHOOK ret = Old_SetWindowsHookExA(idHook, lpfn, hMod, dwThreadId);
+ LOQ("lppl", "HookIdentifier", idHook, "ProcedureAddress", lpfn,
+ "ModuleAddress", hMod, "ThreadId", dwThreadId);
+ return ret;
+}
+
+HOOKDEF(HHOOK, WINAPI, SetWindowsHookExW,
+ __in int idHook,
+ __in HOOKPROC lpfn,
+ __in HINSTANCE hMod,
+ __in DWORD dwThreadId
+) {
+ IS_SUCCESS_HHOOK();
+
+ HHOOK ret = Old_SetWindowsHookExW(idHook, lpfn, hMod, dwThreadId);
+ LOQ("lppl", "HookIdentifier", idHook, "ProcedureAddress", lpfn,
+ "ModuleAddress", hMod, "ThreadId", dwThreadId);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, UnhookWindowsHookEx,
+ __in HHOOK hhk
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_UnhookWindowsHookEx(hhk);
+ LOQ("p", "HookHandle", hhk);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, LdrLoadDll,
+ __in_opt PWCHAR PathToFile,
+ __in_opt ULONG Flags,
+ __in PUNICODE_STRING ModuleFileName,
+ __out PHANDLE ModuleHandle
+) {
+ COPY_UNICODE_STRING(library, ModuleFileName);
+
+ NTSTATUS ret = Old_LdrLoadDll(PathToFile, Flags, ModuleFileName,
+ ModuleHandle);
+ LOQ("loP", "Flags", Flags, "FileName", &library,
+ "BaseAddress", ModuleHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, LdrGetDllHandle,
+ __in_opt PWORD pwPath,
+ __in_opt PVOID Unused,
+ __in PUNICODE_STRING ModuleFileName,
+ __out PHANDLE pHModule
+) {
+ NTSTATUS ret = Old_LdrGetDllHandle(pwPath, Unused, ModuleFileName,
+ pHModule);
+ LOQ("oP", "FileName", ModuleFileName, "ModuleHandle", pHModule);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, LdrGetProcedureAddress,
+ __in HMODULE ModuleHandle,
+ __in_opt PANSI_STRING FunctionName,
+ __in_opt WORD Ordinal,
+ __out PVOID *FunctionAddress
+) {
+ NTSTATUS ret = Old_LdrGetProcedureAddress(ModuleHandle, FunctionName,
+ Ordinal, FunctionAddress);
+ LOQ("pSlP", "ModuleHandle", ModuleHandle,
+ "FunctionName", FunctionName != NULL ? FunctionName->Length : 0,
+ FunctionName != NULL ? FunctionName->Buffer : NULL,
+ "Ordinal", Ordinal, "FunctionAddress", FunctionAddress);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, DeviceIoControl,
+ __in HANDLE hDevice,
+ __in DWORD dwIoControlCode,
+ __in_opt LPVOID lpInBuffer,
+ __in DWORD nInBufferSize,
+ __out_opt LPVOID lpOutBuffer,
+ __in DWORD nOutBufferSize,
+ __out_opt LPDWORD lpBytesReturned,
+ __inout_opt LPOVERLAPPED lpOverlapped
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer,
+ nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned,
+ lpOverlapped);
+ LOQ("plbb", "DeviceHandle", hDevice, "IoControlCode", dwIoControlCode,
+ "InBuffer", nInBufferSize, lpInBuffer,
+ "OutBuffer", lpBytesReturned ? *lpBytesReturned : nOutBufferSize,
+ lpOutBuffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, ExitWindowsEx,
+ __in UINT uFlags,
+ __in DWORD dwReason
+) {
+ IS_SUCCESS_BOOL();
+
+ int ret = 0;
+ LOQ("ll", "Flags", uFlags, "Reason", dwReason);
+ return Old_ExitWindowsEx(uFlags, dwReason);
+}
+
+HOOKDEF(BOOL, WINAPI, IsDebuggerPresent,
+ void
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_IsDebuggerPresent();
+ LOQ("");
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, LookupPrivilegeValueW,
+ __in_opt LPWSTR lpSystemName,
+ __in LPWSTR lpName,
+ __out PLUID lpLuid
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_LookupPrivilegeValueW(lpSystemName, lpName, lpLuid);
+ LOQ("uu", "SystemName", lpSystemName, "PrivilegeName", lpName);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtClose,
+ __in HANDLE Handle
+) {
+ NTSTATUS ret = Old_NtClose(Handle);
+ LOQ("p", "Handle", Handle);
+ if(NT_SUCCESS(ret)) {
+ file_close(Handle);
+ }
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, WriteConsoleA,
+ _In_ HANDLE hConsoleOutput,
+ _In_ const VOID *lpBuffer,
+ _In_ DWORD nNumberOfCharsToWrite,
+ _Out_ LPDWORD lpNumberOfCharsWritten,
+ _Reserved_ LPVOID lpReseverd
+) {
+ BOOL ret = Old_WriteConsoleA(hConsoleOutput, lpBuffer,
+ nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReseverd);
+ LOQ("pS", "ConsoleHandle", hConsoleOutput,
+ "Buffer", nNumberOfCharsToWrite, lpBuffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, WriteConsoleW,
+ _In_ HANDLE hConsoleOutput,
+ _In_ const VOID *lpBuffer,
+ _In_ DWORD nNumberOfCharsToWrite,
+ _Out_ LPDWORD lpNumberOfCharsWritten,
+ _Reserved_ LPVOID lpReseverd
+) {
+ BOOL ret = Old_WriteConsoleW(hConsoleOutput, lpBuffer,
+ nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReseverd);
+ LOQ("pU", "ConsoleHandle", hConsoleOutput,
+ "Buffer", nNumberOfCharsToWrite, lpBuffer);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, ZwMapViewOfSection,
+ _In_ HANDLE SectionHandle,
+ _In_ HANDLE ProcessHandle,
+ __inout PVOID *BaseAddress,
+ _In_ ULONG_PTR ZeroBits,
+ _In_ SIZE_T CommitSize,
+ __inout PLARGE_INTEGER SectionOffset,
+ __inout PSIZE_T ViewSize,
+ __in UINT InheritDisposition,
+ __in ULONG AllocationType,
+ __in ULONG Win32Protect
+) {
+ NTSTATUS ret = Old_ZwMapViewOfSection(SectionHandle, ProcessHandle,
+ BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize,
+ InheritDisposition, AllocationType, Win32Protect);
+ LOQ("ppPp", "SectionHandle", SectionHandle,
+ "ProcessHandle", ProcessHandle, "BaseAddress", BaseAddress,
+ "SectionOffset", SectionOffset);
+
+ if(NT_SUCCESS(ret)) {
+ pipe("PROCESS:%d", pid_from_process_handle(ProcessHandle));
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(int, WINAPI, GetSystemMetrics,
+ _In_ int nIndex
+) {
+ int ret = Old_GetSystemMetrics(nIndex);
+ LOQ("l", "SystemMetricIndex", nIndex);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, GetCursorPos,
+ _Out_ LPPOINT lpPoint
+) {
+ BOOL ret = Old_GetCursorPos(lpPoint);
+ LOQ("ll", "x", lpPoint != NULL ? lpPoint->x : 0,
+ "y", lpPoint != NULL ? lpPoint->y : 0);
+ return ret;
+}
diff --git a/hook_network.c b/hook_network.c
new file mode 100644
index 0000000..94e9fe9
--- /dev/null
+++ b/hook_network.c
@@ -0,0 +1,328 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+
+static IS_SUCCESS_HINTERNET();
+
+HOOKDEF(HRESULT, WINAPI, URLDownloadToFileW,
+ LPUNKNOWN pCaller,
+ LPWSTR szURL,
+ LPWSTR szFileName,
+ DWORD dwReserved,
+ LPVOID lpfnCB
+) {
+ IS_SUCCESS_HRESULT();
+
+ HRESULT ret = Old_URLDownloadToFileW(pCaller, szURL, szFileName,
+ dwReserved, lpfnCB);
+ LOQ("uu", "URL", szURL, "FileName", szFileName);
+ if(ret == S_OK) {
+ pipe("FILE_NEW:%S", szFileName);
+ }
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, InternetOpenA,
+ _In_ LPCTSTR lpszAgent,
+ _In_ DWORD dwAccessType,
+ _In_ LPCTSTR lpszProxyName,
+ _In_ LPCTSTR lpszProxyBypass,
+ _In_ DWORD dwFlags
+) {
+ HINTERNET ret = Old_InternetOpenA(lpszAgent, dwAccessType, lpszProxyName,
+ lpszProxyBypass, dwFlags);
+ LOQ("spssp", "Agent", lpszAgent, "AccessType", dwAccessType,
+ "ProxyName", lpszProxyName, "ProxyBypass", lpszProxyBypass,
+ "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, InternetOpenW,
+ _In_ LPWSTR lpszAgent,
+ _In_ DWORD dwAccessType,
+ _In_ LPWSTR lpszProxyName,
+ _In_ LPWSTR lpszProxyBypass,
+ _In_ DWORD dwFlags
+) {
+ HINTERNET ret = Old_InternetOpenW(lpszAgent, dwAccessType, lpszProxyName,
+ lpszProxyBypass, dwFlags);
+ LOQ("upuup", "Agent", lpszAgent, "AccessType", dwAccessType,
+ "ProxyName", lpszProxyName, "ProxyBypass", lpszProxyBypass,
+ "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, InternetConnectA,
+ _In_ HINTERNET hInternet,
+ _In_ LPCTSTR lpszServerName,
+ _In_ INTERNET_PORT nServerPort,
+ _In_ LPCTSTR lpszUsername,
+ _In_ LPCTSTR lpszPassword,
+ _In_ DWORD dwService,
+ _In_ DWORD dwFlags,
+ _In_ DWORD_PTR dwContext
+) {
+ HINTERNET ret = Old_InternetConnectA(hInternet, lpszServerName,
+ nServerPort, lpszUsername, lpszPassword, dwService, dwFlags,
+ dwContext);
+ LOQ("pslsslp", "InternetHandle", hInternet, "ServerName", lpszServerName,
+ "ServerPort", nServerPort, "Username", lpszUsername,
+ "Password", lpszPassword, "Service", dwService, "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, InternetConnectW,
+ _In_ HINTERNET hInternet,
+ _In_ LPWSTR lpszServerName,
+ _In_ INTERNET_PORT nServerPort,
+ _In_ LPWSTR lpszUsername,
+ _In_ LPWSTR lpszPassword,
+ _In_ DWORD dwService,
+ _In_ DWORD dwFlags,
+ _In_ DWORD_PTR dwContext
+) {
+ HINTERNET ret = Old_InternetConnectW(hInternet, lpszServerName,
+ nServerPort, lpszUsername, lpszPassword, dwService, dwFlags,
+ dwContext);
+ LOQ("puluulp", "InternetHandle", hInternet, "ServerName", lpszServerName,
+ "ServerPort", nServerPort, "Username", lpszUsername,
+ "Password", lpszPassword, "Service", dwService, "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, InternetOpenUrlA,
+ __in HINTERNET hInternet,
+ __in LPCTSTR lpszUrl,
+ __in LPCTSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+) {
+ HINTERNET ret = Old_InternetOpenUrlA(hInternet, lpszUrl, lpszHeaders,
+ dwHeadersLength, dwFlags, dwContext);
+ if(dwHeadersLength == (DWORD) -1) dwHeadersLength = strlen(lpszHeaders);
+ LOQ("psSp", "ConnectionHandle", hInternet, "URL", lpszUrl,
+ "Headers", dwHeadersLength, lpszHeaders, "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, InternetOpenUrlW,
+ __in HINTERNET hInternet,
+ __in LPWSTR lpszUrl,
+ __in LPWSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+) {
+ HINTERNET ret = Old_InternetOpenUrlW(hInternet, lpszUrl, lpszHeaders,
+ dwHeadersLength, dwFlags, dwContext);
+ LOQ("puUp", "ConnectionHandle", hInternet, "URL", lpszUrl,
+ "Headers", dwHeadersLength, lpszHeaders, "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, HttpOpenRequestA,
+ __in HINTERNET hConnect,
+ __in LPCTSTR lpszVerb,
+ __in LPCTSTR lpszObjectName,
+ __in LPCTSTR lpszVersion,
+ __in LPCTSTR lpszReferer,
+ __in LPCTSTR *lplpszAcceptTypes,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+) {
+ HINTERNET ret = Old_HttpOpenRequestA(hConnect, lpszVerb, lpszObjectName,
+ lpszVersion, lpszReferer, lplpszAcceptTypes, dwFlags, dwContext);
+ LOQ("psl", "InternetHandle", hConnect, "Path", lpszObjectName,
+ "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(HINTERNET, WINAPI, HttpOpenRequestW,
+ __in HINTERNET hConnect,
+ __in LPWSTR lpszVerb,
+ __in LPWSTR lpszObjectName,
+ __in LPWSTR lpszVersion,
+ __in LPWSTR lpszReferer,
+ __in LPWSTR *lplpszAcceptTypes,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+) {
+ HINTERNET ret = Old_HttpOpenRequestW(hConnect, lpszVerb, lpszObjectName,
+ lpszVersion, lpszReferer, lplpszAcceptTypes, dwFlags, dwContext);
+ LOQ("pul", "InternetHandle", hConnect, "Path", lpszObjectName,
+ "Flags", dwFlags);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, HttpSendRequestA,
+ __in HINTERNET hRequest,
+ __in LPCTSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in LPVOID lpOptional,
+ __in DWORD dwOptionalLength
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_HttpSendRequestA(hRequest, lpszHeaders, dwHeadersLength,
+ lpOptional, dwOptionalLength);
+ if(dwHeadersLength == (DWORD) -1) dwHeadersLength = strlen(lpszHeaders);
+ LOQ("pSb", "RequestHandle", hRequest,
+ "Headers", dwHeadersLength, lpszHeaders,
+ "PostData", dwOptionalLength, lpOptional);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, HttpSendRequestW,
+ __in HINTERNET hRequest,
+ __in LPWSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in LPVOID lpOptional,
+ __in DWORD dwOptionalLength
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_HttpSendRequestW(hRequest, lpszHeaders, dwHeadersLength,
+ lpOptional, dwOptionalLength);
+ LOQ("pUb", "RequestHandle", hRequest,
+ "Headers", dwHeadersLength, lpszHeaders,
+ "PostData", dwOptionalLength, lpOptional);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, InternetReadFile,
+ _In_ HINTERNET hFile,
+ _Out_ LPVOID lpBuffer,
+ _In_ DWORD dwNumberOfBytesToRead,
+ _Out_ LPDWORD lpdwNumberOfBytesRead
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead,
+ lpdwNumberOfBytesRead);
+ LOQ("pB", "InternetHandle", hFile,
+ "Buffer", lpdwNumberOfBytesRead, lpBuffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, InternetWriteFile,
+ _In_ HINTERNET hFile,
+ _In_ LPCVOID lpBuffer,
+ _In_ DWORD dwNumberOfBytesToWrite,
+ _Out_ LPDWORD lpdwNumberOfBytesWritten
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_InternetWriteFile(hFile, lpBuffer, dwNumberOfBytesToWrite,
+ lpdwNumberOfBytesWritten);
+ LOQ("pB", "InternetHandle", hFile,
+ "Buffer", lpdwNumberOfBytesWritten, lpBuffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, InternetCloseHandle,
+ _In_ HINTERNET hInternet
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_InternetCloseHandle(hInternet);
+ LOQ("p", "InternetHandle", hInternet);
+ return ret;
+}
+
+HOOKDEF(DNS_STATUS, WINAPI, DnsQuery_A,
+ __in PCSTR lpstrName,
+ __in WORD wType,
+ __in DWORD Options,
+ __inout_opt PVOID pExtra,
+ __out_opt PDNS_RECORD *ppQueryResultsSet,
+ __out_opt PVOID *pReserved
+) {
+ IS_SUCCESS_ZERO();
+
+ DNS_STATUS ret = Old_DnsQuery_A(lpstrName, wType, Options, pExtra,
+ ppQueryResultsSet, pReserved);
+ LOQ("sil", "Name", lpstrName, "Type", wType, "Options", Options);
+ return ret;
+}
+
+HOOKDEF(DNS_STATUS, WINAPI, DnsQuery_UTF8,
+ __in LPBYTE lpstrName,
+ __in WORD wType,
+ __in DWORD Options,
+ __inout_opt PVOID pExtra,
+ __out_opt PDNS_RECORD *ppQueryResultsSet,
+ __out_opt PVOID *pReserved
+) {
+ IS_SUCCESS_ZERO();
+
+ DNS_STATUS ret = Old_DnsQuery_UTF8(lpstrName, wType, Options, pExtra,
+ ppQueryResultsSet, pReserved);
+ LOQ("sil", "Name", lpstrName, "Type", wType, "Options", Options);
+ return ret;
+}
+
+HOOKDEF(DNS_STATUS, WINAPI, DnsQuery_W,
+ __in PWSTR lpstrName,
+ __in WORD wType,
+ __in DWORD Options,
+ __inout_opt PVOID pExtra,
+ __out_opt PDNS_RECORD *ppQueryResultsSet,
+ __out_opt PVOID *pReserved
+) {
+ IS_SUCCESS_ZERO();
+
+ DNS_STATUS ret = Old_DnsQuery_W(lpstrName, wType, Options, pExtra,
+ ppQueryResultsSet, pReserved);
+ LOQ("uil", "Name", lpstrName, "Type", wType, "Options", Options);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, getaddrinfo,
+ _In_opt_ PCSTR pNodeName,
+ _In_opt_ PCSTR pServiceName,
+ _In_opt_ const ADDRINFOA *pHints,
+ _Out_ PADDRINFOA *ppResult
+) {
+ IS_SUCCESS_ZERO();
+
+ BOOL ret = Old_getaddrinfo(pNodeName, pServiceName, pHints, ppResult);
+ LOQ("ss", "NodeName", pNodeName, "ServiceName", pServiceName);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, GetAddrInfoW,
+ _In_opt_ PCWSTR pNodeName,
+ _In_opt_ PCWSTR pServiceName,
+ _In_opt_ const ADDRINFOW *pHints,
+ _Out_ PADDRINFOW *ppResult
+) {
+ IS_SUCCESS_ZERO();
+
+ BOOL ret = Old_GetAddrInfoW(pNodeName, pServiceName, pHints, ppResult);
+ LOQ("uu", "NodeName", pNodeName, "ServiceName", pServiceName);
+ return ret;
+}
diff --git a/hook_process.c b/hook_process.c
new file mode 100644
index 0000000..cc2d485
--- /dev/null
+++ b/hook_process.c
@@ -0,0 +1,456 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+#include "misc.h"
+#include "ignore.h"
+#include "hook_sleep.h"
+
+static IS_SUCCESS_NTSTATUS();
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateProcess,
+ __out PHANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in HANDLE ParentProcess,
+ __in BOOLEAN InheritObjectTable,
+ __in_opt HANDLE SectionHandle,
+ __in_opt HANDLE DebugPort,
+ __in_opt HANDLE ExceptionPort
+) {
+ NTSTATUS ret = Old_NtCreateProcess(ProcessHandle, DesiredAccess,
+ ObjectAttributes, ParentProcess, InheritObjectTable, SectionHandle,
+ DebugPort, ExceptionPort);
+ LOQ("PpO", "ProcessHandle", ProcessHandle, "DesiredAccess", DesiredAccess,
+ "FileName", ObjectAttributes);
+ if(NT_SUCCESS(ret)) {
+ pipe("PROCESS:%d", pid_from_process_handle(*ProcessHandle));
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateProcessEx,
+ __out PHANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in HANDLE ParentProcess,
+ __in ULONG Flags,
+ __in_opt HANDLE SectionHandle,
+ __in_opt HANDLE DebugPort,
+ __in_opt HANDLE ExceptionPort,
+ __in BOOLEAN InJob
+) {
+ NTSTATUS ret = Old_NtCreateProcessEx(ProcessHandle, DesiredAccess,
+ ObjectAttributes, ParentProcess, Flags, SectionHandle, DebugPort,
+ ExceptionPort, InJob);
+ LOQ("PpO", "ProcessHandle", ProcessHandle, "DesiredAccess", DesiredAccess,
+ "FileName", ObjectAttributes);
+ if(NT_SUCCESS(ret)) {
+ pipe("PROCESS:%d", pid_from_process_handle(*ProcessHandle));
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateUserProcess,
+ __out PHANDLE ProcessHandle,
+ __out PHANDLE ThreadHandle,
+ __in ACCESS_MASK ProcessDesiredAccess,
+ __in ACCESS_MASK ThreadDesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ProcessObjectAttributes,
+ __in_opt POBJECT_ATTRIBUTES ThreadObjectAttributes,
+ __in ULONG ProcessFlags,
+ __in ULONG ThreadFlags,
+ __in_opt PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
+ __inout PPS_CREATE_INFO CreateInfo,
+ __in_opt PPS_ATTRIBUTE_LIST AttributeList
+) {
+ RTL_USER_PROCESS_PARAMETERS _ProcessParameters = {};
+ if(ProcessParameters == NULL) ProcessParameters = &_ProcessParameters;
+
+ NTSTATUS ret = Old_NtCreateUserProcess(ProcessHandle, ThreadHandle,
+ ProcessDesiredAccess, ThreadDesiredAccess,
+ ProcessObjectAttributes, ThreadObjectAttributes,
+ ProcessFlags, ThreadFlags, ProcessParameters,
+ CreateInfo, AttributeList);
+ LOQ("PPppOOoo", "ProcessHandle", ProcessHandle,
+ "ThreadHandle", ThreadHandle,
+ "ProcessDesiredAccess", ProcessDesiredAccess,
+ "ThreadDesiredAccess", ThreadDesiredAccess,
+ "ProcessFileName", ProcessObjectAttributes,
+ "ThreadName", ThreadObjectAttributes,
+ "ImagePathName", &ProcessParameters->ImagePathName,
+ "CommandLine", &ProcessParameters->CommandLine);
+ if(NT_SUCCESS(ret)) {
+ pipe("PROCESS:%d,%d", pid_from_process_handle(*ProcessHandle),
+ pid_from_thread_handle(*ThreadHandle));
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, RtlCreateUserProcess,
+ IN PUNICODE_STRING ImagePath,
+ IN ULONG ObjectAttributes,
+ IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
+ IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
+ IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
+ IN HANDLE ParentProcess,
+ IN BOOLEAN InheritHandles,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL,
+ OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation
+) {
+ NTSTATUS ret = Old_RtlCreateUserProcess(ImagePath, ObjectAttributes,
+ ProcessParameters, ProcessSecurityDescriptor,
+ ThreadSecurityDescriptor, ParentProcess, InheritHandles, DebugPort,
+ ExceptionPort, ProcessInformation);
+ LOQ("opp", "ImagePath", ImagePath, "ObjectAttributes", ObjectAttributes,
+ "ParentProcess", ParentProcess);
+ if(NT_SUCCESS(ret)) {
+ pipe("PROCESS:%d,%d",
+ pid_from_process_handle(ProcessInformation->ProcessHandle),
+ pid_from_thread_handle(ProcessInformation->ThreadHandle));
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenProcess,
+ __out PHANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __in_opt PCLIENT_ID ClientId
+) {
+ // although the documentation on msdn is a bit vague, this seems correct
+ // for both XP and Vista (the ClientId->UniqueProcess part, that is)
+
+ int pid = 0;
+ if(ClientId != NULL) {
+ pid = (int) ClientId->UniqueProcess;
+ }
+
+ if(is_protected_pid(pid)) {
+ NTSTATUS ret = STATUS_ACCESS_DENIED;
+ LOQ("ppp", "ProcessHandle", NULL, "DesiredAccess", DesiredAccess,
+ "ProcessIdentifier", &pid);
+ return STATUS_ACCESS_DENIED;
+ }
+
+ NTSTATUS ret = Old_NtOpenProcess(ProcessHandle, DesiredAccess,
+ ObjectAttributes, ClientId);
+ LOQ2("PpP", "ProcessHandle", ProcessHandle,
+ "DesiredAccess", DesiredAccess,
+ "ProcessIdentifier", &pid);
+ /*
+ if(NT_SUCCESS(ret)) {
+ // let's do an extra check here, because the msdn documentation is
+ // so vague..
+ unsigned long pid = pid_from_process_handle(*ProcessHandle);
+ // check if this pid is protected
+ if(is_protected_pid(pid)) {
+ CloseHandle(*ProcessHandle);
+ return STATUS_ACCESS_DENIED;
+ }
+ pipe("PROCESS:%d", pid);
+ }
+ */
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtTerminateProcess,
+ __in_opt HANDLE ProcessHandle,
+ __in NTSTATUS ExitStatus
+) {
+ NTSTATUS ret = Old_NtTerminateProcess(ProcessHandle, ExitStatus);
+ LOQ("pl", "ProcessHandle", ProcessHandle, "ExitCode", ExitStatus);
+ log_flush();
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateSection,
+ __out PHANDLE SectionHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in_opt PLARGE_INTEGER MaximumSize,
+ __in ULONG SectionPageProtection,
+ __in ULONG AllocationAttributes,
+ __in_opt HANDLE FileHandle
+) {
+ NTSTATUS ret = Old_NtCreateSection(SectionHandle, DesiredAccess,
+ ObjectAttributes, MaximumSize, SectionPageProtection,
+ AllocationAttributes, FileHandle);
+ LOQ("PpOp", "SectionHandle", SectionHandle,
+ "DesiredAccess", DesiredAccess, "ObjectAttributes", ObjectAttributes,
+ "FileHandle", FileHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtMakeTemporaryObject,
+ __in HANDLE ObjectHandle
+) {
+ NTSTATUS ret = Old_NtMakeTemporaryObject(ObjectHandle);
+ LOQ("p", "ObjectHandle", ObjectHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtMakePermanentObject,
+ __in HANDLE ObjectHandle
+) {
+ NTSTATUS ret = Old_NtMakePermanentObject(ObjectHandle);
+ LOQ("p", "ObjectHandle", ObjectHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenSection,
+ __out PHANDLE SectionHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+) {
+ NTSTATUS ret = Old_NtOpenSection(SectionHandle, DesiredAccess,
+ ObjectAttributes);
+ LOQ("PpO", "SectionHandle", SectionHandle, "DesiredAccess", DesiredAccess,
+ "ObjectAttributes", ObjectAttributes);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, CreateProcessInternalW,
+ __in_opt LPVOID lpUnknown1,
+ __in_opt LPWSTR lpApplicationName,
+ __inout_opt LPWSTR lpCommandLine,
+ __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in BOOL bInheritHandles,
+ __in DWORD dwCreationFlags,
+ __in_opt LPVOID lpEnvironment,
+ __in_opt LPWSTR lpCurrentDirectory,
+ __in LPSTARTUPINFO lpStartupInfo,
+ __out LPPROCESS_INFORMATION lpProcessInformation,
+ __in_opt LPVOID lpUnknown2
+) {
+ BOOL ret = Old_CreateProcessInternalW(lpUnknown1, lpApplicationName,
+ lpCommandLine, lpProcessAttributes, lpThreadAttributes,
+ bInheritHandles, dwCreationFlags, lpEnvironment,
+ lpCurrentDirectory, lpStartupInfo, lpProcessInformation, lpUnknown2);
+ LOQ("uupllpp", "ApplicationName", lpApplicationName,
+ "CommandLine", lpCommandLine, "CreationFlags", dwCreationFlags,
+ "ProcessId", lpProcessInformation->dwProcessId,
+ "ThreadId", lpProcessInformation->dwThreadId,
+ "ProcessHandle", lpProcessInformation->hProcess,
+ "ThreadHandle", lpProcessInformation->hThread);
+ return ret;
+}
+
+HOOKDEF(VOID, WINAPI, ExitProcess,
+ __in UINT uExitCode
+) {
+ IS_SUCCESS_VOID();
+
+ int ret = 0;
+ LOQ("l", "ExitCode", uExitCode);
+ log_free();
+ Old_ExitProcess(uExitCode);
+}
+
+HOOKDEF(BOOL, WINAPI, ShellExecuteExW,
+ __inout SHELLEXECUTEINFOW *pExecInfo
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_ShellExecuteExW(pExecInfo);
+ LOQ("2ul", "FilePath", pExecInfo->lpFile,
+ "Parameters", pExecInfo->lpParameters, "Show", pExecInfo->nShow);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtUnmapViewOfSection,
+ _In_ HANDLE ProcessHandle,
+ _In_opt_ PVOID BaseAddress
+) {
+ unsigned int map_size = 0; MEMORY_BASIC_INFORMATION mbi;
+ if(VirtualQueryEx(ProcessHandle, BaseAddress, &mbi,
+ sizeof(mbi)) == sizeof(mbi)) {
+ map_size = mbi.RegionSize;
+ }
+ NTSTATUS ret = Old_NtUnmapViewOfSection(ProcessHandle, BaseAddress);
+ if(NT_SUCCESS(ret)) {
+ pipe("UNMAP:%d,%x,%x", pid_from_process_handle(ProcessHandle),
+ BaseAddress, map_size);
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtAllocateVirtualMemory,
+ __in HANDLE ProcessHandle,
+ __inout PVOID *BaseAddress,
+ __in ULONG_PTR ZeroBits,
+ __inout PSIZE_T RegionSize,
+ __in ULONG AllocationType,
+ __in ULONG Protect
+) {
+ NTSTATUS ret = Old_NtAllocateVirtualMemory(ProcessHandle, BaseAddress,
+ ZeroBits, RegionSize, AllocationType, Protect);
+ LOQ("pPPp", "ProcessHandle", ProcessHandle, "BaseAddress", BaseAddress,
+ "RegionSize", RegionSize, "Protection", Protect);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtReadVirtualMemory,
+ __in HANDLE ProcessHandle,
+ __in LPCVOID BaseAddress,
+ __out LPVOID Buffer,
+ __in ULONG NumberOfBytesToRead,
+ __out_opt PULONG NumberOfBytesReaded
+) {
+ ENSURE_ULONG(NumberOfBytesReaded);
+
+ BOOL ret = Old_NtReadVirtualMemory(ProcessHandle, BaseAddress, Buffer,
+ NumberOfBytesToRead, NumberOfBytesReaded);
+
+ LOQ("2pB", "ProcessHandle", ProcessHandle, "BaseAddress", BaseAddress,
+ "Buffer", NumberOfBytesReaded, Buffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, ReadProcessMemory,
+ _In_ HANDLE hProcess,
+ _In_ LPCVOID lpBaseAddress,
+ _Out_ LPVOID lpBuffer,
+ _In_ SIZE_T nSize,
+ _Out_ SIZE_T *lpNumberOfBytesRead
+) {
+ IS_SUCCESS_BOOL();
+ ENSURE_SIZET(lpNumberOfBytesRead);
+
+ BOOL ret = Old_ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer,
+ nSize, lpNumberOfBytesRead);
+
+ LOQ("ppB", "ProcessHandle", hProcess, "BaseAddress", lpBaseAddress,
+ "Buffer", lpNumberOfBytesRead, lpBuffer);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtWriteVirtualMemory,
+ __in HANDLE ProcessHandle,
+ __in LPVOID BaseAddress,
+ __in LPCVOID Buffer,
+ __in ULONG NumberOfBytesToWrite,
+ __out_opt ULONG *NumberOfBytesWritten
+) {
+ ENSURE_ULONG(NumberOfBytesWritten);
+
+ BOOL ret = Old_NtWriteVirtualMemory(ProcessHandle, BaseAddress, Buffer,
+ NumberOfBytesToWrite, NumberOfBytesWritten);
+
+ LOQ("2pB", "ProcessHandle", ProcessHandle, "BaseAddress", BaseAddress,
+ "Buffer", NumberOfBytesWritten, Buffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, WriteProcessMemory,
+ _In_ HANDLE hProcess,
+ _In_ LPVOID lpBaseAddress,
+ _In_ LPCVOID lpBuffer,
+ _In_ SIZE_T nSize,
+ _Out_ SIZE_T *lpNumberOfBytesWritten
+) {
+ IS_SUCCESS_BOOL();
+ ENSURE_SIZET(lpNumberOfBytesWritten);
+
+ BOOL ret = Old_WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer,
+ nSize, lpNumberOfBytesWritten);
+
+ LOQ("ppB", "ProcessHandle", hProcess, "BaseAddress", lpBaseAddress,
+ "Buffer", lpNumberOfBytesWritten, lpBuffer);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtProtectVirtualMemory,
+ IN HANDLE ProcessHandle,
+ IN OUT PVOID *BaseAddress,
+ IN OUT PULONG NumberOfBytesToProtect,
+ IN ULONG NewAccessProtection,
+ OUT PULONG OldAccessProtection
+) {
+ NTSTATUS ret = Old_NtProtectVirtualMemory(ProcessHandle, BaseAddress,
+ NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection);
+ LOQ("pPPpP", "ProcessHandle", ProcessHandle, "BaseAddress", BaseAddress,
+ "NumberOfBytesProtected", NumberOfBytesToProtect,
+ "NewAccessProtection", NewAccessProtection,
+ "OldAccessProtection", OldAccessProtection);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, VirtualProtectEx,
+ __in HANDLE hProcess,
+ __in LPVOID lpAddress,
+ __in SIZE_T dwSize,
+ __in DWORD flNewProtect,
+ __out PDWORD lpflOldProtect
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect,
+ lpflOldProtect);
+ LOQ("pppp", "ProcessHandle", hProcess, "Address", lpAddress,
+ "Size", dwSize, "Protection", flNewProtect);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtFreeVirtualMemory,
+ IN HANDLE ProcessHandle,
+ IN PVOID *BaseAddress,
+ IN OUT PULONG RegionSize,
+ IN ULONG FreeType
+) {
+ NTSTATUS ret = Old_NtFreeVirtualMemory(ProcessHandle, BaseAddress,
+ RegionSize, FreeType);
+ LOQ("pPPp", "ProcessHandle", ProcessHandle, "BaseAddress", BaseAddress,
+ "RegionSize", RegionSize, "FreeType", FreeType);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, VirtualFreeEx,
+ __in HANDLE hProcess,
+ __in LPVOID lpAddress,
+ __in SIZE_T dwSize,
+ __in DWORD dwFreeType
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_VirtualFreeEx(hProcess, lpAddress, dwSize, dwFreeType);
+ LOQ("pppl", "ProcessHandle", hProcess, "Address", lpAddress,
+ "Size", dwSize, "FreeType", dwFreeType);
+ return ret;
+}
+
+HOOKDEF(int, CDECL, system,
+ const char *command
+) {
+ IS_SUCCESS_INTM1();
+
+ int ret = Old_system(command);
+ LOQ("s", "Command", command);
+ return ret;
+}
diff --git a/hook_reg.c b/hook_reg.c
new file mode 100644
index 0000000..6d226bb
--- /dev/null
+++ b/hook_reg.c
@@ -0,0 +1,370 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+
+static IS_SUCCESS_LONGREG();
+
+HOOKDEF(LONG, WINAPI, RegOpenKeyExA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpSubKey,
+ __reserved DWORD ulOptions,
+ __in REGSAM samDesired,
+ __out PHKEY phkResult
+) {
+ LONG ret = Old_RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired,
+ phkResult);
+ LOQ("psP", "Registry", hKey, "SubKey", lpSubKey, "Handle", phkResult);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegOpenKeyExW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpSubKey,
+ __reserved DWORD ulOptions,
+ __in REGSAM samDesired,
+ __out PHKEY phkResult
+) {
+ LONG ret = Old_RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired,
+ phkResult);
+ LOQ("puP", "Registry", hKey, "SubKey", lpSubKey, "Handle", phkResult);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegCreateKeyExA,
+ __in HKEY hKey,
+ __in LPCTSTR lpSubKey,
+ __reserved DWORD Reserved,
+ __in_opt LPTSTR lpClass,
+ __in DWORD dwOptions,
+ __in REGSAM samDesired,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ __out PHKEY phkResult,
+ __out_opt LPDWORD lpdwDisposition
+) {
+ LONG ret = Old_RegCreateKeyExA(hKey, lpSubKey, Reserved, lpClass,
+ dwOptions, samDesired, lpSecurityAttributes, phkResult,
+ lpdwDisposition);
+ LOQ("psslP", "Registry", hKey, "SubKey", lpSubKey, "Class", lpClass,
+ "Access", samDesired, "Handle", phkResult);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegCreateKeyExW,
+ __in HKEY hKey,
+ __in LPWSTR lpSubKey,
+ __reserved DWORD Reserved,
+ __in_opt LPWSTR lpClass,
+ __in DWORD dwOptions,
+ __in REGSAM samDesired,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ __out PHKEY phkResult,
+ __out_opt LPDWORD lpdwDisposition
+) {
+ LONG ret = Old_RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass,
+ dwOptions, samDesired, lpSecurityAttributes, phkResult,
+ lpdwDisposition);
+ LOQ("puulP", "Registry", hKey, "SubKey", lpSubKey, "Class", lpClass,
+ "Access", samDesired, "Handle", phkResult);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegDeleteKeyA,
+ __in HKEY hKey,
+ __in LPCTSTR lpSubKey
+) {
+ LONG ret = Old_RegDeleteKeyA(hKey, lpSubKey);
+ LOQ("ps", "Handle", hKey, "SubKey", lpSubKey);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegDeleteKeyW,
+ __in HKEY hKey,
+ __in LPWSTR lpSubKey
+) {
+ LONG ret = Old_RegDeleteKeyW(hKey, lpSubKey);
+ LOQ("pu", "Handle", hKey, "SubKey", lpSubKey);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegEnumKeyW,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPWSTR lpName,
+ __in DWORD cchName
+) {
+ LONG ret = Old_RegEnumKeyW(hKey, dwIndex, lpName, cchName);
+ LOQ("plu", "Handle", hKey, "Index", dwIndex, "Name", lpName);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegEnumKeyExA,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPTSTR lpName,
+ __inout LPDWORD lpcName,
+ __reserved LPDWORD lpReserved,
+ __inout LPTSTR lpClass,
+ __inout_opt LPDWORD lpcClass,
+ __out_opt PFILETIME lpftLastWriteTime
+) {
+ LONG ret = Old_RegEnumKeyExA(hKey, dwIndex, lpName, lpcName, lpReserved,
+ lpClass, lpcClass, lpftLastWriteTime);
+ LOQ("plss", "Handle", hKey, "Index", dwIndex, "Name", lpName,
+ "Class", lpClass);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegEnumKeyExW,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPWSTR lpName,
+ __inout LPDWORD lpcName,
+ __reserved LPDWORD lpReserved,
+ __inout LPWSTR lpClass,
+ __inout_opt LPDWORD lpcClass,
+ __out_opt PFILETIME lpftLastWriteTime
+) {
+ LONG ret = Old_RegEnumKeyExW(hKey, dwIndex, lpName, lpcName, lpReserved,
+ lpClass, lpcClass, lpftLastWriteTime);
+ LOQ("pluu", "Handle", hKey, "Index", dwIndex, "Name", lpName,
+ "Class", lpClass);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegEnumValueA,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPTSTR lpValueName,
+ __inout LPDWORD lpcchValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+) {
+ ENSURE_DWORD(lpType);
+ LONG ret = Old_RegEnumValueA(hKey, dwIndex, lpValueName, lpcchValueName,
+ lpReserved, lpType, lpData, lpcbData);
+ if(ret == ERROR_SUCCESS && lpType != NULL && lpData != NULL &&
+ lpcbData != NULL) {
+ LOQ("plsr", "Handle", hKey, "Index", dwIndex,
+ "ValueName", lpValueName, "Data", *lpType, *lpcbData, lpData);
+ }
+ else {
+ LOQ2("plsLL", "Handle", hKey, "Index", dwIndex,
+ "ValueName", lpValueName, "Type", lpType, "DataLength", lpcbData);
+ }
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegEnumValueW,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPWSTR lpValueName,
+ __inout LPDWORD lpcchValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+) {
+ ENSURE_DWORD(lpType);
+ LONG ret = Old_RegEnumValueW(hKey, dwIndex, lpValueName, lpcchValueName,
+ lpReserved, lpType, lpData, lpcbData);
+ if(ret == ERROR_SUCCESS && lpType != NULL && lpData != NULL &&
+ lpcbData != NULL) {
+ LOQ("pluR", "Handle", hKey, "Index", dwIndex,
+ "ValueName", lpValueName, "Data", *lpType, *lpcbData, lpData);
+ }
+ else {
+ LOQ2("pluLL", "Handle", hKey, "Index", dwIndex,
+ "ValueName", lpValueName, "Type", lpType, "DataLength", lpcbData);
+ }
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegSetValueExA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpValueName,
+ __reserved DWORD Reserved,
+ __in DWORD dwType,
+ __in const BYTE *lpData,
+ __in DWORD cbData
+) {
+ LONG ret = Old_RegSetValueExA(hKey, lpValueName, Reserved, dwType, lpData,
+ cbData);
+ if(ret == ERROR_SUCCESS) {
+ LOQ("pslr", "Handle", hKey, "ValueName", lpValueName, "Type", dwType,
+ "Buffer", dwType, cbData, lpData);
+ }
+ else {
+ LOQ2("psl", "Handle", hKey, "ValueName", lpValueName, "Type", dwType);
+ }
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegSetValueExW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpValueName,
+ __reserved DWORD Reserved,
+ __in DWORD dwType,
+ __in const BYTE *lpData,
+ __in DWORD cbData
+) {
+ LONG ret = Old_RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData,
+ cbData);
+ if(ret == ERROR_SUCCESS) {
+ LOQ("pulR", "Handle", hKey, "ValueName", lpValueName, "Type", dwType,
+ "Buffer", dwType, cbData, lpData);
+ }
+ else {
+ LOQ2("pul", "Handle", hKey, "ValueName", lpValueName, "Type", dwType);
+ }
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegQueryValueExA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+) {
+ ENSURE_DWORD(lpType);
+ LONG ret = Old_RegQueryValueExA(hKey, lpValueName, lpReserved, lpType,
+ lpData, lpcbData);
+ if(ret == ERROR_SUCCESS && lpType != NULL && lpData != NULL &&
+ lpcbData != NULL) {
+ LOQ("psr", "Handle", hKey, "ValueName", lpValueName,
+ "Data", *lpType, *lpcbData, lpData);
+ }
+ else {
+ LOQ2("psLL", "Handle", hKey, "ValueName", lpValueName,
+ "Type", lpType, "DataLength", lpcbData);
+ }
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegQueryValueExW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+) {
+ ENSURE_DWORD(lpType);
+ LONG ret = Old_RegQueryValueExW(hKey, lpValueName, lpReserved, lpType,
+ lpData, lpcbData);
+ if(ret == ERROR_SUCCESS && lpType != NULL && lpData != NULL &&
+ lpcbData != NULL) {
+ LOQ("puR", "Handle", hKey, "ValueName", lpValueName,
+ "Data", *lpType, *lpcbData, lpData);
+ }
+ else {
+ LOQ2("puLL", "Handle", hKey, "ValueName", lpValueName,
+ "Type", lpType, "DataLength", lpcbData);
+ }
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegDeleteValueA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpValueName
+) {
+ LONG ret = Old_RegDeleteValueA(hKey, lpValueName);
+ LOQ("ps", "Handle", hKey, "ValueName", lpValueName);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegDeleteValueW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpValueName
+) {
+ LONG ret = Old_RegDeleteValueW(hKey, lpValueName);
+ LOQ("pu", "Handle", hKey, "ValueName", lpValueName);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegQueryInfoKeyA,
+ _In_ HKEY hKey,
+ _Out_opt_ LPTSTR lpClass,
+ _Inout_opt_ LPDWORD lpcClass,
+ _Reserved_ LPDWORD lpReserved,
+ _Out_opt_ LPDWORD lpcSubKeys,
+ _Out_opt_ LPDWORD lpcMaxSubKeyLen,
+ _Out_opt_ LPDWORD lpcMaxClassLen,
+ _Out_opt_ LPDWORD lpcValues,
+ _Out_opt_ LPDWORD lpcMaxValueNameLen,
+ _Out_opt_ LPDWORD lpcMaxValueLen,
+ _Out_opt_ LPDWORD lpcbSecurityDescriptor,
+ _Out_opt_ PFILETIME lpftLastWriteTime
+) {
+ IS_SUCCESS_LONGREG();
+
+ LONG ret = Old_RegQueryInfoKeyA(hKey, lpClass, lpcClass, lpReserved,
+ lpcSubKeys, lpcMaxSubKeyLen, lpcMaxClassLen, lpcValues,
+ lpcMaxValueNameLen, lpcMaxValueLen, lpcbSecurityDescriptor,
+ lpftLastWriteTime);
+ LOQ("pS6L", "KeyHandle", hKey, "Class", lpcClass ? *lpcClass : 0, lpClass,
+ "SubKeyCount", lpcSubKeys, "MaxSubKeyLength", lpcMaxSubKeyLen,
+ "MaxClassLength", lpcMaxClassLen, "ValueCount", lpcValues,
+ "MaxValueNameLength", lpcMaxValueNameLen,
+ "MaxValueLength", lpcMaxValueLen);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegQueryInfoKeyW,
+ _In_ HKEY hKey,
+ _Out_opt_ LPWSTR lpClass,
+ _Inout_opt_ LPDWORD lpcClass,
+ _Reserved_ LPDWORD lpReserved,
+ _Out_opt_ LPDWORD lpcSubKeys,
+ _Out_opt_ LPDWORD lpcMaxSubKeyLen,
+ _Out_opt_ LPDWORD lpcMaxClassLen,
+ _Out_opt_ LPDWORD lpcValues,
+ _Out_opt_ LPDWORD lpcMaxValueNameLen,
+ _Out_opt_ LPDWORD lpcMaxValueLen,
+ _Out_opt_ LPDWORD lpcbSecurityDescriptor,
+ _Out_opt_ PFILETIME lpftLastWriteTime
+) {
+ IS_SUCCESS_LONGREG();
+
+ LONG ret = Old_RegQueryInfoKeyW(hKey, lpClass, lpcClass, lpReserved,
+ lpcSubKeys, lpcMaxSubKeyLen, lpcMaxClassLen, lpcValues,
+ lpcMaxValueNameLen, lpcMaxValueLen, lpcbSecurityDescriptor,
+ lpftLastWriteTime);
+ LOQ("pU6L", "KeyHandle", hKey, "Class", lpcClass ? *lpcClass : 0, lpClass,
+ "SubKeyCount", lpcSubKeys, "MaxSubKeyLength", lpcMaxSubKeyLen,
+ "MaxClassLength", lpcMaxClassLen, "ValueCount", lpcValues,
+ "MaxValueNameLength", lpcMaxValueNameLen,
+ "MaxValueLength", lpcMaxValueLen);
+ return ret;
+}
+
+HOOKDEF(LONG, WINAPI, RegCloseKey,
+ __in HKEY hKey
+) {
+ LONG ret = Old_RegCloseKey(hKey);
+ LOQ("p", "Handle", hKey);
+ return ret;
+}
diff --git a/hook_reg_native.c b/hook_reg_native.c
new file mode 100644
index 0000000..436e321
--- /dev/null
+++ b/hook_reg_native.c
@@ -0,0 +1,283 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+
+static IS_SUCCESS_LONGREG();
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateKey,
+ __out PHANDLE KeyHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __reserved ULONG TitleIndex,
+ __in_opt PUNICODE_STRING Class,
+ __in ULONG CreateOptions,
+ __out_opt PULONG Disposition
+) {
+ NTSTATUS ret = Old_NtCreateKey(KeyHandle, DesiredAccess, ObjectAttributes,
+ TitleIndex, Class, CreateOptions, Disposition);
+ LOQ("Ploo", "KeyHandle", KeyHandle, "DesiredAccess", DesiredAccess,
+ "ObjectAttributes", unistr_from_objattr(ObjectAttributes),
+ "Class", Class);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenKey,
+ __out PHANDLE KeyHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+) {
+ NTSTATUS ret = Old_NtOpenKey(KeyHandle, DesiredAccess, ObjectAttributes);
+ LOQ("Plo", "KeyHandle", KeyHandle, "DesiredAccess", DesiredAccess,
+ "ObjectAttributes", unistr_from_objattr(ObjectAttributes));
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenKeyEx,
+ __out PHANDLE KeyHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __in ULONG OpenOptions
+) {
+ NTSTATUS ret = Old_NtOpenKeyEx(KeyHandle, DesiredAccess, ObjectAttributes,
+ OpenOptions);
+ LOQ("Plo", "KeyHandle", KeyHandle, "DesiredAccess", DesiredAccess,
+ "ObjectAttributes", unistr_from_objattr(ObjectAttributes));
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtRenameKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING NewName
+) {
+ NTSTATUS ret = Old_NtRenameKey(KeyHandle, NewName);
+ LOQ("po", "KeyHandle", KeyHandle, "NewName", NewName);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtReplaceKey,
+ __in POBJECT_ATTRIBUTES NewHiveFileName,
+ __in HANDLE KeyHandle,
+ __in POBJECT_ATTRIBUTES BackupHiveFileName
+) {
+ NTSTATUS ret = Old_NtReplaceKey(NewHiveFileName, KeyHandle,
+ BackupHiveFileName);
+ LOQ("poo", "KeyHandle", KeyHandle,
+ "NewHiveFileName", unistr_from_objattr(NewHiveFileName),
+ "BackupHiveFileName", unistr_from_objattr(BackupHiveFileName));
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtEnumerateKey,
+ __in HANDLE KeyHandle,
+ __in ULONG Index,
+ __in KEY_INFORMATION_CLASS KeyInformationClass,
+ __out_opt PVOID KeyInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+) {
+ NTSTATUS ret = Old_NtEnumerateKey(KeyHandle, Index, KeyInformationClass,
+ KeyInformation, Length, ResultLength);
+ LOQ("pl", "KeyHandle", KeyHandle, "Index", Index);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtEnumerateValueKey,
+ __in HANDLE KeyHandle,
+ __in ULONG Index,
+ __in KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ __out_opt PVOID KeyValueInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+) {
+ NTSTATUS ret = Old_NtEnumerateValueKey(KeyHandle, Index,
+ KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
+ LOQ("pll", "KeyHandle", KeyHandle, "Index", Index,
+ "KeyValueInformationClass", KeyValueInformationClass);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtSetValueKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING ValueName,
+ __in_opt ULONG TitleIndex,
+ __in ULONG Type,
+ __in_opt PVOID Data,
+ __in ULONG DataSize
+) {
+ NTSTATUS ret = Old_NtSetValueKey(KeyHandle, ValueName, TitleIndex,
+ Type, Data, DataSize);
+ if(NT_SUCCESS(ret)) {
+ LOQ("polR", "KeyHandle", KeyHandle, "ValueName", ValueName,
+ "Type", Type, "Buffer", Type, DataSize, Data);
+ }
+ else {
+ LOQ2("pol", "KeyHandle", KeyHandle, "ValueName", ValueName,
+ "Type", Type);
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtQueryValueKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING ValueName,
+ __in KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ __out_opt PVOID KeyValueInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+) {
+ ENSURE_ULONG_ZERO(ResultLength);
+
+ NTSTATUS ret = Old_NtQueryValueKey(KeyHandle, ValueName,
+ KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
+ if(NT_SUCCESS(ret) &&
+ *ResultLength >= sizeof(ULONG) * 3) {
+ ULONG Type, DataLength = 0; UCHAR *Data = NULL;
+
+ // someday add support for Name and NameLength, if there's use for it
+
+ Type = ((KEY_VALUE_PARTIAL_INFORMATION *) KeyValueInformation)->Type;
+ if(KeyValueInformationClass == KeyValueFullInformation) {
+ KEY_VALUE_FULL_INFORMATION *p =
+ (KEY_VALUE_FULL_INFORMATION *) KeyValueInformation;
+ DataLength = p->DataLength;
+ Data = (UCHAR *) KeyValueInformation + p->DataOffset;
+ }
+ else if(KeyValueInformationClass == KeyValuePartialInformation) {
+ KEY_VALUE_PARTIAL_INFORMATION *p =
+ (KEY_VALUE_PARTIAL_INFORMATION *) KeyValueInformation;
+ DataLength = p->DataLength;
+ Data = p->Data;
+ }
+
+ LOQ("polR", "KeyHandle", KeyHandle, "ValueName", ValueName,
+ "Type", Type, "Information", Type, DataLength, Data);
+ }
+ else {
+ LOQ2("po", "KeyHandle", KeyHandle, "ValueName", ValueName);
+ }
+
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtQueryMultipleValueKey,
+ __in HANDLE KeyHandle,
+ __inout PKEY_VALUE_ENTRY ValueEntries,
+ __in ULONG EntryCount,
+ __out PVOID ValueBuffer,
+ __inout PULONG BufferLength,
+ __out_opt PULONG RequiredBufferLength
+) {
+ NTSTATUS ret = Old_NtQueryMultipleValueKey(KeyHandle, ValueEntries,
+ EntryCount, ValueBuffer, BufferLength, RequiredBufferLength);
+ LOQ("poS", "KeyHandle", KeyHandle, "ValueName", ValueEntries->ValueName,
+ "ValueBuffer", *BufferLength, ValueBuffer);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtDeleteKey,
+ __in HANDLE KeyHandle
+) {
+ NTSTATUS ret = Old_NtDeleteKey(KeyHandle);
+ LOQ("p", "KeyHandle", KeyHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtDeleteValueKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING ValueName
+) {
+ NTSTATUS ret = Old_NtDeleteValueKey(KeyHandle, ValueName);
+ LOQ("po", "KeyHandle", KeyHandle, "ValueName", ValueName);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtLoadKey,
+ __in POBJECT_ATTRIBUTES TargetKey,
+ __in POBJECT_ATTRIBUTES SourceFile
+) {
+ NTSTATUS ret = Old_NtLoadKey(TargetKey, SourceFile);
+ LOQ("oo", "TargetKey", unistr_from_objattr(TargetKey),
+ "SourceFile", unistr_from_objattr(SourceFile));
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtLoadKey2,
+ __in POBJECT_ATTRIBUTES TargetKey,
+ __in POBJECT_ATTRIBUTES SourceFile,
+ __in ULONG Flags
+) {
+ NTSTATUS ret = Old_NtLoadKey2(TargetKey, SourceFile, Flags);
+ LOQ("ool", "TargetKey", unistr_from_objattr(TargetKey),
+ "SourceFile", unistr_from_objattr(SourceFile), "Flags", Flags);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtLoadKeyEx,
+ __in POBJECT_ATTRIBUTES TargetKey,
+ __in POBJECT_ATTRIBUTES SourceFile,
+ __in ULONG Flags,
+ __in_opt HANDLE TrustClassKey
+) {
+ NTSTATUS ret = Old_NtLoadKeyEx(TargetKey, SourceFile, Flags,
+ TrustClassKey);
+ LOQ("pool", "TrustClassKey", TrustClassKey,
+ "TargetKey", unistr_from_objattr(TargetKey),
+ "SourceFile", unistr_from_objattr(SourceFile), "Flags", Flags);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtQueryKey,
+ __in HANDLE KeyHandle,
+ __in KEY_INFORMATION_CLASS KeyInformationClass,
+ __out_opt PVOID KeyInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+) {
+ NTSTATUS ret = Old_NtQueryKey(KeyHandle, KeyInformationClass,
+ KeyInformation, Length, ResultLength);
+ LOQ("pSl", "KeyHandle", KeyHandle,
+ "KeyInformation", Length, KeyInformation,
+ "KeyInformationClass", KeyInformationClass);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtSaveKey,
+ __in HANDLE KeyHandle,
+ __in HANDLE FileHandle
+) {
+ NTSTATUS ret = Old_NtSaveKey(KeyHandle, FileHandle);
+ LOQ("pp", "KeyHandle", KeyHandle, "FileHandle", FileHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtSaveKeyEx,
+ __in HANDLE KeyHandle,
+ __in HANDLE FileHandle,
+ __in ULONG Format
+) {
+ NTSTATUS ret = Old_NtSaveKeyEx(KeyHandle, FileHandle, Format);
+ LOQ("ppl", "KeyHandle", KeyHandle, "FileHandle", FileHandle,
+ "Format", Format);
+ return ret;
+}
diff --git a/hook_services.c b/hook_services.c
new file mode 100644
index 0000000..10a77f8
--- /dev/null
+++ b/hook_services.c
@@ -0,0 +1,181 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+
+static IS_SUCCESS_SCHANDLE();
+
+HOOKDEF(SC_HANDLE, WINAPI, OpenSCManagerA,
+ __in_opt LPCTSTR lpMachineName,
+ __in_opt LPCTSTR lpDatabaseName,
+ __in DWORD dwDesiredAccess
+) {
+ SC_HANDLE ret = Old_OpenSCManagerA(lpMachineName, lpDatabaseName,
+ dwDesiredAccess);
+ LOQ("ssl", "MachineName", lpMachineName, "DatabaseName", lpDatabaseName,
+ "DesiredAccess", dwDesiredAccess);
+ return ret;
+}
+
+HOOKDEF(SC_HANDLE, WINAPI, OpenSCManagerW,
+ __in_opt LPWSTR lpMachineName,
+ __in_opt LPWSTR lpDatabaseName,
+ __in DWORD dwDesiredAccess
+) {
+ SC_HANDLE ret = Old_OpenSCManagerW(lpMachineName, lpDatabaseName,
+ dwDesiredAccess);
+ LOQ("uul", "MachineName", lpMachineName, "DatabaseName", lpDatabaseName,
+ "DesiredAccess", dwDesiredAccess);
+ return ret;
+}
+
+HOOKDEF(SC_HANDLE, WINAPI, CreateServiceA,
+ __in SC_HANDLE hSCManager,
+ __in LPCTSTR lpServiceName,
+ __in_opt LPCTSTR lpDisplayName,
+ __in DWORD dwDesiredAccess,
+ __in DWORD dwServiceType,
+ __in DWORD dwStartType,
+ __in DWORD dwErrorControl,
+ __in_opt LPCTSTR lpBinaryPathName,
+ __in_opt LPCTSTR lpLoadOrderGroup,
+ __out_opt LPDWORD lpdwTagId,
+ __in_opt LPCTSTR lpDependencies,
+ __in_opt LPCTSTR lpServiceStartName,
+ __in_opt LPCTSTR lpPassword
+) {
+ SC_HANDLE ret = Old_CreateServiceA(hSCManager, lpServiceName,
+ lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType,
+ dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId,
+ lpDependencies, lpServiceStartName, lpPassword);
+ LOQ("pss4l3s", "ServiceControlHandle", hSCManager,
+ "ServiceName", lpServiceName, "DisplayName", lpDisplayName,
+ "DesiredAccess", dwDesiredAccess, "ServiceType", dwServiceType,
+ "StartType", dwStartType, "ErrorControl", dwErrorControl,
+ "BinaryPathName", lpBinaryPathName,
+ "ServiceStartName", lpServiceStartName,
+ "Password", lpPassword);
+ return ret;
+}
+
+HOOKDEF(SC_HANDLE, WINAPI, CreateServiceW,
+ __in SC_HANDLE hSCManager,
+ __in LPWSTR lpServiceName,
+ __in_opt LPWSTR lpDisplayName,
+ __in DWORD dwDesiredAccess,
+ __in DWORD dwServiceType,
+ __in DWORD dwStartType,
+ __in DWORD dwErrorControl,
+ __in_opt LPWSTR lpBinaryPathName,
+ __in_opt LPWSTR lpLoadOrderGroup,
+ __out_opt LPDWORD lpdwTagId,
+ __in_opt LPWSTR lpDependencies,
+ __in_opt LPWSTR lpServiceStartName,
+ __in_opt LPWSTR lpPassword
+) {
+ SC_HANDLE ret = Old_CreateServiceW(hSCManager, lpServiceName,
+ lpDisplayName, dwDesiredAccess, dwServiceType, dwStartType,
+ dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, lpdwTagId,
+ lpDependencies, lpServiceStartName, lpPassword);
+ LOQ("puu4l3u", "ServiceControlHandle", hSCManager,
+ "ServiceName", lpServiceName, "DisplayName", lpDisplayName,
+ "DesiredAccess", dwDesiredAccess, "ServiceType", dwServiceType,
+ "StartType", dwStartType, "ErrorControl", dwErrorControl,
+ "BinaryPathName", lpBinaryPathName,
+ "ServiceStartName", lpServiceStartName,
+ "Password", lpPassword);
+ return ret;
+}
+
+HOOKDEF(SC_HANDLE, WINAPI, OpenServiceA,
+ __in SC_HANDLE hSCManager,
+ __in LPCTSTR lpServiceName,
+ __in DWORD dwDesiredAccess
+) {
+ SC_HANDLE ret = Old_OpenServiceA(hSCManager, lpServiceName,
+ dwDesiredAccess);
+ LOQ("psl", "ServiceControlManager", hSCManager,
+ "ServiceName", lpServiceName, "DesiredAccess", dwDesiredAccess);
+ return ret;
+}
+
+HOOKDEF(SC_HANDLE, WINAPI, OpenServiceW,
+ __in SC_HANDLE hSCManager,
+ __in LPWSTR lpServiceName,
+ __in DWORD dwDesiredAccess
+) {
+ SC_HANDLE ret = Old_OpenServiceW(hSCManager, lpServiceName,
+ dwDesiredAccess);
+ LOQ("pul", "ServiceControlManager", hSCManager,
+ "ServiceName", lpServiceName, "DesiredAccess", dwDesiredAccess);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, StartServiceA,
+ __in SC_HANDLE hService,
+ __in DWORD dwNumServiceArgs,
+ __in_opt LPCTSTR *lpServiceArgVectors
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_StartServiceA(hService, dwNumServiceArgs,
+ lpServiceArgVectors);
+ LOQ("pa", "ServiceHandle", hService, "Arguments", dwNumServiceArgs,
+ lpServiceArgVectors);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, StartServiceW,
+ __in SC_HANDLE hService,
+ __in DWORD dwNumServiceArgs,
+ __in_opt LPWSTR *lpServiceArgVectors
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_StartServiceW(hService, dwNumServiceArgs,
+ lpServiceArgVectors);
+ LOQ("pA", "ServiceHandle", hService, "Arguments", dwNumServiceArgs,
+ lpServiceArgVectors);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, ControlService,
+ __in SC_HANDLE hService,
+ __in DWORD dwControl,
+ __out LPSERVICE_STATUS lpServiceStatus
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_ControlService(hService, dwControl, lpServiceStatus);
+ LOQ("pl", "ServiceHandle", hService, "ControlCode", dwControl);
+ return ret;
+}
+
+HOOKDEF(BOOL, WINAPI, DeleteService,
+ __in SC_HANDLE hService
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_DeleteService(hService);
+ LOQ("p", "ServiceHandle", hService);
+ return ret;
+}
diff --git a/hook_sleep.c b/hook_sleep.c
new file mode 100644
index 0000000..207e3d5
--- /dev/null
+++ b/hook_sleep.c
@@ -0,0 +1,141 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+
+// only skip Sleep()'s the first five seconds
+#define MAX_SLEEP_SKIP_DIFF 5000
+
+static IS_SUCCESS_NTSTATUS();
+
+// skipping sleep calls is done while this variable is set to true
+static int sleep_skip_active = 1;
+
+// the amount of time skipped, in 100-nanosecond
+static LARGE_INTEGER time_skipped;
+static LARGE_INTEGER time_start;
+
+HOOKDEF(NTSTATUS, WINAPI, NtDelayExecution,
+ __in BOOLEAN Alertable,
+ __in PLARGE_INTEGER DelayInterval
+) {
+ NTSTATUS ret = 0;
+
+ // do we want to skip this sleep?
+ if(sleep_skip_active != 0) {
+ FILETIME ft; LARGE_INTEGER li;
+ GetSystemTimeAsFileTime(&ft);
+ li.HighPart = ft.dwHighDateTime;
+ li.LowPart = ft.dwLowDateTime;
+
+ // check if we're still within the hardcoded limit
+ if(li.QuadPart < time_start.QuadPart + MAX_SLEEP_SKIP_DIFF * 10000) {
+ time_skipped.QuadPart += -DelayInterval->QuadPart;
+
+ // notify how much we've skipped
+ unsigned long milli = -DelayInterval->QuadPart / 10000;
+ LOQ("ls", "Milliseconds", milli, "Status", "Skipped");
+ return ret;
+ }
+ else {
+ sleep_skip_active = 0;
+ }
+ }
+ unsigned long milli = -DelayInterval->QuadPart / 10000;
+ LOQ2("l", "Milliseconds", milli);
+ return Old_NtDelayExecution(Alertable, DelayInterval);
+}
+
+HOOKDEF(void, WINAPI, GetLocalTime,
+ __out LPSYSTEMTIME lpSystemTime
+) {
+ Old_GetLocalTime(lpSystemTime);
+
+ LARGE_INTEGER li; FILETIME ft;
+ SystemTimeToFileTime(lpSystemTime, &ft);
+ li.HighPart = ft.dwHighDateTime;
+ li.LowPart = ft.dwLowDateTime;
+ li.QuadPart += time_skipped.QuadPart;
+ ft.dwHighDateTime = li.HighPart;
+ ft.dwLowDateTime = li.LowPart;
+ FileTimeToSystemTime(&ft, lpSystemTime);
+}
+
+HOOKDEF(void, WINAPI, GetSystemTime,
+ __out LPSYSTEMTIME lpSystemTime
+) {
+ Old_GetSystemTime(lpSystemTime);
+
+ LARGE_INTEGER li; FILETIME ft;
+ SystemTimeToFileTime(lpSystemTime, &ft);
+ li.HighPart = ft.dwHighDateTime;
+ li.LowPart = ft.dwLowDateTime;
+ li.QuadPart += time_skipped.QuadPart;
+ ft.dwHighDateTime = li.HighPart;
+ ft.dwLowDateTime = li.LowPart;
+ FileTimeToSystemTime(&ft, lpSystemTime);
+}
+
+HOOKDEF(DWORD, WINAPI, GetTickCount,
+ void
+) {
+ DWORD ret = Old_GetTickCount();
+
+ // add the time we've skipped
+ ret += time_skipped.QuadPart / 10000;
+
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtQuerySystemTime,
+ _Out_ PLARGE_INTEGER SystemTime
+) {
+ NTSTATUS ret = Old_NtQuerySystemTime(SystemTime);
+ if(NT_SUCCESS(ret)) {
+ SystemTime->QuadPart += time_skipped.QuadPart;
+ }
+ return 0;
+}
+
+void disable_sleep_skip()
+{
+ sleep_skip_active = 0;
+}
+
+void init_sleep_skip(int first_process)
+{
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ time_start.HighPart = ft.dwHighDateTime;
+ time_start.LowPart = ft.dwLowDateTime;
+
+ // we don't want to skip sleep calls in child processes
+ if(first_process == 0) {
+ disable_sleep_skip();
+ }
+}
+
+void init_startup_time(unsigned int startup_time)
+{
+ time_skipped.QuadPart += (unsigned __int64) startup_time * 10000;
+}
diff --git a/hook_sleep.h b/hook_sleep.h
new file mode 100644
index 0000000..ea13fd5
--- /dev/null
+++ b/hook_sleep.h
@@ -0,0 +1,21 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+void disable_sleep_skip();
+void init_sleep_skip(int first_process);
+void init_startup_time(unsigned int startup_time);
diff --git a/hook_socket.c b/hook_socket.c
new file mode 100644
index 0000000..2f3d0cf
--- /dev/null
+++ b/hook_socket.c
@@ -0,0 +1,337 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+
+static IS_SUCCESS_INTM1();
+
+HOOKDEF(int, WINAPI, WSAStartup,
+ _In_ WORD wVersionRequested,
+ _Out_ LPWSADATA lpWSAData
+) {
+ IS_SUCCESS_ZERO();
+
+ int ret = Old_WSAStartup(wVersionRequested, lpWSAData);
+ LOQ("p", "VersionRequested", wVersionRequested);
+ return ret;
+}
+
+HOOKDEF(struct hostent *, WSAAPI, gethostbyname,
+ __in const char *name
+) {
+ IS_SUCCESS_HANDLE();
+
+ struct hostent *ret = Old_gethostbyname(name);
+ LOQ("s", "Name", name);
+ return ret;
+}
+
+HOOKDEF(SOCKET, WSAAPI, socket,
+ __in int af,
+ __in int type,
+ __in int protocol
+) {
+ SOCKET ret = Old_socket(af, type, protocol);
+ LOQ("lll", "af", af, "type", type, "protocol", protocol);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, connect,
+ __in SOCKET s,
+ __in const struct sockaddr *name,
+ __in int namelen
+) {
+ int ret = Old_connect(s, name, namelen);
+ LOQ("p", "socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, send,
+ __in SOCKET s,
+ __in const char *buf,
+ __in int len,
+ __in int flags
+) {
+ int ret = Old_send(s, buf, len, flags);
+ LOQ("pb", "socket", s, "buffer", ret < 1 ? 0 : ret, buf);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, sendto,
+ __in SOCKET s,
+ __in const char *buf,
+ __in int len,
+ __in int flags,
+ __in const struct sockaddr *to,
+ __in int tolen
+) {
+ int ret = Old_sendto(s, buf, len, flags, to, tolen);
+ LOQ("pb", "socket", s, "buffer", ret < 1 ? 0 : ret, buf);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, recv,
+ __in SOCKET s,
+ __out char *buf,
+ __in int len,
+ __in int flags
+) {
+ int ret = Old_recv(s, buf, len, flags);
+ LOQ("pb", "socket", s, "buffer", ret < 1 ? 0 : len, buf);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, recvfrom,
+ __in SOCKET s,
+ __out char *buf,
+ __in int len,
+ __in int flags,
+ __out struct sockaddr *from,
+ __inout_opt int *fromlen
+) {
+ int ret = Old_recvfrom(s, buf, len, flags, from, fromlen);
+ LOQ("pb", "socket", s, "buffer", ret < 1 ? 0 : ret, buf);
+ return ret;
+}
+
+HOOKDEF(SOCKET, WSAAPI, accept,
+ __in SOCKET s,
+ __out struct sockaddr *addr,
+ __inout int *addrlen
+) {
+ SOCKET ret = Old_accept(s, addr, addrlen);
+ LOQ("pp", "socket", s, "ClientSocket", ret);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, bind,
+ __in SOCKET s,
+ __in const struct sockaddr *name,
+ __in int namelen
+) {
+ int ret = Old_bind(s, name, namelen);
+ if(ret == 0) {
+ LOQ("psl", "socket", s,
+ "ip", inet_ntoa(((struct sockaddr_in *) name)->sin_addr),
+ "port", htons(((struct sockaddr_in *) name)->sin_port));
+ }
+ else {
+ LOQ2("p", "socket", s);
+ }
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, listen,
+ __in SOCKET s,
+ __in int backlog
+) {
+ int ret = Old_listen(s, backlog);
+ LOQ("p", "socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, select,
+ __in SOCKET s,
+ __inout fd_set *readfds,
+ __inout fd_set *writefds,
+ __inout fd_set *exceptfds,
+ __in const struct timeval *timeout
+) {
+ int ret = Old_select(s, readfds, writefds, exceptfds, timeout);
+ LOQ("p", "socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, setsockopt,
+ __in SOCKET s,
+ __in int level,
+ __in int optname,
+ __in const char *optval,
+ __in int optlen
+) {
+ int ret = Old_setsockopt(s, level, optname, optval, optlen);
+ LOQ("pllb", "socket", s, "level", level, "optname", optname,
+ "optval", optlen, optval);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, ioctlsocket,
+ __in SOCKET s,
+ __in long cmd,
+ __inout u_long *argp
+) {
+ int ret = Old_ioctlsocket(s, cmd, argp);
+ LOQ("pl", "socket", s, "command", cmd);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, closesocket,
+ __in SOCKET s
+) {
+ int ret = Old_closesocket(s);
+ LOQ("p", "socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, shutdown,
+ __in SOCKET s,
+ __in int how
+) {
+ int ret = Old_shutdown(s, how);
+ LOQ("pl", "socket", s, "how", how);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, WSARecv,
+ __in SOCKET s,
+ __inout LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesRecvd,
+ __inout LPDWORD lpFlags,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+) {
+ BOOL ret = Old_WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd,
+ lpFlags, lpOverlapped, lpCompletionRoutine);
+ // TODO dump buffers
+ LOQ("p", "socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, WSARecvFrom,
+ __in SOCKET s,
+ __inout LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesRecvd,
+ __inout LPDWORD lpFlags,
+ __out struct sockaddr *lpFrom,
+ __inout LPINT lpFromlen,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+) {
+ BOOL ret = Old_WSARecvFrom(s, lpBuffers, dwBufferCount,
+ lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped,
+ lpCompletionRoutine);
+ // TODO dump buffer
+ LOQ("p", "socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, WSASend,
+ __in SOCKET s,
+ __in LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesSent,
+ __in DWORD dwFlags,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+) {
+ BOOL ret = Old_WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent,
+ dwFlags, lpOverlapped, lpCompletionRoutine);
+ // TODO dump buffers
+ LOQ("p", "Socket", s);
+ return ret;
+}
+
+HOOKDEF(int, WSAAPI, WSASendTo,
+ __in SOCKET s,
+ __in LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesSent,
+ __in DWORD dwFlags,
+ __in const struct sockaddr *lpTo,
+ __in int iToLen,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+) {
+ BOOL ret = Old_WSASendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent,
+ dwFlags, lpTo, iToLen, lpOverlapped, lpCompletionRoutine);
+ // TODO dump buffers
+ LOQ("p", "Socket", s);
+ return ret;
+}
+
+HOOKDEF(SOCKET, WSAAPI, WSASocketA,
+ __in int af,
+ __in int type,
+ __in int protocol,
+ __in LPWSAPROTOCOL_INFO lpProtocolInfo,
+ __in GROUP g,
+ __in DWORD dwFlags
+) {
+ SOCKET ret = Old_WSASocketA(af, type, protocol, lpProtocolInfo,
+ g, dwFlags);
+ LOQ("lll", "af", af, "type", type, "protocol", protocol);
+ return ret;
+}
+
+HOOKDEF(SOCKET, WSAAPI, WSASocketW,
+ __in int af,
+ __in int type,
+ __in int protocol,
+ __in LPWSAPROTOCOL_INFO lpProtocolInfo,
+ __in GROUP g,
+ __in DWORD dwFlags
+) {
+ SOCKET ret = Old_WSASocketW(af, type, protocol, lpProtocolInfo,
+ g, dwFlags);
+ LOQ("lll", "af", af, "type", type, "protocol", protocol);
+ return ret;
+}
+
+HOOKDEF(BOOL, PASCAL, ConnectEx,
+ _In_ SOCKET s,
+ _In_ const struct sockaddr *name,
+ _In_ int namelen,
+ _In_opt_ PVOID lpSendBuffer,
+ _In_ DWORD dwSendDataLength,
+ _Out_ LPDWORD lpdwBytesSent,
+ _In_ LPOVERLAPPED lpOverlapped
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_ConnectEx(s, name, namelen, lpSendBuffer, dwSendDataLength,
+ lpdwBytesSent, lpOverlapped);
+ LOQ("pB", "socket", s, "SendBuffer", lpdwBytesSent, lpSendBuffer);
+ return ret;
+}
+
+HOOKDEF(BOOL, PASCAL, TransmitFile,
+ SOCKET hSocket,
+ HANDLE hFile,
+ DWORD nNumberOfBytesToWrite,
+ DWORD nNumberOfBytesPerSend,
+ LPOVERLAPPED lpOverlapped,
+ LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
+ DWORD dwFlags
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old_TransmitFile(hSocket, hFile, nNumberOfBytesToWrite,
+ nNumberOfBytesPerSend, lpOverlapped, lpTransmitBuffers, dwFlags);
+ LOQ("ppll", "socket", hSocket, "FileHandle", hFile,
+ "NumberOfBytesToWrite", nNumberOfBytesToWrite,
+ "NumberOfBytesPerSend", nNumberOfBytesPerSend);
+ return ret;
+}
diff --git a/hook_special.c b/hook_special.c
new file mode 100644
index 0000000..694d52d
--- /dev/null
+++ b/hook_special.c
@@ -0,0 +1,109 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+#include "hook_sleep.h"
+
+static IS_SUCCESS_NTSTATUS();
+
+void set_hooks_dll(const wchar_t *library, int len);
+
+HOOKDEF2(NTSTATUS, WINAPI, LdrLoadDll,
+ __in_opt PWCHAR PathToFile,
+ __in_opt ULONG Flags,
+ __in PUNICODE_STRING ModuleFileName,
+ __out PHANDLE ModuleHandle
+) {
+ //
+ // In the event that loading this dll results in loading another dll as
+ // well, then the unicode string (which is located in the TEB) will be
+ // overwritten, therefore we make a copy of it for our own use.
+ //
+
+ COPY_UNICODE_STRING(library, ModuleFileName);
+
+ NTSTATUS ret = Old2_LdrLoadDll(PathToFile, Flags, ModuleFileName,
+ ModuleHandle);
+
+ if (hook_info()->depth_count == 1) {
+ LOQspecial("loP", "Flags", Flags, "FileName", &library,
+ "BaseAddress", ModuleHandle);
+ }
+
+ //
+ // Check this DLL against our table of hooks, because we might have to
+ // place some new hooks.
+ //
+
+ if(NT_SUCCESS(ret)) {
+ set_hooks_dll(library.Buffer, library.Length >> 1);
+ }
+
+ return ret;
+}
+
+HOOKDEF2(BOOL, WINAPI, CreateProcessInternalW,
+ __in_opt LPVOID lpUnknown1,
+ __in_opt LPWSTR lpApplicationName,
+ __inout_opt LPWSTR lpCommandLine,
+ __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in BOOL bInheritHandles,
+ __in DWORD dwCreationFlags,
+ __in_opt LPVOID lpEnvironment,
+ __in_opt LPWSTR lpCurrentDirectory,
+ __in LPSTARTUPINFO lpStartupInfo,
+ __out LPPROCESS_INFORMATION lpProcessInformation,
+ __in_opt LPVOID lpUnknown2
+) {
+ IS_SUCCESS_BOOL();
+
+ BOOL ret = Old2_CreateProcessInternalW(lpUnknown1, lpApplicationName,
+ lpCommandLine, lpProcessAttributes, lpThreadAttributes,
+ bInheritHandles, dwCreationFlags | CREATE_SUSPENDED, lpEnvironment,
+ lpCurrentDirectory, lpStartupInfo, lpProcessInformation, lpUnknown2);
+
+ if(ret != FALSE) {
+ pipe("PROCESS:%d,%d", lpProcessInformation->dwProcessId,
+ lpProcessInformation->dwThreadId);
+
+ // if the CREATE_SUSPENDED flag was not set, then we have to resume
+ // the main thread ourself
+ if((dwCreationFlags & CREATE_SUSPENDED) == 0) {
+ ResumeThread(lpProcessInformation->hThread);
+ }
+
+ disable_sleep_skip();
+ }
+
+ if (hook_info()->depth_count == 1) {
+ LOQspecial("uupllpp", "ApplicationName", lpApplicationName,
+ "CommandLine", lpCommandLine, "CreationFlags", dwCreationFlags,
+ "ProcessId", lpProcessInformation->dwProcessId,
+ "ThreadId", lpProcessInformation->dwThreadId,
+ "ProcessHandle", lpProcessInformation->hProcess,
+ "ThreadHandle", lpProcessInformation->hThread);
+ }
+
+ return ret;
+}
diff --git a/hook_sync.c b/hook_sync.c
new file mode 100644
index 0000000..afc8b3f
--- /dev/null
+++ b/hook_sync.c
@@ -0,0 +1,78 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+
+static IS_SUCCESS_NTSTATUS();
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateMutant,
+ __out PHANDLE MutantHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in BOOLEAN InitialOwner
+) {
+ NTSTATUS ret = Old_NtCreateMutant(MutantHandle, DesiredAccess,
+ ObjectAttributes, InitialOwner);
+ LOQ("Pol", "Handle", MutantHandle,
+ "MutexName", unistr_from_objattr(ObjectAttributes),
+ "InitialOwner", InitialOwner);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenMutant,
+ __out PHANDLE MutantHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+) {
+ NTSTATUS ret = Old_NtOpenMutant(MutantHandle, DesiredAccess,
+ ObjectAttributes);
+ LOQ("Po", "Handle", MutantHandle,
+ "MutexName", unistr_from_objattr(ObjectAttributes));
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateNamedPipeFile,
+ OUT PHANDLE NamedPipeFileHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG ShareAccess,
+ IN ULONG CreateDisposition,
+ IN ULONG CreateOptions,
+ IN BOOLEAN WriteModeMessage,
+ IN BOOLEAN ReadModeMessage,
+ IN BOOLEAN NonBlocking,
+ IN ULONG MaxInstances,
+ IN ULONG InBufferSize,
+ IN ULONG OutBufferSize,
+ IN PLARGE_INTEGER DefaultTimeOut
+) {
+ NTSTATUS ret = Old_NtCreateNamedPipeFile(NamedPipeFileHandle,
+ DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess,
+ CreateDisposition, CreateOptions, WriteModeMessage, ReadModeMessage,
+ NonBlocking, MaxInstances, InBufferSize, OutBufferSize,
+ DefaultTimeOut);
+ LOQ("PpOl", "NamedPipeHandle", NamedPipeFileHandle,
+ "DesiredAccess", DesiredAccess, "PipeName", ObjectAttributes,
+ "ShareAccess", ShareAccess);
+ return ret;
+}
diff --git a/hook_thread.c b/hook_thread.c
new file mode 100644
index 0000000..06f85c7
--- /dev/null
+++ b/hook_thread.c
@@ -0,0 +1,225 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+#include "pipe.h"
+#include "misc.h"
+#include "hook_sleep.h"
+
+static IS_SUCCESS_NTSTATUS();
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateThread,
+ __out PHANDLE ThreadHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in HANDLE ProcessHandle,
+ __out PCLIENT_ID ClientId,
+ __in PCONTEXT ThreadContext,
+ __in PINITIAL_TEB InitialTeb,
+ __in BOOLEAN CreateSuspended
+) {
+ pipe("PROCESS:%d", pid_from_process_handle(ProcessHandle));
+
+ NTSTATUS ret = Old_NtCreateThread(ThreadHandle, DesiredAccess,
+ ObjectAttributes, ProcessHandle, ClientId, ThreadContext,
+ InitialTeb, CreateSuspended);
+ LOQ("PpO", "ThreadHandle", ThreadHandle, "ProcessHandle", ProcessHandle,
+ "ObjectAttributes", ObjectAttributes);
+ if(NT_SUCCESS(ret)) {
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtCreateThreadEx,
+ OUT PHANDLE hThread,
+ IN ACCESS_MASK DesiredAccess,
+ IN PVOID ObjectAttributes,
+ IN HANDLE ProcessHandle,
+ IN LPTHREAD_START_ROUTINE lpStartAddress,
+ IN PVOID lpParameter,
+ IN BOOL CreateSuspended,
+ IN LONG StackZeroBits,
+ IN LONG SizeOfStackCommit,
+ IN LONG SizeOfStackReserve,
+ OUT PVOID lpBytesBuffer
+) {
+ NTSTATUS ret = Old_NtCreateThreadEx(hThread, DesiredAccess,
+ ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter,
+ CreateSuspended, StackZeroBits, SizeOfStackCommit, SizeOfStackReserve,
+ lpBytesBuffer);
+ LOQ("Pppl", "ThreadHandle", hThread, "ProcessHandle", ProcessHandle,
+ "StartAddress", lpStartAddress, "CreateSuspended", CreateSuspended);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenThread,
+ __out PHANDLE ThreadHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __in PCLIENT_ID ClientId
+) {
+ NTSTATUS ret = Old_NtOpenThread(ThreadHandle, DesiredAccess,
+ ObjectAttributes, ClientId);
+ LOQ("PlO", "ThreadHandle", ThreadHandle, "DesiredAccess", DesiredAccess,
+ "ObjectAttributes", ObjectAttributes);
+ if(NT_SUCCESS(ret)) {
+ // TODO: are we sure that OpenThread specifies the PID?
+ pipe("PROCESS:%d", ClientId->UniqueProcess);
+ }
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtGetContextThread,
+ __in HANDLE ThreadHandle,
+ __inout LPCONTEXT Context
+) {
+ NTSTATUS ret = Old_NtGetContextThread(ThreadHandle, Context);
+ LOQ("p", "ThreadHandle", ThreadHandle);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtSetContextThread,
+ __in HANDLE ThreadHandle,
+ __in const CONTEXT *Context
+) {
+ NTSTATUS ret = Old_NtSetContextThread(ThreadHandle, Context);
+ LOQ("p", "ThreadHandle", ThreadHandle);
+
+ pipe("PROCESS:%d", pid_from_thread_handle(ThreadHandle));
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtSuspendThread,
+ __in HANDLE ThreadHandle,
+ __out_opt ULONG *PreviousSuspendCount
+) {
+ ENSURE_ULONG(PreviousSuspendCount);
+
+ NTSTATUS ret = Old_NtSuspendThread(ThreadHandle, PreviousSuspendCount);
+ LOQ("pL", "ThreadHandle", ThreadHandle,
+ "SuspendCount", PreviousSuspendCount);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtResumeThread,
+ __in HANDLE ThreadHandle,
+ __out_opt ULONG *SuspendCount
+) {
+ ENSURE_ULONG(SuspendCount);
+
+ NTSTATUS ret = Old_NtResumeThread(ThreadHandle, SuspendCount);
+ LOQ("pL", "ThreadHandle", ThreadHandle, "SuspendCount", SuspendCount);
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtTerminateThread,
+ __in HANDLE ThreadHandle,
+ __in NTSTATUS ExitStatus
+) {
+ NTSTATUS ret = Old_NtTerminateThread(ThreadHandle, ExitStatus);
+ LOQ("pl", "ThreadHandle", ThreadHandle, "ExitStatus", ExitStatus);
+ return ret;
+}
+
+HOOKDEF(HANDLE, WINAPI, CreateThread,
+ __in LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in SIZE_T dwStackSize,
+ __in LPTHREAD_START_ROUTINE lpStartAddress,
+ __in LPVOID lpParameter,
+ __in DWORD dwCreationFlags,
+ __out LPDWORD lpThreadId
+) {
+ IS_SUCCESS_HANDLE();
+
+ HANDLE ret = Old_CreateThread(lpThreadAttributes, dwStackSize,
+ lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
+ LOQ("pplL", "StartRoutine", lpStartAddress, "Parameter", lpParameter,
+ "CreationFlags", dwCreationFlags, "ThreadId", lpThreadId);
+ if(NT_SUCCESS(ret)) {
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(HANDLE, WINAPI, CreateRemoteThread,
+ __in HANDLE hProcess,
+ __in LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in SIZE_T dwStackSize,
+ __in LPTHREAD_START_ROUTINE lpStartAddress,
+ __in LPVOID lpParameter,
+ __in DWORD dwCreationFlags,
+ __out LPDWORD lpThreadId
+) {
+ IS_SUCCESS_HANDLE();
+
+ pipe("PROCESS:%d", pid_from_process_handle(hProcess));
+
+ HANDLE ret = Old_CreateRemoteThread(hProcess, lpThreadAttributes,
+ dwStackSize, lpStartAddress, lpParameter, dwCreationFlags,
+ lpThreadId);
+ LOQ("3plL", "ProcessHandle", hProcess, "StartRoutine", lpStartAddress,
+ "Parameter", lpParameter, "CreationFlags", dwCreationFlags,
+ "ThreadId", lpThreadId);
+ if(NT_SUCCESS(ret)) {
+ disable_sleep_skip();
+ }
+ return ret;
+}
+
+HOOKDEF(VOID, WINAPI, ExitThread,
+ __in DWORD dwExitCode
+) {
+ IS_SUCCESS_VOID();
+
+ int ret = 0;
+ LOQ("l", "ExitCode", dwExitCode);
+ Old_ExitThread(dwExitCode);
+}
+
+HOOKDEF(NTSTATUS, WINAPI, RtlCreateUserThread,
+ IN HANDLE ProcessHandle,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
+ IN BOOLEAN CreateSuspended,
+ IN ULONG StackZeroBits,
+ IN OUT PULONG StackReserved,
+ IN OUT PULONG StackCommit,
+ IN PVOID StartAddress,
+ IN PVOID StartParameter OPTIONAL,
+ OUT PHANDLE ThreadHandle,
+ OUT PCLIENT_ID ClientId
+) {
+ ENSURE_CLIENT_ID(ClientId);
+
+ NTSTATUS ret = Old_RtlCreateUserThread(ProcessHandle, SecurityDescriptor,
+ CreateSuspended, StackZeroBits, StackReserved, StackCommit,
+ StartAddress, StartParameter, ThreadHandle, ClientId);
+ LOQ("plppPl", "ProcessHandle", ProcessHandle,
+ "CreateSuspended", CreateSuspended, "StartAddress", StartAddress,
+ "StartParameter", StartParameter, "ThreadHandle", ThreadHandle,
+ "ThreadIdentifier", ClientId->UniqueThread);
+ if(NT_SUCCESS(ret)) {
+ pipe("PROCESS:0,%d", ClientId->UniqueThread);
+ disable_sleep_skip();
+ }
+ return ret;
+}
diff --git a/hook_window.c b/hook_window.c
new file mode 100644
index 0000000..f9b63a8
--- /dev/null
+++ b/hook_window.c
@@ -0,0 +1,94 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+#include "log.h"
+
+static IS_SUCCESS_HWND();
+
+HOOKDEF(HWND, WINAPI, FindWindowA,
+ __in_opt LPCTSTR lpClassName,
+ __in_opt LPCTSTR lpWindowName
+) {
+ // The atom must be in the low-order word of lpClassName;
+ // the high-order word must be zero (from MSDN documentation.)
+ HWND ret = Old_FindWindowA(lpClassName, lpWindowName);
+ if(((DWORD_PTR) lpClassName & 0xffff) == (DWORD_PTR) lpClassName) {
+ LOQ("ls", "ClassName", lpClassName, "WindowName", lpWindowName);
+ }
+ else {
+ LOQ("ss", "ClassName", lpClassName, "WindowName", lpWindowName);
+ }
+ return ret;
+}
+
+HOOKDEF(HWND, WINAPI, FindWindowW,
+ __in_opt LPWSTR lpClassName,
+ __in_opt LPWSTR lpWindowName
+) {
+ HWND ret = Old_FindWindowW(lpClassName, lpWindowName);
+ if(((DWORD_PTR) lpClassName & 0xffff) == (DWORD_PTR) lpClassName) {
+ LOQ("lu", "ClassName", lpClassName, "WindowName", lpWindowName);
+ }
+ else {
+ LOQ("uu", "ClassName", lpClassName, "WindowName", lpWindowName);
+ }
+ return ret;
+}
+
+HOOKDEF(HWND, WINAPI, FindWindowExA,
+ __in_opt HWND hwndParent,
+ __in_opt HWND hwndChildAfter,
+ __in_opt LPCTSTR lpszClass,
+ __in_opt LPCTSTR lpszWindow
+) {
+ HWND ret = Old_FindWindowExA(hwndParent, hwndChildAfter, lpszClass,
+ lpszWindow);
+
+ // lpszClass can be one of the predefined window controls.. which lay in
+ // the 0..ffff range
+ if(((DWORD_PTR) lpszClass & 0xffff) == (DWORD_PTR) lpszClass) {
+ LOQ("ls", "ClassName", lpszClass, "WindowName", lpszWindow);
+ }
+ else {
+ LOQ2("ss", "ClassName", lpszClass, "WindowName", lpszWindow);
+ }
+ return ret;
+}
+
+HOOKDEF(HWND, WINAPI, FindWindowExW,
+ __in_opt HWND hwndParent,
+ __in_opt HWND hwndChildAfter,
+ __in_opt LPWSTR lpszClass,
+ __in_opt LPWSTR lpszWindow
+) {
+ HWND ret = Old_FindWindowExW(hwndParent, hwndChildAfter, lpszClass,
+ lpszWindow);
+ // lpszClass can be one of the predefined window controls.. which lay in
+ // the 0..ffff range
+ if(((DWORD_PTR) lpszClass & 0xffff) == (DWORD_PTR) lpszClass) {
+ LOQ("lu", "ClassName", lpszClass, "WindowName", lpszWindow);
+ }
+ else {
+ LOQ2("uu", "ClassName", lpszClass, "WindowName", lpszWindow);
+ }
+ return ret;
+}
diff --git a/hooking.c b/hooking.c
new file mode 100644
index 0000000..7bf1f7c
--- /dev/null
+++ b/hooking.c
@@ -0,0 +1,815 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include "hooking.h"
+#include "distorm.h"
+#include "mnemonics.h"
+#include "ntapi.h"
+#include "ignore.h"
+
+// this number can be changed if required to do so
+#define TLS_HOOK_INFO 0x44
+
+// do not change this number
+#define TLS_LAST_ERROR 0x34
+
+// hook return address stack space
+#define TLS_HOOK_INFO_RETADDR_SPACE 0x100
+
+static void ensure_valid_hook_info();
+
+// by default we enable the retaddr check
+static int g_enable_retaddr_check = 1;
+
+// length disassembler engine
+int lde(void *addr)
+{
+ // the length of an instruction is 16 bytes max, but there can also be
+ // 16 instructions of length one, so.. we support "decomposing" 16
+ // instructions at once, max
+ unsigned int used_instruction_count; _DInst instructions[16];
+ _CodeInfo code_info = {0, 0, addr, 16, Decode32Bits};
+ _DecodeResult ret = distorm_decompose(&code_info, instructions, 16,
+ &used_instruction_count);
+
+ return ret == DECRES_SUCCESS ? instructions[0].size : 0;
+}
+
+static int is_interesting_backtrace(unsigned int ebp)
+{
+ // only perform this function when the retaddr-check is enabled, otherwise
+ // return true in all cases (if retaddr-check is disabled, then every
+ // backtrace is interesting)
+ if(g_enable_retaddr_check == 0) {
+ return 1;
+ }
+
+ // http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
+ unsigned int top = __readfsdword(0x04);
+ unsigned int bottom = __readfsdword(0x08);
+
+ unsigned int count = HOOK_BACKTRACE_DEPTH;
+ while (ebp >= bottom && ebp < top && count-- != 0) {
+
+ // obtain the return address and the next value of ebp
+ unsigned int addr = *(unsigned int *)(ebp + 4);
+ ebp = *(unsigned int *) ebp;
+
+ // if this return address is *not* to be ignored, then it's
+ // interesting
+ if(is_ignored_retaddr(addr) == 0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// create a trampoline at the given address, that is, we are going to replace
+// the original instructions at this particular address. So, in order to
+// call the original function from our hook, we have to execute the original
+// instructions *before* jumping into addr+offset, where offset is the length
+// which totals the size of the instructions which we place in the `tramp'.
+// returns 0 on failure, or a positive integer defining the size of the tramp
+// NOTE: tramp represents the memory address where the trampoline will be
+// placed, copying it to another memory address will result into failure
+static int hook_create_trampoline(unsigned char *addr, int len,
+ unsigned char *tramp)
+{
+ const unsigned char *base = tramp;
+
+ // after the original function has returned, we have to make a backup of
+ // the Last Error Code, so what we do is the following (we use the same
+ // method below in the pre-tramp.) We store the current return address in
+ // info->ret_last_error, then we overwrite the return address with a
+ // return address in our trampoline. When we reach the trampoline, we make
+ // a backup of the Last Error Code and jmp to the real return address.
+
+ unsigned char pre_backup[] = {
+ // push eax
+ 0x50,
+
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+ // test eax, eax
+ 0x85, 0xc0,
+ // jnz $+0d
+ 0x75, 0x0d,
+ // pushad
+ 0x60,
+ // call ensure_valid_hook_info
+ 0xe8, 0x00, 0x00, 0x00, 0x00,
+ // popad
+ 0x61,
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+
+ // cmp dword [eax+hook_info_t.hook_count], 0
+ 0x83, 0x78, offsetof(hook_info_t, hook_count), 0x00,
+ // jg $+12
+ 0x7f, 0x12,
+ // inc dword [eax+hook_info_t.hook_count]
+ 0xff, 0x40, offsetof(hook_info_t, hook_count),
+ // push dword [esp+4]
+ 0xff, 0x74, 0xe4, 0x04,
+ // pop dword [eax+hook_info_t.ret_last_error]
+ 0x8f, 0x40, offsetof(hook_info_t, ret_last_error),
+ // mov dword [esp+4], new_return_address
+ 0xc7, 0x44, 0xe4, 0x04, 0x00, 0x00, 0x00, 0x00,
+
+ // pop eax
+ 0x58,
+ };
+
+ // the function returns here after executing, backup the Last Error Code
+ unsigned char post_backup[] = {
+ // push eax
+ 0x50,
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+ // dec dword [eax+hook_info_t.hook_count]
+ 0xff, 0x48, offsetof(hook_info_t, hook_count),
+ // cmp dword [eax+hook_info_t.depth_count], 1
+ 0x83, 0x78, offsetof(hook_info_t, depth_count), 0x01,
+ // jg $+0a
+ 0x7f, 0x0a,
+ // push dword fs:[TLS_LAST_ERROR]
+ 0x64, 0xff, 0x35, TLS_LAST_ERROR, 0x00, 0x00, 0x00,
+ // pop dword [eax+hook_info_t.last_error]
+ 0x8f, 0x40, offsetof(hook_info_t, last_error),
+ // mov eax, dword [eax+hook_info_t.ret_last_error]
+ 0x8b, 0x40, offsetof(hook_info_t, ret_last_error),
+ // xchg eax, dword [esp]
+ 0x87, 0x04, 0xe4,
+ // retn
+ 0xc3,
+ };
+
+ *(unsigned int *)(pre_backup + 13) =
+ (unsigned char *) &ensure_valid_hook_info - tramp - 12 - 5;
+
+ memcpy(tramp, pre_backup, sizeof(pre_backup));
+ tramp += sizeof(pre_backup);
+
+ unsigned char **pre_backup_addr = (unsigned char **)(tramp - 5);
+
+ // our trampoline should contain at least enough bytes to fit the given
+ // length
+ while (len > 0) {
+
+ // obtain the length of this instruction
+ int length = lde(addr);
+
+ // error?
+ if(length == 0) {
+ return 0;
+ }
+
+ // how many bytes left?
+ len -= length;
+
+ // check the type of instruction at this particular address, if it's
+ // a jump or a call instruction, then we have to calculate some fancy
+ // addresses, otherwise we can simply copy the instruction to our
+ // trampoline
+
+ // it's a (conditional) jump or call with 32bit relative offset
+ if(*addr == 0xe9 || *addr == 0xe8 || (*addr == 0x0f &&
+ addr[1] >= 0x80 && addr[1] < 0x90)) {
+
+ // copy the jmp or call instruction (conditional jumps are two
+ // bytes, the rest is one byte)
+ *tramp++ += *addr++;
+ if(addr[-1] != 0xe9 && addr[-1] != 0xe8) {
+ *tramp++ += *addr++;
+ }
+
+ // when a jmp/call is performed, then the relative offset +
+ // the instruction pointer + the size of the instruction is the
+ // calculated address, so that's our target address as well.
+ // (note that `addr' is already increased by one or two, so the
+ // 4 represents the 32bit offset of this particular instruction)
+ unsigned long jmp_addr = *(unsigned long *) addr + 4 +
+ (unsigned long) addr;
+ addr += 4;
+
+ // trampoline is already filled with the opcode itself (the jump
+ // instruction), now we will actually jump to the location by
+ // calculating the relative offset which points to the real
+ // address (this is the reverse operation of the one to calculate
+ // the absolute address of a jump)
+ *(unsigned long *) tramp = jmp_addr - (unsigned long) tramp - 4;
+ tramp += 4;
+
+ // because an unconditional jump denotes the end of a basic block
+ // we will return failure if we have not yet processed enough room
+ // to store our hook code
+ if(tramp[-5] == 0xe9 && len > 0) return 0;
+ }
+ // (conditional) jump with 8bit relative offset
+ else if(*addr == 0xeb || (*addr >= 0x70 && *addr < 0x80)) {
+
+ // same rules apply as with the 32bit relative offsets, except
+ // for the fact that both conditional and unconditional 8bit
+ // relative jumps take only one byte for the opcode
+
+ // 8bit relative offset, we have to sign-extend it (by casting it
+ // as signed char) in order to calculate the correct address
+ unsigned long jmp_addr = (unsigned long) addr + 2 +
+ *(signed char *)(addr + 1);
+
+ // the chance is *fairly* high that we will not be able to perform
+ // a jump from the trampoline to the original function, so instead
+ // we will use 32bit relative offset jumps
+ if(*addr == 0xeb) {
+ *tramp++ = 0xe9;
+ }
+ else {
+ // hex representation of the two types of 32bit jumps
+ // 8bit relative conditional jumps: 70..80
+ // 32bit relative conditional jumps: 0f 80..90
+ // so we will simply add 0x10 to the opcode of 8bit relative
+ // offset jump to obtain the 32bit relative offset jump opcode
+ *tramp++ = 0x0f;
+ *tramp++ = *addr + 0x10;
+ }
+
+ // calculate the correct relative offset address
+ *(unsigned long *) tramp = jmp_addr - (unsigned long) tramp - 4;
+ tramp += 4;
+
+ // again, end of basic block, check for length
+ if(*addr == 0xeb && len > 0) {
+ return 0;
+ }
+
+ // add the instruction length
+ addr += 2;
+ }
+ // return instruction, indicates end of basic block as well, so we
+ // have to check if we already have enough space for our hook..
+ else if((*addr == 0xc3 || *addr == 0xc2) && len > 0) {
+ return 0;
+ }
+ else {
+ // copy the instruction directly to the trampoline
+ while (length-- != 0) {
+ *tramp++ = *addr++;
+ }
+ }
+ }
+
+ // append a jump from the trampoline to the original function
+ *tramp++ = 0xe9;
+ *(unsigned int *) tramp =
+ (unsigned int) addr - (unsigned int) tramp - 4;
+ tramp += 4;
+
+ // return address is the next instruction after the jmp
+ *pre_backup_addr = tramp;
+
+ memcpy(tramp, post_backup, sizeof(post_backup));
+ tramp += sizeof(post_backup);
+
+ // return the length of this trampoline
+ return tramp - base;
+}
+
+// this function constructs the so-called pre-trampoline, this pre-trampoline
+// determines if a hook should really be executed. An example will be the
+// easiest; imagine we have a hook on CreateProcessInternalW() and on
+// NtCreateProcessEx() (this is actually the case currently), now, if all goes
+// well, a call to CreateProcess() will call CreateProcessInternalW() followed
+// by a call to NtCreateProcessEx(). Because we already hook the higher-level
+// API CreateProcessInternalW() it is not really useful to us to log the
+// information retrieved in the NtCreateProcessEx() function as well,
+// therefore, because one is called by the other, we can tell the hooking
+// engine "once inside a hook, don't hook further API calls" by setting the
+// allow_hook_recursion flag to false. The example above is what happens when
+// the hook recursion is not allowed.
+static void hook_create_pre_tramp(hook_t *h, uint8_t is_special_hook)
+{
+ unsigned char pre_tramp[] = {
+ // push ebx
+ 0x53,
+ // push eax
+ 0x50,
+
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+ // test eax, eax
+ 0x85, 0xc0,
+ // jnz $+0d
+ 0x75, 0x0d,
+ // pushad
+ 0x60,
+ // call ensure_valid_hook_info
+ 0xe8, 0x00, 0x00, 0x00, 0x00,
+ // popad
+ 0x61,
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+
+ // inc dword [eax+hook_info_t.depth_count]
+ 0xff, 0x40, offsetof(hook_info_t, depth_count),
+
+ // mov ebx, [esp+8]
+ 0x8b, 0x5c, 0xe4, 0x08,
+ // xchg esp, [eax+hook_info_t.retaddr_esp]
+ 0x87, 0x60, offsetof(hook_info_t, retaddr_esp),
+ // push ebx
+ 0x53,
+ // xchg esp, [eax+hook_info_t.retaddr_esp]
+ 0x87, 0x60, offsetof(hook_info_t, retaddr_esp),
+ // mov dword [esp+8], new_return_address
+ 0xc7, 0x44, 0xe4, 0x08, 0x00, 0x00, 0x00, 0x00,
+
+ // special hook support
+ // mov ebx, 1
+ 0xbb, 0x01, 0x00, 0x00, 0x00,
+ // cmp ebx, is_special_hook
+ 0x83, 0xfb, is_special_hook,
+ // jnz $+7
+ 0x75, 0x07,
+ // pop eax; pop ebx
+ 0x58, 0x5b,
+ // jmp h->store_exc
+ 0xe9, 0x00, 0x00, 0x00, 0x00,
+
+ // cmp dword [eax+hook_info_t.depth_count], 1
+ 0x83, 0x78, offsetof(hook_info_t, depth_count), 0x01,
+ // jle $+7
+ 0x7e, 0x07,
+ // pop eax; pop ebx
+ 0x58, 0x5b,
+ // jmp h->tramp
+ 0xe9, 0x00, 0x00, 0x00, 0x00,
+
+ // pushad
+ 0x60,
+ // push ebp
+ 0x55,
+ // call is_interesting_backtrace
+ 0xe8, 0x00, 0x00, 0x00, 0x00,
+ // test eax, eax
+ 0x85, 0xc0,
+ // pop eax
+ 0x58,
+ // popad
+ 0x61,
+ // jnz $+7
+ 0x75, 0x07,
+ // pop eax; pop ebx
+ 0x58, 0x5b,
+ // jmp h->tramp
+ 0xe9, 0x00, 0x00, 0x00, 0x00,
+
+ // pop eax; pop ebx
+ 0x58, 0x5b,
+ // jmp h->store_exc
+ 0xe9, 0x00, 0x00, 0x00, 0x00,
+
+
+ // push ebx; push eax
+ 0x53, 0x50,
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+ // dec dword [eax+hook_info_t.depth_count]
+ 0xff, 0x48, offsetof(hook_info_t, depth_count),
+ // push dword [eax+hook_info_t.last_error]
+ 0xff, 0x70, offsetof(hook_info_t, last_error),
+ // pop dword fs:[0x34]
+ 0x64, 0x8f, 0x05, 0x34, 0x00, 0x00, 0x00,
+
+ // xchg esp, [eax+hook_info_t.retaddr_esp]
+ 0x87, 0x60, offsetof(hook_info_t, retaddr_esp),
+ // pop ebx
+ 0x5b,
+ // xchg esp, [eax+hook_info_t.retaddr_esp]
+ 0x87, 0x60, offsetof(hook_info_t, retaddr_esp),
+ // pop eax
+ 0x58,
+ // xchg ebx, dword [esp]
+ 0x87, 0x1c, 0xe4,
+ // retn
+ 0xc3,
+
+ };
+
+ *(unsigned int *)(pre_tramp + 14) =
+ (unsigned char *) &ensure_valid_hook_info - h->pre_tramp - 13 - 5;
+ *(unsigned int *)(pre_tramp + 43) = (unsigned int) h->pre_tramp + 104;
+
+ *(unsigned int *)(pre_tramp + 60) =
+ (unsigned char *) h->store_exc - h->pre_tramp - 59 - 5;
+
+ *(unsigned int *)(pre_tramp + 73) = h->tramp - h->pre_tramp - 72 - 5;
+ *(unsigned int *)(pre_tramp + 80) =
+ (unsigned char *) &is_interesting_backtrace - h->pre_tramp - 79 - 5;
+ *(unsigned int *)(pre_tramp + 93) = h->tramp - h->pre_tramp - 92 - 5;
+ *(unsigned int *)(pre_tramp + 100) =
+ (unsigned char *) h->store_exc - h->pre_tramp - 99 - 5;
+
+ memcpy(h->pre_tramp, pre_tramp, sizeof(pre_tramp));
+}
+
+static void hook_store_exception_info(hook_t *h)
+{
+ unsigned char store_exception[] = {
+ // push eax
+ 0x50,
+ // mov eax, fs:[TLS_HOOK_INFO]
+ 0x64, 0xa1, TLS_HOOK_INFO, 0x00, 0x00, 0x00,
+ // xchg ebx, dword [esp]
+ 0x87, 0x1c, 0xe4,
+ // mov dword [eax+hook_info_t.eax], ebx
+ 0x89, 0x58, offsetof(hook_info_t, eax),
+ // xchg ebx, dword [esp]
+ 0x87, 0x1c, 0xe4,
+ // mov dword [eax+hook_info_t.ecx], ecx
+ 0x89, 0x48, offsetof(hook_info_t, ecx),
+ // mov dword [eax+hook_info_t.edx], edx
+ 0x89, 0x50, offsetof(hook_info_t, edx),
+ // mov dword [eax+hook_info_t.ebx], ebx
+ 0x89, 0x58, offsetof(hook_info_t, ebx),
+ // mov dword [eax+hook_info_t.esp], esp
+ 0x89, 0x60, offsetof(hook_info_t, esp),
+ // mov dword [eax+hook_info_t.ebp], ebp
+ 0x89, 0x68, offsetof(hook_info_t, ebp),
+ // mov dword [eax+hook_info_t.esi], esi
+ 0x89, 0x70, offsetof(hook_info_t, esi),
+ // mov dword [eax+hook_info_t.edi], edi
+ 0x89, 0x78, offsetof(hook_info_t, edi),
+ // pop eax
+ 0x58,
+ // jmp h->new_func
+ 0xe9, 0x00, 0x00, 0x00, 0x00,
+ };
+
+ unsigned int offset = sizeof(store_exception) - 5;
+ *(unsigned int *)(store_exception + offset + 1) =
+ (unsigned char *) h->new_func - h->store_exc - offset - 5;
+ memcpy(h->store_exc, store_exception, sizeof(store_exception));
+}
+
+static int hook_api_jmp_direct(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // unconditional jump opcode
+ *from = 0xe9;
+
+ // store the relative address from this opcode to our hook function
+ *(unsigned long *)(from + 1) = (unsigned char *) to - from - 5;
+ return 0;
+}
+
+static int hook_api_nop_jmp_direct(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // nop
+ *from++ = 0x90;
+
+ return hook_api_jmp_direct(h, from, to);
+}
+
+static int hook_api_hotpatch_jmp_direct(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // mov edi, edi
+ *from++ = 0x8b;
+ *from++ = 0xff;
+
+ return hook_api_jmp_direct(h, from, to);
+}
+
+static int hook_api_push_retn(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // push addr
+ *from++ = 0x68;
+ *(unsigned char **) from = to;
+
+ // retn
+ from[4] = 0xc3;
+
+ return 0;
+}
+
+static int hook_api_nop_push_retn(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // nop
+ *from++ = 0x90;
+
+ return hook_api_push_retn(h, from, to);
+}
+
+static int hook_api_jmp_indirect(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // jmp dword [hook_data]
+ *from++ = 0xff;
+ *from++ = 0x25;
+
+ *(unsigned char **) from = h->hook_data;
+
+ // the real address is stored in hook_data
+ memcpy(h->hook_data, &to, sizeof(to));
+ return 0;
+}
+
+static int hook_api_mov_eax_jmp_eax(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // mov eax, address
+ *from++ = 0xb8;
+ *(unsigned char **) from = to;
+ from += 4;
+
+ // jmp eax
+ *from++ = 0xff;
+ *from++ = 0xe0;
+ return 0;
+}
+
+static int hook_api_mov_eax_push_retn(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // mov eax, address
+ *from++ = 0xb8;
+ *(unsigned char **) from = to;
+ from += 4;
+
+ // push eax
+ *from++ = 0x50;
+
+ // retn
+ *from++ = 0xc3;
+ return 0;
+}
+
+static int hook_api_mov_eax_indirect_jmp_eax(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // mov eax, [hook_data]
+ *from++ = 0xa1;
+ *(unsigned char **) from = h->hook_data;
+ from += 4;
+
+ // store the address at hook_data
+ memcpy(h->hook_data, &to, sizeof(to));
+
+ // jmp eax
+ *from++ = 0xff;
+ *from++ = 0xe0;
+ return 0;
+}
+
+static int hook_api_mov_eax_indirect_push_retn(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // mov eax, [hook_data]
+ *from++ = 0xa1;
+ *(unsigned char **) from = h->hook_data;
+ from += 4;
+
+ // store the address at hook_data
+ memcpy(h->hook_data, &to, sizeof(to));
+
+ // push eax
+ *from++ = 0x50;
+
+ // retn
+ *from++ = 0xc3;
+ return 0;
+}
+
+#if HOOK_ENABLE_FPU
+static int hook_api_push_fpu_retn(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // push ebp
+ *from++ = 0x55;
+
+ // fld qword [hook_data]
+ *from++ = 0xdd;
+ *from++ = 0x05;
+
+ *(unsigned char **) from = h->hook_data;
+ from += 4;
+
+ // fistp dword [esp]
+ *from++ = 0xdb;
+ *from++ = 0x1c;
+ *from++ = 0xe4;
+
+ // retn
+ *from++ = 0xc3;
+
+ // store the address as double
+ double addr = (double) (unsigned long) to;
+ memcpy(h->hook_data, &addr, sizeof(addr));
+ return 0;
+}
+#endif
+
+static int hook_api_special_jmp(hook_t *h, unsigned char *from,
+ unsigned char *to)
+{
+ // our largest hook in use is currently 7 bytes. so we have to make sure
+ // that this special hook (a hook that will be patched over again later)
+ // is atleast seven bytes.
+ *from++ = 0x90;
+ *from++ = 0x90;
+ return hook_api_jmp_direct(h, from, to);
+}
+
+int hook_api(hook_t *h, int type)
+{
+ // table with all possible hooking types
+ static struct {
+ int(*hook)(hook_t *h, unsigned char *from, unsigned char *to);
+ int len;
+ } hook_types[] = {
+ /* HOOK_JMP_DIRECT */ {&hook_api_jmp_direct, 5},
+ /* HOOK_NOP_JMP_DIRECT */ {&hook_api_nop_jmp_direct, 6},
+ /* HOOK_HOTPATCH_JMP_DIRECT */ {&hook_api_hotpatch_jmp_direct, 7},
+ /* HOOK_PUSH_RETN */ {&hook_api_push_retn, 6},
+ /* HOOK_NOP_PUSH_RETN */ {&hook_api_nop_push_retn, 7},
+ /* HOOK_JMP_INDIRECT */ {&hook_api_jmp_indirect, 6},
+ /* HOOK_MOV_EAX_JMP_EAX */ {&hook_api_mov_eax_jmp_eax, 7},
+ /* HOOK_MOV_EAX_PUSH_RETN */ {&hook_api_mov_eax_push_retn, 7},
+ /* HOOK_MOV_EAX_INDIRECT_JMP_EAX */
+ {&hook_api_mov_eax_indirect_jmp_eax, 7},
+ /* HOOK_MOV_EAX_INDIRECT_PUSH_RETN */
+ {&hook_api_mov_eax_indirect_push_retn, 7},
+#if HOOK_ENABLE_FPU
+ /* HOOK_PUSH_FPU_RETN */ {&hook_api_push_fpu_retn, 11},
+#endif
+ /* HOOK_SPECIAL_JMP */ {&hook_api_special_jmp, 7},
+ };
+
+ // is this address already hooked?
+ if(h->is_hooked != 0) {
+ return 0;
+ }
+
+ // resolve the address to hook
+ unsigned char *addr = h->addr;
+
+ if(addr == NULL && h->library != NULL && h->funcname != NULL) {
+ addr = (unsigned char *) GetProcAddress(GetModuleHandleW(h->library),
+ h->funcname);
+ }
+ if(addr == NULL) {
+ return -1;
+ }
+
+ int ret = -1;
+
+ // check if this is a valid hook type
+ if(type >= 0 && type < ARRAYSIZE(hook_types)) {
+
+ // determine whether we're running under win7, if so, we might have to
+ // follow a short relative jmp and an indirect jump before reaching
+ // the real address
+ OSVERSIONINFO os_info = {sizeof(OSVERSIONINFO)};
+ if(GetVersionEx(&os_info) && os_info.dwMajorVersion == 6 &&
+ os_info.dwMinorVersion == 1) {
+ // windows 7 has a DLL called kernelbase.dll which basically acts
+ // as a layer between the program and kernel32 (and related?) it
+ // allows easy hotpatching of a set of functions which is why
+ // there's a short relative jump and an indirect jump. we want to
+ // resolve the address of the real function, so we follow these
+ // two jumps.
+ if(!memcmp(addr, "\xeb\x05", 2) &&
+ !memcmp(addr + 7, "\xff\x25", 2)) {
+ addr = **(unsigned char ***)(addr + 9);
+ }
+
+ // Some functions don't just have the short jump and indirect
+ // jump, but also an empty function prolog
+ // ("mov edi, edi ; push ebp ; mov ebp, esp ; pop ebp"). Other
+ // than that, this edge case is equivalent to the case above.
+ else if(!memcmp(addr, "\x8b\xff\x55\x8b\xec\x5d\xeb\x05", 8) &&
+ !memcmp(addr + 13, "\xff\x25", 2)) {
+ addr = **(unsigned char ***)(addr + 15);
+ }
+
+ // the following applies for "inlined" functions on windows 7,
+ // some functions are inlined into kernelbase.dll, rather than
+ // kernelbase.dll jumping to e.g. kernel32.dll. for these
+ // functions there is a short relative jump, followed by the
+ // inlined function.
+ if(!memcmp(addr, "\xeb\x02", 2) &&
+ !memcmp(addr - 5, "\xcc\xcc\xcc\xcc\xcc", 5)) {
+ // step over the short jump and the relative offset
+ addr += 4;
+ }
+ }
+
+ DWORD old_protect;
+
+ // make the address writable
+ if(VirtualProtect(addr, hook_types[type].len, PAGE_EXECUTE_READWRITE,
+ &old_protect)) {
+
+ if(hook_create_trampoline(addr, hook_types[type].len, h->tramp)) {
+
+ hook_store_exception_info(h);
+
+ uint8_t special = 0;
+
+ if(h->allow_hook_recursion == 1) {
+ special = 1;
+ }
+
+ hook_create_pre_tramp(h, special);
+
+ // insert the hook (jump from the api to the
+ // pre-trampoline)
+ ret = hook_types[type].hook(h, addr, h->pre_tramp);
+
+ // if successful, assign the trampoline address to *old_func
+ if(ret == 0) {
+ *h->old_func = h->tramp;
+
+ // successful hook is successful
+ h->is_hooked = 1;
+ }
+ }
+
+ // restore the old protection
+ VirtualProtect(addr, hook_types[type].len, old_protect,
+ &old_protect);
+ }
+ }
+
+ return ret;
+}
+
+hook_info_t *hook_info()
+{
+ return (hook_info_t *) __readfsdword(TLS_HOOK_INFO);
+}
+
+static void ensure_valid_hook_info()
+{
+ if(hook_info() == NULL) {
+ hook_info_t *info = (hook_info_t *) calloc(1, sizeof(hook_info_t)+TLS_HOOK_INFO_RETADDR_SPACE);
+ info->retaddr_esp = (unsigned int) info + sizeof(hook_info_t) + TLS_HOOK_INFO_RETADDR_SPACE;
+ __writefsdword(TLS_HOOK_INFO, (unsigned int) info);
+ }
+}
+
+void hook_enable()
+{
+ ensure_valid_hook_info();
+ hook_info()->depth_count--;
+}
+
+void hook_disable()
+{
+ ensure_valid_hook_info();
+ hook_info()->depth_count++;
+}
+
+int hook_is_inside()
+{
+ ensure_valid_hook_info();
+ return hook_info()->depth_count || hook_info()->hook_count;
+}
+
+unsigned int hook_get_last_error()
+{
+ ensure_valid_hook_info();
+ return hook_info()->last_error;
+}
+
+void hook_set_last_error(unsigned int errcode)
+{
+ ensure_valid_hook_info();
+ hook_info()->last_error = errcode;
+}
+
+void hook_disable_retaddr_check()
+{
+ g_enable_retaddr_check = 0;
+}
diff --git a/hooking.h b/hooking.h
new file mode 100644
index 0000000..572b352
--- /dev/null
+++ b/hooking.h
@@ -0,0 +1,125 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+typedef struct _hook_info_t {
+ unsigned int depth_count;
+
+ unsigned int hook_count;
+ unsigned int retaddr_esp;
+
+ unsigned int last_error;
+ unsigned int ret_last_error;
+
+ // in case of an exception, this is the state of all registers upon
+ // execution of our hook
+ unsigned int eax;
+ unsigned int ecx;
+ unsigned int edx;
+ unsigned int ebx;
+ unsigned int esp;
+ unsigned int ebp;
+ unsigned int esi;
+ unsigned int edi;
+} hook_info_t;
+
+typedef struct _hook_t {
+ const wchar_t *library;
+ const char *funcname;
+
+ // instead of a library/funcname combination, an address can be given
+ // as well (this address has more priority than library/funcname)
+ void *addr;
+
+ // pointer to the new function
+ void *new_func;
+
+ // "function" which jumps over the trampoline and executes the original
+ // function call
+ void **old_func;
+
+ // allow hook recursion on this hook?
+ // (see comments @ hook_create_pre_trampoline)
+ int allow_hook_recursion;
+
+ // this hook has been performed
+ int is_hooked;
+
+ unsigned char tramp[128];
+ unsigned char pre_tramp[150];
+ unsigned char store_exc[128];
+ unsigned char hook_data[32];
+} hook_t;
+
+int lde(void *addr);
+
+int hook_api(hook_t *h, int type);
+
+hook_info_t* hook_info();
+void hook_enable();
+void hook_disable();
+
+int hook_is_inside();
+
+unsigned int hook_get_last_error();
+void hook_set_last_error(unsigned int errcode);
+
+void hook_disable_retaddr_check();
+
+#define HOOK_BACKTRACE_DEPTH 20
+
+#define HOOK_ENABLE_FPU 0
+
+enum {
+ HOOK_JMP_DIRECT,
+ HOOK_NOP_JMP_DIRECT,
+ HOOK_HOTPATCH_JMP_DIRECT,
+ HOOK_PUSH_RETN,
+ HOOK_NOP_PUSH_RETN,
+ HOOK_JMP_INDIRECT,
+ HOOK_MOV_EAX_JMP_EAX,
+ HOOK_MOV_EAX_PUSH_RETN,
+ HOOK_MOV_EAX_INDIRECT_JMP_EAX,
+ HOOK_MOV_EAX_INDIRECT_PUSH_RETN,
+#if HOOK_ENABLE_FPU
+ HOOK_PUSH_FPU_RETN,
+#endif
+ HOOK_SPECIAL_JMP,
+ HOOK_TECHNIQUE_MAXTYPE,
+};
+
+#define HOOKDEF(return_value, calling_convention, apiname, ...) \
+ return_value (calling_convention *Old_##apiname)(__VA_ARGS__); \
+ return_value calling_convention New_##apiname(__VA_ARGS__)
+
+#define HOOKDEF2(return_value, calling_convention, apiname, ...) \
+ return_value (calling_convention *Old2_##apiname)(__VA_ARGS__); \
+ return_value calling_convention New2_##apiname(__VA_ARGS__)
+
+// each thread has a special 260-wchar counting unicode_string buffer in its
+// thread information block, this is likely to be overwritten in certain
+// functions, therefore we have this macro which copies it to the stack.
+// (so we can use the unicode_string after executing the original function)
+#define COPY_UNICODE_STRING(local_name, param_name) \
+ UNICODE_STRING local_name = {0}; wchar_t local_name##_buf[260]; \
+ local_name.Buffer = local_name##_buf; \
+ if(param_name != NULL && param_name->MaximumLength < 520) { \
+ local_name.Length = param_name->Length; \
+ local_name.MaximumLength = param_name->MaximumLength; \
+ memcpy(local_name.Buffer, param_name->Buffer, \
+ local_name.MaximumLength); \
+ }
diff --git a/hooks.h b/hooks.h
new file mode 100644
index 0000000..9e8f038
--- /dev/null
+++ b/hooks.h
@@ -0,0 +1,1486 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include "ntapi.h"
+
+//
+// File Hooks
+//
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateFile,
+ __out PHANDLE FileHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in_opt PLARGE_INTEGER AllocationSize,
+ __in ULONG FileAttributes,
+ __in ULONG ShareAccess,
+ __in ULONG CreateDisposition,
+ __in ULONG CreateOptions,
+ __in PVOID EaBuffer,
+ __in ULONG EaLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenFile,
+ __out PHANDLE FileHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in ULONG ShareAccess,
+ __in ULONG OpenOptions
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtReadFile,
+ __in HANDLE FileHandle,
+ __in_opt HANDLE Event,
+ __in_opt PIO_APC_ROUTINE ApcRoutine,
+ __in_opt PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __out PVOID Buffer,
+ __in ULONG Length,
+ __in_opt PLARGE_INTEGER ByteOffset,
+ __in_opt PULONG Key
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtWriteFile,
+ __in HANDLE FileHandle,
+ __in_opt HANDLE Event,
+ __in_opt PIO_APC_ROUTINE ApcRoutine,
+ __in_opt PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in PVOID Buffer,
+ __in ULONG Length,
+ __in_opt PLARGE_INTEGER ByteOffset,
+ __in_opt PULONG Key
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtDeleteFile,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtDeviceIoControlFile,
+ __in HANDLE FileHandle,
+ __in HANDLE Event,
+ __in PIO_APC_ROUTINE ApcRoutine,
+ __in PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in ULONG IoControlCode,
+ __in PVOID InputBuffer,
+ __in ULONG InputBufferLength,
+ __out PVOID OutputBuffer,
+ __in ULONG OutputBufferLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtQueryDirectoryFile,
+ __in HANDLE FileHandle,
+ __in_opt HANDLE Event,
+ __in_opt PIO_APC_ROUTINE ApcRoutine,
+ __in_opt PVOID ApcContext,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __out PVOID FileInformation,
+ __in ULONG Length,
+ __in FILE_INFORMATION_CLASS FileInformationClass,
+ __in BOOLEAN ReturnSingleEntry,
+ __in_opt PUNICODE_STRING FileName,
+ __in BOOLEAN RestartScan
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtQueryInformationFile,
+ __in HANDLE FileHandle,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __out PVOID FileInformation,
+ __in ULONG Length,
+ __in FILE_INFORMATION_CLASS FileInformationClass
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtSetInformationFile,
+ __in HANDLE FileHandle,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in PVOID FileInformation,
+ __in ULONG Length,
+ __in FILE_INFORMATION_CLASS FileInformationClass
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenDirectoryObject,
+ __out PHANDLE DirectoryHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateDirectoryObject,
+ __out PHANDLE DirectoryHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+);
+
+extern HOOKDEF(BOOL, WINAPI, MoveFileWithProgressW,
+ __in LPWSTR lpExistingFileName,
+ __in_opt LPWSTR lpNewFileName,
+ __in_opt LPPROGRESS_ROUTINE lpProgressRoutine,
+ __in_opt LPVOID lpData,
+ __in DWORD dwFlags
+);
+
+extern HOOKDEF(BOOL, WINAPI, CreateDirectoryW,
+ __in LPCTSTR lpPathName,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
+);
+
+extern HOOKDEF(BOOL, WINAPI, CreateDirectoryExW,
+ __in LPWSTR lpTemplateDirectory,
+ __in LPWSTR lpNewDirectory,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
+);
+
+extern HOOKDEF(BOOL, WINAPI, RemoveDirectoryA,
+ __in LPCTSTR lpPathName
+);
+
+extern HOOKDEF(BOOL, WINAPI, RemoveDirectoryW,
+ __in LPWSTR lpPathName
+);
+
+extern HOOKDEF(BOOL, WINAPI, MoveFileWithProgressW,
+ __in LPWSTR lpExistingFileName,
+ __in_opt LPWSTR lpNewFileName,
+ __in_opt LPPROGRESS_ROUTINE lpProgressRoutine,
+ __in_opt LPVOID lpData,
+ __in DWORD dwFlags
+);
+
+extern HOOKDEF(HANDLE, WINAPI, FindFirstFileExA,
+ __in LPCTSTR lpFileName,
+ __in FINDEX_INFO_LEVELS fInfoLevelId,
+ __out LPVOID lpFindFileData,
+ __in FINDEX_SEARCH_OPS fSearchOp,
+ __reserved LPVOID lpSearchFilter,
+ __in DWORD dwAdditionalFlags
+);
+
+extern HOOKDEF(HANDLE, WINAPI, FindFirstFileExW,
+ __in LPWSTR lpFileName,
+ __in FINDEX_INFO_LEVELS fInfoLevelId,
+ __out LPVOID lpFindFileData,
+ __in FINDEX_SEARCH_OPS fSearchOp,
+ __reserved LPVOID lpSearchFilter,
+ __in DWORD dwAdditionalFlags
+);
+
+extern HOOKDEF(BOOL, WINAPI, CopyFileA,
+ __in LPCTSTR lpExistingFileName,
+ __in LPCTSTR lpNewFileName,
+ __in BOOL bFailIfExists
+);
+
+extern HOOKDEF(BOOL, WINAPI, CopyFileW,
+ __in LPWSTR lpExistingFileName,
+ __in LPWSTR lpNewFileName,
+ __in BOOL bFailIfExists
+);
+
+extern HOOKDEF(BOOL, WINAPI, CopyFileExW,
+ _In_ LPWSTR lpExistingFileName,
+ _In_ LPWSTR lpNewFileName,
+ _In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine,
+ _In_opt_ LPVOID lpData,
+ _In_opt_ LPBOOL pbCancel,
+ _In_ DWORD dwCopyFlags
+);
+
+extern HOOKDEF(BOOL, WINAPI, DeleteFileA,
+ __in LPCSTR lpFileName
+);
+
+extern HOOKDEF(BOOL, WINAPI, DeleteFileW,
+ __in LPWSTR lpFileName
+);
+
+//
+// Registry Hooks
+//
+
+extern HOOKDEF(LONG, WINAPI, RegOpenKeyExA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpSubKey,
+ __reserved DWORD ulOptions,
+ __in REGSAM samDesired,
+ __out PHKEY phkResult
+);
+
+extern HOOKDEF(LONG, WINAPI, RegOpenKeyExW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpSubKey,
+ __reserved DWORD ulOptions,
+ __in REGSAM samDesired,
+ __out PHKEY phkResult
+);
+
+extern HOOKDEF(LONG, WINAPI, RegCreateKeyExA,
+ __in HKEY hKey,
+ __in LPCTSTR lpSubKey,
+ __reserved DWORD Reserved,
+ __in_opt LPTSTR lpClass,
+ __in DWORD dwOptions,
+ __in REGSAM samDesired,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ __out PHKEY phkResult,
+ __out_opt LPDWORD lpdwDisposition
+);
+
+extern HOOKDEF(LONG, WINAPI, RegCreateKeyExW,
+ __in HKEY hKey,
+ __in LPWSTR lpSubKey,
+ __reserved DWORD Reserved,
+ __in_opt LPWSTR lpClass,
+ __in DWORD dwOptions,
+ __in REGSAM samDesired,
+ __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ __out PHKEY phkResult,
+ __out_opt LPDWORD lpdwDisposition
+);
+
+extern HOOKDEF(LONG, WINAPI, RegDeleteKeyA,
+ __in HKEY hKey,
+ __in LPCTSTR lpSubKey
+);
+
+extern HOOKDEF(LONG, WINAPI, RegDeleteKeyW,
+ __in HKEY hKey,
+ __in LPWSTR lpSubKey
+);
+
+extern HOOKDEF(LONG, WINAPI, RegEnumKeyW,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPWSTR lpName,
+ __in DWORD cchName
+);
+
+extern HOOKDEF(LONG, WINAPI, RegEnumKeyExA,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPTSTR lpName,
+ __inout LPDWORD lpcName,
+ __reserved LPDWORD lpReserved,
+ __inout LPTSTR lpClass,
+ __inout_opt LPDWORD lpcClass,
+ __out_opt PFILETIME lpftLastWriteTime
+);
+
+extern HOOKDEF(LONG, WINAPI, RegEnumKeyExW,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPWSTR lpName,
+ __inout LPDWORD lpcName,
+ __reserved LPDWORD lpReserved,
+ __inout LPWSTR lpClass,
+ __inout_opt LPDWORD lpcClass,
+ __out_opt PFILETIME lpftLastWriteTime
+);
+
+extern HOOKDEF(LONG, WINAPI, RegEnumValueA,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPTSTR lpValueName,
+ __inout LPDWORD lpcchValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+);
+
+extern HOOKDEF(LONG, WINAPI, RegEnumValueW,
+ __in HKEY hKey,
+ __in DWORD dwIndex,
+ __out LPWSTR lpValueName,
+ __inout LPDWORD lpcchValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+);
+
+extern HOOKDEF(LONG, WINAPI, RegSetValueExA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpValueName,
+ __reserved DWORD Reserved,
+ __in DWORD dwType,
+ __in const BYTE *lpData,
+ __in DWORD cbData
+);
+
+extern HOOKDEF(LONG, WINAPI, RegSetValueExW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpValueName,
+ __reserved DWORD Reserved,
+ __in DWORD dwType,
+ __in const BYTE *lpData,
+ __in DWORD cbData
+);
+
+extern HOOKDEF(LONG, WINAPI, RegQueryValueExA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+);
+
+extern HOOKDEF(LONG, WINAPI, RegQueryValueExW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpValueName,
+ __reserved LPDWORD lpReserved,
+ __out_opt LPDWORD lpType,
+ __out_opt LPBYTE lpData,
+ __inout_opt LPDWORD lpcbData
+);
+
+extern HOOKDEF(LONG, WINAPI, RegDeleteValueA,
+ __in HKEY hKey,
+ __in_opt LPCTSTR lpValueName
+);
+
+extern HOOKDEF(LONG, WINAPI, RegDeleteValueW,
+ __in HKEY hKey,
+ __in_opt LPWSTR lpValueName
+);
+
+extern HOOKDEF(LONG, WINAPI, RegQueryInfoKeyA,
+ _In_ HKEY hKey,
+ _Out_opt_ LPTSTR lpClass,
+ _Inout_opt_ LPDWORD lpcClass,
+ _Reserved_ LPDWORD lpReserved,
+ _Out_opt_ LPDWORD lpcSubKeys,
+ _Out_opt_ LPDWORD lpcMaxSubKeyLen,
+ _Out_opt_ LPDWORD lpcMaxClassLen,
+ _Out_opt_ LPDWORD lpcValues,
+ _Out_opt_ LPDWORD lpcMaxValueNameLen,
+ _Out_opt_ LPDWORD lpcMaxValueLen,
+ _Out_opt_ LPDWORD lpcbSecurityDescriptor,
+ _Out_opt_ PFILETIME lpftLastWriteTime
+);
+
+extern HOOKDEF(LONG, WINAPI, RegQueryInfoKeyW,
+ _In_ HKEY hKey,
+ _Out_opt_ LPWSTR lpClass,
+ _Inout_opt_ LPDWORD lpcClass,
+ _Reserved_ LPDWORD lpReserved,
+ _Out_opt_ LPDWORD lpcSubKeys,
+ _Out_opt_ LPDWORD lpcMaxSubKeyLen,
+ _Out_opt_ LPDWORD lpcMaxClassLen,
+ _Out_opt_ LPDWORD lpcValues,
+ _Out_opt_ LPDWORD lpcMaxValueNameLen,
+ _Out_opt_ LPDWORD lpcMaxValueLen,
+ _Out_opt_ LPDWORD lpcbSecurityDescriptor,
+ _Out_opt_ PFILETIME lpftLastWriteTime
+);
+
+extern HOOKDEF(LONG, WINAPI, RegCloseKey,
+ __in HKEY hKey
+);
+
+//
+// Native Registry Hooks
+//
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateKey,
+ __out PHANDLE KeyHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __reserved ULONG TitleIndex,
+ __in_opt PUNICODE_STRING Class,
+ __in ULONG CreateOptions,
+ __out_opt PULONG Disposition
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenKey,
+ __out PHANDLE KeyHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenKeyEx,
+ __out PHANDLE KeyHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __in ULONG OpenOptions
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtRenameKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING NewName
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtReplaceKey,
+ __in POBJECT_ATTRIBUTES NewHiveFileName,
+ __in HANDLE KeyHandle,
+ __in POBJECT_ATTRIBUTES BackupHiveFileName
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtEnumerateKey,
+ __in HANDLE KeyHandle,
+ __in ULONG Index,
+ __in KEY_INFORMATION_CLASS KeyInformationClass,
+ __out_opt PVOID KeyInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtEnumerateValueKey,
+ __in HANDLE KeyHandle,
+ __in ULONG Index,
+ __in KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ __out_opt PVOID KeyValueInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtSetValueKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING ValueName,
+ __in_opt ULONG TitleIndex,
+ __in ULONG Type,
+ __in_opt PVOID Data,
+ __in ULONG DataSize
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtQueryValueKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING ValueName,
+ __in KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
+ __out_opt PVOID KeyValueInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtQueryMultipleValueKey,
+ __in HANDLE KeyHandle,
+ __inout PKEY_VALUE_ENTRY ValueEntries,
+ __in ULONG EntryCount,
+ __out PVOID ValueBuffer,
+ __inout PULONG BufferLength,
+ __out_opt PULONG RequiredBufferLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtDeleteKey,
+ __in HANDLE KeyHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtDeleteValueKey,
+ __in HANDLE KeyHandle,
+ __in PUNICODE_STRING ValueName
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtLoadKey,
+ __in POBJECT_ATTRIBUTES TargetKey,
+ __in POBJECT_ATTRIBUTES SourceFile
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtLoadKey2,
+ __in POBJECT_ATTRIBUTES TargetKey,
+ __in POBJECT_ATTRIBUTES SourceFile,
+ __in ULONG Flags
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtLoadKeyEx,
+ __in POBJECT_ATTRIBUTES TargetKey,
+ __in POBJECT_ATTRIBUTES SourceFile,
+ __in ULONG Flags,
+ __in_opt HANDLE TrustClassKey
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtQueryKey,
+ __in HANDLE KeyHandle,
+ __in KEY_INFORMATION_CLASS KeyInformationClass,
+ __out_opt PVOID KeyInformation,
+ __in ULONG Length,
+ __out PULONG ResultLength
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtSaveKey,
+ __in HANDLE KeyHandle,
+ __in HANDLE FileHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtSaveKeyEx,
+ __in HANDLE KeyHandle,
+ __in HANDLE FileHandle,
+ __in ULONG Format
+);
+
+//
+// Window Hooks
+//
+
+extern HOOKDEF(HWND, WINAPI, FindWindowA,
+ __in_opt LPCTSTR lpClassName,
+ __in_opt LPCTSTR lpWindowName
+);
+
+extern HOOKDEF(HWND, WINAPI, FindWindowW,
+ __in_opt LPWSTR lpClassName,
+ __in_opt LPWSTR lpWindowName
+);
+
+extern HOOKDEF(HWND, WINAPI, FindWindowExA,
+ __in_opt HWND hwndParent,
+ __in_opt HWND hwndChildAfter,
+ __in_opt LPCTSTR lpszClass,
+ __in_opt LPCTSTR lpszWindow
+);
+
+extern HOOKDEF(HWND, WINAPI, FindWindowExW,
+ __in_opt HWND hwndParent,
+ __in_opt HWND hwndChildAfter,
+ __in_opt LPWSTR lpszClass,
+ __in_opt LPWSTR lpszWindow
+);
+
+//
+// Sync Hooks
+//
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateMutant,
+ __out PHANDLE MutantHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in BOOLEAN InitialOwner
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenMutant,
+ __out PHANDLE MutantHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateNamedPipeFile,
+ OUT PHANDLE NamedPipeFileHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG ShareAccess,
+ IN ULONG CreateDisposition,
+ IN ULONG CreateOptions,
+ IN BOOLEAN WriteModeMessage,
+ IN BOOLEAN ReadModeMessage,
+ IN BOOLEAN NonBlocking,
+ IN ULONG MaxInstances,
+ IN ULONG InBufferSize,
+ IN ULONG OutBufferSize,
+ IN PLARGE_INTEGER DefaultTimeOut
+);
+
+//
+// Process Hooks
+//
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateProcess,
+ __out PHANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in HANDLE ParentProcess,
+ __in BOOLEAN InheritObjectTable,
+ __in_opt HANDLE SectionHandle,
+ __in_opt HANDLE DebugPort,
+ __in_opt HANDLE ExceptionPort
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateProcessEx,
+ __out PHANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in HANDLE ParentProcess,
+ __in ULONG Flags,
+ __in_opt HANDLE SectionHandle,
+ __in_opt HANDLE DebugPort,
+ __in_opt HANDLE ExceptionPort,
+ __in BOOLEAN InJob
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateUserProcess,
+ __out PHANDLE ProcessHandle,
+ __out PHANDLE ThreadHandle,
+ __in ACCESS_MASK ProcessDesiredAccess,
+ __in ACCESS_MASK ThreadDesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ProcessObjectAttributes,
+ __in_opt POBJECT_ATTRIBUTES ThreadObjectAttributes,
+ __in ULONG ProcessFlags,
+ __in ULONG ThreadFlags,
+ __in_opt PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
+ __inout PPS_CREATE_INFO CreateInfo,
+ __in_opt PPS_ATTRIBUTE_LIST AttributeList
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, RtlCreateUserProcess,
+ IN PUNICODE_STRING ImagePath,
+ IN ULONG ObjectAttributes,
+ IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
+ IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
+ IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
+ IN HANDLE ParentProcess,
+ IN BOOLEAN InheritHandles,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL,
+ OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenProcess,
+ __out PHANDLE ProcessHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __in_opt PCLIENT_ID ClientId
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtTerminateProcess,
+ __in_opt HANDLE ProcessHandle,
+ __in NTSTATUS ExitStatus
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateSection,
+ __out PHANDLE SectionHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in_opt PLARGE_INTEGER MaximumSize,
+ __in ULONG SectionPageProtection,
+ __in ULONG AllocationAttributes,
+ __in_opt HANDLE FileHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtMakeTemporaryObject,
+ __in HANDLE ObjectHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtMakePermanentObject,
+ __in HANDLE ObjectHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenSection,
+ __out PHANDLE SectionHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes
+);
+
+extern HOOKDEF(BOOL, WINAPI, CreateProcessInternalW,
+ __in_opt LPVOID lpUnknown1,
+ __in_opt LPWSTR lpApplicationName,
+ __inout_opt LPWSTR lpCommandLine,
+ __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in BOOL bInheritHandles,
+ __in DWORD dwCreationFlags,
+ __in_opt LPVOID lpEnvironment,
+ __in_opt LPWSTR lpCurrentDirectory,
+ __in LPSTARTUPINFO lpStartupInfo,
+ __out LPPROCESS_INFORMATION lpProcessInformation,
+ __in_opt LPVOID lpUnknown2
+);
+
+extern HOOKDEF2(BOOL, WINAPI, CreateProcessInternalW,
+ __in_opt LPVOID lpUnknown1,
+ __in_opt LPWSTR lpApplicationName,
+ __inout_opt LPWSTR lpCommandLine,
+ __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in BOOL bInheritHandles,
+ __in DWORD dwCreationFlags,
+ __in_opt LPVOID lpEnvironment,
+ __in_opt LPWSTR lpCurrentDirectory,
+ __in LPSTARTUPINFO lpStartupInfo,
+ __out LPPROCESS_INFORMATION lpProcessInformation,
+ __in_opt LPVOID lpUnknown2
+);
+
+extern HOOKDEF(VOID, WINAPI, ExitProcess,
+ __in UINT uExitCode
+);
+
+extern HOOKDEF(BOOL, WINAPI, ShellExecuteExW,
+ __inout SHELLEXECUTEINFOW *pExecInfo
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtUnmapViewOfSection,
+ _In_ HANDLE ProcessHandle,
+ _In_opt_ PVOID BaseAddress
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtAllocateVirtualMemory,
+ __in HANDLE ProcessHandle,
+ __inout PVOID *BaseAddress,
+ __in ULONG_PTR ZeroBits,
+ __inout PSIZE_T RegionSize,
+ __in ULONG AllocationType,
+ __in ULONG Protect
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtReadVirtualMemory,
+ __in HANDLE ProcessHandle,
+ __in LPCVOID BaseAddress,
+ __out LPVOID Buffer,
+ __in ULONG NumberOfBytesToRead,
+ __out_opt PULONG NumberOfBytesReaded
+);
+
+extern HOOKDEF(BOOL, WINAPI, ReadProcessMemory,
+ _In_ HANDLE hProcess,
+ _In_ LPCVOID lpBaseAddress,
+ _Out_ LPVOID lpBuffer,
+ _In_ SIZE_T nSize,
+ _Out_ SIZE_T *lpNumberOfBytesRead
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtWriteVirtualMemory,
+ __in HANDLE ProcessHandle,
+ __in LPVOID BaseAddress,
+ __in LPCVOID Buffer,
+ __in ULONG NumberOfBytesToWrite,
+ __out_opt ULONG *NumberOfBytesWritten
+);
+
+extern HOOKDEF(BOOL, WINAPI, WriteProcessMemory,
+ _In_ HANDLE hProcess,
+ _In_ LPVOID lpBaseAddress,
+ _In_ LPCVOID lpBuffer,
+ _In_ SIZE_T nSize,
+ _Out_ SIZE_T *lpNumberOfBytesWritten
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtProtectVirtualMemory,
+ IN HANDLE ProcessHandle,
+ IN OUT PVOID *BaseAddress,
+ IN OUT PULONG NumberOfBytesToProtect,
+ IN ULONG NewAccessProtection,
+ OUT PULONG OldAccessProtection
+);
+
+extern HOOKDEF(BOOL, WINAPI, VirtualProtectEx,
+ __in HANDLE hProcess,
+ __in LPVOID lpAddress,
+ __in SIZE_T dwSize,
+ __in DWORD flNewProtect,
+ __out PDWORD lpflOldProtect
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtFreeVirtualMemory,
+ IN HANDLE ProcessHandle,
+ IN PVOID *BaseAddress,
+ IN OUT PULONG RegionSize,
+ IN ULONG FreeType
+);
+
+extern HOOKDEF(BOOL, WINAPI, VirtualFreeEx,
+ __in HANDLE hProcess,
+ __in LPVOID lpAddress,
+ __in SIZE_T dwSize,
+ __in DWORD dwFreeType
+);
+
+extern HOOKDEF(int, CDECL, system,
+ const char *command
+);
+
+//
+// Thread Hooks
+//
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateThread,
+ __out PHANDLE ThreadHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
+ __in HANDLE ProcessHandle,
+ __out PCLIENT_ID ClientId,
+ __in PCONTEXT ThreadContext,
+ __in PINITIAL_TEB InitialTeb,
+ __in BOOLEAN CreateSuspended
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtCreateThreadEx,
+ OUT PHANDLE hThread,
+ IN ACCESS_MASK DesiredAccess,
+ IN PVOID ObjectAttributes,
+ IN HANDLE ProcessHandle,
+ IN LPTHREAD_START_ROUTINE lpStartAddress,
+ IN PVOID lpParameter,
+ IN BOOL CreateSuspended,
+ IN LONG StackZeroBits,
+ IN LONG SizeOfStackCommit,
+ IN LONG SizeOfStackReserve,
+ OUT PVOID lpBytesBuffer
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtOpenThread,
+ __out PHANDLE ThreadHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __in PCLIENT_ID ClientId
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtGetContextThread,
+ __in HANDLE ThreadHandle,
+ __inout LPCONTEXT Context
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtSetContextThread,
+ __in HANDLE ThreadHandle,
+ __in const CONTEXT *Context
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtSuspendThread,
+ __in HANDLE ThreadHandle,
+ __out_opt ULONG *PreviousSuspendCount
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtResumeThread,
+ __in HANDLE ThreadHandle,
+ __out_opt ULONG *SuspendCount
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtTerminateThread,
+ __in HANDLE ThreadHandle,
+ __in NTSTATUS ExitStatus
+);
+
+extern HOOKDEF(HANDLE, WINAPI, CreateThread,
+ __in LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in SIZE_T dwStackSize,
+ __in LPTHREAD_START_ROUTINE lpStartAddress,
+ __in LPVOID lpParameter,
+ __in DWORD dwCreationFlags,
+ __out LPDWORD lpThreadId
+);
+
+extern HOOKDEF(HANDLE, WINAPI, CreateRemoteThread,
+ __in HANDLE hProcess,
+ __in LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ __in SIZE_T dwStackSize,
+ __in LPTHREAD_START_ROUTINE lpStartAddress,
+ __in LPVOID lpParameter,
+ __in DWORD dwCreationFlags,
+ __out LPDWORD lpThreadId
+);
+
+extern HOOKDEF(BOOL, WINAPI, TerminateThread,
+ __inout HANDLE hThread,
+ __in DWORD dwExitCode
+);
+
+extern HOOKDEF(VOID, WINAPI, ExitThread,
+ __in DWORD dwExitCode
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, RtlCreateUserThread,
+ IN HANDLE ProcessHandle,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
+ IN BOOLEAN CreateSuspended,
+ IN ULONG StackZeroBits,
+ IN OUT PULONG StackReserved,
+ IN OUT PULONG StackCommit,
+ IN PVOID StartAddress,
+ IN PVOID StartParameter OPTIONAL,
+ OUT PHANDLE ThreadHandle,
+ OUT PCLIENT_ID ClientId
+);
+
+//
+// Misc Hooks
+//
+
+extern HOOKDEF(HHOOK, WINAPI, SetWindowsHookExA,
+ __in int idHook,
+ __in HOOKPROC lpfn,
+ __in HINSTANCE hMod,
+ __in DWORD dwThreadId
+);
+
+extern HOOKDEF(HHOOK, WINAPI, SetWindowsHookExW,
+ __in int idHook,
+ __in HOOKPROC lpfn,
+ __in HINSTANCE hMod,
+ __in DWORD dwThreadId
+);
+
+extern HOOKDEF(BOOL, WINAPI, UnhookWindowsHookEx,
+ __in HHOOK hhk
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, LdrLoadDll,
+ __in_opt PWCHAR PathToFile,
+ __in_opt ULONG Flags,
+ __in PUNICODE_STRING ModuleFileName,
+ __out PHANDLE ModuleHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, LdrGetDllHandle,
+ __in_opt PWORD pwPath,
+ __in_opt PVOID Unused,
+ __in PUNICODE_STRING ModuleFileName,
+ __out PHANDLE pHModule
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, LdrGetProcedureAddress,
+ __in HMODULE ModuleHandle,
+ __in_opt PANSI_STRING FunctionName,
+ __in_opt WORD Ordinal,
+ __out PVOID *FunctionAddress
+);
+
+extern HOOKDEF(BOOL, WINAPI, DeviceIoControl,
+ __in HANDLE hDevice,
+ __in DWORD dwIoControlCode,
+ __in_opt LPVOID lpInBuffer,
+ __in DWORD nInBufferSize,
+ __out_opt LPVOID lpOutBuffer,
+ __in DWORD nOutBufferSize,
+ __out_opt LPDWORD lpBytesReturned,
+ __inout_opt LPOVERLAPPED lpOverlapped
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtDelayExecution,
+ __in BOOLEAN Alertable,
+ __in PLARGE_INTEGER DelayInterval
+);
+
+extern HOOKDEF(BOOL, WINAPI, ExitWindowsEx,
+ __in UINT uFlags,
+ __in DWORD dwReason
+);
+
+extern HOOKDEF(BOOL, WINAPI, IsDebuggerPresent,
+ void
+);
+
+extern HOOKDEF(BOOL, WINAPI, LookupPrivilegeValueW,
+ __in_opt LPWSTR lpSystemName,
+ __in LPWSTR lpName,
+ __out PLUID lpLuid
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtClose,
+ __in HANDLE Handle
+);
+
+extern HOOKDEF(BOOL, WINAPI, WriteConsoleA,
+ _In_ HANDLE hConsoleOutput,
+ _In_ const VOID *lpBuffer,
+ _In_ DWORD nNumberOfCharsToWrite,
+ _Out_ LPDWORD lpNumberOfCharsWritten,
+ _Reserved_ LPVOID lpReseverd
+);
+
+extern HOOKDEF(BOOL, WINAPI, WriteConsoleW,
+ _In_ HANDLE hConsoleOutput,
+ _In_ const VOID *lpBuffer,
+ _In_ DWORD nNumberOfCharsToWrite,
+ _Out_ LPDWORD lpNumberOfCharsWritten,
+ _Reserved_ LPVOID lpReseverd
+);
+
+extern HOOKDEF(int, WINAPI, GetSystemMetrics,
+ _In_ int nIndex
+);
+
+extern HOOKDEF(BOOL, WINAPI, GetCursorPos,
+ _Out_ LPPOINT lpPoint
+);
+
+//
+// Network Hooks
+//
+
+extern HOOKDEF(HRESULT, WINAPI, URLDownloadToFileW,
+ LPUNKNOWN pCaller,
+ LPWSTR szURL,
+ LPWSTR szFileName,
+ DWORD dwReserved,
+ LPVOID lpfnCB
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, InternetOpenA,
+ _In_ LPCTSTR lpszAgent,
+ _In_ DWORD dwAccessType,
+ _In_ LPCTSTR lpszProxyName,
+ _In_ LPCTSTR lpszProxyBypass,
+ _In_ DWORD dwFlags
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, InternetOpenW,
+ _In_ LPWSTR lpszAgent,
+ _In_ DWORD dwAccessType,
+ _In_ LPWSTR lpszProxyName,
+ _In_ LPWSTR lpszProxyBypass,
+ _In_ DWORD dwFlags
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, InternetConnectA,
+ _In_ HINTERNET hInternet,
+ _In_ LPCTSTR lpszServerName,
+ _In_ INTERNET_PORT nServerPort,
+ _In_ LPCTSTR lpszUsername,
+ _In_ LPCTSTR lpszPassword,
+ _In_ DWORD dwService,
+ _In_ DWORD dwFlags,
+ _In_ DWORD_PTR dwContext
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, InternetConnectW,
+ _In_ HINTERNET hInternet,
+ _In_ LPWSTR lpszServerName,
+ _In_ INTERNET_PORT nServerPort,
+ _In_ LPWSTR lpszUsername,
+ _In_ LPWSTR lpszPassword,
+ _In_ DWORD dwService,
+ _In_ DWORD dwFlags,
+ _In_ DWORD_PTR dwContext
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, InternetOpenUrlA,
+ __in HINTERNET hInternet,
+ __in LPCTSTR lpszUrl,
+ __in LPCTSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, InternetOpenUrlW,
+ __in HINTERNET hInternet,
+ __in LPWSTR lpszUrl,
+ __in LPWSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, HttpOpenRequestA,
+ __in HINTERNET hConnect,
+ __in LPCTSTR lpszVerb,
+ __in LPCTSTR lpszObjectName,
+ __in LPCTSTR lpszVersion,
+ __in LPCTSTR lpszReferer,
+ __in LPCTSTR *lplpszAcceptTypes,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+);
+
+extern HOOKDEF(HINTERNET, WINAPI, HttpOpenRequestW,
+ __in HINTERNET hConnect,
+ __in LPWSTR lpszVerb,
+ __in LPWSTR lpszObjectName,
+ __in LPWSTR lpszVersion,
+ __in LPWSTR lpszReferer,
+ __in LPWSTR *lplpszAcceptTypes,
+ __in DWORD dwFlags,
+ __in DWORD_PTR dwContext
+);
+
+extern HOOKDEF(BOOL, WINAPI, HttpSendRequestA,
+ __in HINTERNET hRequest,
+ __in LPCTSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in LPVOID lpOptional,
+ __in DWORD dwOptionalLength
+);
+
+extern HOOKDEF(BOOL, WINAPI, HttpSendRequestW,
+ __in HINTERNET hRequest,
+ __in LPWSTR lpszHeaders,
+ __in DWORD dwHeadersLength,
+ __in LPVOID lpOptional,
+ __in DWORD dwOptionalLength
+);
+
+extern HOOKDEF(BOOL, WINAPI, InternetReadFile,
+ _In_ HINTERNET hFile,
+ _Out_ LPVOID lpBuffer,
+ _In_ DWORD dwNumberOfBytesToRead,
+ _Out_ LPDWORD lpdwNumberOfBytesRead
+);
+
+extern HOOKDEF(BOOL, WINAPI, InternetWriteFile,
+ _In_ HINTERNET hFile,
+ _In_ LPCVOID lpBuffer,
+ _In_ DWORD dwNumberOfBytesToWrite,
+ _Out_ LPDWORD lpdwNumberOfBytesWritten
+);
+
+extern HOOKDEF(BOOL, WINAPI, InternetCloseHandle,
+ _In_ HINTERNET hInternet
+);
+
+extern HOOKDEF(DNS_STATUS, WINAPI, DnsQuery_A,
+ __in PCSTR lpstrName,
+ __in WORD wType,
+ __in DWORD Options,
+ __inout_opt PVOID pExtra,
+ __out_opt PDNS_RECORD *ppQueryResultsSet,
+ __out_opt PVOID *pReserved
+);
+
+extern HOOKDEF(DNS_STATUS, WINAPI, DnsQuery_UTF8,
+ __in LPBYTE lpstrName,
+ __in WORD wType,
+ __in DWORD Options,
+ __inout_opt PVOID pExtra,
+ __out_opt PDNS_RECORD *ppQueryResultsSet,
+ __out_opt PVOID *pReserved
+);
+
+extern HOOKDEF(DNS_STATUS, WINAPI, DnsQuery_W,
+ __in PWSTR lpstrName,
+ __in WORD wType,
+ __in DWORD Options,
+ __inout_opt PVOID pExtra,
+ __out_opt PDNS_RECORD *ppQueryResultsSet,
+ __out_opt PVOID *pReserved
+);
+
+extern HOOKDEF(int, WSAAPI, getaddrinfo,
+ _In_opt_ PCSTR pNodeName,
+ _In_opt_ PCSTR pServiceName,
+ _In_opt_ const ADDRINFOA *pHints,
+ _Out_ PADDRINFOA *ppResult
+);
+
+extern HOOKDEF(int, WSAAPI, GetAddrInfoW,
+ _In_opt_ PCWSTR pNodeName,
+ _In_opt_ PCWSTR pServiceName,
+ _In_opt_ const ADDRINFOW *pHints,
+ _Out_ PADDRINFOW *ppResult
+);
+
+//
+// Service Hooks
+//
+
+extern HOOKDEF(SC_HANDLE, WINAPI, OpenSCManagerA,
+ __in_opt LPCTSTR lpMachineName,
+ __in_opt LPCTSTR lpDatabaseName,
+ __in DWORD dwDesiredAccess
+);
+
+extern HOOKDEF(SC_HANDLE, WINAPI, OpenSCManagerW,
+ __in_opt LPWSTR lpMachineName,
+ __in_opt LPWSTR lpDatabaseName,
+ __in DWORD dwDesiredAccess
+);
+
+extern HOOKDEF(SC_HANDLE, WINAPI, CreateServiceA,
+ __in SC_HANDLE hSCManager,
+ __in LPCTSTR lpServiceName,
+ __in_opt LPCTSTR lpDisplayName,
+ __in DWORD dwDesiredAccess,
+ __in DWORD dwServiceType,
+ __in DWORD dwStartType,
+ __in DWORD dwErrorControl,
+ __in_opt LPCTSTR lpBinaryPathName,
+ __in_opt LPCTSTR lpLoadOrderGroup,
+ __out_opt LPDWORD lpdwTagId,
+ __in_opt LPCTSTR lpDependencies,
+ __in_opt LPCTSTR lpServiceStartName,
+ __in_opt LPCTSTR lpPassword
+);
+
+extern HOOKDEF(SC_HANDLE, WINAPI, CreateServiceW,
+ __in SC_HANDLE hSCManager,
+ __in LPWSTR lpServiceName,
+ __in_opt LPWSTR lpDisplayName,
+ __in DWORD dwDesiredAccess,
+ __in DWORD dwServiceType,
+ __in DWORD dwStartType,
+ __in DWORD dwErrorControl,
+ __in_opt LPWSTR lpBinaryPathName,
+ __in_opt LPWSTR lpLoadOrderGroup,
+ __out_opt LPDWORD lpdwTagId,
+ __in_opt LPWSTR lpDependencies,
+ __in_opt LPWSTR lpServiceStartName,
+ __in_opt LPWSTR lpPassword
+);
+
+extern HOOKDEF(SC_HANDLE, WINAPI, OpenServiceA,
+ __in SC_HANDLE hSCManager,
+ __in LPCTSTR lpServiceName,
+ __in DWORD dwDesiredAccess
+);
+
+extern HOOKDEF(SC_HANDLE, WINAPI, OpenServiceW,
+ __in SC_HANDLE hSCManager,
+ __in LPWSTR lpServiceName,
+ __in DWORD dwDesiredAccess
+);
+
+extern HOOKDEF(BOOL, WINAPI, StartServiceA,
+ __in SC_HANDLE hService,
+ __in DWORD dwNumServiceArgs,
+ __in_opt LPCTSTR *lpServiceArgVectors
+);
+
+extern HOOKDEF(BOOL, WINAPI, StartServiceW,
+ __in SC_HANDLE hService,
+ __in DWORD dwNumServiceArgs,
+ __in_opt LPWSTR *lpServiceArgVectors
+);
+
+extern HOOKDEF(BOOL, WINAPI, ControlService,
+ __in SC_HANDLE hService,
+ __in DWORD dwControl,
+ __out LPSERVICE_STATUS lpServiceStatus
+);
+
+extern HOOKDEF(BOOL, WINAPI, DeleteService,
+ __in SC_HANDLE hService
+);
+
+//
+// Sleep Hooks
+//
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtDelayExecution,
+ __in BOOLEAN Alertable,
+ __in PLARGE_INTEGER DelayInterval
+);
+
+extern HOOKDEF(void, WINAPI, GetLocalTime,
+ __out LPSYSTEMTIME lpSystemTime
+);
+
+extern HOOKDEF(void, WINAPI, GetSystemTime,
+ __out LPSYSTEMTIME lpSystemTime
+);
+
+extern HOOKDEF(DWORD, WINAPI, GetTickCount,
+ void
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, NtQuerySystemTime,
+ _Out_ PLARGE_INTEGER SystemTime
+);
+
+//
+// Socket Hooks
+//
+
+extern HOOKDEF(int, WINAPI, WSAStartup,
+ _In_ WORD wVersionRequested,
+ _Out_ LPWSADATA lpWSAData
+);
+
+extern HOOKDEF(struct hostent *, WSAAPI, gethostbyname,
+ __in const char *name
+);
+
+extern HOOKDEF(SOCKET, WSAAPI, socket,
+ __in int af,
+ __in int type,
+ __in int protocol
+);
+
+extern HOOKDEF(int, WSAAPI, connect,
+ __in SOCKET s,
+ __in const struct sockaddr *name,
+ __in int namelen
+);
+
+extern HOOKDEF(int, WSAAPI, send,
+ __in SOCKET s,
+ __in const char *buf,
+ __in int len,
+ __in int flags
+);
+
+extern HOOKDEF(int, WSAAPI, sendto,
+ __in SOCKET s,
+ __in const char *buf,
+ __in int len,
+ __in int flags,
+ __in const struct sockaddr *to,
+ __in int tolen
+);
+
+extern HOOKDEF(int, WSAAPI, recv,
+ __in SOCKET s,
+ __out char *buf,
+ __in int len,
+ __in int flags
+);
+
+extern HOOKDEF(int, WSAAPI, recvfrom,
+ __in SOCKET s,
+ __out char *buf,
+ __in int len,
+ __in int flags,
+ __out struct sockaddr *from,
+ __inout_opt int *fromlen
+);
+
+extern HOOKDEF(SOCKET, WSAAPI, accept,
+ __in SOCKET s,
+ __out struct sockaddr *addr,
+ __inout int *addrlen
+);
+
+extern HOOKDEF(int, WSAAPI, bind,
+ __in SOCKET s,
+ __in const struct sockaddr *name,
+ __in int namelen
+);
+
+extern HOOKDEF(int, WSAAPI, listen,
+ __in SOCKET s,
+ __in int backlog
+);
+
+extern HOOKDEF(int, WSAAPI, select,
+ __in SOCKET s,
+ __inout fd_set *readfds,
+ __inout fd_set *writefds,
+ __inout fd_set *exceptfds,
+ __in const struct timeval *timeout
+);
+
+extern HOOKDEF(int, WSAAPI, setsockopt,
+ __in SOCKET s,
+ __in int level,
+ __in int optname,
+ __in const char *optval,
+ __in int optlen
+);
+
+extern HOOKDEF(int, WSAAPI, ioctlsocket,
+ __in SOCKET s,
+ __in long cmd,
+ __inout u_long *argp
+);
+
+extern HOOKDEF(int, WSAAPI, closesocket,
+ __in SOCKET s
+);
+
+extern HOOKDEF(int, WSAAPI, shutdown,
+ __in SOCKET s,
+ __in int how
+);
+
+extern HOOKDEF(int, WSAAPI, WSARecv,
+ __in SOCKET s,
+ __inout LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesRecvd,
+ __inout LPDWORD lpFlags,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+);
+
+extern HOOKDEF(int, WSAAPI, WSARecvFrom,
+ __in SOCKET s,
+ __inout LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesRecvd,
+ __inout LPDWORD lpFlags,
+ __out struct sockaddr *lpFrom,
+ __inout LPINT lpFromlen,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+);
+
+extern HOOKDEF(int, WSAAPI, WSASend,
+ __in SOCKET s,
+ __in LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesSent,
+ __in DWORD dwFlags,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+);
+
+extern HOOKDEF(int, WSAAPI, WSASendTo,
+ __in SOCKET s,
+ __in LPWSABUF lpBuffers,
+ __in DWORD dwBufferCount,
+ __out LPDWORD lpNumberOfBytesSent,
+ __in DWORD dwFlags,
+ __in const struct sockaddr *lpTo,
+ __in int iToLen,
+ __in LPWSAOVERLAPPED lpOverlapped,
+ __in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
+);
+
+extern HOOKDEF(SOCKET, WSAAPI, WSASocketA,
+ __in int af,
+ __in int type,
+ __in int protocol,
+ __in LPWSAPROTOCOL_INFO lpProtocolInfo,
+ __in GROUP g,
+ __in DWORD dwFlags
+);
+
+extern HOOKDEF(SOCKET, WSAAPI, WSASocketW,
+ __in int af,
+ __in int type,
+ __in int protocol,
+ __in LPWSAPROTOCOL_INFO lpProtocolInfo,
+ __in GROUP g,
+ __in DWORD dwFlags
+);
+
+
+extern HOOKDEF(BOOL, PASCAL, ConnectEx,
+ _In_ SOCKET s,
+ _In_ const struct sockaddr *name,
+ _In_ int namelen,
+ _In_opt_ PVOID lpSendBuffer,
+ _In_ DWORD dwSendDataLength,
+ _Out_ LPDWORD lpdwBytesSent,
+ _In_ LPOVERLAPPED lpOverlapped
+);
+
+extern HOOKDEF(BOOL, PASCAL, TransmitFile,
+ SOCKET hSocket,
+ HANDLE hFile,
+ DWORD nNumberOfBytesToWrite,
+ DWORD nNumberOfBytesPerSend,
+ LPOVERLAPPED lpOverlapped,
+ LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
+ DWORD dwFlags
+);
+
+//
+// Special Hooks
+//
+
+extern HOOKDEF2(NTSTATUS, WINAPI, LdrLoadDll,
+ __in_opt PWCHAR PathToFile,
+ __in_opt ULONG Flags,
+ __in PUNICODE_STRING ModuleFileName,
+ __out PHANDLE ModuleHandle
+);
+
+extern HOOKDEF(NTSTATUS, WINAPI, ZwMapViewOfSection,
+ _In_ HANDLE SectionHandle,
+ _In_ HANDLE ProcessHandle,
+ __inout PVOID *BaseAddress,
+ _In_ ULONG_PTR ZeroBits,
+ _In_ SIZE_T CommitSize,
+ __inout PLARGE_INTEGER SectionOffset,
+ __inout PSIZE_T ViewSize,
+ __in UINT InheritDisposition,
+ __in ULONG AllocationType,
+ __in ULONG Win32Protect
+);
diff --git a/ignore.c b/ignore.c
new file mode 100644
index 0000000..3e9e45a
--- /dev/null
+++ b/ignore.c
@@ -0,0 +1,151 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "ntapi.h"
+#include "ignore.h"
+#include "misc.h"
+#include "pipe.h"
+
+//
+// Protected Processes
+//
+
+static unsigned long g_pids[MAX_PROTECTED_PIDS];
+static unsigned long g_pid_count;
+
+void add_protected_pid(unsigned long pid)
+{
+ g_pids[g_pid_count++] = pid;
+}
+
+int is_protected_pid(unsigned long pid)
+{
+ for (unsigned long i = 0; i < g_pid_count; i++) {
+ if(pid == g_pids[i]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//
+// Blacklist for Dumping Files
+//
+
+#define S(s, f) {L##s, sizeof(s)-1, f}
+
+#define FLAG_NONE 0
+#define FLAG_BEGINS_WITH 1
+
+static struct _ignored_file_t {
+ const wchar_t *unicode;
+ unsigned int length;
+ unsigned int flags;
+} g_ignored_files[] = {
+ S("\\??\\PIPE\\lsarpc", FLAG_NONE),
+ S("\\??\\IDE#", FLAG_BEGINS_WITH),
+ S("\\??\\STORAGE#", FLAG_BEGINS_WITH),
+ S("\\??\\MountPointManager", FLAG_NONE),
+ S("\\??\\root#", FLAG_BEGINS_WITH),
+ S("\\Device\\", FLAG_BEGINS_WITH),
+};
+
+int is_ignored_file_unicode(const wchar_t *fname, int length)
+{
+ struct _ignored_file_t *f = g_ignored_files;
+ for (unsigned int i = 0; i < ARRAYSIZE(g_ignored_files); i++, f++) {
+ if(f->flags == FLAG_NONE && length == f->length &&
+ !wcsnicmp(fname, f->unicode, length)) {
+ return 1;
+ }
+ else if(f->flags == FLAG_BEGINS_WITH && length >= f->length &&
+ !wcsnicmp(fname, f->unicode, f->length)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int is_ignored_file_objattr(const OBJECT_ATTRIBUTES *obj)
+{
+ return is_ignored_file_unicode(obj->ObjectName->Buffer,
+ obj->ObjectName->Length / sizeof(wchar_t));
+}
+
+static wchar_t *g_ignored_processpaths[] = {
+ L"C:\\WINDOWS\\system32\\dwwin.exe",
+ L"C:\\WINDOWS\\system32\\dumprep.exe",
+ L"C:\\WINDOWS\\system32\\drwtsn32.exe",
+};
+
+int is_ignored_process()
+{
+ wchar_t process_path[MAX_PATH];
+ GetModuleFileNameW(NULL, process_path, ARRAYSIZE(process_path));
+
+ for (int i = 0; i < ARRAYSIZE(g_ignored_processpaths); i++) {
+ if(!wcsicmp(g_ignored_processpaths[i], process_path)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//
+// Whitelist for Return Addresses
+//
+
+// for each high 20-bits of an address, there are two bits:
+// - is this address ignored
+// - is the ignored bit initialized yet?
+static unsigned char retaddr[0x40000];
+
+void init_ignored_retaddr()
+{
+ // send the address of the retaddr buffer to analyzer.py
+ pipe("RET_INIT:%d,%x", GetCurrentProcessId(), retaddr);
+}
+
+/*
+static void ret_get_flags(unsigned int addr, unsigned int *ignored,
+ unsigned int *initialized)
+{
+ unsigned int index = addr / 0x1000;
+ unsigned char info = retaddr[index / 4] >> ((index % 4) << 1);
+ // first bit defines whether the address is ignored
+ *ignored = info & 1;
+ // second bit defines whether the ignored bit has been initialized yet
+ *initialized = (info >> 1) & 1;
+}
+
+static void ret_set_flags(unsigned int addr, unsigned int ignored)
+{
+ unsigned int index = addr / 0x1000;
+ // reset the original flags
+ retaddr[index / 4] &= ~(3 << (index % 4) << 1);
+ // set the new flags
+ retaddr[index / 4] |= (!!ignored + 2) << (index % 4) << 1;
+}
+*/
+
+int is_ignored_retaddr(unsigned int addr)
+{
+ return 0;
+}
diff --git a/ignore.h b/ignore.h
new file mode 100644
index 0000000..b2f6575
--- /dev/null
+++ b/ignore.h
@@ -0,0 +1,35 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#define MAX_PROTECTED_PIDS 32
+
+#include "ntapi.h"
+
+void add_protected_pid(unsigned long pid);
+int is_protected_pid(unsigned long pid);
+
+int is_ignored_file_ascii(const char *fname, int length);
+int is_ignored_file_unicode(const wchar_t *fname, int length);
+int is_ignored_file_objattr(const OBJECT_ATTRIBUTES *obj);
+
+void ignore_file_prepend_stuff(const OBJECT_ATTRIBUTES *obj,
+ wchar_t **str, unsigned int *length);
+
+int is_ignored_process();
+
+int is_ignored_retaddr(unsigned int addr);
diff --git a/install.sh b/install.sh
new file mode 100644
index 0000000..ab1c0c9
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# directory in which the main repository of Cuckoo Sandbox can be found
+if [ -z "$CUCKOODIR" ]; then
+ CUCKOODIR=../cuckoo
+fi
+
+# target filename - in case of testing with custom dll's one may wish to
+# use a different filename, such as "cuckoomon_bson.dll"
+if [ -z "$CUCKOOMON" ]; then
+ CUCKOOMON=cuckoomon.dll
+fi
+
+make && cp cuckoomon.dll "$CUCKOODIR/analyzer/windows/dll/$CUCKOOMON"
diff --git a/log.c b/log.c
new file mode 100644
index 0000000..fe06332
--- /dev/null
+++ b/log.c
@@ -0,0 +1,563 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "ntapi.h"
+#include "misc.h"
+#include "utf8.h"
+#include "log.h"
+#include "bson.h"
+
+// the size of the logging buffer
+#define BUFFERSIZE 1024 * 1024
+#define BUFFER_LOG_MAX 256
+
+static CRITICAL_SECTION g_mutex;
+static int g_sock;
+static unsigned int g_starttick;
+
+static char g_buffer[BUFFERSIZE];
+static int g_idx;
+
+// current to-be-logged API call
+static bson g_bson[1];
+static char g_istr[4];
+
+static char logtbl_explained[256] = {0};
+
+//
+// Log API
+//
+
+void log_flush()
+{
+ if(g_idx != 0) {
+ int written;
+ if(g_sock == INVALID_SOCKET) {
+ written = fwrite(g_buffer, 1, g_idx, stderr);
+ }
+ else {
+ written = send(g_sock, g_buffer, g_idx, 0);
+ }
+
+ // TODO add more error checking
+
+ // if this call didn't write the entire buffer, then we have to move
+ // around some stuff in the buffer
+ if(written < g_idx) {
+ memcpy(g_buffer, g_buffer + written, g_idx - written);
+ }
+
+ // subtract the amount of written bytes from the index
+ g_idx -= written;
+ }
+}
+
+/*
+static void log_raw(const char *buf, size_t length) {
+ for (int i=0; i= BUFFERSIZE -1) {
+ log_flush();
+ }
+ }
+}
+*/
+
+static void log_raw_direct(const char *buf, size_t length) {
+ int sent = 0;
+ int r;
+ while (sent < length) {
+ r = send(g_sock, buf+sent, length-sent, 0);
+ if (r == -1) {
+ fprintf(stderr, "send returned -1.\n");
+ return;
+ }
+ sent += r;
+ }
+}
+
+static void debug_message(const char *msg) {
+ bson b[1];
+ bson_init( b );
+ bson_append_string( b, "type", "debug" );
+ bson_append_string( b, "msg", msg );
+ bson_finish( b );
+ log_raw_direct(bson_data( b ), bson_size( b ));
+ bson_destroy( b );
+ // log_flush();
+}
+
+/*
+static void log_int8(char value)
+{
+ bson_append_int( g_bson, g_istr, value );
+}
+
+static void log_int16(short value)
+{
+ bson_append_int( g_bson, g_istr, value );
+}
+*/
+
+static void log_int32(int value)
+{
+ bson_append_int( g_bson, g_istr, value );
+}
+
+static void log_string(const char *str, int length)
+{
+ if (str == NULL) {
+ bson_append_string_n( g_bson, g_istr, "", 0 );
+ return;
+ }
+ int ret;
+ char * utf8s = utf8_string(str, length);
+ int utf8len = * (int *) utf8s;
+ ret = bson_append_binary( g_bson, g_istr, BSON_BIN_BINARY, utf8s+4, utf8len );
+ if (ret == BSON_ERROR) {
+ char tmp[64];
+ snprintf(tmp, 64, "dbg bson err string %x utf8len %d", g_bson->err, utf8len);
+ debug_message(tmp);
+ }
+ free(utf8s);
+}
+
+static void log_wstring(const wchar_t *str, int length)
+{
+ if (str == NULL) {
+ bson_append_string_n( g_bson, g_istr, "", 0 );
+ return;
+ }
+ int ret;
+ char * utf8s = utf8_wstring(str, length);
+ int utf8len = * (int *) utf8s;
+ ret = bson_append_binary( g_bson, g_istr, BSON_BIN_BINARY, utf8s+4, utf8len );
+ if (ret == BSON_ERROR) {
+ char tmp[64];
+ snprintf(tmp, 64, "dbg bson err wstring %x utf8len %d", g_bson->err, utf8len);
+ debug_message(tmp);
+ }
+ free(utf8s);
+}
+
+static void log_argv(int argc, const char ** argv) {
+ bson_append_start_array( g_bson, g_istr );
+
+ for (int i=0; i= '2' && *fmt <= '9' ? *fmt++ - '0' : 1;
+
+ // the next format specifier
+ key = *fmt++;
+ }
+
+ pname = va_arg(args, const char *);
+ snprintf(g_istr, 4, "%u", argnum);
+ argnum++;
+
+ //on certain formats, we need to tell cuckoo about them for nicer display / matching
+ if (key == 'p' || key == 'P') {
+ bson_append_start_array( b, g_istr );
+ bson_append_string( b, "0", pname );
+ bson_append_string( b, "1", "p" );
+ bson_append_finish_array( b );
+ } else {
+ bson_append_string( b, g_istr, pname );
+ }
+
+ //now ignore the values
+ if(key == 's') {
+ (void) va_arg(args, const char *);
+ }
+ else if(key == 'S') {
+ (void) va_arg(args, int);
+ (void) va_arg(args, const char *);
+ }
+ else if(key == 'u') {
+ (void) va_arg(args, const wchar_t *);
+ }
+ else if(key == 'U') {
+ (void) va_arg(args, int);
+ (void) va_arg(args, const wchar_t *);
+ }
+ else if(key == 'b') {
+ (void) va_arg(args, size_t);
+ (void) va_arg(args, const char *);
+ }
+ else if(key == 'B') {
+ (void) va_arg(args, size_t *);
+ (void) va_arg(args, const char *);
+ }
+ else if(key == 'i') {
+ (void) va_arg(args, int);
+ }
+ else if(key == 'l' || key == 'p') {
+ (void) va_arg(args, long);
+ }
+ else if(key == 'L' || key == 'P') {
+ (void) va_arg(args, long *);
+ }
+ else if(key == 'o') {
+ (void) va_arg(args, UNICODE_STRING *);
+ }
+ else if(key == 'O') {
+ (void) va_arg(args, OBJECT_ATTRIBUTES *);
+ }
+ else if(key == 'a') {
+ (void) va_arg(args, int);
+ (void) va_arg(args, const char **);
+ }
+ else if(key == 'A') {
+ (void) va_arg(args, int);
+ (void) va_arg(args, const wchar_t **);
+ }
+ else if(key == 'r' || key == 'R') {
+ (void) va_arg(args, unsigned long);
+ (void) va_arg(args, unsigned long);
+ (void) va_arg(args, unsigned char *);
+ }
+
+ }
+ bson_append_finish_array( b );
+ bson_finish( b );
+ log_raw_direct(bson_data( b ), bson_size( b ));
+ bson_destroy( b );
+ // log_flush();
+ }
+
+ va_end(args);
+ fmt = fmtbak;
+ va_start(args, fmt);
+ count = 1; key = 0; argnum = 2;
+
+ bson_init( g_bson );
+ bson_append_int( g_bson, "I", index );
+ bson_append_int( g_bson, "T", GetCurrentThreadId() );
+ bson_append_int( g_bson, "t", GetTickCount() - g_starttick );
+ bson_append_start_array( g_bson, "args" );
+ bson_append_int( g_bson, "0", is_success );
+ bson_append_int( g_bson, "1", return_value );
+
+ while (--count != 0 || *fmt != 0) {
+
+ // we have to find the next format specifier
+ if(count == 0) {
+ // end of format
+ if(*fmt == 0) break;
+
+ // set the count, possibly with a repeated format specifier
+ count = *fmt >= '2' && *fmt <= '9' ? *fmt++ - '0' : 1;
+
+ // the next format specifier
+ key = *fmt++;
+ }
+
+ // pop the key and omit it
+ (void) va_arg(args, const char *);
+ snprintf(g_istr, 4, "%u", argnum);
+ argnum++;
+
+ // log the value
+ if(key == 's') {
+ const char *s = va_arg(args, const char *);
+ if(s == NULL) s = "";
+ log_string(s, -1);
+ }
+ else if(key == 'S') {
+ int len = va_arg(args, int);
+ const char *s = va_arg(args, const char *);
+ if(s == NULL) { s = ""; len = 0; }
+ log_string(s, len);
+ }
+ else if(key == 'u') {
+ const wchar_t *s = va_arg(args, const wchar_t *);
+ if(s == NULL) s = L"";
+ log_wstring(s, -1);
+ }
+ else if(key == 'U') {
+ int len = va_arg(args, int);
+ const wchar_t *s = va_arg(args, const wchar_t *);
+ if(s == NULL) { s = L""; len = 0; }
+ log_wstring(s, len);
+ }
+ else if(key == 'b') {
+ size_t len = va_arg(args, size_t);
+ const char *s = va_arg(args, const char *);
+ log_buffer(s, len);
+ }
+ else if(key == 'B') {
+ size_t *len = va_arg(args, size_t *);
+ const char *s = va_arg(args, const char *);
+ log_buffer(s, *len);
+ }
+ else if(key == 'i') {
+ int value = va_arg(args, int);
+ log_int32(value);
+ }
+ else if(key == 'l' || key == 'p') {
+ long value = va_arg(args, long);
+ log_int32(value);
+ }
+ else if(key == 'L' || key == 'P') {
+ long *ptr = va_arg(args, long *);
+ log_int32(ptr != NULL ? *ptr : 0);
+ }
+ else if(key == 'o') {
+ UNICODE_STRING *str = va_arg(args, UNICODE_STRING *);
+ if(str == NULL) {
+ log_string("", 0);
+ }
+ else {
+ log_wstring(str->Buffer, str->Length / sizeof(wchar_t));
+ }
+ }
+ else if(key == 'O') {
+ OBJECT_ATTRIBUTES *obj = va_arg(args, OBJECT_ATTRIBUTES *);
+ if(obj == NULL || obj->ObjectName == NULL) {
+ log_string("", 0);
+ }
+ else {
+ wchar_t path[MAX_PATH_PLUS_TOLERANCE]; int length;
+
+ length = path_from_object_attributes(
+ obj, path, MAX_PATH_PLUS_TOLERANCE);
+
+ length = ensure_absolute_path(path, path, length);
+
+ log_wstring(path, length);
+ }
+ }
+ else if(key == 'a') {
+ int argc = va_arg(args, int);
+ const char **argv = va_arg(args, const char **);
+ log_argv(argc, argv);
+ }
+ else if(key == 'A') {
+ int argc = va_arg(args, int);
+ const wchar_t **argv = va_arg(args, const wchar_t **);
+ log_wargv(argc, argv);
+ }
+ else if(key == 'r' || key == 'R') {
+ unsigned long type = va_arg(args, unsigned long);
+ unsigned long size = va_arg(args, unsigned long);
+ unsigned char *data = va_arg(args, unsigned char *);
+
+ // bson_append_start_object( g_bson, g_istr );
+ // bson_append_int( g_bson, "type", type );
+
+ // strncpy(g_istr, "val", 4);
+ if(type == REG_NONE) {
+ log_string("", 0);
+ }
+ else if(type == REG_DWORD || type == REG_DWORD_LITTLE_ENDIAN) {
+ unsigned int value = *(unsigned int *) data;
+ log_int32(value);
+ }
+ else if(type == REG_DWORD_BIG_ENDIAN) {
+ unsigned int value = *(unsigned int *) data;
+ log_int32(htonl(value));
+ }
+ else if(type == REG_EXPAND_SZ || type == REG_SZ) {
+
+ if(data == NULL) {
+ bson_append_binary(g_bson, g_istr, BSON_BIN_BINARY,
+ (const char *) data, 0);
+ }
+ // ascii strings
+ else if(key == 'r') {
+ bson_append_binary(g_bson, g_istr, BSON_BIN_BINARY,
+ (const char *) data, size);
+ }
+ // unicode strings
+ else {
+ bson_append_binary(g_bson, g_istr, BSON_BIN_BINARY,
+ (const char *) data, size);
+ }
+ } else {
+ bson_append_binary(g_bson, g_istr, BSON_BIN_BINARY,
+ (const char *) data, 0);
+ }
+
+ // bson_append_finish_object( g_bson );
+ }
+ }
+
+ va_end(args);
+
+ bson_append_finish_array( g_bson );
+ bson_finish( g_bson );
+ // if (bson_size( g_bson ) > BUFFERSIZE) {
+ // //DBGWARN, ignoring bson obj
+ // } else {
+ log_raw_direct(bson_data( g_bson ), bson_size( g_bson ));
+ // }
+
+ bson_destroy( g_bson );
+ // log_flush();
+ LeaveCriticalSection(&g_mutex);
+}
+
+void announce_netlog()
+{
+ char protoname[32];
+ strcpy(protoname, "BSON\n");
+ //sprintf(protoname+5, "logs/%lu.bson\n", GetCurrentProcessId());
+ log_raw_direct(protoname, strlen(protoname));
+}
+
+void log_new_process()
+{
+ wchar_t module_path[MAX_PATH];
+ GetModuleFileNameW(NULL, module_path, ARRAYSIZE(module_path));
+
+ g_starttick = GetTickCount();
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ loq(0, "__process__", 1, 0, "llllu", "TimeLow", st.dwLowDateTime,
+ "TimeHigh", st.dwHighDateTime,
+ "ProcessIdentifier", GetCurrentProcessId(),
+ "ParentProcessIdentifier", parent_process_id(),
+ "ModulePath", module_path);
+}
+
+void log_new_thread()
+{
+ loq(1, "__thread__", 1, 0, "l", "ProcessIdentifier", GetCurrentProcessId());
+}
+
+void log_init(unsigned int ip, unsigned short port, int debug)
+{
+ InitializeCriticalSection(&g_mutex);
+
+ if(debug != 0) {
+ g_sock = INVALID_SOCKET;
+ }
+ else {
+ WSADATA wsa;
+ WSAStartup(MAKEWORD(2, 2), &wsa);
+
+ g_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ struct sockaddr_in addr = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = ip,
+ .sin_port = htons(port),
+ };
+
+ connect(g_sock, (struct sockaddr *) &addr, sizeof(addr));
+ }
+
+ announce_netlog();
+ log_new_process();
+ log_new_thread();
+ // flushing here so host can create files / keep timestamps
+ // log_flush();
+}
+
+void log_free()
+{
+ DeleteCriticalSection(&g_mutex);
+ log_flush();
+ if(g_sock != INVALID_SOCKET) {
+ closesocket(g_sock);
+ }
+}
+
+int log_resolve_index(const char *funcname, int index)
+{
+ for (int i = 0; logtbl[i][0] != NULL; i++) {
+ if(!strcmp(funcname, logtbl[i][0])) {
+ if(index != 0) {
+ index--;
+ }
+ else {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
diff --git a/log.h b/log.h
new file mode 100644
index 0000000..df320b1
--- /dev/null
+++ b/log.h
@@ -0,0 +1,125 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+//
+// Log API
+//
+// The Log takes a format string and parses the extra arguments accordingly
+//
+// The following Format Specifiers are available:
+// s -> (char *) -> zero-terminated string
+// S -> (int, char *) -> string with length
+// u -> (wchar_t *) -> zero-terminated unicode string
+// U -> (int, wchar_t *) -> unicode string with length
+// b -> (int, void *) -> memory with a given size (alias for S)
+// B -> (int *, void *) -> memory with a given size (value at integer)
+// i -> (int) -> integer
+// l -> (long) -> long integer
+// L -> (long *) -> pointer to a long integer
+// p -> (void *) -> pointer (alias for l)
+// P -> (void **) -> pointer to a handle (alias for L)
+// o -> (UNICODE_STRING *) -> unicode string
+// O -> (OBJECT_ATTRIBUTES *) -> wrapper around a unicode string
+// a -> (int, char **) -> array of string
+// A -> (int, wchar_t **) -> array of unicode strings
+// r -> (Type, int, char *) type as defined for Registry operations
+// R -> (Type, int, wchar_t *) type as defined for Registry operations
+// type r is for ascii functions, R for unicode (Nt* are unicode)
+//
+// Each of these format specifiers are prefixed with a zero-terminated key
+// value, e.g.
+//
+// log("s", "key", "value");
+//
+// A format specifier can also be repeated for n times (with n in the range
+// 2..9), e.g.
+//
+// loq("sss", "key1", "value", "key2", "value2", "key3", "value3");
+// loq("3s", "key1", "value", "key2", "value2", "key3", "value3");
+//
+
+void loq(int index, const char *name, int is_success, int return_value, const char *fmt, ...);
+void log_new_process();
+void log_new_thread();
+
+void log_init(unsigned int ip, unsigned short port, int debug);
+void log_flush();
+void log_free();
+
+int log_resolve_index(const char *funcname, int index);
+extern const char *logtbl[][2];
+
+#define LOQ(fmt, ...) { static int _index; if(_index == 0) \
+ _index = log_resolve_index(&__FUNCTION__[4], 0); loq(_index, \
+ &__FUNCTION__[4], is_success(ret), (int) ret, fmt, ##__VA_ARGS__); }
+
+#define LOQ2(fmt, ...) { static int _index; if(_index == 0) \
+ _index = log_resolve_index(&__FUNCTION__[4], 1); loq(_index, \
+ &__FUNCTION__[4], is_success(ret), (int) ret, fmt, ##__VA_ARGS__); }
+
+#define LOQ3(fmt, ...) { static int _index; if(_index == 0) \
+ _index = log_resolve_index(&__FUNCTION__[4], 2); loq(_index, \
+ &__FUNCTION__[4], is_success(ret), (int) ret, fmt, ##__VA_ARGS__); }
+
+#define LOQspecial(fmt, ...) { static int _index; if(_index == 0) \
+ _index = log_resolve_index(&__FUNCTION__[5], 0); loq(_index, \
+ &__FUNCTION__[5], is_success(ret), (int) ret, fmt, ##__VA_ARGS__); }
+
+#define IS_SUCCESS_NTSTATUS() int is_success(NTSTATUS ret) { \
+ return NT_SUCCESS(ret); }
+#define IS_SUCCESS_BOOL() int is_success(BOOL ret) { \
+ return ret != FALSE; }
+#define IS_SUCCESS_HHOOK() int is_success(HHOOK ret) { \
+ return ret != NULL; }
+#define IS_SUCCESS_HINTERNET() int is_success(HINTERNET ret) { \
+ return ret != NULL; }
+#define IS_SUCCESS_HRESULT() int is_success(HRESULT ret) { \
+ return ret == S_OK; }
+#define IS_SUCCESS_HANDLE() int is_success(HANDLE ret) { \
+ return ret != NULL; }
+#define IS_SUCCESS_HANDLE2() int is_success(HANDLE ret) { \
+ return ret != NULL && ret != INVALID_HANDLE_VALUE; }
+#define IS_SUCCESS_VOID() int is_success(int ret) { return TRUE; }
+#define IS_SUCCESS_LONGREG() int is_success(LONG ret) { \
+ return ret == ERROR_SUCCESS; }
+#define IS_SUCCESS_SCHANDLE() int is_success(SC_HANDLE ret) { \
+ return ret != NULL; }
+#define IS_SUCCESS_DWORDTHREAD() int is_success(DWORD ret) { \
+ return ret != (DWORD) -1; }
+#define IS_SUCCESS_HWND() int is_success(HWND ret) { \
+ return ret != NULL; }
+#define IS_SUCCESS_ZERO() int is_success(int ret) { \
+ return ret == 0; }
+#define IS_SUCCESS_INTM1() int is_success(int ret) { \
+ return ret != -1; }
+
+#define ENSURE_DWORD(param) \
+ DWORD _##param = 0; if(param == NULL) param = &_##param
+
+#define ENSURE_ULONG(param) \
+ ULONG _##param = 0; if(param == NULL) param = &_##param
+#define ENSURE_ULONG_ZERO(param) \
+ ENSURE_ULONG(param); else *param = 0
+
+#define ENSURE_SIZET(param) \
+ ULONG _##param = 0; if(param == NULL) param = &_##param
+#define ENSURE_SIZET_ZERO(param) \
+ ENSURE_ULONG(param); else *param = 0
+
+#define ENSURE_CLIENT_ID(param) \
+ CLIENT_ID _##param = {}; if(param == NULL) param = &_##param
diff --git a/logtbl.py b/logtbl.py
new file mode 100644
index 0000000..076553d
--- /dev/null
+++ b/logtbl.py
@@ -0,0 +1,200 @@
+# Copyright (C) 2010-2014 Cuckoo Sandbox Developers.
+# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
+# See the file 'docs/LICENSE' for copying permission.
+
+"""Table for all hook logging statements.
+
+This table is not automatically generated at the moment, but kept up-to-date
+by hand.
+
+"""
+table = [
+ ("__process__", "__init__", ("",)),
+ ("__thread__", "__init__", ("",)),
+ ("NtDeleteFile", "filesystem", ("O", "FileName")),
+ ("CreateDirectoryW", "filesystem", ("u", "DirectoryName")),
+ ("CreateDirectoryExW", "filesystem", ("u", "DirectoryName")),
+ ("RemoveDirectoryA", "filesystem", ("s", "DirectoryName")),
+ ("RemoveDirectoryW", "filesystem", ("u", "DirectoryName")),
+ ("FindFirstFileExA", "filesystem", ("s", "FileName")),
+ ("FindFirstFileExW", "filesystem", ("u", "FileName")),
+ ("DeleteFileA", "filesystem", ("s", "FileName")),
+ ("DeleteFileW", "filesystem", ("u", "FileName")),
+ ("UnhookWindowsHookEx", "hooking", ("p", "HookHandle")),
+ ("LdrGetDllHandle", "system", ("oP", "FileName", "ModuleHandle")),
+ ("ExitWindowsEx", "system", ("ll", "Flags", "Reason")),
+ ("IsDebuggerPresent", "system", ("",)),
+ ("LookupPrivilegeValueW", "system", ("uu", "SystemName", "PrivilegeName")),
+ ("NtClose", "system", ("p", "Handle")),
+ ("URLDownloadToFileW", "network", ("uu", "URL", "FileName")),
+ ("InternetReadFile", "network", ("pB", "InternetHandle", "Buffer")),
+ ("InternetWriteFile", "network", ("pB", "InternetHandle", "Buffer")),
+ ("InternetCloseHandle", "network", ("p", "InternetHandle")),
+ ("DnsQuery_A", "network", ("sil", "Name", "Type", "Options")),
+ ("DnsQuery_UTF8", "network", ("sil", "Name", "Type", "Options")),
+ ("DnsQuery_W", "network", ("uil", "Name", "Type", "Options")),
+ ("getaddrinfo", "network", ("ss", "NodeName", "ServiceName")),
+ ("GetAddrInfoW", "network", ("uu", "NodeName", "ServiceName")),
+ ("NtTerminateProcess", "process", ("pl", "ProcessHandle", "ExitCode")),
+ ("ExitProcess", "process", ("l", "ExitCode")),
+ ("system", "process", ("s", "Command")),
+ ("RegOpenKeyExA", "registry", ("psP", "Registry", "SubKey", "Handle")),
+ ("RegOpenKeyExW", "registry", ("puP", "Registry", "SubKey", "Handle")),
+ ("RegDeleteKeyA", "registry", ("ps", "Handle", "SubKey")),
+ ("RegDeleteKeyW", "registry", ("pu", "Handle", "SubKey")),
+ ("RegEnumKeyW", "registry", ("plu", "Handle", "Index", "Name")),
+ ("RegDeleteValueA", "registry", ("ps", "Handle", "ValueName")),
+ ("RegDeleteValueW", "registry", ("pu", "Handle", "ValueName")),
+ ("RegCloseKey", "registry", ("p", "Handle")),
+ ("NtRenameKey", "registry", ("po", "KeyHandle", "NewName")),
+ ("NtEnumerateKey", "registry", ("pl", "KeyHandle", "Index")),
+ ("NtDeleteKey", "registry", ("p", "KeyHandle")),
+ ("NtDeleteValueKey", "registry", ("po", "KeyHandle", "ValueName")),
+ ("NtLoadKey", "registry", ("OO", "TargetKey", "SourceFile")),
+ ("NtSaveKey", "registry", ("pp", "KeyHandle", "FileHandle")),
+ ("ControlService", "services", ("pl", "ServiceHandle", "ControlCode")),
+ ("DeleteService", "services", ("p", "ServiceHandle")),
+ ("NtDelayExecution", "system", ("ls", "Milliseconds", "Status")),
+ ("NtDelayExecution", "system", ("l", "Milliseconds")),
+ ("WSAStartup", "socket", ("p", "VersionRequested")),
+ ("gethostbyname", "socket", ("s", "Name")),
+ ("socket", "socket", ("lll", "af", "type", "protocol")),
+ ("connect", "socket", ("p", "socket")),
+ ("send", "socket", ("pb", "socket", "buffer")),
+ ("sendto", "socket", ("pb", "socket", "buffer")),
+ ("recv", "socket", ("pb", "socket", "buffer")),
+ ("recvfrom", "socket", ("pb", "socket", "buffer")),
+ ("accept", "socket", ("pp", "socket", "ClientSocket")),
+ ("bind", "socket", ("psl", "socket", "ip", "port")),
+ ("bind", "socket", ("p", "socket")),
+ ("setsockopt", "socket", ("pllb", "socket", "level", "optname", "optval")),
+ ("listen", "socket", ("p", "socket")),
+ ("select", "socket", ("p", "socket")),
+ ("ioctlsocket", "socket", ("pl", "socket", "command")),
+ ("closesocket", "socket", ("p", "socket")),
+ ("shutdown", "socket", ("pl", "socket", "how")),
+ ("WSARecv", "socket", ("p", "socket")),
+ ("WSARecvFrom", "socket", ("p", "socket")),
+ ("WSASend", "socket", ("p", "Socket")),
+ ("WSASendTo", "socket", ("p", "Socket")),
+ ("WSASocketA", "socket", ("lll", "af", "type", "protocol")),
+ ("WSASocketW", "socket", ("lll", "af", "type", "protocol")),
+ ("ConnectEx", "socket", ("pB", "socket", "SendBuffer")),
+ ("NtOpenMutant", "synchronization", ("PO", "Handle", "MutexName")),
+ ("NtGetContextThread", "threading", ("p", "ThreadHandle")),
+ ("NtSetContextThread", "threading", ("p", "ThreadHandle")),
+ ("NtResumeThread", "threading", ("pL", "ThreadHandle", "SuspendCount")),
+ ("NtTerminateThread", "threading", ("pl", "ThreadHandle", "ExitStatus")),
+ ("ExitThread", "threading", ("l", "ExitCode")),
+ ("FindWindowA", "windows", ("ss", "ClassName", "WindowName")),
+ ("FindWindowW", "windows", ("uu", "ClassName", "WindowName")),
+ ("FindWindowExA", "windows", ("ls", "ClassName", "WindowName")),
+ ("FindWindowExA", "windows", ("ss", "ClassName", "WindowName")),
+ ("FindWindowExW", "windows", ("lu", "ClassName", "WindowName")),
+ ("FindWindowExW", "windows", ("uu", "ClassName", "WindowName")),
+ ("NtCreateFile", "filesystem", ("PpOll", "FileHandle", "DesiredAccess", "FileName", "CreateDisposition", "ShareAccess")),
+ ("NtOpenFile", "filesystem", ("PpOl", "FileHandle", "DesiredAccess", "FileName", "ShareAccess")),
+ ("NtReadFile", "filesystem", ("pb", "FileHandle", "Buffer")),
+ ("NtWriteFile", "filesystem", ("pb", "FileHandle", "Buffer")),
+ ("NtDeviceIoControlFile", "filesystem", ("pbb", "FileHandle", "InputBuffer", "OutputBuffer")),
+ ("NtQueryDirectoryFile", "filesystem", ("pbo", "FileHandle", "FileInformation", "FileName")),
+ ("NtQueryInformationFile", "filesystem", ("pb", "FileHandle", "FileInformation")),
+ ("NtSetInformationFile", "filesystem", ("pb", "FileHandle", "FileInformation")),
+ ("NtOpenDirectoryObject", "filesystem", ("PlO", "DirectoryHandle", "DesiredAccess", "ObjectAttributes")),
+ ("NtCreateDirectoryObject", "filesystem", ("PlO", "DirectoryHandle", "DesiredAccess", "ObjectAttributes")),
+ ("MoveFileWithProgressW", "filesystem", ("uu", "ExistingFileName", "NewFileName")),
+ ("CopyFileA", "filesystem", ("ss", "ExistingFileName", "NewFileName")),
+ ("CopyFileW", "filesystem", ("uu", "ExistingFileName", "NewFileName")),
+ ("CopyFileExW", "filesystem", ("uul", "ExistingFileName", "NewFileName", "CopyFlags")),
+ ("SetWindowsHookExA", "system", ("lppl", "HookIdentifier", "ProcedureAddress", "ModuleAddress", "ThreadId")),
+ ("SetWindowsHookExW", "system", ("lppl", "HookIdentifier", "ProcedureAddress", "ModuleAddress", "ThreadId")),
+ ("LdrLoadDll", "system", ("loP", "Flags", "FileName", "BaseAddress")),
+ ("LdrGetProcedureAddress", "system", ("pSlP", "ModuleHandle", "FunctionName", "Ordinal", "FunctionAddress")),
+ ("DeviceIoControl", "device", ("plbb", "DeviceHandle", "IoControlCode", "InBuffer", "OutBuffer")),
+ ("WriteConsoleA", "system", ("pS", "ConsoleHandle", "Buffer")),
+ ("WriteConsoleW", "system", ("pU", "ConsoleHandle", "Buffer")),
+ ("InternetOpenA", "network", ("spssp", "Agent", "AccessType", "ProxyName", "ProxyBypass", "Flags")),
+ ("InternetOpenW", "network", ("upuup", "Agent", "AccessType", "ProxyName", "ProxyBypass", "Flags")),
+ ("InternetConnectA", "network", ("pslsslp", "InternetHandle", "ServerName", "ServerPort", "Username", "Password", "Service", "Flags")),
+ ("InternetConnectW", "network", ("puluulp", "InternetHandle", "ServerName", "ServerPort", "Username", "Password", "Service", "Flags")),
+ ("InternetOpenUrlA", "network", ("psSp", "ConnectionHandle", "URL", "Headers", "Flags")),
+ ("InternetOpenUrlW", "network", ("puUp", "ConnectionHandle", "URL", "Headers", "Flags")),
+ ("HttpOpenRequestA", "network", ("psl", "InternetHandle", "Path", "Flags")),
+ ("HttpOpenRequestW", "network", ("pul", "InternetHandle", "Path", "Flags")),
+ ("HttpSendRequestA", "network", ("pSb", "RequestHandle", "Headers", "PostData")),
+ ("HttpSendRequestW", "network", ("pUb", "RequestHandle", "Headers", "PostData")),
+ ("NtCreateProcess", "process", ("PpO", "ProcessHandle", "DesiredAccess", "FileName")),
+ ("NtCreateProcessEx", "process", ("PpO", "ProcessHandle", "DesiredAccess", "FileName")),
+ ("NtCreateUserProcess", "process", ("PPppOOoo", "ProcessHandle", "ThreadHandle", "ProcessDesiredAccess", "ThreadDesiredAccess", "ProcessFileName", "ThreadName", "ImagePathName", "CommandLine")),
+ ("NtOpenProcess", "process", ("ppp", "ProcessHandle", "DesiredAccess", "ProcessIdentifier")),
+ ("NtOpenProcess", "process", ("PpP", "ProcessHandle", "DesiredAccess", "ProcessIdentifier")),
+ ("NtCreateSection", "process", ("PpOp", "SectionHandle", "DesiredAccess", "ObjectAttributes", "FileHandle")),
+ ("NtMakeTemporaryObject", "process", ("p", "ObjectHandle")),
+ ("NtMakePermanentObject", "process", ("p", "ObjectHandle")),
+ ("NtOpenSection", "process", ("PpO", "SectionHandle", "DesiredAccess", "ObjectAttributes")),
+ ("CreateProcessInternalW", "process", ("uupllpp", "ApplicationName", "CommandLine", "CreationFlags", "ProcessId", "ThreadId", "ProcessHandle", "ThreadHandle")),
+ ("ShellExecuteExW", "process", ("2ul", "FilePath", "Parameters", "Show")),
+ ("NtAllocateVirtualMemory", "process", ("pPPp", "ProcessHandle", "BaseAddress", "RegionSize", "Protection")),
+ ("NtReadVirtualMemory", "process", ("2pB", "ProcessHandle", "BaseAddress", "Buffer")),
+ ("ReadProcessMemory", "process", ("ppB", "ProcessHandle", "BaseAddress", "Buffer")),
+ ("NtWriteVirtualMemory", "process", ("2pB", "ProcessHandle", "BaseAddress", "Buffer")),
+ ("WriteProcessMemory", "process", ("ppB", "ProcessHandle", "BaseAddress", "Buffer")),
+ ("NtProtectVirtualMemory", "process", ("pPPpP", "ProcessHandle", "BaseAddress", "NumberOfBytesProtected", "NewAccessProtection", "OldAccessProtection")),
+ ("VirtualProtectEx", "process", ("pppp", "ProcessHandle", "Address", "Size", "Protection")),
+ ("NtFreeVirtualMemory", "process", ("pPPp", "ProcessHandle", "BaseAddress", "RegionSize", "FreeType")),
+ ("VirtualFreeEx", "process", ("pppl", "ProcessHandle", "Address", "Size", "FreeType")),
+ ("RegCreateKeyExA", "registry", ("psslP", "Registry", "SubKey", "Class", "Access", "Handle")),
+ ("RegCreateKeyExW", "registry", ("puulP", "Registry", "SubKey", "Class", "Access", "Handle")),
+ ("RegEnumKeyExA", "registry", ("plss", "Handle", "Index", "Name", "Class")),
+ ("RegEnumKeyExW", "registry", ("pluu", "Handle", "Index", "Name", "Class")),
+ ("RegEnumValueA", "registry", ("plsr", "Handle", "Index", "ValueName", "Data")),
+ ("RegEnumValueA", "registry", ("plsLL", "Handle", "Index", "ValueName", "Type", "DataLength")),
+ ("RegEnumValueW", "registry", ("pluR", "Handle", "Index", "ValueName", "Data")),
+ ("RegEnumValueW", "registry", ("pluLL", "Handle", "Index", "ValueName", "Type", "DataLength")),
+ ("RegSetValueExA", "registry", ("pslr", "Handle", "ValueName", "Type", "Buffer")),
+ ("RegSetValueExA", "registry", ("psl", "Handle", "ValueName", "Type")),
+ ("RegSetValueExW", "registry", ("pulR", "Handle", "ValueName", "Type", "Buffer")),
+ ("RegSetValueExW", "registry", ("pul", "Handle", "ValueName", "Type")),
+ ("RegQueryValueExA", "registry", ("psr", "Handle", "ValueName", "Data")),
+ ("RegQueryValueExA", "registry", ("psLL", "Handle", "ValueName", "Type", "DataLength")),
+ ("RegQueryValueExW", "registry", ("puR", "Handle", "ValueName", "Data")),
+ ("RegQueryValueExW", "registry", ("puLL", "Handle", "ValueName", "Type", "DataLength")),
+ ("RegQueryInfoKeyA", "registry", ("pS6L", "KeyHandle", "Class", "SubKeyCount", "MaxSubKeyLength", "MaxClassLength", "ValueCount", "MaxValueNameLength", "MaxValueLength")),
+ ("RegQueryInfoKeyW", "registry", ("pU6L", "KeyHandle", "Class", "SubKeyCount", "MaxSubKeyLength", "MaxClassLength", "ValueCount", "MaxValueNameLength", "MaxValueLength")),
+ ("NtCreateKey", "registry", ("PlOo", "KeyHandle", "DesiredAccess", "ObjectAttributes", "Class")),
+ ("NtOpenKey", "registry", ("PlO", "KeyHandle", "DesiredAccess", "ObjectAttributes")),
+ ("NtOpenKeyEx", "registry", ("PlO", "KeyHandle", "DesiredAccess", "ObjectAttributes")),
+ ("NtReplaceKey", "registry", ("pOO", "KeyHandle", "NewHiveFileName", "BackupHiveFileName")),
+ ("NtEnumerateValueKey", "registry", ("pll", "KeyHandle", "Index", "KeyValueInformationClass")),
+ ("NtSetValueKey", "registry", ("polR", "KeyHandle", "ValueName", "Type", "Buffer")),
+ ("NtSetValueKey", "registry", ("pol", "KeyHandle", "ValueName", "Type")),
+ ("NtQueryValueKey", "registry", ("polR", "KeyHandle", "ValueName", "Type", "Information")),
+ ("NtQueryValueKey", "registry", ("po", "KeyHandle", "ValueName")),
+ ("NtQueryMultipleValueKey", "registry", ("poS", "KeyHandle", "ValueName", "ValueBuffer")),
+ ("NtLoadKey2", "registry", ("OOl", "TargetKey", "SourceFile", "Flags")),
+ ("NtLoadKeyEx", "registry", ("pOOl", "TrustClassKey", "TargetKey", "SourceFile", "Flags")),
+ ("NtQueryKey", "registry", ("pSl", "KeyHandle", "KeyInformation", "KeyInformationClass")),
+ ("NtSaveKeyEx", "registry", ("ppl", "KeyHandle", "FileHandle", "Format")),
+ ("OpenSCManagerA", "services", ("ssl", "MachineName", "DatabaseName", "DesiredAccess")),
+ ("OpenSCManagerW", "services", ("uul", "MachineName", "DatabaseName", "DesiredAccess")),
+ ("CreateServiceA", "services", ("pss4l3s", "ServiceControlHandle", "ServiceName", "DisplayName", "DesiredAccess", "ServiceType", "StartType", "ErrorControl", "BinaryPathName", "ServiceStartName", "Password")),
+ ("CreateServiceW", "services", ("puu4l3u", "ServiceControlHandle", "ServiceName", "DisplayName", "DesiredAccess", "ServiceType", "StartType", "ErrorControl", "BinaryPathName", "ServiceStartName", "Password")),
+ ("OpenServiceA", "services", ("psl", "ServiceControlManager", "ServiceName", "DesiredAccess")),
+ ("OpenServiceW", "services", ("pul", "ServiceControlManager", "ServiceName", "DesiredAccess")),
+ ("StartServiceA", "services", ("pa", "ServiceHandle", "Arguments")),
+ ("StartServiceW", "services", ("pA", "ServiceHandle", "Arguments")),
+ ("TransmitFile", "socket", ("ppll", "socket", "FileHandle", "NumberOfBytesToWrite", "NumberOfBytesPerSend")),
+ ("NtCreateMutant", "synchronization", ("POl", "Handle", "MutexName", "InitialOwner")),
+ ("NtCreateNamedPipeFile", "synchronization", ("PpOl", "NamedPipeHandle", "DesiredAccess", "PipeName", "ShareAccess")),
+ ("NtCreateThread", "threading", ("PpO", "ThreadHandle", "ProcessHandle", "ObjectAttributes")),
+ ("NtOpenThread", "threading", ("PlO", "ThreadHandle", "DesiredAccess", "ObjectAttributes")),
+ ("NtSuspendThread", "threading", ("pL", "ThreadHandle", "SuspendCount")),
+ ("CreateThread", "threading", ("pplL", "StartRoutine", "Parameter", "CreationFlags", "ThreadId")),
+ ("CreateRemoteThread", "threading", ("3plL", "ProcessHandle", "StartRoutine", "Parameter", "CreationFlags", "ThreadId")),
+ ("RtlCreateUserThread", "threading", ("plppPl", "ProcessHandle", "CreateSuspended", "StartAddress", "StartParameter", "ThreadHandle", "ThreadIdentifier")),
+ ("ZwMapViewOfSection", "process", ("ppPp", "SectionHandle", "ProcessHandle", "BaseAddress", "SectionOffset")),
+ ("GetSystemMetrics", "misc", ("l", "SystemMetricIndex")),
+ ("GetCursorPos", "misc", ("ll", "x", "y")),
+ ("RtlCreateUserProcess", "process", ("opp", "ImagePath", "ObjectAttributes", "ParentProcess")),
+ ("NtCreateThreadEx", "threading", ("Pppl", "ThreadHandle", "ProcessHandle", "StartAddress", "CreateSuspended")),
+]
diff --git a/lookup.c b/lookup.c
new file mode 100644
index 0000000..9264ea7
--- /dev/null
+++ b/lookup.c
@@ -0,0 +1,97 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include "lookup.h"
+
+#define ENTER() EnterCriticalSection(&d->cs)
+#define LEAVE() LeaveCriticalSection(&d->cs)
+
+typedef struct _entry_t {
+ struct _entry_t *next;
+ unsigned int id;
+ unsigned int size;
+ unsigned char data[0];
+} entry_t;
+
+void lookup_init(lookup_t *d)
+{
+ d->root = NULL;
+ InitializeCriticalSection(&d->cs);
+}
+
+void lookup_free(lookup_t *d)
+{
+ // TODO
+}
+
+void *lookup_add(lookup_t *d, unsigned int id, unsigned int size)
+{
+ entry_t *t = (entry_t *) malloc(sizeof(entry_t) + size);
+ ENTER();
+ *t = (entry_t) {
+ .next = d->root,
+ .id = id,
+ .size = size,
+ };
+ d->root = t;
+ LEAVE();
+ return t->data;
+}
+
+void *lookup_get(lookup_t *d, unsigned int id, unsigned int *size)
+{
+ ENTER();
+ for (entry_t *p = d->root; p != NULL; p = p->next) {
+ if(p->id == id) {
+ if(size != NULL) {
+ *size = p->size;
+ }
+ void *data = p->data;
+ LEAVE();
+ return data;
+ }
+ }
+ LEAVE();
+ return NULL;
+}
+
+void lookup_del(lookup_t *d, unsigned int id)
+{
+ ENTER();
+ entry_t *p = d->root;
+ // edge case; we want to delete the first entry
+ if(p != NULL && p->id == id) {
+ entry_t *t = p->next;
+ free(d->root);
+ d->root = t;
+ LEAVE();
+ return;
+ }
+ for (entry_t *last = NULL; p != NULL; last = p, p = p->next) {
+ if(p->id == id) {
+ last->next = p->next;
+ free(p);
+ break;
+ }
+ }
+ LEAVE();
+}
diff --git a/lookup.h b/lookup.h
new file mode 100644
index 0000000..9581145
--- /dev/null
+++ b/lookup.h
@@ -0,0 +1,29 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+
+typedef struct _lookup_internal_t {
+ CRITICAL_SECTION cs;
+ void *root;
+} lookup_t;
+
+void lookup_init(lookup_t *d);
+void *lookup_add(lookup_t *d, unsigned int id, unsigned int size);
+void *lookup_get(lookup_t *d, unsigned int id, unsigned int *size);
+void lookup_del(lookup_t *d, unsigned int id);
diff --git a/misc.c b/misc.c
new file mode 100644
index 0000000..37dff1f
--- /dev/null
+++ b/misc.c
@@ -0,0 +1,269 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include "ntapi.h"
+#include "misc.h"
+
+ULONG_PTR parent_process_id() // By Napalm @ NetCore2K (rohitab.com)
+{
+ ULONG_PTR pbi[6]; ULONG ulSize = 0;
+ LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle,
+ ULONG ProcessInformationClass, PVOID ProcessInformation,
+ ULONG ProcessInformationLength, PULONG ReturnLength);
+
+ *(FARPROC *) &NtQueryInformationProcess = GetProcAddress(
+ GetModuleHandle("ntdll"), "NtQueryInformationProcess");
+
+ if(NtQueryInformationProcess != NULL && NtQueryInformationProcess(
+ GetCurrentProcess(), 0, &pbi, sizeof(pbi), &ulSize) >= 0 &&
+ ulSize == sizeof(pbi)) {
+ return pbi[5];
+ }
+ return 0;
+}
+
+DWORD pid_from_process_handle(HANDLE process_handle)
+{
+ PROCESS_BASIC_INFORMATION pbi = {}; ULONG ulSize;
+ LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle,
+ ULONG ProcessInformationClass, PVOID ProcessInformation,
+ ULONG ProcessInformationLength, PULONG ReturnLength);
+
+ *(FARPROC *) &NtQueryInformationProcess = GetProcAddress(
+ GetModuleHandle("ntdll"), "NtQueryInformationProcess");
+
+ if(NtQueryInformationProcess != NULL && NtQueryInformationProcess(
+ process_handle, 0, &pbi, sizeof(pbi), &ulSize) >= 0 &&
+ ulSize == sizeof(pbi)) {
+ return pbi.UniqueProcessId;
+ }
+ return 0;
+}
+
+DWORD pid_from_thread_handle(HANDLE thread_handle)
+{
+ THREAD_BASIC_INFORMATION tbi = {}; ULONG ulSize;
+ LONG (WINAPI *NtQueryInformationThread)(HANDLE ThreadHandle,
+ ULONG ThreadInformationClass, PVOID ThreadInformation,
+ ULONG ThreadInformationLength, PULONG ReturnLength);
+
+ *(FARPROC *) &NtQueryInformationThread = GetProcAddress(
+ GetModuleHandle("ntdll"), "NtQueryInformationThread");
+
+ if(NtQueryInformationThread != NULL && NtQueryInformationThread(
+ thread_handle, 0, &tbi, sizeof(tbi), &ulSize) >= 0 &&
+ ulSize == sizeof(tbi)) {
+ return (DWORD) tbi.ClientId.UniqueProcess;
+ }
+ return 0;
+}
+
+DWORD random()
+{
+ static BOOLEAN (WINAPI *pRtlGenRandom)(PVOID RandomBuffer,
+ ULONG RandomBufferLength);
+
+ if(pRtlGenRandom == NULL) {
+ *(FARPROC *) &pRtlGenRandom = GetProcAddress(
+ GetModuleHandle("advapi32"), "SystemFunction036");
+ }
+
+ DWORD ret;
+ return pRtlGenRandom(&ret, sizeof(ret)) ? ret : rand();
+}
+
+DWORD randint(DWORD min, DWORD max)
+{
+ return min + (random() % (max - min + 1));
+}
+
+BOOL is_directory_objattr(const OBJECT_ATTRIBUTES *obj)
+{
+ static NTSTATUS (WINAPI *pNtQueryAttributesFile)(
+ _In_ const OBJECT_ATTRIBUTES *ObjectAttributes,
+ _Out_ PFILE_BASIC_INFORMATION FileInformation
+ );
+
+ if(pNtQueryAttributesFile == NULL) {
+ *(FARPROC *) &pNtQueryAttributesFile = GetProcAddress(
+ GetModuleHandle("ntdll"), "NtQueryAttributesFile");
+ }
+
+ FILE_BASIC_INFORMATION basic_information;
+ if(NT_SUCCESS(pNtQueryAttributesFile(obj, &basic_information))) {
+ return basic_information.FileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ }
+ return FALSE;
+}
+
+// hide our module from PEB
+// http://www.openrce.org/blog/view/844/How_to_hide_dll
+
+#define CUT_LIST(item) \
+ item.Blink->Flink = item.Flink; \
+ item.Flink->Blink = item.Blink
+
+void hide_module_from_peb(HMODULE module_handle)
+{
+ LDR_MODULE *mod; PEB *peb = (PEB *) __readfsdword(0x30);
+
+ for (mod = (LDR_MODULE *) peb->LoaderData->InLoadOrderModuleList.Flink;
+ mod->BaseAddress != NULL;
+ mod = (LDR_MODULE *) mod->InLoadOrderModuleList.Flink) {
+
+ if(mod->BaseAddress == module_handle) {
+ CUT_LIST(mod->InLoadOrderModuleList);
+ CUT_LIST(mod->InInitializationOrderModuleList);
+ CUT_LIST(mod->InMemoryOrderModuleList);
+
+ // TODO test whether this list is really used as a linked list
+ // like InLoadOrderModuleList etc
+ CUT_LIST(mod->HashTableEntry);
+
+ memset(mod, 0, sizeof(LDR_MODULE));
+ break;
+ }
+ }
+}
+
+uint32_t path_from_handle(HANDLE handle,
+ wchar_t *path, uint32_t path_buffer_len)
+{
+ static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(
+ _In_ HANDLE FileHandle,
+ _Out_ PIO_STATUS_BLOCK IoStatusBlock,
+ _Out_ PVOID FsInformation,
+ _In_ ULONG Length,
+ _In_ FS_INFORMATION_CLASS FsInformationClass
+ );
+
+ if(pNtQueryVolumeInformationFile == NULL) {
+ *(FARPROC *) &pNtQueryVolumeInformationFile = GetProcAddress(
+ GetModuleHandle("ntdll"), "NtQueryVolumeInformationFile");
+ }
+
+ static NTSTATUS (WINAPI *pNtQueryInformationFile)(
+ _In_ HANDLE FileHandle,
+ _Out_ PIO_STATUS_BLOCK IoStatusBlock,
+ _Out_ PVOID FileInformation,
+ _In_ ULONG Length,
+ _In_ FILE_INFORMATION_CLASS FileInformationClass
+ );
+
+ if(pNtQueryInformationFile == NULL) {
+ *(FARPROC *) &pNtQueryInformationFile = GetProcAddress(
+ GetModuleHandle("ntdll"), "NtQueryInformationFile");
+ }
+
+ IO_STATUS_BLOCK status = {};
+ FILE_FS_VOLUME_INFORMATION volume_information;
+
+ unsigned char buf[FILE_NAME_INFORMATION_REQUIRED_SIZE];
+ FILE_NAME_INFORMATION *name_information = (FILE_NAME_INFORMATION *) buf;
+
+ // get the volume serial number of the directory handle
+ if(NT_SUCCESS(pNtQueryVolumeInformationFile(handle, &status,
+ &volume_information, sizeof(volume_information),
+ FileFsVolumeInformation)) == 0) {
+ return 0;
+ }
+
+ unsigned long serial_number;
+
+ // enumerate all harddisks in order to find the
+ // corresponding serial number
+ wcscpy(path, L"?:\\");
+ for (path[0] = 'A'; path[0] <= 'Z'; path[0]++) {
+ if(GetVolumeInformationW(path, NULL, 0, &serial_number, NULL,
+ NULL, NULL, 0) == 0 ||
+ serial_number != volume_information.VolumeSerialNumber) {
+ continue;
+ }
+
+ // obtain the relative path for this filename on the given harddisk
+ if(NT_SUCCESS(pNtQueryInformationFile(handle, &status,
+ name_information, FILE_NAME_INFORMATION_REQUIRED_SIZE,
+ FileNameInformation))) {
+
+ uint32_t length =
+ name_information->FileNameLength / sizeof(wchar_t);
+
+ // NtQueryInformationFile omits the "C:" part in a
+ // filename, apparently
+ wcsncpy(path + 2, name_information->FileName,
+ path_buffer_len - 2);
+
+ return length + 2 < path_buffer_len ?
+ length + 2 : path_buffer_len - 1;
+ }
+ }
+ return 0;
+}
+
+uint32_t path_from_object_attributes(const OBJECT_ATTRIBUTES *obj,
+ wchar_t *path, uint32_t buffer_length)
+{
+ if(obj->ObjectName == NULL || obj->ObjectName->Buffer == NULL) {
+ return 0;
+ }
+
+ // ObjectName->Length is actually the size in bytes.
+ uint32_t obj_length = obj->ObjectName->Length / sizeof(wchar_t);
+
+ if(obj->RootDirectory == NULL) {
+ wcsncpy(path, obj->ObjectName->Buffer, buffer_length);
+ return obj_length > buffer_length ? buffer_length : obj_length;
+ }
+
+ uint32_t length = path_from_handle(obj->RootDirectory,
+ path, buffer_length);
+
+ path[length++] = L'\\';
+ wcsncpy(&path[length], obj->ObjectName->Buffer, buffer_length - length);
+
+ length += obj_length;
+ return length > buffer_length ? buffer_length : length;
+}
+
+int ensure_absolute_path(wchar_t *out, const wchar_t *in, int length)
+{
+ if(!wcsncmp(in, L"\\??\\", 4)) {
+ length -= 4, in += 4;
+ wcsncpy(out, in, length < MAX_PATH ? length : MAX_PATH);
+ return out[length] = 0, length;
+ }
+ else if(in[1] != ':' || (in[2] != '\\' && in[2] != '/')) {
+ wchar_t cur_dir[MAX_PATH], fname[MAX_PATH];
+ GetCurrentDirectoryW(ARRAYSIZE(cur_dir), cur_dir);
+
+ // ensure the filename is zero-terminated
+ wcsncpy(fname, in, length < MAX_PATH ? length : MAX_PATH);
+ fname[length] = 0;
+
+ PathCombineW(out, cur_dir, fname);
+ return lstrlenW(out);
+ }
+ else {
+ wcsncpy(out, in, length < MAX_PATH ? length : MAX_PATH);
+ return out[length] = 0, length;
+ }
+}
diff --git a/misc.h b/misc.h
new file mode 100644
index 0000000..aa6f8dd
--- /dev/null
+++ b/misc.h
@@ -0,0 +1,40 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+ULONG_PTR parent_process_id(); // By Napalm @ NetCore2K (rohitab.com)
+DWORD pid_from_process_handle(HANDLE process_handle);
+DWORD pid_from_thread_handle(HANDLE thread_handle);
+DWORD random();
+DWORD randint(DWORD min, DWORD max);
+BOOL is_directory_objattr(const OBJECT_ATTRIBUTES *obj);
+void hide_module_from_peb(HMODULE module_handle);
+
+uint32_t path_from_handle(HANDLE handle,
+ wchar_t *path, uint32_t path_buffer_len);
+
+uint32_t path_from_object_attributes(const OBJECT_ATTRIBUTES *obj,
+ wchar_t *path, uint32_t buffer_length);
+
+int ensure_absolute_path(wchar_t *out, const wchar_t *in, int length);
+
+// imported but for some doesn't show up when #including string.h etc
+int wcsnicmp(const wchar_t *a, const wchar_t *b, int len);
+int wcsicmp(const wchar_t *a, const wchar_t *b);
+
+// Define MAX_PATH plus tolerance for windows "tolerance"
+#define MAX_PATH_PLUS_TOLERANCE MAX_PATH + 64
diff --git a/netlog.py b/netlog.py
new file mode 100644
index 0000000..5ba65a1
--- /dev/null
+++ b/netlog.py
@@ -0,0 +1,87 @@
+"""Simple utility to generate code to communicate between C and Python.
+
+This utility generates C definitions and Python definitions in order to
+send integers, strings, lists, and other custom types over a socket.
+
+"""
+import logtbl
+import sys
+from struct import unpack
+
+
+def read_int32(buf, offset):
+ """Reads a 32bit integer from the buffer."""
+ return 4, unpack('I', buf[offset:offset+4])[0]
+
+
+def read_ptr(buf, offset):
+ """Read a pointer from the buffer."""
+ length, value = read_int32(buf, offset)
+ return length, '0x%08x' % value
+
+
+def read_string(buf, offset):
+ """Reads an utf8 string from the buffer."""
+ length, maxlength = unpack('HH', buf[offset:offset+8])
+ return length+4, (length, maxlength, buf[offset+4:offset+4+length])
+
+
+def read_buffer(buf, offset):
+ """Reads a memory buffer from the buffer."""
+ length, maxlength = unpack('HH', buf[offset:offset+8])
+ # only return the maxlength, as we don't log the actual buffer right now
+ return 4, maxlength
+
+
+def read_registry(buf, offset):
+ """Read logged registry data from the buffer."""
+ typ = unpack('H', buf[offset:offset+2])[0]
+ # do something depending on type
+ return
+
+
+def read_list(buf, offset, fn):
+ """Reads a list of _fn_ from the buffer."""
+ count = unpack('H', buf[offset:offset+2])[0]
+ ret, length = [], 0
+ for x in xrange(count):
+ item_length, item = fn(buf, offset+length)
+ length += item_length
+ ret.append(item)
+ return item_length+2, ret
+
+
+def parse_fmt(funcname, fmt, *args):
+ typ = {
+ 's': read_string,
+ 'S': read_string,
+ 'u': read_string,
+ 'U': read_string,
+ 'b': read_buffer,
+ 'B': read_buffer,
+ 'i': read_int32,
+ 'l': read_int32,
+ 'L': read_int32,
+ 'p': read_ptr,
+ 'P': read_ptr,
+ 'o': read_string,
+ 'O': read_string,
+ 'a': None,
+ 'A': None,
+ 'r': read_registry,
+ 'R': read_registry,
+ }
+
+
+def generate_c_code(fname):
+ lines = ['#include ', '', 'const char *logtbl[][2] = {']
+ for index, (funcname, module, args) in enumerate(logtbl.table):
+ lines.append(' {"%s", "%s"},' % (funcname, module))
+ lines.append(' {NULL, NULL},')
+ lines.append('};')
+ lines.append('char logtbl_explained[sizeof(logtbl)/sizeof(char *)] = {0};')
+ open(fname, 'w').write('\n'.join(lines) + '\n')
+
+if __name__ == '__main__':
+ if sys.argv[1] == 'c-header':
+ generate_c_code(sys.argv[2])
diff --git a/ntapi.h b/ntapi.h
new file mode 100644
index 0000000..6e42f4a
--- /dev/null
+++ b/ntapi.h
@@ -0,0 +1,470 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+
+#ifndef __NTAPI_H__
+#define __NTAPI_H__
+
+typedef LONG NTSTATUS;
+
+#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
+
+#define __out
+#define __in
+#define __in_opt
+#define __reserved
+#define __out_opt
+#define __inout
+#define __inout_opt
+#define _In_
+#define _In_opt_
+#define _Out_
+#define _Out_opt_
+#define _Inout_opt_
+#define _Reserved_
+
+typedef struct _STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PCHAR Buffer;
+} ANSI_STRING, *PANSI_STRING;
+
+typedef struct _LSA_UNICODE_STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
+
+typedef struct _IO_STATUS_BLOCK {
+ union {
+ NTSTATUS Status;
+ PVOID Pointer;
+ };
+ ULONG_PTR Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+typedef struct _OBJECT_ATTRIBUTES {
+ ULONG Length;
+ HANDLE RootDirectory;
+ PUNICODE_STRING ObjectName;
+ ULONG Attributes;
+ PVOID SecurityDescriptor;
+ PVOID SecurityQualityOfService;
+} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
+
+// for now..
+typedef void *PIO_APC_ROUTINE;
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+typedef void *HINTERNET;
+
+typedef struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct addrinfo *ai_next;
+} ADDRINFOA, *PADDRINFOA;
+
+typedef struct addrinfoW {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ PWSTR ai_canonname;
+ struct sockaddr *ai_addr;
+ struct addrinfoW *ai_next;
+} ADDRINFOW, *PADDRINFOW;
+
+typedef enum _KEY_INFORMATION_CLASS {
+ KeyBasicInformation = 0,
+ KeyNodeInformation = 1,
+ KeyFullInformation = 2,
+ KeyNameInformation = 3,
+ KeyCachedInformation = 4,
+ KeyFlagsInformation = 5,
+ KeyVirtualizationInformation = 6,
+ KeyHandleTagsInformation = 7,
+ MaxKeyInfoClass = 8
+} KEY_INFORMATION_CLASS;
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS {
+ KeyValueBasicInformation = 0,
+ KeyValueFullInformation = 1,
+ KeyValuePartialInformation = 2,
+ KeyValueFullInformationAlign64 = 3,
+ KeyValuePartialInformationAlign64 = 4,
+ MaxKeyValueInfoClass = 5
+} KEY_VALUE_INFORMATION_CLASS;
+
+typedef struct _KEY_VALUE_BASIC_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG NameLength;
+ WCHAR Name[1];
+} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
+
+typedef struct _KEY_VALUE_FULL_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG DataOffset;
+ ULONG DataLength;
+ ULONG NameLength;
+ WCHAR Name[1];
+} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
+
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
+ ULONG TitleIndex;
+ ULONG Type;
+ ULONG DataLength;
+ UCHAR Data[1];
+} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
+
+typedef struct _KEY_VALUE_ENTRY {
+ PUNICODE_STRING ValueName;
+ ULONG DataLength;
+ ULONG DataOffset;
+ ULONG Type;
+} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
+
+typedef struct _PROCESS_BASIC_INFORMATION {
+ PVOID Reserved1;
+ void *PebBaseAddress;
+ PVOID Reserved2[2];
+ ULONG_PTR UniqueProcessId;
+ PVOID Reserved3;
+} PROCESS_BASIC_INFORMATION;
+
+typedef struct _CLIENT_ID {
+ PVOID UniqueProcess;
+ PVOID UniqueThread;
+} CLIENT_ID, *PCLIENT_ID;
+
+typedef ULONG_PTR KAFFINITY;
+typedef LONG KPRIORITY;
+
+typedef struct _THREAD_BASIC_INFORMATION {
+ NTSTATUS ExitStatus;
+ PVOID TebBaseAddress;
+ CLIENT_ID ClientId;
+ KAFFINITY AffinityMask;
+ KPRIORITY Priority;
+ KPRIORITY BasePriority;
+} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
+
+typedef struct _INITIAL_TEB {
+ PVOID StackBase;
+ PVOID StackLimit;
+ PVOID StackCommit;
+ PVOID StackCommitMax;
+ PVOID StackReserved;
+} INITIAL_TEB, *PINITIAL_TEB;
+
+typedef enum _FILE_INFORMATION_CLASS {
+ FileDirectoryInformation = 1,
+ FileFullDirectoryInformation,
+ FileBothDirectoryInformation,
+ FileBasicInformation,
+ FileStandardInformation,
+ FileInternalInformation,
+ FileEaInformation,
+ FileAccessInformation,
+ FileNameInformation,
+ FileRenameInformation,
+ FileLinkInformation,
+ FileNamesInformation,
+ FileDispositionInformation,
+ FilePositionInformation,
+ FileFullEaInformation,
+ FileModeInformation,
+ FileAlignmentInformation,
+ FileAllInformation,
+ FileAllocationInformation,
+ FileEndOfFileInformation,
+ FileAlternateNameInformation,
+ FileStreamInformation,
+ FilePipeInformation,
+ FilePipeLocalInformation,
+ FilePipeRemoteInformation,
+ FileMailslotQueryInformation,
+ FileMailslotSetInformation,
+ FileCompressionInformation,
+ FileObjectIdInformation,
+ FileCompletionInformation,
+ FileMoveClusterInformation,
+ FileQuotaInformation,
+ FileReparsePointInformation,
+ FileNetworkOpenInformation,
+ FileAttributeTagInformation,
+ FileTrackingInformation,
+ FileIdBothDirectoryInformation,
+ FileIdFullDirectoryInformation,
+ FileValidDataLengthInformation,
+ FileShortNameInformation,
+ FileIoCompletionNotificationInformation,
+ FileIoStatusBlockRangeInformation,
+ FileIoPriorityHintInformation,
+ FileSfioReserveInformation,
+ FileSfioVolumeInformation,
+ FileHardLinkInformation,
+ FileProcessIdsUsingFileInformation,
+ FileNormalizedNameInformation,
+ FileNetworkPhysicalNameInformation,
+ FileIdGlobalTxDirectoryInformation,
+ FileIsRemoteDeviceInformation,
+ FileAttributeCacheInformation,
+ FileNumaNodeInformation,
+ FileStandardLinkInformation,
+ FileRemoteProtocolInformation,
+ FileMaximumInformation
+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
+
+#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022)
+
+typedef struct _FILE_BASIC_INFORMATION {
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ ULONG FileAttributes;
+} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
+
+typedef struct _RTL_DRIVE_LETTER_CURDIR {
+ USHORT Flags;
+ USHORT Length;
+ ULONG TimeStamp;
+ UNICODE_STRING DosPath;
+} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
+
+typedef struct _RTL_USER_PROCESS_PARAMETERS {
+ ULONG MaximumLength;
+ ULONG Length;
+ ULONG Flags;
+ ULONG DebugFlags;
+ PVOID ConsoleHandle;
+ ULONG ConsoleFlags;
+ HANDLE StdInputHandle;
+ HANDLE StdOutputHandle;
+ HANDLE StdErrorHandle;
+ UNICODE_STRING CurrentDirectoryPath;
+ HANDLE CurrentDirectoryHandle;
+ UNICODE_STRING DllPath;
+ UNICODE_STRING ImagePathName;
+ UNICODE_STRING CommandLine;
+ PVOID Environment;
+ ULONG StartingPositionLeft;
+ ULONG StartingPositionTop;
+ ULONG Width;
+ ULONG Height;
+ ULONG CharWidth;
+ ULONG CharHeight;
+ ULONG ConsoleTextAttributes;
+ ULONG WindowFlags;
+ ULONG ShowWindowFlags;
+ UNICODE_STRING WindowTitle;
+ UNICODE_STRING DesktopName;
+ UNICODE_STRING ShellInfo;
+ UNICODE_STRING RuntimeData;
+ RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
+} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
+
+typedef void *PPS_CREATE_INFO, *PPS_ATTRIBUTE_LIST;
+
+typedef void *PVOID, **PPVOID;
+
+typedef struct _PEB_LDR_DATA {
+ ULONG Length;
+ BOOLEAN Initialized;
+ PVOID SsHandle;
+ LIST_ENTRY InLoadOrderModuleList;
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+} PEB_LDR_DATA, *PPEB_LDR_DATA;
+
+typedef struct _LDR_MODULE {
+ LIST_ENTRY InLoadOrderModuleList;
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+ PVOID BaseAddress;
+ PVOID EntryPoint;
+ ULONG SizeOfImage;
+ UNICODE_STRING FullDllName;
+ UNICODE_STRING BaseDllName;
+ ULONG Flags;
+ SHORT LoadCount;
+ SHORT TlsIndex;
+ LIST_ENTRY HashTableEntry;
+ ULONG TimeDateStamp;
+} LDR_MODULE, *PLDR_MODULE;
+
+typedef struct _PEB {
+ BOOLEAN InheritedAddressSpace;
+ BOOLEAN ReadImageFileExecOptions;
+ BOOLEAN BeingDebugged;
+ BOOLEAN Spare;
+ HANDLE Mutant;
+ PVOID ImageBaseAddress;
+ PPEB_LDR_DATA LoaderData;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
+ PVOID SubSystemData;
+ PVOID ProcessHeap;
+ PVOID FastPebLock;
+ void *FastPebLockRoutine;
+ void *FastPebUnlockRoutine;
+ ULONG EnvironmentUpdateCount;
+ PPVOID KernelCallbackTable;
+ PVOID EventLogSection;
+ PVOID EventLog;
+ void *FreeList;
+ ULONG TlsExpansionCounter;
+ PVOID TlsBitmap;
+ ULONG TlsBitmapBits[0x2];
+ PVOID ReadOnlySharedMemoryBase;
+ PVOID ReadOnlySharedMemoryHeap;
+ PPVOID ReadOnlyStaticServerData;
+ PVOID AnsiCodePageData;
+ PVOID OemCodePageData;
+ PVOID UnicodeCaseTableData;
+ ULONG NumberOfProcessors;
+ ULONG NtGlobalFlag;
+ BYTE Spare2[0x4];
+ LARGE_INTEGER CriticalSectionTimeout;
+ ULONG HeapSegmentReserve;
+ ULONG HeapSegmentCommit;
+ ULONG HeapDeCommitTotalFreeThreshold;
+ ULONG HeapDeCommitFreeBlockThreshold;
+ ULONG NumberOfHeaps;
+ ULONG MaximumNumberOfHeaps;
+ PPVOID *ProcessHeaps;
+ PVOID GdiSharedHandleTable;
+ PVOID ProcessStarterHelper;
+ PVOID GdiDCAttributeList;
+ PVOID LoaderLock;
+ ULONG OSMajorVersion;
+ ULONG OSMinorVersion;
+ ULONG OSBuildNumber;
+ ULONG OSPlatformId;
+ ULONG ImageSubSystem;
+ ULONG ImageSubSystemMajorVersion;
+ ULONG ImageSubSystemMinorVersion;
+ ULONG GdiHandleBuffer[0x22];
+ ULONG PostProcessInitRoutine;
+ ULONG TlsExpansionBitmap;
+ BYTE TlsExpansionBitmapBits[0x80];
+ ULONG SessionId;
+} PEB, *PPEB;
+
+static inline unsigned int __readfsdword(unsigned int index)
+{
+ unsigned int ret;
+ __asm__("movl %%fs:(%1), %0" : "=r" (ret) : "r" (index));
+ return ret;
+}
+
+static inline void __writefsdword(unsigned int index, unsigned int value)
+{
+ __asm__("movl %0, %%fs:(%1)" :: "r" (value), "r" (index));
+}
+
+typedef struct _SECTION_IMAGE_INFORMATION {
+ VOID* TransferAddress;
+ uint32_t ZeroBits;
+ uint8_t _PADDING0_[0x4];
+ uint64_t MaximumStackSize;
+ uint64_t CommittedStackSize;
+ uint32_t SubSystemType;
+ union {
+ struct {
+ uint16_t SubSystemMinorVersion;
+ uint16_t SubSystemMajorVersion;
+ };
+ uint32_t SubSystemVersion;
+ };
+ uint32_t GpValue;
+ uint16_t ImageCharacteristics;
+ uint16_t DllCharacteristics;
+ uint16_t Machine;
+ uint8_t ImageContainsCode;
+ union {
+ uint8_t ImageFlags;
+ struct {
+ uint8_t ComPlusNativeReady : 1;
+ uint8_t ComPlusILOnly : 1;
+ uint8_t ImageDynamicallyRelocated : 1;
+ uint8_t ImageMappedFlat : 1;
+ uint8_t Reserved : 4;
+ };
+ };
+ uint32_t LoaderFlags;
+ uint32_t ImageFileSize;
+ uint32_t CheckSum;
+} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
+
+typedef struct _RTL_USER_PROCESS_INFORMATION {
+ ULONG Size;
+ HANDLE ProcessHandle;
+ HANDLE ThreadHandle;
+ CLIENT_ID ClientId;
+ SECTION_IMAGE_INFORMATION ImageInformation;
+} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
+
+#define FILE_NAME_INFORMATION_REQUIRED_SIZE \
+ sizeof(FILE_NAME_INFORMATION) + sizeof(wchar_t) * MAX_PATH
+
+typedef struct _FILE_NAME_INFORMATION {
+ ULONG FileNameLength;
+ WCHAR FileName[1];
+} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
+
+typedef enum {
+ FileFsVolumeInformation = 1,
+ FileFsLabelInformation = 2,
+ FileFsSizeInformation = 3,
+ FileFsDeviceInformation = 4,
+ FileFsAttributeInformation = 5,
+ FileFsControlInformation = 6,
+ FileFsFullSizeInformation = 7,
+ FileFsObjectIdInformation = 8,
+ FileFsDriverPathInformation = 9,
+ FileFsVolumeFlagsInformation = 10,
+ FileFsSectorSizeInformation = 11
+} FS_INFORMATION_CLASS;
+
+typedef struct _FILE_FS_VOLUME_INFORMATION {
+ LARGE_INTEGER VolumeCreationTime;
+ ULONG VolumeSerialNumber;
+ ULONG VolumeLabelLength;
+ BOOLEAN SupportsObjects;
+ WCHAR VolumeLabel[1];
+} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
+
+static inline UNICODE_STRING *unistr_from_objattr(OBJECT_ATTRIBUTES *obj)
+{
+ return obj != NULL ? obj->ObjectName : NULL;
+}
+
+#endif
diff --git a/pipe.c b/pipe.c
new file mode 100644
index 0000000..86fe2ea
--- /dev/null
+++ b/pipe.c
@@ -0,0 +1,154 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "ntapi.h"
+#include "pipe.h"
+#include "utf8.h"
+#include "misc.h"
+
+const char *g_pipe_name;
+
+static int _pipe_utf8x(char **out, unsigned short x)
+{
+ unsigned char buf[3];
+ int len = utf8_encode(x, buf);
+ if(*out != NULL) {
+ memcpy(*out, buf, len);
+ *out += len;
+ }
+ return len;
+}
+
+static int _pipe_ascii(char **out, const char *s, int len)
+{
+ int ret = 0;
+ while (len-- != 0) {
+ ret += _pipe_utf8x(out, *(unsigned char *) s++);
+ }
+ return ret;
+}
+
+static int _pipe_unicode(char **out, const wchar_t *s, int len)
+{
+ int ret = 0;
+ while (len-- != 0) {
+ ret += _pipe_utf8x(out, *(unsigned short *) s++);
+ }
+ return ret;
+}
+
+static int _pipe_sprintf(char *out, const char *fmt, va_list args)
+{
+ int ret = 0;
+ while (*fmt != 0) {
+ if(*fmt != '%') {
+ ret += _pipe_utf8x(&out, *fmt++);
+ continue;
+ }
+ if(*++fmt == 'z') {
+ const char *s = va_arg(args, const char *);
+ if(s == NULL) return -1;
+
+ ret += _pipe_ascii(&out, s, strlen(s));
+ }
+ else if(*fmt == 'Z') {
+ const wchar_t *s = va_arg(args, const wchar_t *);
+ if(s == NULL) return -1;
+
+ ret += _pipe_unicode(&out, s, lstrlenW(s));
+ }
+ else if(*fmt == 's') {
+ int len = va_arg(args, int);
+ const char *s = va_arg(args, const char *);
+ if(s == NULL) return -1;
+
+ ret += _pipe_ascii(&out, s, len < 0 ? strlen(s) : len);
+ }
+ else if(*fmt == 'S') {
+ int len = va_arg(args, int);
+ const wchar_t *s = va_arg(args, const wchar_t *);
+ if(s == NULL) return -1;
+
+ ret += _pipe_unicode(&out, s, len < 0 ? lstrlenW(s) : len);
+ }
+ else if(*fmt == 'o') {
+ UNICODE_STRING *str = va_arg(args, UNICODE_STRING *);
+ if(str == NULL) return -1;
+
+ ret += _pipe_unicode(&out, str->Buffer,
+ str->Length / sizeof(wchar_t));
+ }
+ else if(*fmt == 'O') {
+ OBJECT_ATTRIBUTES *obj = va_arg(args, OBJECT_ATTRIBUTES *);
+ if(obj == NULL || obj->ObjectName == NULL) return -1;
+
+ wchar_t path[MAX_PATH_PLUS_TOLERANCE]; int length;
+ length = path_from_object_attributes(obj, path, (unsigned int) MAX_PATH_PLUS_TOLERANCE);
+
+ length = ensure_absolute_path(path, path, length);
+
+ ret += _pipe_unicode(&out, path, length);
+ }
+ else if(*fmt == 'd') {
+ char s[32];
+ sprintf(s, "%d", va_arg(args, int));
+ ret += _pipe_ascii(&out, s, strlen(s));
+ }
+ else if(*fmt == 'x') {
+ char s[16];
+ sprintf(s, "%x", va_arg(args, int));
+ ret += _pipe_ascii(&out, s, strlen(s));
+ }
+ fmt++;
+ }
+ return ret;
+}
+
+int pipe(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ int len = _pipe_sprintf(NULL, fmt, args);
+ if(len > 0) {
+ char buf[len + 1];
+ _pipe_sprintf(buf, fmt, args);
+ va_end(args);
+
+ return CallNamedPipe(g_pipe_name, buf, len, buf, len,
+ (unsigned long *) &len, NMPWAIT_WAIT_FOREVER);
+ }
+ return -1;
+}
+
+int pipe2(void *out, int *outlen, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ int len = _pipe_sprintf(NULL, fmt, args);
+ if(len > 0) {
+ char buf[len + 1];
+ _pipe_sprintf(buf, fmt, args);
+ va_end(args);
+
+ return CallNamedPipe(g_pipe_name, buf, len, out, *outlen,
+ (DWORD *) outlen, NMPWAIT_WAIT_FOREVER);
+ }
+ return -1;
+}
diff --git a/pipe.h b/pipe.h
new file mode 100644
index 0000000..d4282d3
--- /dev/null
+++ b/pipe.h
@@ -0,0 +1,38 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+//
+// Pipe API
+//
+// The following Format Specifiers are available:
+// z -> (char *) -> zero-terminated ascii string
+// Z -> (wchar_t *) -> zero-terminated unicode string
+// s -> (int, char *) -> ascii string with length
+// S -> (int, wchar_t *) -> unicode string with length
+// o -> (UNICODE_STRING *) -> unicode string
+// O -> (OBJECT_ATTRIBUTES *) -> wrapper around unicode string
+// d -> (int) -> integer
+// x -> (int) -> hexadecimal integer
+//
+
+int pipe(const char *fmt, ...);
+int pipe2(void *out, int *outlen, const char *fmt, ...);
+
+#define PIPE_MAX_TIMEOUT 10000
+
+extern const char *g_pipe_name;
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..201f863
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,26 @@
+MAKEFLAGS = -j8
+CFLAGS = -Wall -std=c99 -s -O2
+LIBS = -ldnsapi -lws2_32 -lwininet -lshlwapi
+
+ifneq ($(OS),Windows_NT)
+ CC = i586-mingw32msvc-cc
+else
+ CC = gcc
+endif
+
+TESTS = $(wildcard *.c)
+TESTSEXE = $(TESTS:.c=.exe)
+
+# please build all the object files using the main Makefile (in the parent
+# directory)
+CUCKOOOBJ := $(wildcard ../objects/*.o)
+CUCKOOOBJ += $(wildcard ../objects/bson/*.o)
+CUCKOOOBJ += $(wildcard ../objects/distorm3.2/*.o)
+
+all: $(TESTSEXE)
+
+%.exe: %.c $(CUCKOOOBJ) $(DISTORM3OBJ)
+ $(CC) $(CFLAGS) -I../distorm3.2-package/include -I.. -o $@ $^ $(LIBS)
+
+clean:
+ rm -f $(TESTSEXE)
diff --git a/tests/apc-inject.c b/tests/apc-inject.c
new file mode 100644
index 0000000..50e95c1
--- /dev/null
+++ b/tests/apc-inject.c
@@ -0,0 +1,39 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#define _WIN32_WINNT 0x0500
+#include
+#include
+#include
+
+int main()
+{
+ LoadLibrary("../cuckoomon.dll");
+
+ FARPROC sleep = GetProcAddress(GetModuleHandle("kernel32"), "Sleep");
+
+ for (uint32_t tid = 2000; ; tid += 4) {
+ HANDLE thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
+ if(thread_handle != NULL) {
+ printf("tid %d .. :)\n", tid);
+ QueueUserAPC((PAPCFUNC) sleep, thread_handle, 1337);
+ CloseHandle(thread_handle);
+ break;
+ }
+ }
+}
diff --git a/tests/apihooks.c b/tests/apihooks.c
new file mode 100644
index 0000000..61ac3b0
--- /dev/null
+++ b/tests/apihooks.c
@@ -0,0 +1,64 @@
+#include
+#include
+#include
+
+DWORD WINAPI dummy(LPVOID lpValue)
+{
+ printf("dummy here!\n");
+ return 0;
+}
+
+int main()
+{
+ // there we go
+ LoadLibrary("../cuckoomon.dll");
+
+ FILE *fp = fopen("test-hello", "r");
+ if(fp != NULL) fclose(fp);
+
+ fp = fopen("test-hello", "wb");
+ fwrite("whatsup", 1, 6, fp);
+ fclose(fp);
+
+ fp = fopen("test-hello", "rb");
+ char buf[6];
+ fread(buf, 1, 6, fp);
+ fclose(fp);
+
+ _mkdir("abc");
+
+ DeleteFile("test-hello");
+
+ HKEY hKey;
+ if(RegCreateKeyEx(HKEY_CURRENT_USER,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0,
+ KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) {
+ RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ RegSetValueEx(hKey, "TestApiHooks", 0, REG_SZ, (BYTE *) "Hoi", 3);
+ RegDeleteValue(hKey, "TestApiHooks");
+ RegCloseKey(hKey);
+ }
+
+ system("echo hai");
+
+ WinExec("echo hi there", SW_SHOW);
+
+ CreateMutex(NULL, FALSE, "MutexNam3");
+ OpenMutex(MUTEX_ALL_ACCESS, FALSE, "OpenMutexName");
+
+ // just some random dll
+ LoadLibrary("urlmon.dll");
+
+ FARPROC sleep = GetProcAddress(GetModuleHandle("kernel32"), "Sleep");
+ sleep(1000);
+
+ printf("debugger: %d\n", IsDebuggerPresent());
+
+ CloseHandle(CreateThread(NULL, 0, &dummy, NULL, 0, NULL));
+
+ HANDLE thread_handle = CreateRemoteThread(GetCurrentProcess(), NULL, 0,
+ &dummy, NULL, 0, NULL);
+ WaitForSingleObject(thread_handle, INFINITE);
+ CloseHandle(thread_handle);
+}
diff --git a/tests/bind-port.c b/tests/bind-port.c
new file mode 100644
index 0000000..16d461d
--- /dev/null
+++ b/tests/bind-port.c
@@ -0,0 +1,17 @@
+#include
+#include
+
+int main()
+{
+ WSADATA wsa;
+ WSAStartup(MAKEWORD(2, 2), &wsa);
+
+ SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
+
+ struct sockaddr_in addr = {};
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = 0;
+ addr.sin_port = htons(0x29a);
+
+ bind(s, (struct sockaddr *) &addr, sizeof(addr));
+}
diff --git a/tests/blacklist.c b/tests/blacklist.c
new file mode 100644
index 0000000..ee4530a
--- /dev/null
+++ b/tests/blacklist.c
@@ -0,0 +1,18 @@
+#include
+#include
+#include
+#include "ignore.h"
+#include "ntapi.h"
+
+int main()
+{
+ const wchar_t *unicode[] = {
+ L"abcd",
+ L"\\??\\IDE#what's up bro?",
+ };
+ for (int i = 0; i < ARRAYSIZE(unicode); i++) {
+ printf("%d <= %S\n",
+ is_ignored_file_unicode(unicode[i], wcslen(unicode[i])),
+ unicode[i]);
+ }
+}
diff --git a/tests/child-sleep.c b/tests/child-sleep.c
new file mode 100644
index 0000000..40206d3
--- /dev/null
+++ b/tests/child-sleep.c
@@ -0,0 +1,16 @@
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ if(argc == 4) {
+ Sleep(5000);
+ return 0;
+ }
+
+ Sleep(10000);
+
+ char buf[256];
+ sprintf(buf, "%s a b c", argv[0]);
+ system(buf);
+}
diff --git a/tests/crash.c b/tests/crash.c
new file mode 100644
index 0000000..4e8baeb
--- /dev/null
+++ b/tests/crash.c
@@ -0,0 +1,7 @@
+#include
+
+int main()
+{
+ char *p = NULL;
+ *p = 0;
+}
diff --git a/tests/create-file.c b/tests/create-file.c
new file mode 100644
index 0000000..257af06
--- /dev/null
+++ b/tests/create-file.c
@@ -0,0 +1,24 @@
+#include
+#include
+
+int main()
+{
+ const char *modes[] = {"r", "r+", "w", "w+", "a", "a+"};
+ const char *fname = "abc";
+
+ for (int i = 0; i < sizeof(modes)/sizeof(char *); i++) {
+ DeleteFile(fname);
+ FILE *fp = fopen(fname, modes[i]);
+ if(fp != NULL) {
+ fclose(fp);
+ }
+ }
+
+ fclose(fopen(fname, "w"));
+ for (int i = 0; i < sizeof(modes)/sizeof(char *); i++) {
+ FILE *fp = fopen(fname, modes[i]);
+ if(fp != NULL) {
+ fclose(fp);
+ }
+ }
+}
diff --git a/tests/delete-file.c b/tests/delete-file.c
new file mode 100644
index 0000000..3d7627d
--- /dev/null
+++ b/tests/delete-file.c
@@ -0,0 +1,150 @@
+#include
+#include
+#include "../ntapi.h"
+
+#define OBJ_CASE_INSENSITIVE 0x00000040
+#define OBJ_KERNEL_HANDLE 0x00000200
+
+#define InitializeObjectAttributes(p, n, a, r, s) { \
+ (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
+ (p)->RootDirectory = r; \
+ (p)->Attributes = a; \
+ (p)->ObjectName = n; \
+ (p)->SecurityDescriptor = s; \
+ (p)->SecurityQualityOfService = NULL; \
+ }
+
+VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING DestinationString,
+ PCWSTR SourceString);
+
+NTSTATUS (WINAPI *pZwDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes);
+
+NTSTATUS (WINAPI *pZwCreateFile)(PHANDLE FileHandle,
+ ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
+ PIO_STATUS_BLOCK IoStatusBlock, PVOID AllocationSize,
+ ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition,
+ ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
+
+NTSTATUS (WINAPI *pZwSetInformationFile)(HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass);
+
+void write_file(const char *fname, const char *s)
+{
+ FILE *fp = fopen(fname, "wb");
+ if(fp != NULL) {
+ fputs(s, fp);
+ fclose(fp);
+ }
+}
+
+int main()
+{
+ printf(
+ "Going to try to delete files using various techiques.\n"
+ "Note that the MoveFileEx method will fail (see source why)\n"
+ );
+
+ write_file("abc.txt", "DeleteFile");
+
+ //
+ // delete the file using the well-known DeleteFile function
+ //
+
+ printf("DeleteFile: %s (0x%08x)\n", DeleteFile("abc.txt") ?
+ "SUCCESS" : "FAILURE", GetLastError());
+
+ write_file("abc.txt", "MoveFileEx");
+
+ //
+ // delete the file using MoveFileEx, note that a NULL destination filename
+ // is only supported when the MOVEFILE_DELAY_UNTIL_REBOOT flag is set.
+ // (so this call will actually fail..)
+ //
+
+ printf("MoveFileEx: %s (0x%08x)\n", MoveFileEx("abc.txt", NULL, 0) ?
+ "SUCCESS" : "FAILURE", GetLastError());
+
+ write_file("abc.txt", "ZwDeleteFile");
+
+ //
+ // delete the file using ZwDeleteFile
+ //
+
+ UNICODE_STRING dir_fname, file_fname;
+ OBJECT_ATTRIBUTES obj_dir, obj_file;
+ IO_STATUS_BLOCK io_dir;
+ HANDLE dir_handle;
+
+ *(FARPROC *) &pRtlInitUnicodeString = GetProcAddress(
+ GetModuleHandle("ntdll"), "RtlInitUnicodeString");
+ *(FARPROC *) &pZwDeleteFile = GetProcAddress(
+ GetModuleHandle("ntdll"), "ZwDeleteFile");
+ *(FARPROC *) &pZwCreateFile = GetProcAddress(
+ GetModuleHandle("ntdll"), "ZwCreateFile");
+ *(FARPROC *) &pZwSetInformationFile = GetProcAddress(
+ GetModuleHandle("ntdll"), "ZwSetInformationFile");
+
+ // prepend the path with "\\??\\"
+ wchar_t cur_dir[MAX_PATH] = L"\\??\\";
+ GetCurrentDirectoryW(MAX_PATH-4, cur_dir+4);
+
+ pRtlInitUnicodeString(&dir_fname, cur_dir);
+ pRtlInitUnicodeString(&file_fname, L"abc.txt");
+
+ InitializeObjectAttributes(&obj_dir, &dir_fname,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ // open the directory
+ NTSTATUS ret = pZwCreateFile(&dir_handle, FILE_TRAVERSE, &obj_dir,
+ &io_dir, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN,
+ FILE_DIRECTORY_FILE, NULL, 0);
+
+ if(NT_SUCCESS(ret)) {
+ InitializeObjectAttributes(&obj_file, &file_fname,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, dir_handle, NULL);
+
+ // delete the file
+ ret = pZwDeleteFile(&obj_file);
+ printf("ZwDeleteFile: %s (0x%08x)\n", NT_SUCCESS(ret) ?
+ "SUCCESS" : "FAILURE", ret);
+ CloseHandle(dir_handle);
+ }
+ else {
+ printf("ZwDeleteFile: FAILURE (0x%08x)\n", ret);
+ }
+
+ write_file("abc.txt", "ZwSetInformationFile");
+
+ //
+ // delete the file using ZwSetInformationFile
+ //
+
+ IO_STATUS_BLOCK io_file;
+ HANDLE file_handle;
+
+ // prepend the path with "\\??\\" and append "abc.txt"
+ wchar_t file_name[MAX_PATH] = L"\\??\\";
+ GetCurrentDirectoryW(MAX_PATH-4, file_name+4);
+ lstrcatW(file_name, L"\\abc.txt");
+
+ pRtlInitUnicodeString(&file_fname, file_name);
+ InitializeObjectAttributes(&obj_file, &file_fname,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ // open the file with DELETE access rights
+ ret = pZwCreateFile(&file_handle, DELETE, &obj_file, &io_file, NULL,
+ FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, NULL, 0);
+ if(NT_SUCCESS(ret)) {
+ BOOLEAN disp_info = TRUE;
+ ret = pZwSetInformationFile(file_handle, &io_file, &disp_info,
+ sizeof(disp_info), FileDispositionInformation);
+ CloseHandle(file_handle);
+
+ printf("ZwSetInformationFile: %s (0x%08x)\n", NT_SUCCESS(ret) ?
+ "SUCCESS" : "FAILURE", ret);
+ }
+ else {
+ printf("ZwSetInformationFile: FAILURE (0x%08x)\n", ret);
+ }
+}
diff --git a/tests/getcursorpos.c b/tests/getcursorpos.c
new file mode 100644
index 0000000..2773b7e
--- /dev/null
+++ b/tests/getcursorpos.c
@@ -0,0 +1,29 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+
+int main()
+{
+ for (int i = 0; i < 10; i++) {
+ POINT p = {}; GetCursorPos(&p);
+ printf("{x: %ld, y: %ld}\n", p.x, p.y);
+ Sleep(100);
+ }
+}
diff --git a/tests/logging.c b/tests/logging.c
new file mode 100644
index 0000000..9244248
--- /dev/null
+++ b/tests/logging.c
@@ -0,0 +1,33 @@
+#include
+#include
+#include "../log.h"
+
+const char *module_name = "logging";
+
+int main()
+{
+ int is_success(int ret) { return 1; }
+ int ret = 0;
+
+ log_init(0, 0, 1);
+
+ LOQ("2s", "a", "b", "c", "d");
+ LOQ("S", "a", 4, "hello");
+ LOQ("U", "b", 4, L"ab\u1337c");
+ LOQ("s", "c", NULL);
+ LOQ("lUl", "a", 32, "b", 6, L"HelloWorld", "c", 32);
+
+ // utf8 encoding examples from wikipedia, should result in the following:
+ // "\x24\xc2\xa2\xe2\x82\xac"
+ LOQ("u", "a", L"\u0024\u00a2\u20ac");
+
+ int argc = 4;
+ char *argv[] = {"a", "b", "c", "d"};
+ LOQ("a", "a", argc, argv);
+
+ // registry stuff
+ LOQ("r", "a", REG_SZ, 0, "lolz");
+ LOQ("r", "a", REG_DWORD, 4, "\x10\x00\x00\x00");
+ LOQ("R", "a", REG_SZ, 1337, L"omgz0r");
+ LOQ("R", "a", REG_BINARY, 8, "Hello World");
+}
diff --git a/tests/lookup.c b/tests/lookup.c
new file mode 100644
index 0000000..cbd43e9
--- /dev/null
+++ b/tests/lookup.c
@@ -0,0 +1,31 @@
+#include
+#include
+#include "lookup.h"
+
+typedef struct _entry_t {
+ struct _entry_t *next;
+ unsigned int id;
+ unsigned int size;
+ unsigned char data[0];
+} entry_t;
+
+int main()
+{
+ lookup_t a;
+
+ lookup_init(&a);
+ strcpy((char *) lookup_add(&a, 1, 10), "abc");
+ strcpy((char *) lookup_add(&a, 2, 20), "def");
+ lookup_del(&a, 1);
+ strcpy((char *) lookup_add(&a, 3, 30), "ghi");
+ strcpy((char *) lookup_add(&a, 4, 40), "jkl");
+ lookup_del(&a, 4);
+
+ for (int i = 0; i < 5; i++) {
+ printf("%d -> %p\n", i, lookup_get(&a, i, NULL));
+ }
+
+ for (entry_t *p = a.root; p != NULL; p = p->next) {
+ printf("%p %d %d\n", p, p->id, p->size);
+ }
+}
diff --git a/tests/migrate-process.c b/tests/migrate-process.c
new file mode 100644
index 0000000..9734fe4
--- /dev/null
+++ b/tests/migrate-process.c
@@ -0,0 +1,8 @@
+#include
+#include
+
+int main()
+{
+ // process identifier of explorer.exe on my VM
+ CloseHandle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, 468));
+}
diff --git a/tests/mitigate-process.c b/tests/mitigate-process.c
new file mode 100644
index 0000000..5336c06
--- /dev/null
+++ b/tests/mitigate-process.c
@@ -0,0 +1,32 @@
+#include
+#include
+
+/* multiple ways to inject into another process */
+
+int main(int argc, char *argv[])
+{
+ if(argc == 2) {
+ printf("Child process %s.. exiting..\n", argv[1]);
+ ExitProcess(0);
+ }
+
+ char buf[256];
+
+ // WinExec
+ sprintf(buf, "\"%s\" a", argv[0]);
+ WinExec(buf, SW_SHOW);
+
+ // ShellExecute
+ ShellExecute(NULL, NULL, argv[0], "b", NULL, SW_SHOW);
+
+ // CreateProcess
+ sprintf(buf, "\"%s\" c", argv[0]);
+ STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi = {};
+ CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+
+ // system
+ sprintf(buf, "\"%s\" d", argv[0]);
+ system(buf);
+
+ return 0;
+}
diff --git a/tests/mousebutton-count.c b/tests/mousebutton-count.c
new file mode 100644
index 0000000..32d7311
--- /dev/null
+++ b/tests/mousebutton-count.c
@@ -0,0 +1,25 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+
+int main()
+{
+ printf("count: %d\n", GetSystemMetrics(SM_CMOUSEBUTTONS));
+}
diff --git a/tests/open-protected-pid.c b/tests/open-protected-pid.c
new file mode 100644
index 0000000..25f4115
--- /dev/null
+++ b/tests/open-protected-pid.c
@@ -0,0 +1,10 @@
+#include
+#include
+
+int main()
+{
+ // this is the process identifier of agent.py on my VM
+ HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1576);
+ printf("process-handle: %p -> %d\n", process_handle, GetLastError());
+ return 0;
+}
diff --git a/tests/peb-check.c b/tests/peb-check.c
new file mode 100644
index 0000000..2b01a4d
--- /dev/null
+++ b/tests/peb-check.c
@@ -0,0 +1,29 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+
+int main()
+{
+ LoadLibrary("../cuckoomon.dll");
+
+ HMODULE cuckoomon_handle = GetModuleHandle("cuckoomon.dll");
+ printf("cuckoomon -> 0x%08x\n", cuckoomon_handle);
+ return 0;
+}
diff --git a/tests/sleep.c b/tests/sleep.c
new file mode 100644
index 0000000..3e5066e
--- /dev/null
+++ b/tests/sleep.c
@@ -0,0 +1,30 @@
+#include
+#include
+
+DWORD WINAPI thread(LPVOID lpNothing)
+{
+ return 0;
+}
+
+int main()
+{
+ LoadLibrary("../cuckoomon.dll");
+
+ // sleep for five seconds (skipped)
+ for (int i = 0; i < 100; i++) {
+ Sleep(50);
+
+ printf("tick: %ld\n", GetTickCount());
+ }
+
+ // sleep for 10 seconds (skipped)
+ Sleep(10000);
+
+ printf("tick: %ld\n", GetTickCount());
+
+ printf("starting second thread\n");
+ CloseHandle(CreateThread(NULL, 0, &thread, NULL, 0, NULL));
+
+ // sleep for 5 seconds (not skipped)
+ Sleep(5000);
+}
diff --git a/tests/sleep2.c b/tests/sleep2.c
new file mode 100644
index 0000000..605941b
--- /dev/null
+++ b/tests/sleep2.c
@@ -0,0 +1,24 @@
+#include
+#include
+
+int main()
+{
+ LoadLibrary("../cuckoomon.dll");
+
+ unsigned int start = GetTickCount();
+ printf("%d\n", start);
+
+ Sleep(1000);
+
+ printf("%d -> %d\n", GetTickCount(), GetTickCount() - start);
+
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 0xfffffff; j++);
+ }
+
+ printf("%d -> %d\n", GetTickCount(), GetTickCount() - start);
+
+ Sleep(1000);
+
+ printf("%d -> %d\n", GetTickCount(), GetTickCount() - start);
+}
diff --git a/tests/startup-time.c b/tests/startup-time.c
new file mode 100644
index 0000000..abf33c3
--- /dev/null
+++ b/tests/startup-time.c
@@ -0,0 +1,16 @@
+#include
+#include
+#include
+
+// Idea originally taken from the following article
+// http://spth.virii.lu/v4/articles/m0sa/evade.html
+
+int main()
+{
+ if(GetTickCount() < 10 * 60 * 1000) {
+ printf("Running under a VM!\n");
+ }
+ else {
+ printf("This computer is ok! Uptime: %d\n", GetTickCount());
+ }
+}
diff --git a/tests/suspended-process.c b/tests/suspended-process.c
new file mode 100644
index 0000000..c4b883a
--- /dev/null
+++ b/tests/suspended-process.c
@@ -0,0 +1,30 @@
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ if(argc != 1) {
+ printf("arg: %s\n", argv[1]);
+ fflush(stdout);
+ return 1337;
+ }
+
+ STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi; char buf[256];
+
+ sprintf(buf, "\"%s\" a", argv[0]);
+
+ BOOL ret = CreateProcess(argv[0], buf, NULL, NULL, FALSE,
+ CREATE_SUSPENDED, NULL, NULL, &si, &pi);
+
+ printf("ret: %d\n", ret);
+ fflush(stdout);
+
+ ResumeThread(pi.hThread);
+ WaitForSingleObject(pi.hThread, INFINITE);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ DWORD exit_code;
+ GetExitCodeProcess(pi.hProcess, &exit_code);
+ printf("ret: %d\n", exit_code);
+ fflush(stdout);
+}
diff --git a/tests/test-dns.c b/tests/test-dns.c
new file mode 100644
index 0000000..58783cf
--- /dev/null
+++ b/tests/test-dns.c
@@ -0,0 +1,19 @@
+#define _WIN32_WINNT 0x0501
+#include
+#include
+#include
+#include
+
+int main()
+{
+ LoadLibrary("../cuckoomon.dll");
+
+ printf("DnsQuery -> %d\n", DnsQuery("jbremer.org", DNS_TYPE_A,
+ DNS_QUERY_STANDARD, NULL, NULL, NULL));
+
+ struct addrinfo *info = NULL;
+ printf("getaddrinfo -> %d\n", getaddrinfo("jbremer.org", NULL, NULL,
+ &info));
+
+ printf("gethostbyname -> %p\n", gethostbyname("jbremer.org"));
+}
diff --git a/tests/test-lasterr.c b/tests/test-lasterr.c
new file mode 100644
index 0000000..dc25663
--- /dev/null
+++ b/tests/test-lasterr.c
@@ -0,0 +1,60 @@
+#include
+#include
+#include "hooking.h"
+#include "ntapi.h"
+
+#define HOOK(library, funcname) {L###library, #funcname, NULL, \
+ &New_##funcname##0, (void **) &Old_##funcname##0}
+
+HOOKDEF(BOOL, WINAPI, DeleteFileW0,
+ __in LPWSTR lpFileName
+) {
+ BOOL ret = Old_DeleteFileW0(lpFileName);
+
+ printf("ret: %d, lasterr: %d, %d\n", ret, GetLastError(),
+ hook_get_last_error());
+
+ SetLastError(0x1337);
+
+ printf("ret: %d, lasterr: %d, %d\n", ret, GetLastError(),
+ hook_get_last_error());
+
+ hook_set_last_error(0xb00b);
+
+ printf("ret: %d, lasterr: %d, %d\n", ret, GetLastError(),
+ hook_get_last_error());
+
+ return ret;
+}
+
+HOOKDEF(NTSTATUS, WINAPI, NtOpenFile0,
+ __out PHANDLE FileHandle,
+ __in ACCESS_MASK DesiredAccess,
+ __in POBJECT_ATTRIBUTES ObjectAttributes,
+ __out PIO_STATUS_BLOCK IoStatusBlock,
+ __in ULONG ShareAccess,
+ __in ULONG OpenOptions
+) {
+ NTSTATUS ret = Old_NtOpenFile0(FileHandle, DesiredAccess, ObjectAttributes,
+ IoStatusBlock, ShareAccess, OpenOptions);
+ SetLastError(0x1338);
+ printf("OMG!!! %d\n", GetLastError());
+ return ret;
+}
+
+int main()
+{
+ static hook_t hook[] = {
+ HOOK(kernel32, DeleteFileW),
+ HOOK(ntdll, NtOpenFile),
+ };
+
+ DWORD old_protect;
+ VirtualProtect(hook, sizeof(hook), PAGE_EXECUTE_READWRITE, &old_protect);
+
+ hook_api(&hook[0], HOOK_JMP_DIRECT);
+ hook_api(&hook[1], HOOK_JMP_DIRECT);
+
+ DeleteFile("hoi");
+ printf("lasterr: %d\n", GetLastError());
+}
diff --git a/tests/test-lde.c b/tests/test-lde.c
new file mode 100644
index 0000000..48bc1d0
--- /dev/null
+++ b/tests/test-lde.c
@@ -0,0 +1,15 @@
+#include
+#include "../hooking.h"
+
+int main()
+{
+ unsigned char b[][8] = {
+ {0x55},
+ {0x89, 0xe5},
+ {0x83, 0xec, 0x18},
+ };
+
+ for (int i = 0; i < sizeof(b)/sizeof(b[0]); i++) {
+ printf("%d\n", lde(b[i]));
+ }
+}
diff --git a/tests/wininet.c b/tests/wininet.c
new file mode 100644
index 0000000..754c611
--- /dev/null
+++ b/tests/wininet.c
@@ -0,0 +1,33 @@
+#include
+#include
+#include
+
+int print_url_contents(const char *url)
+{
+ HINTERNET internet_handle, request_handle;
+ char buffer[1024]; unsigned long bytes_read;
+
+ internet_handle = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL,
+ NULL, 0);
+ if(internet_handle == NULL) return FALSE;
+
+ request_handle = InternetOpenUrl(internet_handle, url, NULL, 0, 0, 0);
+ if(request_handle == NULL) {
+ InternetCloseHandle(internet_handle);
+ return FALSE;
+ }
+
+ while (InternetReadFile(request_handle, buffer, sizeof(buffer),
+ &bytes_read) != FALSE && bytes_read != 0) {
+ fwrite(buffer, bytes_read, 1, stderr);
+ }
+
+ InternetCloseHandle(internet_handle);
+ InternetCloseHandle(request_handle);
+ return TRUE;
+}
+
+int main()
+{
+ print_url_contents("http://jbremer.org/");
+}
diff --git a/tests/write-file.c b/tests/write-file.c
new file mode 100644
index 0000000..9c7d279
--- /dev/null
+++ b/tests/write-file.c
@@ -0,0 +1,30 @@
+#include
+#include
+
+int main()
+{
+ const char *fnames[] = {
+ "C:\\a.txt",
+ "C:\\b.txt",
+ "C:\\c.txt",
+ "C:\\d.txt",
+ "C:\\e.txt",
+ };
+
+ FILE *fp[3];
+ for (int i = 0; i < 5; i++) {
+ fp[i] = fopen(fnames[i], "w");
+ }
+
+ for (int i = 0; i < 20; i++) {
+ fprintf(fp[rand() % 5], "Hello %d\n", i);
+ }
+
+ for (int i = 0; i < 20; i++) {
+ int idx = rand() % 5;
+ if(fp[idx] != NULL) {
+ fclose(fp[idx]);
+ fp[idx] = NULL;
+ }
+ }
+}
diff --git a/utf8.c b/utf8.c
new file mode 100644
index 0000000..7193787
--- /dev/null
+++ b/utf8.c
@@ -0,0 +1,98 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+#include
+#include
+#include "utf8.h"
+
+int utf8_encode(unsigned short c, unsigned char *out)
+{
+ if(c < 0x80) {
+ *out = c & 0x7f;
+ return 1;
+ }
+ else if(c < 0x800) {
+ *out = 0xc0 + ((c >> 8) << 2) + (c >> 6);
+ out[1] = 0x80 + (c & 0x3f);
+ return 2;
+ }
+ else {
+ *out = 0xe0 + (c >> 12);
+ out[1] = 0x80 + (((c >> 8) & 0x1f) << 2) + ((c >> 6) & 0x3);
+ out[2] = 0x80 + (c & 0x3f);
+ return 3;
+ }
+}
+
+int utf8_length(unsigned short x)
+{
+ unsigned char buf[3];
+ return utf8_encode(x, buf);
+}
+
+int utf8_strlen_ascii(const char *s, int len)
+{
+ if(len < 0) len = strlen(s);
+
+ int ret = 0;
+ while (len-- != 0) {
+ ret += utf8_length(*s++);
+ }
+ return ret;
+}
+
+int utf8_strlen_unicode(const wchar_t *s, int len)
+{
+ if(len < 0) len = lstrlenW(s);
+
+ int ret = 0;
+ while (len-- != 0) {
+ ret += utf8_length(*s++);
+ }
+ return ret;
+}
+
+char * utf8_string(const char *str, int length)
+{
+ if (length == -1) length = strlen(str);
+
+ int encoded_length = utf8_strlen_ascii(str, length);
+ char * utf8string = (char *) malloc(encoded_length+4);
+ *((int *) utf8string) = encoded_length;
+ int pos = 4;
+
+ while (length-- != 0) {
+ pos += utf8_encode(*str++, (unsigned char *) &utf8string[pos]);
+ }
+ return utf8string;
+}
+
+char * utf8_wstring(const wchar_t *str, int length)
+{
+ if (length == -1) length = lstrlenW(str);
+
+ int encoded_length = utf8_strlen_unicode(str, length);
+ char * utf8string = (char *) malloc(encoded_length+4);
+ *((int *) utf8string) = encoded_length;
+ int pos = 4;
+
+ while (length-- != 0) {
+ pos += utf8_encode(*str++, (unsigned char *) &utf8string[pos]);
+ }
+ return utf8string;
+}
\ No newline at end of file
diff --git a/utf8.h b/utf8.h
new file mode 100644
index 0000000..30dff04
--- /dev/null
+++ b/utf8.h
@@ -0,0 +1,28 @@
+/*
+Cuckoo Sandbox - Automated Malware Analysis
+Copyright (C) 2010-2014 Cuckoo Sandbox Developers
+
+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 .
+*/
+
+int utf8_encode(unsigned short x, unsigned char *out);
+int utf8_length(unsigned short x);
+
+// name is a bit weird.. but it calculates the length of the utf8 encoded
+// ascii/unicode string "s" in bytes
+int utf8_strlen_ascii(const char *s, int len);
+int utf8_strlen_unicode(const wchar_t *s, int len);
+
+char * utf8_string(const char *str, int length);
+char * utf8_wstring(const wchar_t *str, int length);