commit 266e90241120d4f86ffa9c3177f516658fc7c3c9 Author: Diavolo Date: Thu May 25 22:56:38 2023 +0200 init diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..eea3a0b --- /dev/null +++ b/.clang-format @@ -0,0 +1,12 @@ + +--- +Language: Cpp +BasedOnStyle: LLVM +DerivePointerAlignment: false +PointerAlignment: Left +SortIncludes: false + +# Regroup causes unnecessary noise due to clang-format bug. +IncludeBlocks: Preserve + +--- diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..28cee3f --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.html linguist-detectable=false diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f1cef93 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: gitsubmodule + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f5fdb76 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,52 @@ +name: Build + +on: + push: + branches: + - "*" + pull_request: + branches: + - "*" + types: [opened, synchronize, reopened] + +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build binaries + runs-on: windows-2022 + strategy: + matrix: + configuration: + - Debug + - Release + steps: + - name: Check out files + uses: actions/checkout@v3.5.2 + with: + submodules: true + fetch-depth: 0 + # NOTE - If LFS ever starts getting used during builds, switch this to true! + lfs: false + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.3.1 + + - name: Generate project files + run: tools/premake5 vs2022 + + - name: Set up problem matching + uses: ammaraskar/msvc-problem-matcher@master + + - name: Build ${{matrix.configuration}} binaries + run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:Platform=Win32 build/iw4-sp.sln + + - name: Upload ${{matrix.configuration}} binaries + uses: actions/upload-artifact@v3.1.2 + with: + name: ${{matrix.configuration}} binaries + path: | + build/bin/Win32/${{matrix.configuration}}/iw4-sp.exe + build/bin/Win32/${{matrix.configuration}}/iw4-sp.pdb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5be63f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,150 @@ +### Windows + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Shortcuts +*.lnk + +### OSX + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Visual Studio + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +build + +# Visual Studio 2015 cache/options directory +.vs/ + +#Visual Studio Code +.vscode/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +### IDA +*.id0 +*.id1 +*.id2 +*.nam +*.til + +### Custom user files +# User scripts +user*.bat diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1cd37f2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,24 @@ +[submodule "deps/GSL"] + path = deps/GSL + url = https://github.com/microsoft/GSL.git +[submodule "deps/udis86"] + path = deps/udis86 + url = https://github.com/vmt/udis86.git +[submodule "deps/minhook"] + path = deps/minhook + url = https://github.com/TsudaKageyu/minhook.git +[submodule "deps/zlib"] + path = deps/zlib + url = https://github.com/madler/zlib.git +[submodule "deps/rapidjson"] + path = deps/rapidjson + url = https://github.com/Tencent/rapidjson.git +[submodule "deps/discord-rpc"] + path = deps/discord-rpc + url = https://github.com/discord/discord-rpc.git +[submodule "deps/libtommath"] + path = deps/libtommath + url = https://github.com/libtom/libtommath.git +[submodule "deps/libtomcrypt"] + path = deps/libtomcrypt + url = https://github.com/libtom/libtomcrypt.git diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -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/README.md b/README.md new file mode 100644 index 0000000..576cdf8 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +[![build](https://github.com/alterware/iw4-sp/workflows/Build/badge.svg)](https://github.com/alterware/iw4-sp/actions) + +# IW4: SP Client + +This is a client modification for IW4 (Singleplayer) 159 +**NOTE**: You must legally own Call of Duty®: Modern Warfare® 2 (2009) to run this mod. Cracked/Pirated versions of the game are **NOT** supported. + +## How to compile + +- Run `premake5 vs2022` or use the delivered `generate.bat`. +- Build via solution file in `build\iw4-sp.sln`. + +## Premake arguments + +| Argument | Description | +|:----------------------------|:-----------------------------------------------| +| `--copy-to=PATH` | Optional, copy the exe to a custom folder after build. | + +## Command line arguments + +| Argument | Description | +|:------------------------|:-----------------------------------------------| +| `-nosteam` | Disable Steam integration. | + +## Disclaimer + +This software has been created purely for the purposes of academic research. It is not intended to be used to attack other systems. Project maintainers are not responsible or liable for misuse of the software. Use responsibly. diff --git a/deps/GSL b/deps/GSL new file mode 160000 index 0000000..303d964 --- /dev/null +++ b/deps/GSL @@ -0,0 +1 @@ +Subproject commit 303d964a241cb2f2a058fe0baa14013eb9afa116 diff --git a/deps/discord-rpc b/deps/discord-rpc new file mode 160000 index 0000000..963aa9f --- /dev/null +++ b/deps/discord-rpc @@ -0,0 +1 @@ +Subproject commit 963aa9f3e5ce81a4682c6ca3d136cddda614db33 diff --git a/deps/extra/udis86/libudis86/itab.c b/deps/extra/udis86/libudis86/itab.c new file mode 100644 index 0000000..953f3e5 --- /dev/null +++ b/deps/extra/udis86/libudis86/itab.c @@ -0,0 +1,5946 @@ +/* itab.c -- generated by udis86:scripts/ud_itab.py, do no edit */ +#include "decode.h" + +#define GROUP(n) (0x8000 | (n)) +#define INVALID 0 + + +const uint16_t ud_itab__0[] = { + /* 0 */ 15, 16, 17, 18, + /* 4 */ 19, 20, GROUP(1), GROUP(2), + /* 8 */ 964, 965, 966, 967, + /* c */ 968, 969, GROUP(3), GROUP(4), + /* 10 */ 5, 6, 7, 8, + /* 14 */ 9, 10, GROUP(284), GROUP(285), + /* 18 */ 1336, 1337, 1338, 1339, + /* 1c */ 1340, 1341, GROUP(286), GROUP(287), + /* 20 */ 49, 50, 51, 52, + /* 24 */ 53, 54, INVALID, GROUP(288), + /* 28 */ 1407, 1408, 1409, 1410, + /* 2c */ 1411, 1412, INVALID, GROUP(289), + /* 30 */ 1487, 1488, 1489, 1490, + /* 34 */ 1491, 1492, INVALID, GROUP(290), + /* 38 */ 100, 101, 102, 103, + /* 3c */ 104, 105, INVALID, GROUP(291), + /* 40 */ 699, 700, 701, 702, + /* 44 */ 703, 704, 705, 706, + /* 48 */ 175, 176, 177, 178, + /* 4c */ 179, 180, 181, 182, + /* 50 */ 1246, 1247, 1248, 1249, + /* 54 */ 1250, 1251, 1252, 1253, + /* 58 */ 1101, 1102, 1103, 1104, + /* 5c */ 1105, 1106, 1107, 1108, + /* 60 */ GROUP(292), GROUP(295), GROUP(298), GROUP(299), + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ 1254, 697, 1256, 698, + /* 6c */ 709, GROUP(300), 982, GROUP(301), + /* 70 */ 726, 728, 730, 732, + /* 74 */ 734, 736, 738, 740, + /* 78 */ 742, 744, 746, 748, + /* 7c */ 750, 752, 754, 756, + /* 80 */ GROUP(302), GROUP(303), GROUP(304), GROUP(313), + /* 84 */ 1433, 1434, 1475, 1476, + /* 88 */ 828, 829, 830, 831, + /* 8c */ 832, 770, 833, GROUP(314), + /* 90 */ 1477, 1478, 1479, 1480, + /* 94 */ 1481, 1482, 1483, 1484, + /* 98 */ GROUP(315), GROUP(316), GROUP(317), 1470, + /* 9c */ GROUP(318), GROUP(322), 1310, 766, + /* a0 */ 834, 835, 836, 837, + /* a4 */ 922, GROUP(326), 114, GROUP(327), + /* a8 */ 1435, 1436, 1402, GROUP(328), + /* ac */ 790, GROUP(329), 1346, GROUP(330), + /* b0 */ 838, 839, 840, 841, + /* b4 */ 842, 843, 844, 845, + /* b8 */ 846, 847, 848, 849, + /* bc */ 850, 851, 852, 853, + /* c0 */ GROUP(331), GROUP(332), 1301, 1302, + /* c4 */ GROUP(333), GROUP(403), GROUP(405), GROUP(406), + /* c8 */ 200, 776, 1303, 1304, + /* cc */ 713, 714, GROUP(407), GROUP(408), + /* d0 */ GROUP(409), GROUP(410), GROUP(411), GROUP(412), + /* d4 */ GROUP(413), GROUP(414), GROUP(415), 1486, + /* d8 */ GROUP(416), GROUP(419), GROUP(422), GROUP(425), + /* dc */ GROUP(428), GROUP(431), GROUP(434), GROUP(437), + /* e0 */ 794, 795, 796, GROUP(440), + /* e4 */ 690, 691, 978, 979, + /* e8 */ 72, 763, GROUP(441), 765, + /* ec */ 692, 693, 980, 981, + /* f0 */ 789, 712, 1299, 1300, + /* f4 */ 687, 83, GROUP(442), GROUP(443), + /* f8 */ 77, 1395, 81, 1398, + /* fc */ 78, 1396, GROUP(444), GROUP(445), +}; + +static const uint16_t ud_itab__1[] = { + /* 0 */ 1240, INVALID, +}; + +static const uint16_t ud_itab__2[] = { + /* 0 */ 1096, INVALID, +}; + +static const uint16_t ud_itab__3[] = { + /* 0 */ 1241, INVALID, +}; + +static const uint16_t ud_itab__4[] = { + /* 0 */ GROUP(5), GROUP(6), 767, 797, + /* 4 */ INVALID, 1426, 82, 1431, + /* 8 */ 716, 1471, INVALID, 1444, + /* c */ INVALID, GROUP(27), 430, GROUP(28), + /* 10 */ GROUP(29), GROUP(30), GROUP(31), GROUP(34), + /* 14 */ GROUP(35), GROUP(36), GROUP(37), GROUP(40), + /* 18 */ GROUP(41), 955, 956, 957, + /* 1c */ 958, 959, 960, 961, + /* 20 */ 854, 855, 856, 857, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ GROUP(42), GROUP(43), GROUP(44), GROUP(45), + /* 2c */ GROUP(46), GROUP(47), GROUP(48), GROUP(49), + /* 30 */ 1472, 1297, 1295, 1296, + /* 34 */ GROUP(50), GROUP(52), INVALID, 1514, + /* 38 */ GROUP(54), INVALID, GROUP(116), INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ 84, 85, 86, 87, + /* 44 */ 88, 89, 90, 91, + /* 48 */ 92, 93, 94, 95, + /* 4c */ 96, 97, 98, 99, + /* 50 */ GROUP(143), GROUP(144), GROUP(145), GROUP(146), + /* 54 */ GROUP(147), GROUP(148), GROUP(149), GROUP(150), + /* 58 */ GROUP(151), GROUP(152), GROUP(153), GROUP(154), + /* 5c */ GROUP(155), GROUP(156), GROUP(157), GROUP(158), + /* 60 */ GROUP(159), GROUP(160), GROUP(161), GROUP(162), + /* 64 */ GROUP(163), GROUP(164), GROUP(165), GROUP(166), + /* 68 */ GROUP(167), GROUP(168), GROUP(169), GROUP(170), + /* 6c */ GROUP(171), GROUP(172), GROUP(173), GROUP(176), + /* 70 */ GROUP(177), GROUP(178), GROUP(182), GROUP(186), + /* 74 */ GROUP(191), GROUP(192), GROUP(193), 199, + /* 78 */ GROUP(194), GROUP(195), INVALID, INVALID, + /* 7c */ GROUP(196), GROUP(197), GROUP(198), GROUP(201), + /* 80 */ 727, 729, 731, 733, + /* 84 */ 735, 737, 739, 741, + /* 88 */ 743, 745, 747, 749, + /* 8c */ 751, 753, 755, 757, + /* 90 */ 1350, 1351, 1352, 1353, + /* 94 */ 1354, 1355, 1356, 1357, + /* 98 */ 1358, 1359, 1360, 1361, + /* 9c */ 1362, 1363, 1364, 1365, + /* a0 */ 1245, 1100, 131, 1670, + /* a4 */ 1375, 1376, GROUP(202), GROUP(207), + /* a8 */ 1244, 1099, 1305, 1675, + /* ac */ 1377, 1378, GROUP(215), 694, + /* b0 */ 122, 123, 775, 1673, + /* b4 */ 772, 773, 940, 941, + /* b8 */ GROUP(221), INVALID, GROUP(222), 1671, + /* bc */ 1659, 1660, 930, 931, + /* c0 */ 1473, 1474, GROUP(223), 904, + /* c4 */ GROUP(224), GROUP(225), GROUP(226), GROUP(227), + /* c8 */ 1661, 1662, 1663, 1664, + /* cc */ 1665, 1666, 1667, 1668, + /* d0 */ GROUP(236), GROUP(237), GROUP(238), GROUP(239), + /* d4 */ GROUP(240), GROUP(241), GROUP(242), GROUP(243), + /* d8 */ GROUP(244), GROUP(245), GROUP(246), GROUP(247), + /* dc */ GROUP(248), GROUP(249), GROUP(250), GROUP(251), + /* e0 */ GROUP(252), GROUP(253), GROUP(254), GROUP(255), + /* e4 */ GROUP(256), GROUP(257), GROUP(258), GROUP(259), + /* e8 */ GROUP(260), GROUP(261), GROUP(262), GROUP(263), + /* ec */ GROUP(264), GROUP(265), GROUP(266), GROUP(267), + /* f0 */ GROUP(268), GROUP(269), GROUP(270), GROUP(271), + /* f4 */ GROUP(272), GROUP(273), GROUP(274), GROUP(275), + /* f8 */ GROUP(277), GROUP(278), GROUP(279), GROUP(280), + /* fc */ GROUP(281), GROUP(282), GROUP(283), INVALID, +}; + +static const uint16_t ud_itab__5[] = { + /* 0 */ 1384, 1406, 786, 798, + /* 4 */ 1453, 1454, INVALID, INVALID, +}; + +static const uint16_t ud_itab__6[] = { + /* 0 */ GROUP(7), GROUP(8), +}; + +static const uint16_t ud_itab__7[] = { + /* 0 */ 1374, 1383, 785, 774, + /* 4 */ 1385, INVALID, 787, 719, +}; + +static const uint16_t ud_itab__8[] = { + /* 0 */ GROUP(9), GROUP(14), GROUP(15), GROUP(16), + /* 4 */ 1386, INVALID, 788, GROUP(25), +}; + +static const uint16_t ud_itab__9[] = { + /* 0 */ INVALID, GROUP(10), GROUP(11), GROUP(12), + /* 4 */ GROUP(13), INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__10[] = { + /* 0 */ INVALID, 1455, INVALID, +}; + +static const uint16_t ud_itab__11[] = { + /* 0 */ INVALID, 1461, INVALID, +}; + +static const uint16_t ud_itab__12[] = { + /* 0 */ INVALID, 1462, INVALID, +}; + +static const uint16_t ud_itab__13[] = { + /* 0 */ INVALID, 1463, INVALID, +}; + +static const uint16_t ud_itab__14[] = { + /* 0 */ 824, 952, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__15[] = { + /* 0 */ 1485, 1508, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__16[] = { + /* 0 */ GROUP(17), GROUP(18), GROUP(19), GROUP(20), + /* 4 */ GROUP(21), GROUP(22), GROUP(23), GROUP(24), +}; + +static const uint16_t ud_itab__17[] = { + /* 0 */ 1466, INVALID, INVALID, +}; + +static const uint16_t ud_itab__18[] = { + /* 0 */ 1467, INVALID, INVALID, +}; + +static const uint16_t ud_itab__19[] = { + /* 0 */ 1468, INVALID, INVALID, +}; + +static const uint16_t ud_itab__20[] = { + /* 0 */ 1469, INVALID, INVALID, +}; + +static const uint16_t ud_itab__21[] = { + /* 0 */ 1397, INVALID, INVALID, +}; + +static const uint16_t ud_itab__22[] = { + /* 0 */ 80, INVALID, INVALID, +}; + +static const uint16_t ud_itab__23[] = { + /* 0 */ 1399, INVALID, INVALID, +}; + +static const uint16_t ud_itab__24[] = { + /* 0 */ 720, INVALID, INVALID, +}; + +static const uint16_t ud_itab__25[] = { + /* 0 */ 1425, GROUP(26), INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__26[] = { + /* 0 */ 1298, INVALID, INVALID, +}; + +static const uint16_t ud_itab__27[] = { + /* 0 */ 1119, 1120, 1121, 1122, + /* 4 */ 1123, 1124, 1125, 1126, +}; + +static const uint16_t ud_itab__28[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ 1216, 1217, INVALID, INVALID, + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ INVALID, INVALID, INVALID, INVALID, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ 1218, 1219, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, 1220, INVALID, + /* 8c */ INVALID, INVALID, 1221, INVALID, + /* 90 */ 1222, INVALID, INVALID, INVALID, + /* 94 */ 1223, INVALID, 1224, 1225, + /* 98 */ INVALID, INVALID, 1226, INVALID, + /* 9c */ INVALID, INVALID, 1227, INVALID, + /* a0 */ 1228, INVALID, INVALID, INVALID, + /* a4 */ 1229, INVALID, 1230, 1231, + /* a8 */ INVALID, INVALID, 1232, INVALID, + /* ac */ INVALID, INVALID, 1233, INVALID, + /* b0 */ 1234, INVALID, INVALID, INVALID, + /* b4 */ 1235, INVALID, 1236, 1237, + /* b8 */ INVALID, INVALID, INVALID, 1238, + /* bc */ INVALID, INVALID, INVALID, 1239, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__29[] = { + /* 0 */ 936, 925, 928, 932, +}; + +static const uint16_t ud_itab__30[] = { + /* 0 */ 938, 926, 929, 934, +}; + +static const uint16_t ud_itab__31[] = { + /* 0 */ GROUP(32), GROUP(33), +}; + +static const uint16_t ud_itab__32[] = { + /* 0 */ 892, 1563, 1571, 888, +}; + +static const uint16_t ud_itab__33[] = { + /* 0 */ 896, 1561, 1569, INVALID, +}; + +static const uint16_t ud_itab__34[] = { + /* 0 */ 894, INVALID, INVALID, 890, +}; + +static const uint16_t ud_itab__35[] = { + /* 0 */ 1449, INVALID, INVALID, 1451, +}; + +static const uint16_t ud_itab__36[] = { + /* 0 */ 1447, INVALID, INVALID, 1445, +}; + +static const uint16_t ud_itab__37[] = { + /* 0 */ GROUP(38), GROUP(39), +}; + +static const uint16_t ud_itab__38[] = { + /* 0 */ 882, INVALID, 1567, 878, +}; + +static const uint16_t ud_itab__39[] = { + /* 0 */ 886, INVALID, 1565, INVALID, +}; + +static const uint16_t ud_itab__40[] = { + /* 0 */ 884, INVALID, INVALID, 880, +}; + +static const uint16_t ud_itab__41[] = { + /* 0 */ 1127, 1128, 1129, 1130, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__42[] = { + /* 0 */ 862, INVALID, INVALID, 858, +}; + +static const uint16_t ud_itab__43[] = { + /* 0 */ 864, INVALID, INVALID, 860, +}; + +static const uint16_t ud_itab__44[] = { + /* 0 */ 141, 152, 154, 142, +}; + +static const uint16_t ud_itab__45[] = { + /* 0 */ 907, INVALID, INVALID, 905, +}; + +static const uint16_t ud_itab__46[] = { + /* 0 */ 165, 166, 168, 162, +}; + +static const uint16_t ud_itab__47[] = { + /* 0 */ 147, 148, 158, 138, +}; + +static const uint16_t ud_itab__48[] = { + /* 0 */ 1442, INVALID, INVALID, 1440, +}; + +static const uint16_t ud_itab__49[] = { + /* 0 */ 129, INVALID, INVALID, 127, +}; + +static const uint16_t ud_itab__50[] = { + /* 0 */ 1427, GROUP(51), +}; + +static const uint16_t ud_itab__51[] = { + /* 0 */ INVALID, 1428, INVALID, +}; + +static const uint16_t ud_itab__52[] = { + /* 0 */ 1429, GROUP(53), +}; + +static const uint16_t ud_itab__53[] = { + /* 0 */ INVALID, 1430, INVALID, +}; + +static const uint16_t ud_itab__54[] = { + /* 0 */ GROUP(67), GROUP(68), GROUP(63), GROUP(64), + /* 4 */ GROUP(65), GROUP(66), GROUP(86), GROUP(90), + /* 8 */ GROUP(69), GROUP(70), GROUP(71), GROUP(72), + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ GROUP(73), INVALID, INVALID, INVALID, + /* 14 */ GROUP(75), GROUP(76), INVALID, GROUP(77), + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ GROUP(78), GROUP(79), GROUP(80), INVALID, + /* 20 */ GROUP(81), GROUP(82), GROUP(83), GROUP(84), + /* 24 */ GROUP(85), GROUP(108), INVALID, INVALID, + /* 28 */ GROUP(87), GROUP(88), GROUP(89), GROUP(74), + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ GROUP(91), GROUP(92), GROUP(93), GROUP(94), + /* 34 */ GROUP(95), GROUP(96), INVALID, GROUP(97), + /* 38 */ GROUP(98), GROUP(99), GROUP(100), GROUP(101), + /* 3c */ GROUP(102), GROUP(103), GROUP(104), GROUP(105), + /* 40 */ GROUP(106), GROUP(107), INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ GROUP(55), GROUP(59), INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, GROUP(109), + /* dc */ GROUP(110), GROUP(111), GROUP(112), GROUP(113), + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ GROUP(114), GROUP(115), INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__55[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(56), +}; + +static const uint16_t ud_itab__56[] = { + /* 0 */ GROUP(57), GROUP(58), +}; + +static const uint16_t ud_itab__57[] = { + /* 0 */ INVALID, 717, INVALID, +}; + +static const uint16_t ud_itab__58[] = { + /* 0 */ INVALID, 718, INVALID, +}; + +static const uint16_t ud_itab__59[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(60), +}; + +static const uint16_t ud_itab__60[] = { + /* 0 */ GROUP(61), GROUP(62), +}; + +static const uint16_t ud_itab__61[] = { + /* 0 */ INVALID, 721, INVALID, +}; + +static const uint16_t ud_itab__62[] = { + /* 0 */ INVALID, 722, INVALID, +}; + +static const uint16_t ud_itab__63[] = { + /* 0 */ 1588, INVALID, INVALID, 1589, +}; + +static const uint16_t ud_itab__64[] = { + /* 0 */ 1591, INVALID, INVALID, 1592, +}; + +static const uint16_t ud_itab__65[] = { + /* 0 */ 1594, INVALID, INVALID, 1595, +}; + +static const uint16_t ud_itab__66[] = { + /* 0 */ 1597, INVALID, INVALID, 1598, +}; + +static const uint16_t ud_itab__67[] = { + /* 0 */ 1582, INVALID, INVALID, 1583, +}; + +static const uint16_t ud_itab__68[] = { + /* 0 */ 1585, INVALID, INVALID, 1586, +}; + +static const uint16_t ud_itab__69[] = { + /* 0 */ 1606, INVALID, INVALID, 1607, +}; + +static const uint16_t ud_itab__70[] = { + /* 0 */ 1612, INVALID, INVALID, 1613, +}; + +static const uint16_t ud_itab__71[] = { + /* 0 */ 1609, INVALID, INVALID, 1610, +}; + +static const uint16_t ud_itab__72[] = { + /* 0 */ 1615, INVALID, INVALID, 1616, +}; + +static const uint16_t ud_itab__73[] = { + /* 0 */ INVALID, INVALID, INVALID, 1621, +}; + +static const uint16_t ud_itab__74[] = { + /* 0 */ INVALID, INVALID, INVALID, 1683, +}; + +static const uint16_t ud_itab__75[] = { + /* 0 */ INVALID, INVALID, INVALID, 1657, +}; + +static const uint16_t ud_itab__76[] = { + /* 0 */ INVALID, INVALID, INVALID, 1656, +}; + +static const uint16_t ud_itab__77[] = { + /* 0 */ INVALID, INVALID, INVALID, 1711, +}; + +static const uint16_t ud_itab__78[] = { + /* 0 */ 1573, INVALID, INVALID, 1574, +}; + +static const uint16_t ud_itab__79[] = { + /* 0 */ 1576, INVALID, INVALID, 1577, +}; + +static const uint16_t ud_itab__80[] = { + /* 0 */ 1579, INVALID, INVALID, 1580, +}; + +static const uint16_t ud_itab__81[] = { + /* 0 */ INVALID, INVALID, INVALID, 1685, +}; + +static const uint16_t ud_itab__82[] = { + /* 0 */ INVALID, INVALID, INVALID, 1687, +}; + +static const uint16_t ud_itab__83[] = { + /* 0 */ INVALID, INVALID, INVALID, 1689, +}; + +static const uint16_t ud_itab__84[] = { + /* 0 */ INVALID, INVALID, INVALID, 1691, +}; + +static const uint16_t ud_itab__85[] = { + /* 0 */ INVALID, INVALID, INVALID, 1693, +}; + +static const uint16_t ud_itab__86[] = { + /* 0 */ 1600, INVALID, INVALID, 1601, +}; + +static const uint16_t ud_itab__87[] = { + /* 0 */ INVALID, INVALID, INVALID, 1622, +}; + +static const uint16_t ud_itab__88[] = { + /* 0 */ INVALID, INVALID, INVALID, 1708, +}; + +static const uint16_t ud_itab__89[] = { + /* 0 */ INVALID, INVALID, INVALID, 1681, +}; + +static const uint16_t ud_itab__90[] = { + /* 0 */ 1603, INVALID, INVALID, 1604, +}; + +static const uint16_t ud_itab__91[] = { + /* 0 */ INVALID, INVALID, INVALID, 1696, +}; + +static const uint16_t ud_itab__92[] = { + /* 0 */ INVALID, INVALID, INVALID, 1698, +}; + +static const uint16_t ud_itab__93[] = { + /* 0 */ INVALID, INVALID, INVALID, 1700, +}; + +static const uint16_t ud_itab__94[] = { + /* 0 */ INVALID, INVALID, INVALID, 1702, +}; + +static const uint16_t ud_itab__95[] = { + /* 0 */ INVALID, INVALID, INVALID, 1704, +}; + +static const uint16_t ud_itab__96[] = { + /* 0 */ INVALID, INVALID, INVALID, 1706, +}; + +static const uint16_t ud_itab__97[] = { + /* 0 */ INVALID, INVALID, INVALID, 1717, +}; + +static const uint16_t ud_itab__98[] = { + /* 0 */ INVALID, INVALID, INVALID, 1624, +}; + +static const uint16_t ud_itab__99[] = { + /* 0 */ INVALID, INVALID, INVALID, 1626, +}; + +static const uint16_t ud_itab__100[] = { + /* 0 */ INVALID, INVALID, INVALID, 1628, +}; + +static const uint16_t ud_itab__101[] = { + /* 0 */ INVALID, INVALID, INVALID, 1630, +}; + +static const uint16_t ud_itab__102[] = { + /* 0 */ INVALID, INVALID, INVALID, 1632, +}; + +static const uint16_t ud_itab__103[] = { + /* 0 */ INVALID, INVALID, INVALID, 1634, +}; + +static const uint16_t ud_itab__104[] = { + /* 0 */ INVALID, INVALID, INVALID, 1638, +}; + +static const uint16_t ud_itab__105[] = { + /* 0 */ INVALID, INVALID, INVALID, 1636, +}; + +static const uint16_t ud_itab__106[] = { + /* 0 */ INVALID, INVALID, INVALID, 1640, +}; + +static const uint16_t ud_itab__107[] = { + /* 0 */ INVALID, INVALID, INVALID, 1642, +}; + +static const uint16_t ud_itab__108[] = { + /* 0 */ INVALID, INVALID, INVALID, 1695, +}; + +static const uint16_t ud_itab__109[] = { + /* 0 */ INVALID, INVALID, INVALID, 45, +}; + +static const uint16_t ud_itab__110[] = { + /* 0 */ INVALID, INVALID, INVALID, 41, +}; + +static const uint16_t ud_itab__111[] = { + /* 0 */ INVALID, INVALID, INVALID, 43, +}; + +static const uint16_t ud_itab__112[] = { + /* 0 */ INVALID, INVALID, INVALID, 37, +}; + +static const uint16_t ud_itab__113[] = { + /* 0 */ INVALID, INVALID, INVALID, 39, +}; + +static const uint16_t ud_itab__114[] = { + /* 0 */ 1723, 1725, INVALID, INVALID, +}; + +static const uint16_t ud_itab__115[] = { + /* 0 */ 1724, 1726, INVALID, INVALID, +}; + +static const uint16_t ud_itab__116[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ GROUP(117), GROUP(118), GROUP(119), GROUP(120), + /* c */ GROUP(121), GROUP(122), GROUP(123), GROUP(124), + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ GROUP(125), GROUP(126), GROUP(127), GROUP(129), + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ GROUP(130), GROUP(131), GROUP(132), INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ GROUP(134), GROUP(135), GROUP(136), INVALID, + /* 44 */ GROUP(137), INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ GROUP(139), GROUP(140), GROUP(141), GROUP(142), + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, GROUP(138), + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__117[] = { + /* 0 */ INVALID, INVALID, INVALID, 1644, +}; + +static const uint16_t ud_itab__118[] = { + /* 0 */ INVALID, INVALID, INVALID, 1646, +}; + +static const uint16_t ud_itab__119[] = { + /* 0 */ INVALID, INVALID, INVALID, 1648, +}; + +static const uint16_t ud_itab__120[] = { + /* 0 */ INVALID, INVALID, INVALID, 1650, +}; + +static const uint16_t ud_itab__121[] = { + /* 0 */ INVALID, INVALID, INVALID, 1654, +}; + +static const uint16_t ud_itab__122[] = { + /* 0 */ INVALID, INVALID, INVALID, 1652, +}; + +static const uint16_t ud_itab__123[] = { + /* 0 */ INVALID, INVALID, INVALID, 1677, +}; + +static const uint16_t ud_itab__124[] = { + /* 0 */ 1618, INVALID, INVALID, 1619, +}; + +static const uint16_t ud_itab__125[] = { + /* 0 */ INVALID, INVALID, INVALID, 1045, +}; + +static const uint16_t ud_itab__126[] = { + /* 0 */ INVALID, INVALID, INVALID, 1056, +}; + +static const uint16_t ud_itab__127[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(128), +}; + +static const uint16_t ud_itab__128[] = { + /* 0 */ 1047, 1049, 1051, +}; + +static const uint16_t ud_itab__129[] = { + /* 0 */ INVALID, INVALID, INVALID, 201, +}; + +static const uint16_t ud_itab__130[] = { + /* 0 */ INVALID, INVALID, INVALID, 1058, +}; + +static const uint16_t ud_itab__131[] = { + /* 0 */ INVALID, INVALID, INVALID, 1557, +}; + +static const uint16_t ud_itab__132[] = { + /* 0 */ INVALID, INVALID, INVALID, GROUP(133), +}; + +static const uint16_t ud_itab__133[] = { + /* 0 */ 1062, 1063, 1064, +}; + +static const uint16_t ud_itab__134[] = { + /* 0 */ INVALID, INVALID, INVALID, 197, +}; + +static const uint16_t ud_itab__135[] = { + /* 0 */ INVALID, INVALID, INVALID, 195, +}; + +static const uint16_t ud_itab__136[] = { + /* 0 */ INVALID, INVALID, INVALID, 1679, +}; + +static const uint16_t ud_itab__137[] = { + /* 0 */ INVALID, INVALID, INVALID, 1512, +}; + +static const uint16_t ud_itab__138[] = { + /* 0 */ INVALID, INVALID, INVALID, 47, +}; + +static const uint16_t ud_itab__139[] = { + /* 0 */ INVALID, INVALID, INVALID, 1715, +}; + +static const uint16_t ud_itab__140[] = { + /* 0 */ INVALID, INVALID, INVALID, 1713, +}; + +static const uint16_t ud_itab__141[] = { + /* 0 */ INVALID, INVALID, INVALID, 1721, +}; + +static const uint16_t ud_itab__142[] = { + /* 0 */ INVALID, INVALID, INVALID, 1719, +}; + +static const uint16_t ud_itab__143[] = { + /* 0 */ 900, INVALID, INVALID, 898, +}; + +static const uint16_t ud_itab__144[] = { + /* 0 */ 1387, 1391, 1393, 1389, +}; + +static const uint16_t ud_itab__145[] = { + /* 0 */ 1306, INVALID, 1308, INVALID, +}; + +static const uint16_t ud_itab__146[] = { + /* 0 */ 1291, INVALID, 1293, INVALID, +}; + +static const uint16_t ud_itab__147[] = { + /* 0 */ 61, INVALID, INVALID, 59, +}; + +static const uint16_t ud_itab__148[] = { + /* 0 */ 65, INVALID, INVALID, 63, +}; + +static const uint16_t ud_itab__149[] = { + /* 0 */ 976, INVALID, INVALID, 974, +}; + +static const uint16_t ud_itab__150[] = { + /* 0 */ 1499, INVALID, INVALID, 1497, +}; + +static const uint16_t ud_itab__151[] = { + /* 0 */ 27, 29, 31, 25, +}; + +static const uint16_t ud_itab__152[] = { + /* 0 */ 946, 948, 950, 944, +}; + +static const uint16_t ud_itab__153[] = { + /* 0 */ 145, 150, 156, 139, +}; + +static const uint16_t ud_itab__154[] = { + /* 0 */ 134, INVALID, 163, 143, +}; + +static const uint16_t ud_itab__155[] = { + /* 0 */ 1419, 1421, 1423, 1417, +}; + +static const uint16_t ud_itab__156[] = { + /* 0 */ 818, 820, 822, 816, +}; + +static const uint16_t ud_itab__157[] = { + /* 0 */ 189, 191, 193, 187, +}; + +static const uint16_t ud_itab__158[] = { + /* 0 */ 802, 804, 806, 800, +}; + +static const uint16_t ud_itab__159[] = { + /* 0 */ 1209, INVALID, INVALID, 1207, +}; + +static const uint16_t ud_itab__160[] = { + /* 0 */ 1212, INVALID, INVALID, 1210, +}; + +static const uint16_t ud_itab__161[] = { + /* 0 */ 1215, INVALID, INVALID, 1213, +}; + +static const uint16_t ud_itab__162[] = { + /* 0 */ 987, INVALID, INVALID, 985, +}; + +static const uint16_t ud_itab__163[] = { + /* 0 */ 1038, INVALID, INVALID, 1036, +}; + +static const uint16_t ud_itab__164[] = { + /* 0 */ 1041, INVALID, INVALID, 1039, +}; + +static const uint16_t ud_itab__165[] = { + /* 0 */ 1044, INVALID, INVALID, 1042, +}; + +static const uint16_t ud_itab__166[] = { + /* 0 */ 993, INVALID, INVALID, 991, +}; + +static const uint16_t ud_itab__167[] = { + /* 0 */ 1200, INVALID, INVALID, 1198, +}; + +static const uint16_t ud_itab__168[] = { + /* 0 */ 1203, INVALID, INVALID, 1201, +}; + +static const uint16_t ud_itab__169[] = { + /* 0 */ 1206, INVALID, INVALID, 1204, +}; + +static const uint16_t ud_itab__170[] = { + /* 0 */ 990, INVALID, INVALID, 988, +}; + +static const uint16_t ud_itab__171[] = { + /* 0 */ INVALID, INVALID, INVALID, 1547, +}; + +static const uint16_t ud_itab__172[] = { + /* 0 */ INVALID, INVALID, INVALID, 1545, +}; + +static const uint16_t ud_itab__173[] = { + /* 0 */ GROUP(174), INVALID, INVALID, GROUP(175), +}; + +static const uint16_t ud_itab__174[] = { + /* 0 */ 866, 867, 910, +}; + +static const uint16_t ud_itab__175[] = { + /* 0 */ 868, 870, 911, +}; + +static const uint16_t ud_itab__176[] = { + /* 0 */ 920, INVALID, 1522, 1517, +}; + +static const uint16_t ud_itab__177[] = { + /* 0 */ 1134, 1537, 1535, 1539, +}; + +static const uint16_t ud_itab__178[] = { + /* 0 */ INVALID, INVALID, GROUP(179), INVALID, + /* 4 */ GROUP(180), INVALID, GROUP(181), INVALID, +}; + +static const uint16_t ud_itab__179[] = { + /* 0 */ 1159, INVALID, INVALID, 1163, +}; + +static const uint16_t ud_itab__180[] = { + /* 0 */ 1152, INVALID, INVALID, 1150, +}; + +static const uint16_t ud_itab__181[] = { + /* 0 */ 1138, INVALID, INVALID, 1137, +}; + +static const uint16_t ud_itab__182[] = { + /* 0 */ INVALID, INVALID, GROUP(183), INVALID, + /* 4 */ GROUP(184), INVALID, GROUP(185), INVALID, +}; + +static const uint16_t ud_itab__183[] = { + /* 0 */ 1165, INVALID, INVALID, 1169, +}; + +static const uint16_t ud_itab__184[] = { + /* 0 */ 1153, INVALID, INVALID, 1157, +}; + +static const uint16_t ud_itab__185[] = { + /* 0 */ 1142, INVALID, INVALID, 1141, +}; + +static const uint16_t ud_itab__186[] = { + /* 0 */ INVALID, INVALID, GROUP(187), GROUP(188), + /* 4 */ INVALID, INVALID, GROUP(189), GROUP(190), +}; + +static const uint16_t ud_itab__187[] = { + /* 0 */ 1171, INVALID, INVALID, 1175, +}; + +static const uint16_t ud_itab__188[] = { + /* 0 */ INVALID, INVALID, INVALID, 1543, +}; + +static const uint16_t ud_itab__189[] = { + /* 0 */ 1146, INVALID, INVALID, 1145, +}; + +static const uint16_t ud_itab__190[] = { + /* 0 */ INVALID, INVALID, INVALID, 1541, +}; + +static const uint16_t ud_itab__191[] = { + /* 0 */ 1027, INVALID, INVALID, 1028, +}; + +static const uint16_t ud_itab__192[] = { + /* 0 */ 1030, INVALID, INVALID, 1031, +}; + +static const uint16_t ud_itab__193[] = { + /* 0 */ 1033, INVALID, INVALID, 1034, +}; + +static const uint16_t ud_itab__194[] = { + /* 0 */ INVALID, 1464, INVALID, +}; + +static const uint16_t ud_itab__195[] = { + /* 0 */ INVALID, 1465, INVALID, +}; + +static const uint16_t ud_itab__196[] = { + /* 0 */ INVALID, 1551, INVALID, 1549, +}; + +static const uint16_t ud_itab__197[] = { + /* 0 */ INVALID, 1555, INVALID, 1553, +}; + +static const uint16_t ud_itab__198[] = { + /* 0 */ GROUP(199), INVALID, 916, GROUP(200), +}; + +static const uint16_t ud_itab__199[] = { + /* 0 */ 872, 873, 913, +}; + +static const uint16_t ud_itab__200[] = { + /* 0 */ 874, 876, 914, +}; + +static const uint16_t ud_itab__201[] = { + /* 0 */ 921, INVALID, 1524, 1515, +}; + +static const uint16_t ud_itab__202[] = { + /* 0 */ INVALID, GROUP(203), +}; + +static const uint16_t ud_itab__203[] = { + /* 0 */ GROUP(204), GROUP(205), GROUP(206), INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__204[] = { + /* 0 */ 825, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__205[] = { + /* 0 */ 1509, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__206[] = { + /* 0 */ 1510, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__207[] = { + /* 0 */ INVALID, GROUP(208), +}; + +static const uint16_t ud_itab__208[] = { + /* 0 */ GROUP(209), GROUP(210), GROUP(211), GROUP(212), + /* 4 */ GROUP(213), GROUP(214), INVALID, INVALID, +}; + +static const uint16_t ud_itab__209[] = { + /* 0 */ 1511, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__210[] = { + /* 0 */ 1501, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__211[] = { + /* 0 */ 1502, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__212[] = { + /* 0 */ 1503, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__213[] = { + /* 0 */ 1504, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__214[] = { + /* 0 */ 1505, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__215[] = { + /* 0 */ GROUP(216), GROUP(217), +}; + +static const uint16_t ud_itab__216[] = { + /* 0 */ 683, 682, 768, 1400, + /* 4 */ 1507, 1506, INVALID, 79, +}; + +static const uint16_t ud_itab__217[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, GROUP(218), GROUP(219), GROUP(220), +}; + +static const uint16_t ud_itab__218[] = { + /* 0 */ 777, 778, 779, 780, + /* 4 */ 781, 782, 783, 784, +}; + +static const uint16_t ud_itab__219[] = { + /* 0 */ 808, 809, 810, 811, + /* 4 */ 812, 813, 814, 815, +}; + +static const uint16_t ud_itab__220[] = { + /* 0 */ 1366, 1367, 1368, 1369, + /* 4 */ 1370, 1371, 1372, 1373, +}; + +static const uint16_t ud_itab__221[] = { + /* 0 */ INVALID, INVALID, 1710, INVALID, +}; + +static const uint16_t ud_itab__222[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ 1669, 1676, 1674, 1672, +}; + +static const uint16_t ud_itab__223[] = { + /* 0 */ 112, 117, 120, 110, +}; + +static const uint16_t ud_itab__224[] = { + /* 0 */ 1059, INVALID, INVALID, 1060, +}; + +static const uint16_t ud_itab__225[] = { + /* 0 */ 1055, INVALID, INVALID, 1053, +}; + +static const uint16_t ud_itab__226[] = { + /* 0 */ 1381, INVALID, INVALID, 1379, +}; + +static const uint16_t ud_itab__227[] = { + /* 0 */ GROUP(228), GROUP(235), +}; + +static const uint16_t ud_itab__228[] = { + /* 0 */ INVALID, GROUP(229), INVALID, INVALID, + /* 4 */ INVALID, INVALID, GROUP(230), GROUP(234), +}; + +static const uint16_t ud_itab__229[] = { + /* 0 */ 124, 125, 126, +}; + +static const uint16_t ud_itab__230[] = { + /* 0 */ GROUP(231), INVALID, GROUP(232), GROUP(233), +}; + +static const uint16_t ud_itab__231[] = { + /* 0 */ INVALID, 1459, INVALID, +}; + +static const uint16_t ud_itab__232[] = { + /* 0 */ INVALID, 1458, INVALID, +}; + +static const uint16_t ud_itab__233[] = { + /* 0 */ INVALID, 1457, INVALID, +}; + +static const uint16_t ud_itab__234[] = { + /* 0 */ INVALID, 1460, INVALID, +}; + +static const uint16_t ud_itab__235[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, 1456, INVALID, +}; + +static const uint16_t ud_itab__236[] = { + /* 0 */ INVALID, 35, INVALID, 33, +}; + +static const uint16_t ud_itab__237[] = { + /* 0 */ 1160, INVALID, INVALID, 1161, +}; + +static const uint16_t ud_itab__238[] = { + /* 0 */ 1166, INVALID, INVALID, 1167, +}; + +static const uint16_t ud_itab__239[] = { + /* 0 */ 1172, INVALID, INVALID, 1173, +}; + +static const uint16_t ud_itab__240[] = { + /* 0 */ 1527, INVALID, INVALID, 1528, +}; + +static const uint16_t ud_itab__241[] = { + /* 0 */ 1093, INVALID, INVALID, 1094, +}; + +static const uint16_t ud_itab__242[] = { + /* 0 */ INVALID, 1521, 1526, 918, +}; + +static const uint16_t ud_itab__243[] = { + /* 0 */ 1086, INVALID, INVALID, 1084, +}; + +static const uint16_t ud_itab__244[] = { + /* 0 */ 1192, INVALID, INVALID, 1193, +}; + +static const uint16_t ud_itab__245[] = { + /* 0 */ 1195, INVALID, INVALID, 1196, +}; + +static const uint16_t ud_itab__246[] = { + /* 0 */ 1083, INVALID, INVALID, 1081, +}; + +static const uint16_t ud_itab__247[] = { + /* 0 */ 1017, INVALID, INVALID, 1015, +}; + +static const uint16_t ud_itab__248[] = { + /* 0 */ 1009, INVALID, INVALID, 1010, +}; + +static const uint16_t ud_itab__249[] = { + /* 0 */ 1012, INVALID, INVALID, 1013, +}; + +static const uint16_t ud_itab__250[] = { + /* 0 */ 1075, INVALID, INVALID, 1076, +}; + +static const uint16_t ud_itab__251[] = { + /* 0 */ 1020, INVALID, INVALID, 1018, +}; + +static const uint16_t ud_itab__252[] = { + /* 0 */ 1023, INVALID, INVALID, 1021, +}; + +static const uint16_t ud_itab__253[] = { + /* 0 */ 1147, INVALID, INVALID, 1148, +}; + +static const uint16_t ud_itab__254[] = { + /* 0 */ 1156, INVALID, INVALID, 1154, +}; + +static const uint16_t ud_itab__255[] = { + /* 0 */ 1026, INVALID, INVALID, 1024, +}; + +static const uint16_t ud_itab__256[] = { + /* 0 */ 1087, INVALID, INVALID, 1088, +}; + +static const uint16_t ud_itab__257[] = { + /* 0 */ 1092, INVALID, INVALID, 1090, +}; + +static const uint16_t ud_itab__258[] = { + /* 0 */ INVALID, 136, 132, 160, +}; + +static const uint16_t ud_itab__259[] = { + /* 0 */ 909, INVALID, INVALID, 902, +}; + +static const uint16_t ud_itab__260[] = { + /* 0 */ 1186, INVALID, INVALID, 1187, +}; + +static const uint16_t ud_itab__261[] = { + /* 0 */ 1189, INVALID, INVALID, 1190, +}; + +static const uint16_t ud_itab__262[] = { + /* 0 */ 1080, INVALID, INVALID, 1078, +}; + +static const uint16_t ud_itab__263[] = { + /* 0 */ 1118, INVALID, INVALID, 1116, +}; + +static const uint16_t ud_itab__264[] = { + /* 0 */ 1003, INVALID, INVALID, 1004, +}; + +static const uint16_t ud_itab__265[] = { + /* 0 */ 1006, INVALID, INVALID, 1007, +}; + +static const uint16_t ud_itab__266[] = { + /* 0 */ 1074, INVALID, INVALID, 1072, +}; + +static const uint16_t ud_itab__267[] = { + /* 0 */ 1266, INVALID, INVALID, 1264, +}; + +static const uint16_t ud_itab__268[] = { + /* 0 */ INVALID, 1559, INVALID, INVALID, +}; + +static const uint16_t ud_itab__269[] = { + /* 0 */ 1136, INVALID, INVALID, 1135, +}; + +static const uint16_t ud_itab__270[] = { + /* 0 */ 1140, INVALID, INVALID, 1139, +}; + +static const uint16_t ud_itab__271[] = { + /* 0 */ 1144, INVALID, INVALID, 1143, +}; + +static const uint16_t ud_itab__272[] = { + /* 0 */ 1533, INVALID, INVALID, 1534, +}; + +static const uint16_t ud_itab__273[] = { + /* 0 */ 1069, INVALID, INVALID, 1070, +}; + +static const uint16_t ud_itab__274[] = { + /* 0 */ 1133, INVALID, INVALID, 1131, +}; + +static const uint16_t ud_itab__275[] = { + /* 0 */ INVALID, GROUP(276), +}; + +static const uint16_t ud_itab__276[] = { + /* 0 */ 799, INVALID, INVALID, 1519, +}; + +static const uint16_t ud_itab__277[] = { + /* 0 */ 1179, INVALID, INVALID, 1177, +}; + +static const uint16_t ud_itab__278[] = { + /* 0 */ 1182, INVALID, INVALID, 1180, +}; + +static const uint16_t ud_itab__279[] = { + /* 0 */ 1183, INVALID, INVALID, 1184, +}; + +static const uint16_t ud_itab__280[] = { + /* 0 */ 1532, INVALID, INVALID, 1530, +}; + +static const uint16_t ud_itab__281[] = { + /* 0 */ 996, INVALID, INVALID, 994, +}; + +static const uint16_t ud_itab__282[] = { + /* 0 */ 997, INVALID, INVALID, 998, +}; + +static const uint16_t ud_itab__283[] = { + /* 0 */ 1000, INVALID, INVALID, 1001, +}; + +static const uint16_t ud_itab__284[] = { + /* 0 */ 1242, INVALID, +}; + +static const uint16_t ud_itab__285[] = { + /* 0 */ 1097, INVALID, +}; + +static const uint16_t ud_itab__286[] = { + /* 0 */ 1243, INVALID, +}; + +static const uint16_t ud_itab__287[] = { + /* 0 */ 1098, INVALID, +}; + +static const uint16_t ud_itab__288[] = { + /* 0 */ 173, INVALID, +}; + +static const uint16_t ud_itab__289[] = { + /* 0 */ 174, INVALID, +}; + +static const uint16_t ud_itab__290[] = { + /* 0 */ 1, INVALID, +}; + +static const uint16_t ud_itab__291[] = { + /* 0 */ 4, INVALID, +}; + +static const uint16_t ud_itab__292[] = { + /* 0 */ GROUP(293), GROUP(294), INVALID, +}; + +static const uint16_t ud_itab__293[] = { + /* 0 */ 1257, INVALID, +}; + +static const uint16_t ud_itab__294[] = { + /* 0 */ 1258, INVALID, +}; + +static const uint16_t ud_itab__295[] = { + /* 0 */ GROUP(296), GROUP(297), INVALID, +}; + +static const uint16_t ud_itab__296[] = { + /* 0 */ 1110, INVALID, +}; + +static const uint16_t ud_itab__297[] = { + /* 0 */ 1111, INVALID, +}; + +static const uint16_t ud_itab__298[] = { + /* 0 */ 1658, INVALID, +}; + +static const uint16_t ud_itab__299[] = { + /* 0 */ 67, 68, +}; + +static const uint16_t ud_itab__300[] = { + /* 0 */ 710, 711, INVALID, +}; + +static const uint16_t ud_itab__301[] = { + /* 0 */ 983, 984, INVALID, +}; + +static const uint16_t ud_itab__302[] = { + /* 0 */ 21, 970, 11, 1342, + /* 4 */ 55, 1413, 1493, 106, +}; + +static const uint16_t ud_itab__303[] = { + /* 0 */ 23, 971, 13, 1343, + /* 4 */ 57, 1414, 1494, 108, +}; + +static const uint16_t ud_itab__304[] = { + /* 0 */ GROUP(305), GROUP(306), GROUP(307), GROUP(308), + /* 4 */ GROUP(309), GROUP(310), GROUP(311), GROUP(312), +}; + +static const uint16_t ud_itab__305[] = { + /* 0 */ 22, INVALID, +}; + +static const uint16_t ud_itab__306[] = { + /* 0 */ 972, INVALID, +}; + +static const uint16_t ud_itab__307[] = { + /* 0 */ 12, INVALID, +}; + +static const uint16_t ud_itab__308[] = { + /* 0 */ 1344, INVALID, +}; + +static const uint16_t ud_itab__309[] = { + /* 0 */ 56, INVALID, +}; + +static const uint16_t ud_itab__310[] = { + /* 0 */ 1415, INVALID, +}; + +static const uint16_t ud_itab__311[] = { + /* 0 */ 1495, INVALID, +}; + +static const uint16_t ud_itab__312[] = { + /* 0 */ 107, INVALID, +}; + +static const uint16_t ud_itab__313[] = { + /* 0 */ 24, 973, 14, 1345, + /* 4 */ 58, 1416, 1496, 109, +}; + +static const uint16_t ud_itab__314[] = { + /* 0 */ 1109, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__315[] = { + /* 0 */ 74, 75, 76, +}; + +static const uint16_t ud_itab__316[] = { + /* 0 */ 170, 171, 172, +}; + +static const uint16_t ud_itab__317[] = { + /* 0 */ 73, INVALID, +}; + +static const uint16_t ud_itab__318[] = { + /* 0 */ GROUP(319), GROUP(320), GROUP(321), +}; + +static const uint16_t ud_itab__319[] = { + /* 0 */ 1259, 1260, +}; + +static const uint16_t ud_itab__320[] = { + /* 0 */ 1261, 1262, +}; + +static const uint16_t ud_itab__321[] = { + /* 0 */ INVALID, 1263, +}; + +static const uint16_t ud_itab__322[] = { + /* 0 */ GROUP(323), GROUP(324), GROUP(325), +}; + +static const uint16_t ud_itab__323[] = { + /* 0 */ 1112, INVALID, +}; + +static const uint16_t ud_itab__324[] = { + /* 0 */ 1113, 1114, +}; + +static const uint16_t ud_itab__325[] = { + /* 0 */ INVALID, 1115, +}; + +static const uint16_t ud_itab__326[] = { + /* 0 */ 923, 924, 927, +}; + +static const uint16_t ud_itab__327[] = { + /* 0 */ 115, 116, 119, +}; + +static const uint16_t ud_itab__328[] = { + /* 0 */ 1403, 1404, 1405, +}; + +static const uint16_t ud_itab__329[] = { + /* 0 */ 791, 792, 793, +}; + +static const uint16_t ud_itab__330[] = { + /* 0 */ 1347, 1348, 1349, +}; + +static const uint16_t ud_itab__331[] = { + /* 0 */ 1279, 1286, 1267, 1275, + /* 4 */ 1327, 1334, 1318, 1313, +}; + +static const uint16_t ud_itab__332[] = { + /* 0 */ 1284, 1287, 1268, 1274, + /* 4 */ 1323, 1330, 1319, 1315, +}; + +static const uint16_t ud_itab__333[] = { + /* 0 */ GROUP(334), GROUP(335), INVALID, INVALID, + /* 4 */ INVALID, GROUP(341), GROUP(357), GROUP(369), + /* 8 */ INVALID, GROUP(394), INVALID, INVALID, + /* c */ INVALID, GROUP(399), INVALID, INVALID, +}; + +static const uint16_t ud_itab__334[] = { + /* 0 */ 771, INVALID, +}; + +static const uint16_t ud_itab__335[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ 937, 939, GROUP(336), 895, + /* 14 */ 1450, 1448, GROUP(337), 885, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ 863, 865, INVALID, 908, + /* 2c */ INVALID, INVALID, 1443, 130, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ 901, 1388, 1307, 1292, + /* 54 */ 62, 66, 977, 1500, + /* 58 */ 28, 947, 146, 135, + /* 5c */ 1420, 819, 190, 803, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, GROUP(340), + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, GROUP(338), INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 113, INVALID, + /* c4 */ INVALID, INVALID, 1382, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__336[] = { + /* 0 */ 893, 897, +}; + +static const uint16_t ud_itab__337[] = { + /* 0 */ 883, 887, +}; + +static const uint16_t ud_itab__338[] = { + /* 0 */ GROUP(339), INVALID, +}; + +static const uint16_t ud_itab__339[] = { + /* 0 */ INVALID, INVALID, INVALID, 1401, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__340[] = { + /* 0 */ 1742, 1743, +}; + +static const uint16_t ud_itab__341[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ 933, 935, GROUP(342), 891, + /* 14 */ 1452, 1446, GROUP(343), 881, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ 859, 861, INVALID, 906, + /* 2c */ INVALID, INVALID, 1441, 128, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ 899, 1390, INVALID, INVALID, + /* 54 */ 60, 64, 975, 1498, + /* 58 */ 26, 945, 140, 144, + /* 5c */ 1418, 817, 188, 801, + /* 60 */ 1208, 1211, 1214, 986, + /* 64 */ 1037, 1040, 1043, 992, + /* 68 */ 1199, 1202, 1205, 989, + /* 6c */ 1548, 1546, GROUP(344), 1518, + /* 70 */ 1540, GROUP(345), GROUP(347), GROUP(349), + /* 74 */ 1029, 1032, 1035, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ 1550, 1554, GROUP(351), 1516, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 111, INVALID, + /* c4 */ 1061, 1054, 1380, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ 34, 1162, 1168, 1174, + /* d4 */ 1529, 1095, 919, GROUP(352), + /* d8 */ 1194, 1197, 1082, 1016, + /* dc */ 1011, 1014, 1077, 1019, + /* e0 */ 1022, 1149, 1155, 1025, + /* e4 */ 1089, 1091, 161, 903, + /* e8 */ 1188, 1191, 1079, 1117, + /* ec */ 1005, 1008, 1073, 1265, + /* f0 */ INVALID, GROUP(353), GROUP(354), GROUP(355), + /* f4 */ INVALID, 1071, 1132, GROUP(356), + /* f8 */ 1178, 1181, 1185, 1531, + /* fc */ 995, 999, 1002, INVALID, +}; + +static const uint16_t ud_itab__342[] = { + /* 0 */ 889, INVALID, +}; + +static const uint16_t ud_itab__343[] = { + /* 0 */ 879, INVALID, +}; + +static const uint16_t ud_itab__344[] = { + /* 0 */ 869, 871, 912, +}; + +static const uint16_t ud_itab__345[] = { + /* 0 */ INVALID, INVALID, 1164, INVALID, + /* 4 */ 1151, INVALID, GROUP(346), INVALID, +}; + +static const uint16_t ud_itab__346[] = { + /* 0 */ 1756, INVALID, +}; + +static const uint16_t ud_itab__347[] = { + /* 0 */ INVALID, INVALID, 1170, INVALID, + /* 4 */ 1158, INVALID, GROUP(348), INVALID, +}; + +static const uint16_t ud_itab__348[] = { + /* 0 */ 1758, INVALID, +}; + +static const uint16_t ud_itab__349[] = { + /* 0 */ INVALID, INVALID, 1176, 1544, + /* 4 */ INVALID, INVALID, GROUP(350), 1542, +}; + +static const uint16_t ud_itab__350[] = { + /* 0 */ 1760, INVALID, +}; + +static const uint16_t ud_itab__351[] = { + /* 0 */ 875, 877, 915, +}; + +static const uint16_t ud_itab__352[] = { + /* 0 */ 1085, INVALID, +}; + +static const uint16_t ud_itab__353[] = { + /* 0 */ 1755, INVALID, +}; + +static const uint16_t ud_itab__354[] = { + /* 0 */ 1757, INVALID, +}; + +static const uint16_t ud_itab__355[] = { + /* 0 */ 1759, INVALID, +}; + +static const uint16_t ud_itab__356[] = { + /* 0 */ INVALID, 1520, +}; + +static const uint16_t ud_itab__357[] = { + /* 0 */ 1584, 1587, 1590, 1593, + /* 4 */ 1596, 1599, 1602, 1605, + /* 8 */ 1608, 1614, 1611, 1617, + /* c */ GROUP(358), GROUP(359), GROUP(360), GROUP(361), + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ INVALID, INVALID, INVALID, 1712, + /* 18 */ GROUP(362), GROUP(363), INVALID, INVALID, + /* 1c */ 1575, 1578, 1581, INVALID, + /* 20 */ 1686, 1688, 1690, 1692, + /* 24 */ 1694, INVALID, INVALID, INVALID, + /* 28 */ 1623, 1709, 1682, 1684, + /* 2c */ GROUP(365), GROUP(366), GROUP(367), GROUP(368), + /* 30 */ 1697, 1699, 1701, 1703, + /* 34 */ 1705, 1707, INVALID, 1718, + /* 38 */ 1625, 1627, 1629, 1631, + /* 3c */ 1633, 1635, 1639, 1637, + /* 40 */ 1641, 1643, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, 46, + /* dc */ 42, 44, 38, 40, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__358[] = { + /* 0 */ 1737, INVALID, +}; + +static const uint16_t ud_itab__359[] = { + /* 0 */ 1735, INVALID, +}; + +static const uint16_t ud_itab__360[] = { + /* 0 */ 1740, INVALID, +}; + +static const uint16_t ud_itab__361[] = { + /* 0 */ 1741, INVALID, +}; + +static const uint16_t ud_itab__362[] = { + /* 0 */ 1727, INVALID, +}; + +static const uint16_t ud_itab__363[] = { + /* 0 */ GROUP(364), INVALID, +}; + +static const uint16_t ud_itab__364[] = { + /* 0 */ INVALID, 1728, +}; + +static const uint16_t ud_itab__365[] = { + /* 0 */ 1731, INVALID, +}; + +static const uint16_t ud_itab__366[] = { + /* 0 */ 1733, INVALID, +}; + +static const uint16_t ud_itab__367[] = { + /* 0 */ 1732, INVALID, +}; + +static const uint16_t ud_itab__368[] = { + /* 0 */ 1734, INVALID, +}; + +static const uint16_t ud_itab__369[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ GROUP(370), GROUP(371), GROUP(372), INVALID, + /* 8 */ 1645, 1647, 1649, 1651, + /* c */ 1655, 1653, 1678, 1620, + /* 10 */ INVALID, INVALID, INVALID, INVALID, + /* 14 */ GROUP(374), 1057, GROUP(375), 202, + /* 18 */ GROUP(379), GROUP(381), INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ GROUP(383), 1558, GROUP(385), INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ 198, 196, 1680, INVALID, + /* 44 */ 1513, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, GROUP(391), GROUP(392), + /* 4c */ GROUP(393), INVALID, INVALID, INVALID, + /* 50 */ INVALID, INVALID, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ INVALID, INVALID, INVALID, INVALID, + /* 5c */ INVALID, INVALID, INVALID, INVALID, + /* 60 */ 1716, 1714, 1722, 1720, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ INVALID, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, INVALID, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, 48, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, INVALID, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__370[] = { + /* 0 */ 1738, INVALID, +}; + +static const uint16_t ud_itab__371[] = { + /* 0 */ 1736, INVALID, +}; + +static const uint16_t ud_itab__372[] = { + /* 0 */ GROUP(373), INVALID, +}; + +static const uint16_t ud_itab__373[] = { + /* 0 */ INVALID, 1739, +}; + +static const uint16_t ud_itab__374[] = { + /* 0 */ 1046, INVALID, +}; + +static const uint16_t ud_itab__375[] = { + /* 0 */ GROUP(376), GROUP(377), GROUP(378), +}; + +static const uint16_t ud_itab__376[] = { + /* 0 */ 1048, INVALID, +}; + +static const uint16_t ud_itab__377[] = { + /* 0 */ 1050, INVALID, +}; + +static const uint16_t ud_itab__378[] = { + /* 0 */ INVALID, 1052, +}; + +static const uint16_t ud_itab__379[] = { + /* 0 */ GROUP(380), INVALID, +}; + +static const uint16_t ud_itab__380[] = { + /* 0 */ INVALID, 1730, +}; + +static const uint16_t ud_itab__381[] = { + /* 0 */ GROUP(382), INVALID, +}; + +static const uint16_t ud_itab__382[] = { + /* 0 */ INVALID, 1729, +}; + +static const uint16_t ud_itab__383[] = { + /* 0 */ GROUP(384), INVALID, +}; + +static const uint16_t ud_itab__384[] = { + /* 0 */ 1065, INVALID, +}; + +static const uint16_t ud_itab__385[] = { + /* 0 */ GROUP(386), GROUP(388), +}; + +static const uint16_t ud_itab__386[] = { + /* 0 */ GROUP(387), INVALID, +}; + +static const uint16_t ud_itab__387[] = { + /* 0 */ 1066, INVALID, +}; + +static const uint16_t ud_itab__388[] = { + /* 0 */ GROUP(389), GROUP(390), +}; + +static const uint16_t ud_itab__389[] = { + /* 0 */ 1067, INVALID, +}; + +static const uint16_t ud_itab__390[] = { + /* 0 */ 1068, INVALID, +}; + +static const uint16_t ud_itab__391[] = { + /* 0 */ 1745, INVALID, +}; + +static const uint16_t ud_itab__392[] = { + /* 0 */ 1744, INVALID, +}; + +static const uint16_t ud_itab__393[] = { + /* 0 */ 1754, INVALID, +}; + +static const uint16_t ud_itab__394[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ GROUP(395), GROUP(396), GROUP(397), INVALID, + /* 14 */ INVALID, INVALID, GROUP(398), INVALID, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, 155, INVALID, + /* 2c */ 169, 159, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, 1394, 1309, 1294, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ 32, 951, 157, 164, + /* 5c */ 1424, 823, 194, 807, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, 1523, + /* 70 */ 1536, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ INVALID, INVALID, 917, 1525, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 121, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ INVALID, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, 133, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ INVALID, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__395[] = { + /* 0 */ 1751, 1750, +}; + +static const uint16_t ud_itab__396[] = { + /* 0 */ 1753, 1752, +}; + +static const uint16_t ud_itab__397[] = { + /* 0 */ 1572, 1570, +}; + +static const uint16_t ud_itab__398[] = { + /* 0 */ 1568, 1566, +}; + +static const uint16_t ud_itab__399[] = { + /* 0 */ INVALID, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, + /* 8 */ INVALID, INVALID, INVALID, INVALID, + /* c */ INVALID, INVALID, INVALID, INVALID, + /* 10 */ GROUP(402), GROUP(400), GROUP(401), INVALID, + /* 14 */ INVALID, INVALID, INVALID, INVALID, + /* 18 */ INVALID, INVALID, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, INVALID, 153, INVALID, + /* 2c */ 167, 149, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, + /* 40 */ INVALID, INVALID, INVALID, INVALID, + /* 44 */ INVALID, INVALID, INVALID, INVALID, + /* 48 */ INVALID, INVALID, INVALID, INVALID, + /* 4c */ INVALID, INVALID, INVALID, INVALID, + /* 50 */ INVALID, 1392, INVALID, INVALID, + /* 54 */ INVALID, INVALID, INVALID, INVALID, + /* 58 */ 30, 949, 151, INVALID, + /* 5c */ 1422, 821, 192, 805, + /* 60 */ INVALID, INVALID, INVALID, INVALID, + /* 64 */ INVALID, INVALID, INVALID, INVALID, + /* 68 */ INVALID, INVALID, INVALID, INVALID, + /* 6c */ INVALID, INVALID, INVALID, INVALID, + /* 70 */ 1538, INVALID, INVALID, INVALID, + /* 74 */ INVALID, INVALID, INVALID, INVALID, + /* 78 */ INVALID, INVALID, INVALID, INVALID, + /* 7c */ 1552, 1556, INVALID, INVALID, + /* 80 */ INVALID, INVALID, INVALID, INVALID, + /* 84 */ INVALID, INVALID, INVALID, INVALID, + /* 88 */ INVALID, INVALID, INVALID, INVALID, + /* 8c */ INVALID, INVALID, INVALID, INVALID, + /* 90 */ INVALID, INVALID, INVALID, INVALID, + /* 94 */ INVALID, INVALID, INVALID, INVALID, + /* 98 */ INVALID, INVALID, INVALID, INVALID, + /* 9c */ INVALID, INVALID, INVALID, INVALID, + /* a0 */ INVALID, INVALID, INVALID, INVALID, + /* a4 */ INVALID, INVALID, INVALID, INVALID, + /* a8 */ INVALID, INVALID, INVALID, INVALID, + /* ac */ INVALID, INVALID, INVALID, INVALID, + /* b0 */ INVALID, INVALID, INVALID, INVALID, + /* b4 */ INVALID, INVALID, INVALID, INVALID, + /* b8 */ INVALID, INVALID, INVALID, INVALID, + /* bc */ INVALID, INVALID, INVALID, INVALID, + /* c0 */ INVALID, INVALID, 118, INVALID, + /* c4 */ INVALID, INVALID, INVALID, INVALID, + /* c8 */ INVALID, INVALID, INVALID, INVALID, + /* cc */ INVALID, INVALID, INVALID, INVALID, + /* d0 */ 36, INVALID, INVALID, INVALID, + /* d4 */ INVALID, INVALID, INVALID, INVALID, + /* d8 */ INVALID, INVALID, INVALID, INVALID, + /* dc */ INVALID, INVALID, INVALID, INVALID, + /* e0 */ INVALID, INVALID, INVALID, INVALID, + /* e4 */ INVALID, INVALID, 137, INVALID, + /* e8 */ INVALID, INVALID, INVALID, INVALID, + /* ec */ INVALID, INVALID, INVALID, INVALID, + /* f0 */ 1560, INVALID, INVALID, INVALID, + /* f4 */ INVALID, INVALID, INVALID, INVALID, + /* f8 */ INVALID, INVALID, INVALID, INVALID, + /* fc */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__400[] = { + /* 0 */ 1749, 1748, +}; + +static const uint16_t ud_itab__401[] = { + /* 0 */ 1564, 1562, +}; + +static const uint16_t ud_itab__402[] = { + /* 0 */ 1747, 1746, +}; + +static const uint16_t ud_itab__403[] = { + /* 0 */ GROUP(404), GROUP(335), INVALID, INVALID, + /* 4 */ INVALID, GROUP(341), GROUP(357), GROUP(369), + /* 8 */ INVALID, GROUP(394), INVALID, INVALID, + /* c */ INVALID, GROUP(399), INVALID, INVALID, +}; + +static const uint16_t ud_itab__404[] = { + /* 0 */ 769, INVALID, +}; + +static const uint16_t ud_itab__405[] = { + /* 0 */ 826, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__406[] = { + /* 0 */ 827, INVALID, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__407[] = { + /* 0 */ 715, INVALID, +}; + +static const uint16_t ud_itab__408[] = { + /* 0 */ 723, 724, 725, +}; + +static const uint16_t ud_itab__409[] = { + /* 0 */ 1280, 1285, 1269, 1273, + /* 4 */ 1326, 1333, 1320, 1314, +}; + +static const uint16_t ud_itab__410[] = { + /* 0 */ 1281, 1288, 1272, 1276, + /* 4 */ 1325, 1332, 1329, 1312, +}; + +static const uint16_t ud_itab__411[] = { + /* 0 */ 1282, 1289, 1270, 1277, + /* 4 */ 1324, 1331, 1321, 1316, +}; + +static const uint16_t ud_itab__412[] = { + /* 0 */ 1283, 1290, 1271, 1278, + /* 4 */ 1328, 1335, 1322, 1317, +}; + +static const uint16_t ud_itab__413[] = { + /* 0 */ 3, INVALID, +}; + +static const uint16_t ud_itab__414[] = { + /* 0 */ 2, INVALID, +}; + +static const uint16_t ud_itab__415[] = { + /* 0 */ 1311, INVALID, +}; + +static const uint16_t ud_itab__416[] = { + /* 0 */ GROUP(417), GROUP(418), +}; + +static const uint16_t ud_itab__417[] = { + /* 0 */ 206, 503, 307, 357, + /* 4 */ 587, 630, 387, 413, +}; + +static const uint16_t ud_itab__418[] = { + /* 0 */ 215, 216, 217, 218, + /* 4 */ 219, 220, 221, 222, + /* 8 */ 504, 505, 506, 507, + /* c */ 508, 509, 510, 511, + /* 10 */ 309, 310, 311, 312, + /* 14 */ 313, 314, 315, 316, + /* 18 */ 359, 360, 361, 362, + /* 1c */ 363, 364, 365, 366, + /* 20 */ 589, 590, 591, 592, + /* 24 */ 593, 594, 595, 596, + /* 28 */ 614, 615, 616, 617, + /* 2c */ 618, 619, 620, 621, + /* 30 */ 388, 389, 390, 391, + /* 34 */ 392, 393, 394, 395, + /* 38 */ 414, 415, 416, 417, + /* 3c */ 418, 419, 420, 421, +}; + +static const uint16_t ud_itab__419[] = { + /* 0 */ GROUP(420), GROUP(421), +}; + +static const uint16_t ud_itab__420[] = { + /* 0 */ 476, INVALID, 573, 540, + /* 4 */ 493, 492, 584, 583, +}; + +static const uint16_t ud_itab__421[] = { + /* 0 */ 477, 478, 479, 480, + /* 4 */ 481, 482, 483, 484, + /* 8 */ 658, 659, 660, 661, + /* c */ 662, 663, 664, 665, + /* 10 */ 522, INVALID, INVALID, INVALID, + /* 14 */ INVALID, INVALID, INVALID, INVALID, + /* 18 */ 549, 550, 551, 552, + /* 1c */ 553, 554, 555, 556, + /* 20 */ 233, 204, INVALID, INVALID, + /* 24 */ 639, 657, INVALID, INVALID, + /* 28 */ 485, 486, 487, 488, + /* 2c */ 489, 490, 491, INVALID, + /* 30 */ 203, 685, 529, 526, + /* 34 */ 684, 528, 377, 454, + /* 38 */ 527, 686, 537, 536, + /* 3c */ 530, 534, 535, 376, +}; + +static const uint16_t ud_itab__422[] = { + /* 0 */ GROUP(423), GROUP(424), +}; + +static const uint16_t ud_itab__423[] = { + /* 0 */ 456, 520, 448, 450, + /* 4 */ 462, 464, 460, 458, +}; + +static const uint16_t ud_itab__424[] = { + /* 0 */ 235, 236, 237, 238, + /* 4 */ 239, 240, 241, 242, + /* 8 */ 243, 244, 245, 246, + /* c */ 247, 248, 249, 250, + /* 10 */ 251, 252, 253, 254, + /* 14 */ 255, 256, 257, 258, + /* 18 */ 259, 260, 261, 262, + /* 1c */ 263, 264, 265, 266, + /* 20 */ INVALID, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ INVALID, 656, INVALID, INVALID, + /* 2c */ INVALID, INVALID, INVALID, INVALID, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__425[] = { + /* 0 */ GROUP(426), GROUP(427), +}; + +static const uint16_t ud_itab__426[] = { + /* 0 */ 453, 471, 467, 470, + /* 4 */ INVALID, 474, INVALID, 538, +}; + +static const uint16_t ud_itab__427[] = { + /* 0 */ 267, 268, 269, 270, + /* 4 */ 271, 272, 273, 274, + /* 8 */ 275, 276, 277, 278, + /* c */ 279, 280, 281, 282, + /* 10 */ 283, 284, 285, 286, + /* 14 */ 287, 288, 289, 290, + /* 18 */ 291, 292, 293, 294, + /* 1c */ 295, 296, 297, 298, + /* 20 */ 524, 523, 234, 455, + /* 24 */ 525, 532, INVALID, INVALID, + /* 28 */ 299, 300, 301, 302, + /* 2c */ 303, 304, 305, 306, + /* 30 */ 333, 334, 335, 336, + /* 34 */ 337, 338, 339, 340, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__428[] = { + /* 0 */ GROUP(429), GROUP(430), +}; + +static const uint16_t ud_itab__429[] = { + /* 0 */ 205, 494, 308, 358, + /* 4 */ 588, 613, 378, 404, +}; + +static const uint16_t ud_itab__430[] = { + /* 0 */ 207, 208, 209, 210, + /* 4 */ 211, 212, 213, 214, + /* 8 */ 495, 496, 497, 498, + /* c */ 499, 500, 501, 502, + /* 10 */ 317, 318, 319, 320, + /* 14 */ 321, 322, 323, 324, + /* 18 */ 325, 326, 327, 328, + /* 1c */ 329, 330, 331, 332, + /* 20 */ 622, 623, 624, 625, + /* 24 */ 626, 627, 628, 629, + /* 28 */ 597, 598, 599, 600, + /* 2c */ 601, 602, 603, 604, + /* 30 */ 405, 406, 407, 408, + /* 34 */ 409, 410, 411, 412, + /* 38 */ 379, 380, 381, 382, + /* 3c */ 383, 384, 385, 386, +}; + +static const uint16_t ud_itab__431[] = { + /* 0 */ GROUP(432), GROUP(433), +}; + +static const uint16_t ud_itab__432[] = { + /* 0 */ 475, 472, 574, 539, + /* 4 */ 531, INVALID, 533, 585, +}; + +static const uint16_t ud_itab__433[] = { + /* 0 */ 431, 432, 433, 434, + /* 4 */ 435, 436, 437, 438, + /* 8 */ 666, 667, 668, 669, + /* c */ 670, 671, 672, 673, + /* 10 */ 575, 576, 577, 578, + /* 14 */ 579, 580, 581, 582, + /* 18 */ 541, 542, 543, 544, + /* 1c */ 545, 546, 547, 548, + /* 20 */ 640, 641, 642, 643, + /* 24 */ 644, 645, 646, 647, + /* 28 */ 648, 649, 650, 651, + /* 2c */ 652, 653, 654, 655, + /* 30 */ INVALID, INVALID, INVALID, INVALID, + /* 34 */ INVALID, INVALID, INVALID, INVALID, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__434[] = { + /* 0 */ GROUP(435), GROUP(436), +}; + +static const uint16_t ud_itab__435[] = { + /* 0 */ 457, 521, 447, 449, + /* 4 */ 463, 465, 461, 459, +}; + +static const uint16_t ud_itab__436[] = { + /* 0 */ 223, 224, 225, 226, + /* 4 */ 227, 228, 229, 230, + /* 8 */ 512, 513, 514, 515, + /* c */ 516, 517, 518, 519, + /* 10 */ 367, 368, 369, 370, + /* 14 */ 371, 372, 373, 374, + /* 18 */ INVALID, 375, INVALID, INVALID, + /* 1c */ INVALID, INVALID, INVALID, INVALID, + /* 20 */ 631, 632, 633, 634, + /* 24 */ 635, 636, 637, 638, + /* 28 */ 605, 606, 607, 608, + /* 2c */ 609, 610, 611, 612, + /* 30 */ 422, 423, 424, 425, + /* 34 */ 426, 427, 428, 429, + /* 38 */ 396, 397, 398, 399, + /* 3c */ 400, 401, 402, 403, +}; + +static const uint16_t ud_itab__437[] = { + /* 0 */ GROUP(438), GROUP(439), +}; + +static const uint16_t ud_itab__438[] = { + /* 0 */ 451, 473, 466, 468, + /* 4 */ 231, 452, 232, 469, +}; + +static const uint16_t ud_itab__439[] = { + /* 0 */ 439, 440, 441, 442, + /* 4 */ 443, 444, 445, 446, + /* 8 */ 674, 675, 676, 677, + /* c */ 678, 679, 680, 681, + /* 10 */ 557, 558, 559, 560, + /* 14 */ 561, 562, 563, 564, + /* 18 */ 565, 566, 567, 568, + /* 1c */ 569, 570, 571, 572, + /* 20 */ 586, INVALID, INVALID, INVALID, + /* 24 */ INVALID, INVALID, INVALID, INVALID, + /* 28 */ 341, 342, 343, 344, + /* 2c */ 345, 346, 347, 348, + /* 30 */ 349, 350, 351, 352, + /* 34 */ 353, 354, 355, 356, + /* 38 */ INVALID, INVALID, INVALID, INVALID, + /* 3c */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__440[] = { + /* 0 */ 758, 759, 760, +}; + +static const uint16_t ud_itab__441[] = { + /* 0 */ 764, INVALID, +}; + +static const uint16_t ud_itab__442[] = { + /* 0 */ 1432, 1437, 962, 953, + /* 4 */ 942, 695, 186, 689, +}; + +static const uint16_t ud_itab__443[] = { + /* 0 */ 1438, 1439, 963, 954, + /* 4 */ 943, 696, 185, 688, +}; + +static const uint16_t ud_itab__444[] = { + /* 0 */ 708, 183, INVALID, INVALID, + /* 4 */ INVALID, INVALID, INVALID, INVALID, +}; + +static const uint16_t ud_itab__445[] = { + /* 0 */ 707, 184, GROUP(446), 71, + /* 4 */ 761, 762, 1255, INVALID, +}; + +static const uint16_t ud_itab__446[] = { + /* 0 */ 69, 70, +}; + + +struct ud_lookup_table_list_entry ud_lookup_table_list[] = { + /* 000 */ { ud_itab__0, UD_TAB__OPC_TABLE, "opctbl" }, + /* 001 */ { ud_itab__1, UD_TAB__OPC_MODE, "/m" }, + /* 002 */ { ud_itab__2, UD_TAB__OPC_MODE, "/m" }, + /* 003 */ { ud_itab__3, UD_TAB__OPC_MODE, "/m" }, + /* 004 */ { ud_itab__4, UD_TAB__OPC_TABLE, "opctbl" }, + /* 005 */ { ud_itab__5, UD_TAB__OPC_REG, "/reg" }, + /* 006 */ { ud_itab__6, UD_TAB__OPC_MOD, "/mod" }, + /* 007 */ { ud_itab__7, UD_TAB__OPC_REG, "/reg" }, + /* 008 */ { ud_itab__8, UD_TAB__OPC_REG, "/reg" }, + /* 009 */ { ud_itab__9, UD_TAB__OPC_RM, "/rm" }, + /* 010 */ { ud_itab__10, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 011 */ { ud_itab__11, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 012 */ { ud_itab__12, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 013 */ { ud_itab__13, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 014 */ { ud_itab__14, UD_TAB__OPC_RM, "/rm" }, + /* 015 */ { ud_itab__15, UD_TAB__OPC_RM, "/rm" }, + /* 016 */ { ud_itab__16, UD_TAB__OPC_RM, "/rm" }, + /* 017 */ { ud_itab__17, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 018 */ { ud_itab__18, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 019 */ { ud_itab__19, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 020 */ { ud_itab__20, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 021 */ { ud_itab__21, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 022 */ { ud_itab__22, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 023 */ { ud_itab__23, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 024 */ { ud_itab__24, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 025 */ { ud_itab__25, UD_TAB__OPC_RM, "/rm" }, + /* 026 */ { ud_itab__26, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 027 */ { ud_itab__27, UD_TAB__OPC_REG, "/reg" }, + /* 028 */ { ud_itab__28, UD_TAB__OPC_3DNOW, "/3dnow" }, + /* 029 */ { ud_itab__29, UD_TAB__OPC_SSE, "/sse" }, + /* 030 */ { ud_itab__30, UD_TAB__OPC_SSE, "/sse" }, + /* 031 */ { ud_itab__31, UD_TAB__OPC_MOD, "/mod" }, + /* 032 */ { ud_itab__32, UD_TAB__OPC_SSE, "/sse" }, + /* 033 */ { ud_itab__33, UD_TAB__OPC_SSE, "/sse" }, + /* 034 */ { ud_itab__34, UD_TAB__OPC_SSE, "/sse" }, + /* 035 */ { ud_itab__35, UD_TAB__OPC_SSE, "/sse" }, + /* 036 */ { ud_itab__36, UD_TAB__OPC_SSE, "/sse" }, + /* 037 */ { ud_itab__37, UD_TAB__OPC_MOD, "/mod" }, + /* 038 */ { ud_itab__38, UD_TAB__OPC_SSE, "/sse" }, + /* 039 */ { ud_itab__39, UD_TAB__OPC_SSE, "/sse" }, + /* 040 */ { ud_itab__40, UD_TAB__OPC_SSE, "/sse" }, + /* 041 */ { ud_itab__41, UD_TAB__OPC_REG, "/reg" }, + /* 042 */ { ud_itab__42, UD_TAB__OPC_SSE, "/sse" }, + /* 043 */ { ud_itab__43, UD_TAB__OPC_SSE, "/sse" }, + /* 044 */ { ud_itab__44, UD_TAB__OPC_SSE, "/sse" }, + /* 045 */ { ud_itab__45, UD_TAB__OPC_SSE, "/sse" }, + /* 046 */ { ud_itab__46, UD_TAB__OPC_SSE, "/sse" }, + /* 047 */ { ud_itab__47, UD_TAB__OPC_SSE, "/sse" }, + /* 048 */ { ud_itab__48, UD_TAB__OPC_SSE, "/sse" }, + /* 049 */ { ud_itab__49, UD_TAB__OPC_SSE, "/sse" }, + /* 050 */ { ud_itab__50, UD_TAB__OPC_MODE, "/m" }, + /* 051 */ { ud_itab__51, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 052 */ { ud_itab__52, UD_TAB__OPC_MODE, "/m" }, + /* 053 */ { ud_itab__53, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 054 */ { ud_itab__54, UD_TAB__OPC_TABLE, "opctbl" }, + /* 055 */ { ud_itab__55, UD_TAB__OPC_SSE, "/sse" }, + /* 056 */ { ud_itab__56, UD_TAB__OPC_MODE, "/m" }, + /* 057 */ { ud_itab__57, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 058 */ { ud_itab__58, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 059 */ { ud_itab__59, UD_TAB__OPC_SSE, "/sse" }, + /* 060 */ { ud_itab__60, UD_TAB__OPC_MODE, "/m" }, + /* 061 */ { ud_itab__61, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 062 */ { ud_itab__62, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 063 */ { ud_itab__63, UD_TAB__OPC_SSE, "/sse" }, + /* 064 */ { ud_itab__64, UD_TAB__OPC_SSE, "/sse" }, + /* 065 */ { ud_itab__65, UD_TAB__OPC_SSE, "/sse" }, + /* 066 */ { ud_itab__66, UD_TAB__OPC_SSE, "/sse" }, + /* 067 */ { ud_itab__67, UD_TAB__OPC_SSE, "/sse" }, + /* 068 */ { ud_itab__68, UD_TAB__OPC_SSE, "/sse" }, + /* 069 */ { ud_itab__69, UD_TAB__OPC_SSE, "/sse" }, + /* 070 */ { ud_itab__70, UD_TAB__OPC_SSE, "/sse" }, + /* 071 */ { ud_itab__71, UD_TAB__OPC_SSE, "/sse" }, + /* 072 */ { ud_itab__72, UD_TAB__OPC_SSE, "/sse" }, + /* 073 */ { ud_itab__73, UD_TAB__OPC_SSE, "/sse" }, + /* 074 */ { ud_itab__74, UD_TAB__OPC_SSE, "/sse" }, + /* 075 */ { ud_itab__75, UD_TAB__OPC_SSE, "/sse" }, + /* 076 */ { ud_itab__76, UD_TAB__OPC_SSE, "/sse" }, + /* 077 */ { ud_itab__77, UD_TAB__OPC_SSE, "/sse" }, + /* 078 */ { ud_itab__78, UD_TAB__OPC_SSE, "/sse" }, + /* 079 */ { ud_itab__79, UD_TAB__OPC_SSE, "/sse" }, + /* 080 */ { ud_itab__80, UD_TAB__OPC_SSE, "/sse" }, + /* 081 */ { ud_itab__81, UD_TAB__OPC_SSE, "/sse" }, + /* 082 */ { ud_itab__82, UD_TAB__OPC_SSE, "/sse" }, + /* 083 */ { ud_itab__83, UD_TAB__OPC_SSE, "/sse" }, + /* 084 */ { ud_itab__84, UD_TAB__OPC_SSE, "/sse" }, + /* 085 */ { ud_itab__85, UD_TAB__OPC_SSE, "/sse" }, + /* 086 */ { ud_itab__86, UD_TAB__OPC_SSE, "/sse" }, + /* 087 */ { ud_itab__87, UD_TAB__OPC_SSE, "/sse" }, + /* 088 */ { ud_itab__88, UD_TAB__OPC_SSE, "/sse" }, + /* 089 */ { ud_itab__89, UD_TAB__OPC_SSE, "/sse" }, + /* 090 */ { ud_itab__90, UD_TAB__OPC_SSE, "/sse" }, + /* 091 */ { ud_itab__91, UD_TAB__OPC_SSE, "/sse" }, + /* 092 */ { ud_itab__92, UD_TAB__OPC_SSE, "/sse" }, + /* 093 */ { ud_itab__93, UD_TAB__OPC_SSE, "/sse" }, + /* 094 */ { ud_itab__94, UD_TAB__OPC_SSE, "/sse" }, + /* 095 */ { ud_itab__95, UD_TAB__OPC_SSE, "/sse" }, + /* 096 */ { ud_itab__96, UD_TAB__OPC_SSE, "/sse" }, + /* 097 */ { ud_itab__97, UD_TAB__OPC_SSE, "/sse" }, + /* 098 */ { ud_itab__98, UD_TAB__OPC_SSE, "/sse" }, + /* 099 */ { ud_itab__99, UD_TAB__OPC_SSE, "/sse" }, + /* 100 */ { ud_itab__100, UD_TAB__OPC_SSE, "/sse" }, + /* 101 */ { ud_itab__101, UD_TAB__OPC_SSE, "/sse" }, + /* 102 */ { ud_itab__102, UD_TAB__OPC_SSE, "/sse" }, + /* 103 */ { ud_itab__103, UD_TAB__OPC_SSE, "/sse" }, + /* 104 */ { ud_itab__104, UD_TAB__OPC_SSE, "/sse" }, + /* 105 */ { ud_itab__105, UD_TAB__OPC_SSE, "/sse" }, + /* 106 */ { ud_itab__106, UD_TAB__OPC_SSE, "/sse" }, + /* 107 */ { ud_itab__107, UD_TAB__OPC_SSE, "/sse" }, + /* 108 */ { ud_itab__108, UD_TAB__OPC_SSE, "/sse" }, + /* 109 */ { ud_itab__109, UD_TAB__OPC_SSE, "/sse" }, + /* 110 */ { ud_itab__110, UD_TAB__OPC_SSE, "/sse" }, + /* 111 */ { ud_itab__111, UD_TAB__OPC_SSE, "/sse" }, + /* 112 */ { ud_itab__112, UD_TAB__OPC_SSE, "/sse" }, + /* 113 */ { ud_itab__113, UD_TAB__OPC_SSE, "/sse" }, + /* 114 */ { ud_itab__114, UD_TAB__OPC_SSE, "/sse" }, + /* 115 */ { ud_itab__115, UD_TAB__OPC_SSE, "/sse" }, + /* 116 */ { ud_itab__116, UD_TAB__OPC_TABLE, "opctbl" }, + /* 117 */ { ud_itab__117, UD_TAB__OPC_SSE, "/sse" }, + /* 118 */ { ud_itab__118, UD_TAB__OPC_SSE, "/sse" }, + /* 119 */ { ud_itab__119, UD_TAB__OPC_SSE, "/sse" }, + /* 120 */ { ud_itab__120, UD_TAB__OPC_SSE, "/sse" }, + /* 121 */ { ud_itab__121, UD_TAB__OPC_SSE, "/sse" }, + /* 122 */ { ud_itab__122, UD_TAB__OPC_SSE, "/sse" }, + /* 123 */ { ud_itab__123, UD_TAB__OPC_SSE, "/sse" }, + /* 124 */ { ud_itab__124, UD_TAB__OPC_SSE, "/sse" }, + /* 125 */ { ud_itab__125, UD_TAB__OPC_SSE, "/sse" }, + /* 126 */ { ud_itab__126, UD_TAB__OPC_SSE, "/sse" }, + /* 127 */ { ud_itab__127, UD_TAB__OPC_SSE, "/sse" }, + /* 128 */ { ud_itab__128, UD_TAB__OPC_OSIZE, "/o" }, + /* 129 */ { ud_itab__129, UD_TAB__OPC_SSE, "/sse" }, + /* 130 */ { ud_itab__130, UD_TAB__OPC_SSE, "/sse" }, + /* 131 */ { ud_itab__131, UD_TAB__OPC_SSE, "/sse" }, + /* 132 */ { ud_itab__132, UD_TAB__OPC_SSE, "/sse" }, + /* 133 */ { ud_itab__133, UD_TAB__OPC_OSIZE, "/o" }, + /* 134 */ { ud_itab__134, UD_TAB__OPC_SSE, "/sse" }, + /* 135 */ { ud_itab__135, UD_TAB__OPC_SSE, "/sse" }, + /* 136 */ { ud_itab__136, UD_TAB__OPC_SSE, "/sse" }, + /* 137 */ { ud_itab__137, UD_TAB__OPC_SSE, "/sse" }, + /* 138 */ { ud_itab__138, UD_TAB__OPC_SSE, "/sse" }, + /* 139 */ { ud_itab__139, UD_TAB__OPC_SSE, "/sse" }, + /* 140 */ { ud_itab__140, UD_TAB__OPC_SSE, "/sse" }, + /* 141 */ { ud_itab__141, UD_TAB__OPC_SSE, "/sse" }, + /* 142 */ { ud_itab__142, UD_TAB__OPC_SSE, "/sse" }, + /* 143 */ { ud_itab__143, UD_TAB__OPC_SSE, "/sse" }, + /* 144 */ { ud_itab__144, UD_TAB__OPC_SSE, "/sse" }, + /* 145 */ { ud_itab__145, UD_TAB__OPC_SSE, "/sse" }, + /* 146 */ { ud_itab__146, UD_TAB__OPC_SSE, "/sse" }, + /* 147 */ { ud_itab__147, UD_TAB__OPC_SSE, "/sse" }, + /* 148 */ { ud_itab__148, UD_TAB__OPC_SSE, "/sse" }, + /* 149 */ { ud_itab__149, UD_TAB__OPC_SSE, "/sse" }, + /* 150 */ { ud_itab__150, UD_TAB__OPC_SSE, "/sse" }, + /* 151 */ { ud_itab__151, UD_TAB__OPC_SSE, "/sse" }, + /* 152 */ { ud_itab__152, UD_TAB__OPC_SSE, "/sse" }, + /* 153 */ { ud_itab__153, UD_TAB__OPC_SSE, "/sse" }, + /* 154 */ { ud_itab__154, UD_TAB__OPC_SSE, "/sse" }, + /* 155 */ { ud_itab__155, UD_TAB__OPC_SSE, "/sse" }, + /* 156 */ { ud_itab__156, UD_TAB__OPC_SSE, "/sse" }, + /* 157 */ { ud_itab__157, UD_TAB__OPC_SSE, "/sse" }, + /* 158 */ { ud_itab__158, UD_TAB__OPC_SSE, "/sse" }, + /* 159 */ { ud_itab__159, UD_TAB__OPC_SSE, "/sse" }, + /* 160 */ { ud_itab__160, UD_TAB__OPC_SSE, "/sse" }, + /* 161 */ { ud_itab__161, UD_TAB__OPC_SSE, "/sse" }, + /* 162 */ { ud_itab__162, UD_TAB__OPC_SSE, "/sse" }, + /* 163 */ { ud_itab__163, UD_TAB__OPC_SSE, "/sse" }, + /* 164 */ { ud_itab__164, UD_TAB__OPC_SSE, "/sse" }, + /* 165 */ { ud_itab__165, UD_TAB__OPC_SSE, "/sse" }, + /* 166 */ { ud_itab__166, UD_TAB__OPC_SSE, "/sse" }, + /* 167 */ { ud_itab__167, UD_TAB__OPC_SSE, "/sse" }, + /* 168 */ { ud_itab__168, UD_TAB__OPC_SSE, "/sse" }, + /* 169 */ { ud_itab__169, UD_TAB__OPC_SSE, "/sse" }, + /* 170 */ { ud_itab__170, UD_TAB__OPC_SSE, "/sse" }, + /* 171 */ { ud_itab__171, UD_TAB__OPC_SSE, "/sse" }, + /* 172 */ { ud_itab__172, UD_TAB__OPC_SSE, "/sse" }, + /* 173 */ { ud_itab__173, UD_TAB__OPC_SSE, "/sse" }, + /* 174 */ { ud_itab__174, UD_TAB__OPC_OSIZE, "/o" }, + /* 175 */ { ud_itab__175, UD_TAB__OPC_OSIZE, "/o" }, + /* 176 */ { ud_itab__176, UD_TAB__OPC_SSE, "/sse" }, + /* 177 */ { ud_itab__177, UD_TAB__OPC_SSE, "/sse" }, + /* 178 */ { ud_itab__178, UD_TAB__OPC_REG, "/reg" }, + /* 179 */ { ud_itab__179, UD_TAB__OPC_SSE, "/sse" }, + /* 180 */ { ud_itab__180, UD_TAB__OPC_SSE, "/sse" }, + /* 181 */ { ud_itab__181, UD_TAB__OPC_SSE, "/sse" }, + /* 182 */ { ud_itab__182, UD_TAB__OPC_REG, "/reg" }, + /* 183 */ { ud_itab__183, UD_TAB__OPC_SSE, "/sse" }, + /* 184 */ { ud_itab__184, UD_TAB__OPC_SSE, "/sse" }, + /* 185 */ { ud_itab__185, UD_TAB__OPC_SSE, "/sse" }, + /* 186 */ { ud_itab__186, UD_TAB__OPC_REG, "/reg" }, + /* 187 */ { ud_itab__187, UD_TAB__OPC_SSE, "/sse" }, + /* 188 */ { ud_itab__188, UD_TAB__OPC_SSE, "/sse" }, + /* 189 */ { ud_itab__189, UD_TAB__OPC_SSE, "/sse" }, + /* 190 */ { ud_itab__190, UD_TAB__OPC_SSE, "/sse" }, + /* 191 */ { ud_itab__191, UD_TAB__OPC_SSE, "/sse" }, + /* 192 */ { ud_itab__192, UD_TAB__OPC_SSE, "/sse" }, + /* 193 */ { ud_itab__193, UD_TAB__OPC_SSE, "/sse" }, + /* 194 */ { ud_itab__194, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 195 */ { ud_itab__195, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 196 */ { ud_itab__196, UD_TAB__OPC_SSE, "/sse" }, + /* 197 */ { ud_itab__197, UD_TAB__OPC_SSE, "/sse" }, + /* 198 */ { ud_itab__198, UD_TAB__OPC_SSE, "/sse" }, + /* 199 */ { ud_itab__199, UD_TAB__OPC_OSIZE, "/o" }, + /* 200 */ { ud_itab__200, UD_TAB__OPC_OSIZE, "/o" }, + /* 201 */ { ud_itab__201, UD_TAB__OPC_SSE, "/sse" }, + /* 202 */ { ud_itab__202, UD_TAB__OPC_MOD, "/mod" }, + /* 203 */ { ud_itab__203, UD_TAB__OPC_REG, "/reg" }, + /* 204 */ { ud_itab__204, UD_TAB__OPC_RM, "/rm" }, + /* 205 */ { ud_itab__205, UD_TAB__OPC_RM, "/rm" }, + /* 206 */ { ud_itab__206, UD_TAB__OPC_RM, "/rm" }, + /* 207 */ { ud_itab__207, UD_TAB__OPC_MOD, "/mod" }, + /* 208 */ { ud_itab__208, UD_TAB__OPC_REG, "/reg" }, + /* 209 */ { ud_itab__209, UD_TAB__OPC_RM, "/rm" }, + /* 210 */ { ud_itab__210, UD_TAB__OPC_RM, "/rm" }, + /* 211 */ { ud_itab__211, UD_TAB__OPC_RM, "/rm" }, + /* 212 */ { ud_itab__212, UD_TAB__OPC_RM, "/rm" }, + /* 213 */ { ud_itab__213, UD_TAB__OPC_RM, "/rm" }, + /* 214 */ { ud_itab__214, UD_TAB__OPC_RM, "/rm" }, + /* 215 */ { ud_itab__215, UD_TAB__OPC_MOD, "/mod" }, + /* 216 */ { ud_itab__216, UD_TAB__OPC_REG, "/reg" }, + /* 217 */ { ud_itab__217, UD_TAB__OPC_REG, "/reg" }, + /* 218 */ { ud_itab__218, UD_TAB__OPC_RM, "/rm" }, + /* 219 */ { ud_itab__219, UD_TAB__OPC_RM, "/rm" }, + /* 220 */ { ud_itab__220, UD_TAB__OPC_RM, "/rm" }, + /* 221 */ { ud_itab__221, UD_TAB__OPC_SSE, "/sse" }, + /* 222 */ { ud_itab__222, UD_TAB__OPC_REG, "/reg" }, + /* 223 */ { ud_itab__223, UD_TAB__OPC_SSE, "/sse" }, + /* 224 */ { ud_itab__224, UD_TAB__OPC_SSE, "/sse" }, + /* 225 */ { ud_itab__225, UD_TAB__OPC_SSE, "/sse" }, + /* 226 */ { ud_itab__226, UD_TAB__OPC_SSE, "/sse" }, + /* 227 */ { ud_itab__227, UD_TAB__OPC_MOD, "/mod" }, + /* 228 */ { ud_itab__228, UD_TAB__OPC_REG, "/reg" }, + /* 229 */ { ud_itab__229, UD_TAB__OPC_OSIZE, "/o" }, + /* 230 */ { ud_itab__230, UD_TAB__OPC_SSE, "/sse" }, + /* 231 */ { ud_itab__231, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 232 */ { ud_itab__232, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 233 */ { ud_itab__233, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 234 */ { ud_itab__234, UD_TAB__OPC_VENDOR, "/vendor" }, + /* 235 */ { ud_itab__235, UD_TAB__OPC_REG, "/reg" }, + /* 236 */ { ud_itab__236, UD_TAB__OPC_SSE, "/sse" }, + /* 237 */ { ud_itab__237, UD_TAB__OPC_SSE, "/sse" }, + /* 238 */ { ud_itab__238, UD_TAB__OPC_SSE, "/sse" }, + /* 239 */ { ud_itab__239, UD_TAB__OPC_SSE, "/sse" }, + /* 240 */ { ud_itab__240, UD_TAB__OPC_SSE, "/sse" }, + /* 241 */ { ud_itab__241, UD_TAB__OPC_SSE, "/sse" }, + /* 242 */ { ud_itab__242, UD_TAB__OPC_SSE, "/sse" }, + /* 243 */ { ud_itab__243, UD_TAB__OPC_SSE, "/sse" }, + /* 244 */ { ud_itab__244, UD_TAB__OPC_SSE, "/sse" }, + /* 245 */ { ud_itab__245, UD_TAB__OPC_SSE, "/sse" }, + /* 246 */ { ud_itab__246, UD_TAB__OPC_SSE, "/sse" }, + /* 247 */ { ud_itab__247, UD_TAB__OPC_SSE, "/sse" }, + /* 248 */ { ud_itab__248, UD_TAB__OPC_SSE, "/sse" }, + /* 249 */ { ud_itab__249, UD_TAB__OPC_SSE, "/sse" }, + /* 250 */ { ud_itab__250, UD_TAB__OPC_SSE, "/sse" }, + /* 251 */ { ud_itab__251, UD_TAB__OPC_SSE, "/sse" }, + /* 252 */ { ud_itab__252, UD_TAB__OPC_SSE, "/sse" }, + /* 253 */ { ud_itab__253, UD_TAB__OPC_SSE, "/sse" }, + /* 254 */ { ud_itab__254, UD_TAB__OPC_SSE, "/sse" }, + /* 255 */ { ud_itab__255, UD_TAB__OPC_SSE, "/sse" }, + /* 256 */ { ud_itab__256, UD_TAB__OPC_SSE, "/sse" }, + /* 257 */ { ud_itab__257, UD_TAB__OPC_SSE, "/sse" }, + /* 258 */ { ud_itab__258, UD_TAB__OPC_SSE, "/sse" }, + /* 259 */ { ud_itab__259, UD_TAB__OPC_SSE, "/sse" }, + /* 260 */ { ud_itab__260, UD_TAB__OPC_SSE, "/sse" }, + /* 261 */ { ud_itab__261, UD_TAB__OPC_SSE, "/sse" }, + /* 262 */ { ud_itab__262, UD_TAB__OPC_SSE, "/sse" }, + /* 263 */ { ud_itab__263, UD_TAB__OPC_SSE, "/sse" }, + /* 264 */ { ud_itab__264, UD_TAB__OPC_SSE, "/sse" }, + /* 265 */ { ud_itab__265, UD_TAB__OPC_SSE, "/sse" }, + /* 266 */ { ud_itab__266, UD_TAB__OPC_SSE, "/sse" }, + /* 267 */ { ud_itab__267, UD_TAB__OPC_SSE, "/sse" }, + /* 268 */ { ud_itab__268, UD_TAB__OPC_SSE, "/sse" }, + /* 269 */ { ud_itab__269, UD_TAB__OPC_SSE, "/sse" }, + /* 270 */ { ud_itab__270, UD_TAB__OPC_SSE, "/sse" }, + /* 271 */ { ud_itab__271, UD_TAB__OPC_SSE, "/sse" }, + /* 272 */ { ud_itab__272, UD_TAB__OPC_SSE, "/sse" }, + /* 273 */ { ud_itab__273, UD_TAB__OPC_SSE, "/sse" }, + /* 274 */ { ud_itab__274, UD_TAB__OPC_SSE, "/sse" }, + /* 275 */ { ud_itab__275, UD_TAB__OPC_MOD, "/mod" }, + /* 276 */ { ud_itab__276, UD_TAB__OPC_SSE, "/sse" }, + /* 277 */ { ud_itab__277, UD_TAB__OPC_SSE, "/sse" }, + /* 278 */ { ud_itab__278, UD_TAB__OPC_SSE, "/sse" }, + /* 279 */ { ud_itab__279, UD_TAB__OPC_SSE, "/sse" }, + /* 280 */ { ud_itab__280, UD_TAB__OPC_SSE, "/sse" }, + /* 281 */ { ud_itab__281, UD_TAB__OPC_SSE, "/sse" }, + /* 282 */ { ud_itab__282, UD_TAB__OPC_SSE, "/sse" }, + /* 283 */ { ud_itab__283, UD_TAB__OPC_SSE, "/sse" }, + /* 284 */ { ud_itab__284, UD_TAB__OPC_MODE, "/m" }, + /* 285 */ { ud_itab__285, UD_TAB__OPC_MODE, "/m" }, + /* 286 */ { ud_itab__286, UD_TAB__OPC_MODE, "/m" }, + /* 287 */ { ud_itab__287, UD_TAB__OPC_MODE, "/m" }, + /* 288 */ { ud_itab__288, UD_TAB__OPC_MODE, "/m" }, + /* 289 */ { ud_itab__289, UD_TAB__OPC_MODE, "/m" }, + /* 290 */ { ud_itab__290, UD_TAB__OPC_MODE, "/m" }, + /* 291 */ { ud_itab__291, UD_TAB__OPC_MODE, "/m" }, + /* 292 */ { ud_itab__292, UD_TAB__OPC_OSIZE, "/o" }, + /* 293 */ { ud_itab__293, UD_TAB__OPC_MODE, "/m" }, + /* 294 */ { ud_itab__294, UD_TAB__OPC_MODE, "/m" }, + /* 295 */ { ud_itab__295, UD_TAB__OPC_OSIZE, "/o" }, + /* 296 */ { ud_itab__296, UD_TAB__OPC_MODE, "/m" }, + /* 297 */ { ud_itab__297, UD_TAB__OPC_MODE, "/m" }, + /* 298 */ { ud_itab__298, UD_TAB__OPC_MODE, "/m" }, + /* 299 */ { ud_itab__299, UD_TAB__OPC_MODE, "/m" }, + /* 300 */ { ud_itab__300, UD_TAB__OPC_OSIZE, "/o" }, + /* 301 */ { ud_itab__301, UD_TAB__OPC_OSIZE, "/o" }, + /* 302 */ { ud_itab__302, UD_TAB__OPC_REG, "/reg" }, + /* 303 */ { ud_itab__303, UD_TAB__OPC_REG, "/reg" }, + /* 304 */ { ud_itab__304, UD_TAB__OPC_REG, "/reg" }, + /* 305 */ { ud_itab__305, UD_TAB__OPC_MODE, "/m" }, + /* 306 */ { ud_itab__306, UD_TAB__OPC_MODE, "/m" }, + /* 307 */ { ud_itab__307, UD_TAB__OPC_MODE, "/m" }, + /* 308 */ { ud_itab__308, UD_TAB__OPC_MODE, "/m" }, + /* 309 */ { ud_itab__309, UD_TAB__OPC_MODE, "/m" }, + /* 310 */ { ud_itab__310, UD_TAB__OPC_MODE, "/m" }, + /* 311 */ { ud_itab__311, UD_TAB__OPC_MODE, "/m" }, + /* 312 */ { ud_itab__312, UD_TAB__OPC_MODE, "/m" }, + /* 313 */ { ud_itab__313, UD_TAB__OPC_REG, "/reg" }, + /* 314 */ { ud_itab__314, UD_TAB__OPC_REG, "/reg" }, + /* 315 */ { ud_itab__315, UD_TAB__OPC_OSIZE, "/o" }, + /* 316 */ { ud_itab__316, UD_TAB__OPC_OSIZE, "/o" }, + /* 317 */ { ud_itab__317, UD_TAB__OPC_MODE, "/m" }, + /* 318 */ { ud_itab__318, UD_TAB__OPC_OSIZE, "/o" }, + /* 319 */ { ud_itab__319, UD_TAB__OPC_MODE, "/m" }, + /* 320 */ { ud_itab__320, UD_TAB__OPC_MODE, "/m" }, + /* 321 */ { ud_itab__321, UD_TAB__OPC_MODE, "/m" }, + /* 322 */ { ud_itab__322, UD_TAB__OPC_OSIZE, "/o" }, + /* 323 */ { ud_itab__323, UD_TAB__OPC_MODE, "/m" }, + /* 324 */ { ud_itab__324, UD_TAB__OPC_MODE, "/m" }, + /* 325 */ { ud_itab__325, UD_TAB__OPC_MODE, "/m" }, + /* 326 */ { ud_itab__326, UD_TAB__OPC_OSIZE, "/o" }, + /* 327 */ { ud_itab__327, UD_TAB__OPC_OSIZE, "/o" }, + /* 328 */ { ud_itab__328, UD_TAB__OPC_OSIZE, "/o" }, + /* 329 */ { ud_itab__329, UD_TAB__OPC_OSIZE, "/o" }, + /* 330 */ { ud_itab__330, UD_TAB__OPC_OSIZE, "/o" }, + /* 331 */ { ud_itab__331, UD_TAB__OPC_REG, "/reg" }, + /* 332 */ { ud_itab__332, UD_TAB__OPC_REG, "/reg" }, + /* 333 */ { ud_itab__333, UD_TAB__OPC_VEX, "/vex" }, + /* 334 */ { ud_itab__334, UD_TAB__OPC_MODE, "/m" }, + /* 335 */ { ud_itab__335, UD_TAB__OPC_TABLE, "opctbl" }, + /* 336 */ { ud_itab__336, UD_TAB__OPC_MOD, "/mod" }, + /* 337 */ { ud_itab__337, UD_TAB__OPC_MOD, "/mod" }, + /* 338 */ { ud_itab__338, UD_TAB__OPC_MOD, "/mod" }, + /* 339 */ { ud_itab__339, UD_TAB__OPC_REG, "/reg" }, + /* 340 */ { ud_itab__340, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 341 */ { ud_itab__341, UD_TAB__OPC_TABLE, "opctbl" }, + /* 342 */ { ud_itab__342, UD_TAB__OPC_MOD, "/mod" }, + /* 343 */ { ud_itab__343, UD_TAB__OPC_MOD, "/mod" }, + /* 344 */ { ud_itab__344, UD_TAB__OPC_OSIZE, "/o" }, + /* 345 */ { ud_itab__345, UD_TAB__OPC_REG, "/reg" }, + /* 346 */ { ud_itab__346, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 347 */ { ud_itab__347, UD_TAB__OPC_REG, "/reg" }, + /* 348 */ { ud_itab__348, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 349 */ { ud_itab__349, UD_TAB__OPC_REG, "/reg" }, + /* 350 */ { ud_itab__350, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 351 */ { ud_itab__351, UD_TAB__OPC_OSIZE, "/o" }, + /* 352 */ { ud_itab__352, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 353 */ { ud_itab__353, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 354 */ { ud_itab__354, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 355 */ { ud_itab__355, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 356 */ { ud_itab__356, UD_TAB__OPC_MOD, "/mod" }, + /* 357 */ { ud_itab__357, UD_TAB__OPC_TABLE, "opctbl" }, + /* 358 */ { ud_itab__358, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 359 */ { ud_itab__359, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 360 */ { ud_itab__360, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 361 */ { ud_itab__361, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 362 */ { ud_itab__362, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 363 */ { ud_itab__363, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 364 */ { ud_itab__364, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 365 */ { ud_itab__365, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 366 */ { ud_itab__366, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 367 */ { ud_itab__367, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 368 */ { ud_itab__368, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 369 */ { ud_itab__369, UD_TAB__OPC_TABLE, "opctbl" }, + /* 370 */ { ud_itab__370, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 371 */ { ud_itab__371, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 372 */ { ud_itab__372, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 373 */ { ud_itab__373, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 374 */ { ud_itab__374, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 375 */ { ud_itab__375, UD_TAB__OPC_OSIZE, "/o" }, + /* 376 */ { ud_itab__376, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 377 */ { ud_itab__377, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 378 */ { ud_itab__378, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 379 */ { ud_itab__379, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 380 */ { ud_itab__380, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 381 */ { ud_itab__381, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 382 */ { ud_itab__382, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 383 */ { ud_itab__383, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 384 */ { ud_itab__384, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 385 */ { ud_itab__385, UD_TAB__OPC_MODE, "/m" }, + /* 386 */ { ud_itab__386, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 387 */ { ud_itab__387, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 388 */ { ud_itab__388, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 389 */ { ud_itab__389, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 390 */ { ud_itab__390, UD_TAB__OPC_VEX_L, "/vexl" }, + /* 391 */ { ud_itab__391, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 392 */ { ud_itab__392, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 393 */ { ud_itab__393, UD_TAB__OPC_VEX_W, "/vexw" }, + /* 394 */ { ud_itab__394, UD_TAB__OPC_TABLE, "opctbl" }, + /* 395 */ { ud_itab__395, UD_TAB__OPC_MOD, "/mod" }, + /* 396 */ { ud_itab__396, UD_TAB__OPC_MOD, "/mod" }, + /* 397 */ { ud_itab__397, UD_TAB__OPC_MOD, "/mod" }, + /* 398 */ { ud_itab__398, UD_TAB__OPC_MOD, "/mod" }, + /* 399 */ { ud_itab__399, UD_TAB__OPC_TABLE, "opctbl" }, + /* 400 */ { ud_itab__400, UD_TAB__OPC_MOD, "/mod" }, + /* 401 */ { ud_itab__401, UD_TAB__OPC_MOD, "/mod" }, + /* 402 */ { ud_itab__402, UD_TAB__OPC_MOD, "/mod" }, + /* 403 */ { ud_itab__403, UD_TAB__OPC_VEX, "/vex" }, + /* 404 */ { ud_itab__404, UD_TAB__OPC_MODE, "/m" }, + /* 405 */ { ud_itab__405, UD_TAB__OPC_REG, "/reg" }, + /* 406 */ { ud_itab__406, UD_TAB__OPC_REG, "/reg" }, + /* 407 */ { ud_itab__407, UD_TAB__OPC_MODE, "/m" }, + /* 408 */ { ud_itab__408, UD_TAB__OPC_OSIZE, "/o" }, + /* 409 */ { ud_itab__409, UD_TAB__OPC_REG, "/reg" }, + /* 410 */ { ud_itab__410, UD_TAB__OPC_REG, "/reg" }, + /* 411 */ { ud_itab__411, UD_TAB__OPC_REG, "/reg" }, + /* 412 */ { ud_itab__412, UD_TAB__OPC_REG, "/reg" }, + /* 413 */ { ud_itab__413, UD_TAB__OPC_MODE, "/m" }, + /* 414 */ { ud_itab__414, UD_TAB__OPC_MODE, "/m" }, + /* 415 */ { ud_itab__415, UD_TAB__OPC_MODE, "/m" }, + /* 416 */ { ud_itab__416, UD_TAB__OPC_MOD, "/mod" }, + /* 417 */ { ud_itab__417, UD_TAB__OPC_REG, "/reg" }, + /* 418 */ { ud_itab__418, UD_TAB__OPC_X87, "/x87" }, + /* 419 */ { ud_itab__419, UD_TAB__OPC_MOD, "/mod" }, + /* 420 */ { ud_itab__420, UD_TAB__OPC_REG, "/reg" }, + /* 421 */ { ud_itab__421, UD_TAB__OPC_X87, "/x87" }, + /* 422 */ { ud_itab__422, UD_TAB__OPC_MOD, "/mod" }, + /* 423 */ { ud_itab__423, UD_TAB__OPC_REG, "/reg" }, + /* 424 */ { ud_itab__424, UD_TAB__OPC_X87, "/x87" }, + /* 425 */ { ud_itab__425, UD_TAB__OPC_MOD, "/mod" }, + /* 426 */ { ud_itab__426, UD_TAB__OPC_REG, "/reg" }, + /* 427 */ { ud_itab__427, UD_TAB__OPC_X87, "/x87" }, + /* 428 */ { ud_itab__428, UD_TAB__OPC_MOD, "/mod" }, + /* 429 */ { ud_itab__429, UD_TAB__OPC_REG, "/reg" }, + /* 430 */ { ud_itab__430, UD_TAB__OPC_X87, "/x87" }, + /* 431 */ { ud_itab__431, UD_TAB__OPC_MOD, "/mod" }, + /* 432 */ { ud_itab__432, UD_TAB__OPC_REG, "/reg" }, + /* 433 */ { ud_itab__433, UD_TAB__OPC_X87, "/x87" }, + /* 434 */ { ud_itab__434, UD_TAB__OPC_MOD, "/mod" }, + /* 435 */ { ud_itab__435, UD_TAB__OPC_REG, "/reg" }, + /* 436 */ { ud_itab__436, UD_TAB__OPC_X87, "/x87" }, + /* 437 */ { ud_itab__437, UD_TAB__OPC_MOD, "/mod" }, + /* 438 */ { ud_itab__438, UD_TAB__OPC_REG, "/reg" }, + /* 439 */ { ud_itab__439, UD_TAB__OPC_X87, "/x87" }, + /* 440 */ { ud_itab__440, UD_TAB__OPC_ASIZE, "/a" }, + /* 441 */ { ud_itab__441, UD_TAB__OPC_MODE, "/m" }, + /* 442 */ { ud_itab__442, UD_TAB__OPC_REG, "/reg" }, + /* 443 */ { ud_itab__443, UD_TAB__OPC_REG, "/reg" }, + /* 444 */ { ud_itab__444, UD_TAB__OPC_REG, "/reg" }, + /* 445 */ { ud_itab__445, UD_TAB__OPC_REG, "/reg" }, + /* 446 */ { ud_itab__446, UD_TAB__OPC_MODE, "/m" }, +}; + +/* itab entry operand definitions (for readability) */ +#define O_AL { OP_AL, SZ_B } +#define O_AX { OP_AX, SZ_W } +#define O_Av { OP_A, SZ_V } +#define O_C { OP_C, SZ_NA } +#define O_CL { OP_CL, SZ_B } +#define O_CS { OP_CS, SZ_NA } +#define O_CX { OP_CX, SZ_W } +#define O_D { OP_D, SZ_NA } +#define O_DL { OP_DL, SZ_B } +#define O_DS { OP_DS, SZ_NA } +#define O_DX { OP_DX, SZ_W } +#define O_E { OP_E, SZ_NA } +#define O_ES { OP_ES, SZ_NA } +#define O_Eb { OP_E, SZ_B } +#define O_Ed { OP_E, SZ_D } +#define O_Eq { OP_E, SZ_Q } +#define O_Ev { OP_E, SZ_V } +#define O_Ew { OP_E, SZ_W } +#define O_Ey { OP_E, SZ_Y } +#define O_Ez { OP_E, SZ_Z } +#define O_FS { OP_FS, SZ_NA } +#define O_Fv { OP_F, SZ_V } +#define O_G { OP_G, SZ_NA } +#define O_GS { OP_GS, SZ_NA } +#define O_Gb { OP_G, SZ_B } +#define O_Gd { OP_G, SZ_D } +#define O_Gq { OP_G, SZ_Q } +#define O_Gv { OP_G, SZ_V } +#define O_Gw { OP_G, SZ_W } +#define O_Gy { OP_G, SZ_Y } +#define O_Gz { OP_G, SZ_Z } +#define O_H { OP_H, SZ_X } +#define O_Hqq { OP_H, SZ_QQ } +#define O_Hx { OP_H, SZ_X } +#define O_I1 { OP_I1, SZ_NA } +#define O_I3 { OP_I3, SZ_NA } +#define O_Ib { OP_I, SZ_B } +#define O_Iv { OP_I, SZ_V } +#define O_Iw { OP_I, SZ_W } +#define O_Iz { OP_I, SZ_Z } +#define O_Jb { OP_J, SZ_B } +#define O_Jv { OP_J, SZ_V } +#define O_Jz { OP_J, SZ_Z } +#define O_L { OP_L, SZ_O } +#define O_Lx { OP_L, SZ_X } +#define O_M { OP_M, SZ_NA } +#define O_Mb { OP_M, SZ_B } +#define O_MbRd { OP_MR, SZ_BD } +#define O_MbRv { OP_MR, SZ_BV } +#define O_Md { OP_M, SZ_D } +#define O_MdRy { OP_MR, SZ_DY } +#define O_MdU { OP_MU, SZ_DO } +#define O_Mdq { OP_M, SZ_DQ } +#define O_Mo { OP_M, SZ_O } +#define O_Mq { OP_M, SZ_Q } +#define O_MqU { OP_MU, SZ_QO } +#define O_Ms { OP_M, SZ_W } +#define O_Mt { OP_M, SZ_T } +#define O_Mv { OP_M, SZ_V } +#define O_Mw { OP_M, SZ_W } +#define O_MwRd { OP_MR, SZ_WD } +#define O_MwRv { OP_MR, SZ_WV } +#define O_MwRy { OP_MR, SZ_WY } +#define O_MwU { OP_MU, SZ_WO } +#define O_N { OP_N, SZ_Q } +#define O_NONE { OP_NONE, SZ_NA } +#define O_Ob { OP_O, SZ_B } +#define O_Ov { OP_O, SZ_V } +#define O_Ow { OP_O, SZ_W } +#define O_P { OP_P, SZ_Q } +#define O_Q { OP_Q, SZ_Q } +#define O_R { OP_R, SZ_RDQ } +#define O_R0b { OP_R0, SZ_B } +#define O_R0v { OP_R0, SZ_V } +#define O_R0w { OP_R0, SZ_W } +#define O_R0y { OP_R0, SZ_Y } +#define O_R0z { OP_R0, SZ_Z } +#define O_R1b { OP_R1, SZ_B } +#define O_R1v { OP_R1, SZ_V } +#define O_R1w { OP_R1, SZ_W } +#define O_R1y { OP_R1, SZ_Y } +#define O_R1z { OP_R1, SZ_Z } +#define O_R2b { OP_R2, SZ_B } +#define O_R2v { OP_R2, SZ_V } +#define O_R2w { OP_R2, SZ_W } +#define O_R2y { OP_R2, SZ_Y } +#define O_R2z { OP_R2, SZ_Z } +#define O_R3b { OP_R3, SZ_B } +#define O_R3v { OP_R3, SZ_V } +#define O_R3w { OP_R3, SZ_W } +#define O_R3y { OP_R3, SZ_Y } +#define O_R3z { OP_R3, SZ_Z } +#define O_R4b { OP_R4, SZ_B } +#define O_R4v { OP_R4, SZ_V } +#define O_R4w { OP_R4, SZ_W } +#define O_R4y { OP_R4, SZ_Y } +#define O_R4z { OP_R4, SZ_Z } +#define O_R5b { OP_R5, SZ_B } +#define O_R5v { OP_R5, SZ_V } +#define O_R5w { OP_R5, SZ_W } +#define O_R5y { OP_R5, SZ_Y } +#define O_R5z { OP_R5, SZ_Z } +#define O_R6b { OP_R6, SZ_B } +#define O_R6v { OP_R6, SZ_V } +#define O_R6w { OP_R6, SZ_W } +#define O_R6y { OP_R6, SZ_Y } +#define O_R6z { OP_R6, SZ_Z } +#define O_R7b { OP_R7, SZ_B } +#define O_R7v { OP_R7, SZ_V } +#define O_R7w { OP_R7, SZ_W } +#define O_R7y { OP_R7, SZ_Y } +#define O_R7z { OP_R7, SZ_Z } +#define O_S { OP_S, SZ_W } +#define O_SS { OP_SS, SZ_NA } +#define O_ST0 { OP_ST0, SZ_NA } +#define O_ST1 { OP_ST1, SZ_NA } +#define O_ST2 { OP_ST2, SZ_NA } +#define O_ST3 { OP_ST3, SZ_NA } +#define O_ST4 { OP_ST4, SZ_NA } +#define O_ST5 { OP_ST5, SZ_NA } +#define O_ST6 { OP_ST6, SZ_NA } +#define O_ST7 { OP_ST7, SZ_NA } +#define O_U { OP_U, SZ_O } +#define O_Ux { OP_U, SZ_X } +#define O_V { OP_V, SZ_DQ } +#define O_Vdq { OP_V, SZ_DQ } +#define O_Vqq { OP_V, SZ_QQ } +#define O_Vsd { OP_V, SZ_Q } +#define O_Vx { OP_V, SZ_X } +#define O_W { OP_W, SZ_DQ } +#define O_Wdq { OP_W, SZ_DQ } +#define O_Wqq { OP_W, SZ_QQ } +#define O_Wsd { OP_W, SZ_Q } +#define O_Wx { OP_W, SZ_X } +#define O_eAX { OP_eAX, SZ_Z } +#define O_eCX { OP_eCX, SZ_Z } +#define O_eDX { OP_eDX, SZ_Z } +#define O_rAX { OP_rAX, SZ_V } +#define O_rCX { OP_rCX, SZ_V } +#define O_rDX { OP_rDX, SZ_V } +#define O_sIb { OP_sI, SZ_B } +#define O_sIv { OP_sI, SZ_V } +#define O_sIz { OP_sI, SZ_Z } + +struct ud_itab_entry ud_itab[] = { + /* 0000 */ { UD_Iinvalid, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0001 */ { UD_Iaaa, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0002 */ { UD_Iaad, O_Ib, O_NONE, O_NONE, O_NONE, P_none }, + /* 0003 */ { UD_Iaam, O_Ib, O_NONE, O_NONE, O_NONE, P_none }, + /* 0004 */ { UD_Iaas, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0005 */ { UD_Iadc, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0006 */ { UD_Iadc, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0007 */ { UD_Iadc, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0008 */ { UD_Iadc, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0009 */ { UD_Iadc, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0010 */ { UD_Iadc, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0011 */ { UD_Iadc, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0012 */ { UD_Iadc, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0013 */ { UD_Iadc, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0014 */ { UD_Iadc, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0015 */ { UD_Iadd, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0016 */ { UD_Iadd, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0017 */ { UD_Iadd, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0018 */ { UD_Iadd, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0019 */ { UD_Iadd, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0020 */ { UD_Iadd, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0021 */ { UD_Iadd, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0022 */ { UD_Iadd, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0023 */ { UD_Iadd, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0024 */ { UD_Iadd, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0025 */ { UD_Iaddpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0026 */ { UD_Ivaddpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0027 */ { UD_Iaddps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0028 */ { UD_Ivaddps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0029 */ { UD_Iaddsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0030 */ { UD_Ivaddsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0031 */ { UD_Iaddss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0032 */ { UD_Ivaddss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0033 */ { UD_Iaddsubpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0034 */ { UD_Ivaddsubpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0035 */ { UD_Iaddsubps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0036 */ { UD_Ivaddsubps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0037 */ { UD_Iaesdec, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0038 */ { UD_Ivaesdec, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0039 */ { UD_Iaesdeclast, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0040 */ { UD_Ivaesdeclast, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0041 */ { UD_Iaesenc, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0042 */ { UD_Ivaesenc, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0043 */ { UD_Iaesenclast, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0044 */ { UD_Ivaesenclast, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0045 */ { UD_Iaesimc, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0046 */ { UD_Ivaesimc, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0047 */ { UD_Iaeskeygenassist, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0048 */ { UD_Ivaeskeygenassist, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0049 */ { UD_Iand, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0050 */ { UD_Iand, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0051 */ { UD_Iand, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0052 */ { UD_Iand, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0053 */ { UD_Iand, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0054 */ { UD_Iand, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0055 */ { UD_Iand, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0056 */ { UD_Iand, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0057 */ { UD_Iand, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0058 */ { UD_Iand, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0059 */ { UD_Iandpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0060 */ { UD_Ivandpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0061 */ { UD_Iandps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0062 */ { UD_Ivandps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0063 */ { UD_Iandnpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0064 */ { UD_Ivandnpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0065 */ { UD_Iandnps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0066 */ { UD_Ivandnps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0067 */ { UD_Iarpl, O_Ew, O_Gw, O_NONE, O_NONE, P_aso }, + /* 0068 */ { UD_Imovsxd, O_Gq, O_Ed, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexx|P_rexr|P_rexb }, + /* 0069 */ { UD_Icall, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0070 */ { UD_Icall, O_Eq, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 0071 */ { UD_Icall, O_Fv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0072 */ { UD_Icall, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0073 */ { UD_Icall, O_Av, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0074 */ { UD_Icbw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0075 */ { UD_Icwde, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0076 */ { UD_Icdqe, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0077 */ { UD_Iclc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0078 */ { UD_Icld, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0079 */ { UD_Iclflush, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0080 */ { UD_Iclgi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0081 */ { UD_Icli, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0082 */ { UD_Iclts, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0083 */ { UD_Icmc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0084 */ { UD_Icmovo, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0085 */ { UD_Icmovno, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0086 */ { UD_Icmovb, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0087 */ { UD_Icmovae, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0088 */ { UD_Icmovz, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0089 */ { UD_Icmovnz, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0090 */ { UD_Icmovbe, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0091 */ { UD_Icmova, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0092 */ { UD_Icmovs, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0093 */ { UD_Icmovns, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0094 */ { UD_Icmovp, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0095 */ { UD_Icmovnp, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0096 */ { UD_Icmovl, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0097 */ { UD_Icmovge, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0098 */ { UD_Icmovle, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0099 */ { UD_Icmovg, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0100 */ { UD_Icmp, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0101 */ { UD_Icmp, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0102 */ { UD_Icmp, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0103 */ { UD_Icmp, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0104 */ { UD_Icmp, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0105 */ { UD_Icmp, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0106 */ { UD_Icmp, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0107 */ { UD_Icmp, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 0108 */ { UD_Icmp, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0109 */ { UD_Icmp, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0110 */ { UD_Icmppd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0111 */ { UD_Ivcmppd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0112 */ { UD_Icmpps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0113 */ { UD_Ivcmpps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0114 */ { UD_Icmpsb, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_seg }, + /* 0115 */ { UD_Icmpsw, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw|P_seg }, + /* 0116 */ { UD_Icmpsd, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw|P_seg }, + /* 0117 */ { UD_Icmpsd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0118 */ { UD_Ivcmpsd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0119 */ { UD_Icmpsq, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw|P_seg }, + /* 0120 */ { UD_Icmpss, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0121 */ { UD_Ivcmpss, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0122 */ { UD_Icmpxchg, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0123 */ { UD_Icmpxchg, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0124 */ { UD_Icmpxchg8b, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0125 */ { UD_Icmpxchg8b, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0126 */ { UD_Icmpxchg16b, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0127 */ { UD_Icomisd, O_Vsd, O_Wsd, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0128 */ { UD_Ivcomisd, O_Vsd, O_Wsd, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0129 */ { UD_Icomiss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0130 */ { UD_Ivcomiss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0131 */ { UD_Icpuid, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0132 */ { UD_Icvtdq2pd, O_V, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0133 */ { UD_Ivcvtdq2pd, O_Vx, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0134 */ { UD_Icvtdq2ps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0135 */ { UD_Ivcvtdq2ps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0136 */ { UD_Icvtpd2dq, O_Vdq, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0137 */ { UD_Ivcvtpd2dq, O_Vdq, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0138 */ { UD_Icvtpd2pi, O_P, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0139 */ { UD_Icvtpd2ps, O_Vdq, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0140 */ { UD_Ivcvtpd2ps, O_Vdq, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0141 */ { UD_Icvtpi2ps, O_V, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0142 */ { UD_Icvtpi2pd, O_V, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0143 */ { UD_Icvtps2dq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0144 */ { UD_Ivcvtps2dq, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0145 */ { UD_Icvtps2pd, O_V, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0146 */ { UD_Ivcvtps2pd, O_Vx, O_Wdq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0147 */ { UD_Icvtps2pi, O_P, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0148 */ { UD_Icvtsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0149 */ { UD_Ivcvtsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0150 */ { UD_Icvtsd2ss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0151 */ { UD_Ivcvtsd2ss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0152 */ { UD_Icvtsi2sd, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0153 */ { UD_Ivcvtsi2sd, O_Vx, O_Hx, O_Ey, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0154 */ { UD_Icvtsi2ss, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0155 */ { UD_Ivcvtsi2ss, O_Vx, O_Hx, O_Ey, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0156 */ { UD_Icvtss2sd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0157 */ { UD_Ivcvtss2sd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0158 */ { UD_Icvtss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0159 */ { UD_Ivcvtss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0160 */ { UD_Icvttpd2dq, O_Vdq, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0161 */ { UD_Ivcvttpd2dq, O_Vdq, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0162 */ { UD_Icvttpd2pi, O_P, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0163 */ { UD_Icvttps2dq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0164 */ { UD_Ivcvttps2dq, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0165 */ { UD_Icvttps2pi, O_P, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0166 */ { UD_Icvttsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0167 */ { UD_Ivcvttsd2si, O_Gy, O_MqU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0168 */ { UD_Icvttss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0169 */ { UD_Ivcvttss2si, O_Gy, O_MdU, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0170 */ { UD_Icwd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0171 */ { UD_Icdq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0172 */ { UD_Icqo, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0173 */ { UD_Idaa, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 0174 */ { UD_Idas, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 0175 */ { UD_Idec, O_R0z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0176 */ { UD_Idec, O_R1z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0177 */ { UD_Idec, O_R2z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0178 */ { UD_Idec, O_R3z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0179 */ { UD_Idec, O_R4z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0180 */ { UD_Idec, O_R5z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0181 */ { UD_Idec, O_R6z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0182 */ { UD_Idec, O_R7z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0183 */ { UD_Idec, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0184 */ { UD_Idec, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0185 */ { UD_Idiv, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0186 */ { UD_Idiv, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0187 */ { UD_Idivpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0188 */ { UD_Ivdivpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0189 */ { UD_Idivps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0190 */ { UD_Ivdivps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0191 */ { UD_Idivsd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0192 */ { UD_Ivdivsd, O_Vx, O_Hx, O_MqU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0193 */ { UD_Idivss, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0194 */ { UD_Ivdivss, O_Vx, O_Hx, O_MdU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0195 */ { UD_Idppd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0196 */ { UD_Ivdppd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0197 */ { UD_Idpps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0198 */ { UD_Ivdpps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0199 */ { UD_Iemms, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0200 */ { UD_Ienter, O_Iw, O_Ib, O_NONE, O_NONE, P_def64 }, + /* 0201 */ { UD_Iextractps, O_MdRy, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 0202 */ { UD_Ivextractps, O_MdRy, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 0203 */ { UD_If2xm1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0204 */ { UD_Ifabs, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0205 */ { UD_Ifadd, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0206 */ { UD_Ifadd, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0207 */ { UD_Ifadd, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0208 */ { UD_Ifadd, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0209 */ { UD_Ifadd, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0210 */ { UD_Ifadd, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0211 */ { UD_Ifadd, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0212 */ { UD_Ifadd, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0213 */ { UD_Ifadd, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0214 */ { UD_Ifadd, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0215 */ { UD_Ifadd, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0216 */ { UD_Ifadd, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0217 */ { UD_Ifadd, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0218 */ { UD_Ifadd, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0219 */ { UD_Ifadd, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0220 */ { UD_Ifadd, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0221 */ { UD_Ifadd, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0222 */ { UD_Ifadd, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0223 */ { UD_Ifaddp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0224 */ { UD_Ifaddp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0225 */ { UD_Ifaddp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0226 */ { UD_Ifaddp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0227 */ { UD_Ifaddp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0228 */ { UD_Ifaddp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0229 */ { UD_Ifaddp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0230 */ { UD_Ifaddp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0231 */ { UD_Ifbld, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0232 */ { UD_Ifbstp, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0233 */ { UD_Ifchs, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0234 */ { UD_Ifclex, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0235 */ { UD_Ifcmovb, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0236 */ { UD_Ifcmovb, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0237 */ { UD_Ifcmovb, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0238 */ { UD_Ifcmovb, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0239 */ { UD_Ifcmovb, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0240 */ { UD_Ifcmovb, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0241 */ { UD_Ifcmovb, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0242 */ { UD_Ifcmovb, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0243 */ { UD_Ifcmove, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0244 */ { UD_Ifcmove, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0245 */ { UD_Ifcmove, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0246 */ { UD_Ifcmove, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0247 */ { UD_Ifcmove, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0248 */ { UD_Ifcmove, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0249 */ { UD_Ifcmove, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0250 */ { UD_Ifcmove, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0251 */ { UD_Ifcmovbe, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0252 */ { UD_Ifcmovbe, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0253 */ { UD_Ifcmovbe, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0254 */ { UD_Ifcmovbe, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0255 */ { UD_Ifcmovbe, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0256 */ { UD_Ifcmovbe, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0257 */ { UD_Ifcmovbe, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0258 */ { UD_Ifcmovbe, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0259 */ { UD_Ifcmovu, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0260 */ { UD_Ifcmovu, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0261 */ { UD_Ifcmovu, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0262 */ { UD_Ifcmovu, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0263 */ { UD_Ifcmovu, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0264 */ { UD_Ifcmovu, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0265 */ { UD_Ifcmovu, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0266 */ { UD_Ifcmovu, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0267 */ { UD_Ifcmovnb, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0268 */ { UD_Ifcmovnb, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0269 */ { UD_Ifcmovnb, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0270 */ { UD_Ifcmovnb, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0271 */ { UD_Ifcmovnb, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0272 */ { UD_Ifcmovnb, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0273 */ { UD_Ifcmovnb, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0274 */ { UD_Ifcmovnb, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0275 */ { UD_Ifcmovne, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0276 */ { UD_Ifcmovne, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0277 */ { UD_Ifcmovne, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0278 */ { UD_Ifcmovne, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0279 */ { UD_Ifcmovne, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0280 */ { UD_Ifcmovne, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0281 */ { UD_Ifcmovne, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0282 */ { UD_Ifcmovne, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0283 */ { UD_Ifcmovnbe, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0284 */ { UD_Ifcmovnbe, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0285 */ { UD_Ifcmovnbe, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0286 */ { UD_Ifcmovnbe, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0287 */ { UD_Ifcmovnbe, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0288 */ { UD_Ifcmovnbe, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0289 */ { UD_Ifcmovnbe, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0290 */ { UD_Ifcmovnbe, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0291 */ { UD_Ifcmovnu, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0292 */ { UD_Ifcmovnu, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0293 */ { UD_Ifcmovnu, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0294 */ { UD_Ifcmovnu, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0295 */ { UD_Ifcmovnu, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0296 */ { UD_Ifcmovnu, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0297 */ { UD_Ifcmovnu, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0298 */ { UD_Ifcmovnu, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0299 */ { UD_Ifucomi, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0300 */ { UD_Ifucomi, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0301 */ { UD_Ifucomi, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0302 */ { UD_Ifucomi, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0303 */ { UD_Ifucomi, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0304 */ { UD_Ifucomi, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0305 */ { UD_Ifucomi, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0306 */ { UD_Ifucomi, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0307 */ { UD_Ifcom, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0308 */ { UD_Ifcom, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0309 */ { UD_Ifcom, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0310 */ { UD_Ifcom, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0311 */ { UD_Ifcom, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0312 */ { UD_Ifcom, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0313 */ { UD_Ifcom, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0314 */ { UD_Ifcom, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0315 */ { UD_Ifcom, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0316 */ { UD_Ifcom, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0317 */ { UD_Ifcom2, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0318 */ { UD_Ifcom2, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0319 */ { UD_Ifcom2, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0320 */ { UD_Ifcom2, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0321 */ { UD_Ifcom2, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0322 */ { UD_Ifcom2, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0323 */ { UD_Ifcom2, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0324 */ { UD_Ifcom2, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0325 */ { UD_Ifcomp3, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0326 */ { UD_Ifcomp3, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0327 */ { UD_Ifcomp3, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0328 */ { UD_Ifcomp3, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0329 */ { UD_Ifcomp3, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0330 */ { UD_Ifcomp3, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0331 */ { UD_Ifcomp3, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0332 */ { UD_Ifcomp3, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0333 */ { UD_Ifcomi, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0334 */ { UD_Ifcomi, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0335 */ { UD_Ifcomi, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0336 */ { UD_Ifcomi, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0337 */ { UD_Ifcomi, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0338 */ { UD_Ifcomi, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0339 */ { UD_Ifcomi, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0340 */ { UD_Ifcomi, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0341 */ { UD_Ifucomip, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0342 */ { UD_Ifucomip, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0343 */ { UD_Ifucomip, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0344 */ { UD_Ifucomip, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0345 */ { UD_Ifucomip, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0346 */ { UD_Ifucomip, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0347 */ { UD_Ifucomip, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0348 */ { UD_Ifucomip, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0349 */ { UD_Ifcomip, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0350 */ { UD_Ifcomip, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0351 */ { UD_Ifcomip, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0352 */ { UD_Ifcomip, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0353 */ { UD_Ifcomip, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0354 */ { UD_Ifcomip, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0355 */ { UD_Ifcomip, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0356 */ { UD_Ifcomip, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0357 */ { UD_Ifcomp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0358 */ { UD_Ifcomp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0359 */ { UD_Ifcomp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0360 */ { UD_Ifcomp, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0361 */ { UD_Ifcomp, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0362 */ { UD_Ifcomp, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0363 */ { UD_Ifcomp, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0364 */ { UD_Ifcomp, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0365 */ { UD_Ifcomp, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0366 */ { UD_Ifcomp, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0367 */ { UD_Ifcomp5, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0368 */ { UD_Ifcomp5, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0369 */ { UD_Ifcomp5, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0370 */ { UD_Ifcomp5, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0371 */ { UD_Ifcomp5, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0372 */ { UD_Ifcomp5, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0373 */ { UD_Ifcomp5, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0374 */ { UD_Ifcomp5, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0375 */ { UD_Ifcompp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0376 */ { UD_Ifcos, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0377 */ { UD_Ifdecstp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0378 */ { UD_Ifdiv, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0379 */ { UD_Ifdiv, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0380 */ { UD_Ifdiv, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0381 */ { UD_Ifdiv, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0382 */ { UD_Ifdiv, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0383 */ { UD_Ifdiv, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0384 */ { UD_Ifdiv, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0385 */ { UD_Ifdiv, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0386 */ { UD_Ifdiv, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0387 */ { UD_Ifdiv, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0388 */ { UD_Ifdiv, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0389 */ { UD_Ifdiv, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0390 */ { UD_Ifdiv, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0391 */ { UD_Ifdiv, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0392 */ { UD_Ifdiv, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0393 */ { UD_Ifdiv, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0394 */ { UD_Ifdiv, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0395 */ { UD_Ifdiv, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0396 */ { UD_Ifdivp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0397 */ { UD_Ifdivp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0398 */ { UD_Ifdivp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0399 */ { UD_Ifdivp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0400 */ { UD_Ifdivp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0401 */ { UD_Ifdivp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0402 */ { UD_Ifdivp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0403 */ { UD_Ifdivp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0404 */ { UD_Ifdivr, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0405 */ { UD_Ifdivr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0406 */ { UD_Ifdivr, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0407 */ { UD_Ifdivr, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0408 */ { UD_Ifdivr, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0409 */ { UD_Ifdivr, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0410 */ { UD_Ifdivr, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0411 */ { UD_Ifdivr, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0412 */ { UD_Ifdivr, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0413 */ { UD_Ifdivr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0414 */ { UD_Ifdivr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0415 */ { UD_Ifdivr, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0416 */ { UD_Ifdivr, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0417 */ { UD_Ifdivr, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0418 */ { UD_Ifdivr, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0419 */ { UD_Ifdivr, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0420 */ { UD_Ifdivr, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0421 */ { UD_Ifdivr, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0422 */ { UD_Ifdivrp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0423 */ { UD_Ifdivrp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0424 */ { UD_Ifdivrp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0425 */ { UD_Ifdivrp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0426 */ { UD_Ifdivrp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0427 */ { UD_Ifdivrp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0428 */ { UD_Ifdivrp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0429 */ { UD_Ifdivrp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0430 */ { UD_Ifemms, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0431 */ { UD_Iffree, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0432 */ { UD_Iffree, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0433 */ { UD_Iffree, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0434 */ { UD_Iffree, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0435 */ { UD_Iffree, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0436 */ { UD_Iffree, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0437 */ { UD_Iffree, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0438 */ { UD_Iffree, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0439 */ { UD_Iffreep, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0440 */ { UD_Iffreep, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0441 */ { UD_Iffreep, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0442 */ { UD_Iffreep, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0443 */ { UD_Iffreep, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0444 */ { UD_Iffreep, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0445 */ { UD_Iffreep, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0446 */ { UD_Iffreep, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0447 */ { UD_Ificom, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0448 */ { UD_Ificom, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0449 */ { UD_Ificomp, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0450 */ { UD_Ificomp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0451 */ { UD_Ifild, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0452 */ { UD_Ifild, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0453 */ { UD_Ifild, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0454 */ { UD_Ifincstp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0455 */ { UD_Ifninit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0456 */ { UD_Ifiadd, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0457 */ { UD_Ifiadd, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0458 */ { UD_Ifidivr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0459 */ { UD_Ifidivr, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0460 */ { UD_Ifidiv, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0461 */ { UD_Ifidiv, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0462 */ { UD_Ifisub, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0463 */ { UD_Ifisub, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0464 */ { UD_Ifisubr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0465 */ { UD_Ifisubr, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0466 */ { UD_Ifist, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0467 */ { UD_Ifist, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0468 */ { UD_Ifistp, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0469 */ { UD_Ifistp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0470 */ { UD_Ifistp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0471 */ { UD_Ifisttp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0472 */ { UD_Ifisttp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0473 */ { UD_Ifisttp, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0474 */ { UD_Ifld, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0475 */ { UD_Ifld, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0476 */ { UD_Ifld, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0477 */ { UD_Ifld, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0478 */ { UD_Ifld, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0479 */ { UD_Ifld, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0480 */ { UD_Ifld, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0481 */ { UD_Ifld, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0482 */ { UD_Ifld, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0483 */ { UD_Ifld, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0484 */ { UD_Ifld, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0485 */ { UD_Ifld1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0486 */ { UD_Ifldl2t, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0487 */ { UD_Ifldl2e, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0488 */ { UD_Ifldpi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0489 */ { UD_Ifldlg2, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0490 */ { UD_Ifldln2, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0491 */ { UD_Ifldz, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0492 */ { UD_Ifldcw, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0493 */ { UD_Ifldenv, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0494 */ { UD_Ifmul, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0495 */ { UD_Ifmul, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0496 */ { UD_Ifmul, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0497 */ { UD_Ifmul, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0498 */ { UD_Ifmul, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0499 */ { UD_Ifmul, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0500 */ { UD_Ifmul, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0501 */ { UD_Ifmul, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0502 */ { UD_Ifmul, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0503 */ { UD_Ifmul, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0504 */ { UD_Ifmul, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0505 */ { UD_Ifmul, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0506 */ { UD_Ifmul, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0507 */ { UD_Ifmul, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0508 */ { UD_Ifmul, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0509 */ { UD_Ifmul, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0510 */ { UD_Ifmul, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0511 */ { UD_Ifmul, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0512 */ { UD_Ifmulp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0513 */ { UD_Ifmulp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0514 */ { UD_Ifmulp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0515 */ { UD_Ifmulp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0516 */ { UD_Ifmulp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0517 */ { UD_Ifmulp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0518 */ { UD_Ifmulp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0519 */ { UD_Ifmulp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0520 */ { UD_Ifimul, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0521 */ { UD_Ifimul, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0522 */ { UD_Ifnop, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0523 */ { UD_Ifndisi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0524 */ { UD_Ifneni, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0525 */ { UD_Ifnsetpm, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0526 */ { UD_Ifpatan, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0527 */ { UD_Ifprem, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0528 */ { UD_Ifprem1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0529 */ { UD_Ifptan, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0530 */ { UD_Ifrndint, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0531 */ { UD_Ifrstor, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0532 */ { UD_Ifrstpm, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0533 */ { UD_Ifnsave, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0534 */ { UD_Ifscale, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0535 */ { UD_Ifsin, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0536 */ { UD_Ifsincos, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0537 */ { UD_Ifsqrt, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0538 */ { UD_Ifstp, O_Mt, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0539 */ { UD_Ifstp, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0540 */ { UD_Ifstp, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0541 */ { UD_Ifstp, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0542 */ { UD_Ifstp, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0543 */ { UD_Ifstp, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0544 */ { UD_Ifstp, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0545 */ { UD_Ifstp, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0546 */ { UD_Ifstp, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0547 */ { UD_Ifstp, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0548 */ { UD_Ifstp, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0549 */ { UD_Ifstp1, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0550 */ { UD_Ifstp1, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0551 */ { UD_Ifstp1, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0552 */ { UD_Ifstp1, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0553 */ { UD_Ifstp1, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0554 */ { UD_Ifstp1, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0555 */ { UD_Ifstp1, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0556 */ { UD_Ifstp1, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0557 */ { UD_Ifstp8, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0558 */ { UD_Ifstp8, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0559 */ { UD_Ifstp8, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0560 */ { UD_Ifstp8, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0561 */ { UD_Ifstp8, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0562 */ { UD_Ifstp8, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0563 */ { UD_Ifstp8, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0564 */ { UD_Ifstp8, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0565 */ { UD_Ifstp9, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0566 */ { UD_Ifstp9, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0567 */ { UD_Ifstp9, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0568 */ { UD_Ifstp9, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0569 */ { UD_Ifstp9, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0570 */ { UD_Ifstp9, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0571 */ { UD_Ifstp9, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0572 */ { UD_Ifstp9, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0573 */ { UD_Ifst, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0574 */ { UD_Ifst, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0575 */ { UD_Ifst, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0576 */ { UD_Ifst, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0577 */ { UD_Ifst, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0578 */ { UD_Ifst, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0579 */ { UD_Ifst, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0580 */ { UD_Ifst, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0581 */ { UD_Ifst, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0582 */ { UD_Ifst, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0583 */ { UD_Ifnstcw, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0584 */ { UD_Ifnstenv, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0585 */ { UD_Ifnstsw, O_Mw, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0586 */ { UD_Ifnstsw, O_AX, O_NONE, O_NONE, O_NONE, P_none }, + /* 0587 */ { UD_Ifsub, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0588 */ { UD_Ifsub, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0589 */ { UD_Ifsub, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0590 */ { UD_Ifsub, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0591 */ { UD_Ifsub, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0592 */ { UD_Ifsub, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0593 */ { UD_Ifsub, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0594 */ { UD_Ifsub, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0595 */ { UD_Ifsub, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0596 */ { UD_Ifsub, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0597 */ { UD_Ifsub, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0598 */ { UD_Ifsub, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0599 */ { UD_Ifsub, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0600 */ { UD_Ifsub, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0601 */ { UD_Ifsub, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0602 */ { UD_Ifsub, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0603 */ { UD_Ifsub, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0604 */ { UD_Ifsub, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0605 */ { UD_Ifsubp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0606 */ { UD_Ifsubp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0607 */ { UD_Ifsubp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0608 */ { UD_Ifsubp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0609 */ { UD_Ifsubp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0610 */ { UD_Ifsubp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0611 */ { UD_Ifsubp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0612 */ { UD_Ifsubp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0613 */ { UD_Ifsubr, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0614 */ { UD_Ifsubr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0615 */ { UD_Ifsubr, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0616 */ { UD_Ifsubr, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0617 */ { UD_Ifsubr, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0618 */ { UD_Ifsubr, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0619 */ { UD_Ifsubr, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0620 */ { UD_Ifsubr, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0621 */ { UD_Ifsubr, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0622 */ { UD_Ifsubr, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0623 */ { UD_Ifsubr, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0624 */ { UD_Ifsubr, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0625 */ { UD_Ifsubr, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0626 */ { UD_Ifsubr, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0627 */ { UD_Ifsubr, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0628 */ { UD_Ifsubr, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0629 */ { UD_Ifsubr, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0630 */ { UD_Ifsubr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0631 */ { UD_Ifsubrp, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0632 */ { UD_Ifsubrp, O_ST1, O_ST0, O_NONE, O_NONE, P_none }, + /* 0633 */ { UD_Ifsubrp, O_ST2, O_ST0, O_NONE, O_NONE, P_none }, + /* 0634 */ { UD_Ifsubrp, O_ST3, O_ST0, O_NONE, O_NONE, P_none }, + /* 0635 */ { UD_Ifsubrp, O_ST4, O_ST0, O_NONE, O_NONE, P_none }, + /* 0636 */ { UD_Ifsubrp, O_ST5, O_ST0, O_NONE, O_NONE, P_none }, + /* 0637 */ { UD_Ifsubrp, O_ST6, O_ST0, O_NONE, O_NONE, P_none }, + /* 0638 */ { UD_Ifsubrp, O_ST7, O_ST0, O_NONE, O_NONE, P_none }, + /* 0639 */ { UD_Iftst, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0640 */ { UD_Ifucom, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0641 */ { UD_Ifucom, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0642 */ { UD_Ifucom, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0643 */ { UD_Ifucom, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0644 */ { UD_Ifucom, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0645 */ { UD_Ifucom, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0646 */ { UD_Ifucom, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0647 */ { UD_Ifucom, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0648 */ { UD_Ifucomp, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0649 */ { UD_Ifucomp, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0650 */ { UD_Ifucomp, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0651 */ { UD_Ifucomp, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0652 */ { UD_Ifucomp, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0653 */ { UD_Ifucomp, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0654 */ { UD_Ifucomp, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0655 */ { UD_Ifucomp, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0656 */ { UD_Ifucompp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0657 */ { UD_Ifxam, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0658 */ { UD_Ifxch, O_ST0, O_ST0, O_NONE, O_NONE, P_none }, + /* 0659 */ { UD_Ifxch, O_ST0, O_ST1, O_NONE, O_NONE, P_none }, + /* 0660 */ { UD_Ifxch, O_ST0, O_ST2, O_NONE, O_NONE, P_none }, + /* 0661 */ { UD_Ifxch, O_ST0, O_ST3, O_NONE, O_NONE, P_none }, + /* 0662 */ { UD_Ifxch, O_ST0, O_ST4, O_NONE, O_NONE, P_none }, + /* 0663 */ { UD_Ifxch, O_ST0, O_ST5, O_NONE, O_NONE, P_none }, + /* 0664 */ { UD_Ifxch, O_ST0, O_ST6, O_NONE, O_NONE, P_none }, + /* 0665 */ { UD_Ifxch, O_ST0, O_ST7, O_NONE, O_NONE, P_none }, + /* 0666 */ { UD_Ifxch4, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0667 */ { UD_Ifxch4, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0668 */ { UD_Ifxch4, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0669 */ { UD_Ifxch4, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0670 */ { UD_Ifxch4, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0671 */ { UD_Ifxch4, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0672 */ { UD_Ifxch4, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0673 */ { UD_Ifxch4, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0674 */ { UD_Ifxch7, O_ST0, O_NONE, O_NONE, O_NONE, P_none }, + /* 0675 */ { UD_Ifxch7, O_ST1, O_NONE, O_NONE, O_NONE, P_none }, + /* 0676 */ { UD_Ifxch7, O_ST2, O_NONE, O_NONE, O_NONE, P_none }, + /* 0677 */ { UD_Ifxch7, O_ST3, O_NONE, O_NONE, O_NONE, P_none }, + /* 0678 */ { UD_Ifxch7, O_ST4, O_NONE, O_NONE, O_NONE, P_none }, + /* 0679 */ { UD_Ifxch7, O_ST5, O_NONE, O_NONE, O_NONE, P_none }, + /* 0680 */ { UD_Ifxch7, O_ST6, O_NONE, O_NONE, O_NONE, P_none }, + /* 0681 */ { UD_Ifxch7, O_ST7, O_NONE, O_NONE, O_NONE, P_none }, + /* 0682 */ { UD_Ifxrstor, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0683 */ { UD_Ifxsave, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0684 */ { UD_Ifxtract, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0685 */ { UD_Ifyl2x, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0686 */ { UD_Ifyl2xp1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0687 */ { UD_Ihlt, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0688 */ { UD_Iidiv, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0689 */ { UD_Iidiv, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0690 */ { UD_Iin, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0691 */ { UD_Iin, O_eAX, O_Ib, O_NONE, O_NONE, P_oso }, + /* 0692 */ { UD_Iin, O_AL, O_DX, O_NONE, O_NONE, P_none }, + /* 0693 */ { UD_Iin, O_eAX, O_DX, O_NONE, O_NONE, P_oso }, + /* 0694 */ { UD_Iimul, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0695 */ { UD_Iimul, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0696 */ { UD_Iimul, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0697 */ { UD_Iimul, O_Gv, O_Ev, O_Iz, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0698 */ { UD_Iimul, O_Gv, O_Ev, O_sIb, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0699 */ { UD_Iinc, O_R0z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0700 */ { UD_Iinc, O_R1z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0701 */ { UD_Iinc, O_R2z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0702 */ { UD_Iinc, O_R3z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0703 */ { UD_Iinc, O_R4z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0704 */ { UD_Iinc, O_R5z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0705 */ { UD_Iinc, O_R6z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0706 */ { UD_Iinc, O_R7z, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0707 */ { UD_Iinc, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0708 */ { UD_Iinc, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0709 */ { UD_Iinsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0710 */ { UD_Iinsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0711 */ { UD_Iinsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0712 */ { UD_Iint1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0713 */ { UD_Iint3, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0714 */ { UD_Iint, O_Ib, O_NONE, O_NONE, O_NONE, P_none }, + /* 0715 */ { UD_Iinto, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 0716 */ { UD_Iinvd, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0717 */ { UD_Iinvept, O_Gd, O_Mo, O_NONE, O_NONE, P_none }, + /* 0718 */ { UD_Iinvept, O_Gq, O_Mo, O_NONE, O_NONE, P_none }, + /* 0719 */ { UD_Iinvlpg, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0720 */ { UD_Iinvlpga, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0721 */ { UD_Iinvvpid, O_Gd, O_Mo, O_NONE, O_NONE, P_none }, + /* 0722 */ { UD_Iinvvpid, O_Gq, O_Mo, O_NONE, O_NONE, P_none }, + /* 0723 */ { UD_Iiretw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0724 */ { UD_Iiretd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0725 */ { UD_Iiretq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0726 */ { UD_Ijo, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0727 */ { UD_Ijo, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0728 */ { UD_Ijno, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0729 */ { UD_Ijno, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0730 */ { UD_Ijb, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0731 */ { UD_Ijb, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0732 */ { UD_Ijae, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0733 */ { UD_Ijae, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0734 */ { UD_Ijz, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0735 */ { UD_Ijz, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0736 */ { UD_Ijnz, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0737 */ { UD_Ijnz, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0738 */ { UD_Ijbe, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0739 */ { UD_Ijbe, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0740 */ { UD_Ija, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0741 */ { UD_Ija, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0742 */ { UD_Ijs, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0743 */ { UD_Ijs, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0744 */ { UD_Ijns, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0745 */ { UD_Ijns, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0746 */ { UD_Ijp, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0747 */ { UD_Ijp, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0748 */ { UD_Ijnp, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0749 */ { UD_Ijnp, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0750 */ { UD_Ijl, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0751 */ { UD_Ijl, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0752 */ { UD_Ijge, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0753 */ { UD_Ijge, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0754 */ { UD_Ijle, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0755 */ { UD_Ijle, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0756 */ { UD_Ijg, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0757 */ { UD_Ijg, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0758 */ { UD_Ijcxz, O_Jb, O_NONE, O_NONE, O_NONE, P_aso }, + /* 0759 */ { UD_Ijecxz, O_Jb, O_NONE, O_NONE, O_NONE, P_aso }, + /* 0760 */ { UD_Ijrcxz, O_Jb, O_NONE, O_NONE, O_NONE, P_aso }, + /* 0761 */ { UD_Ijmp, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 0762 */ { UD_Ijmp, O_Fv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0763 */ { UD_Ijmp, O_Jz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 0764 */ { UD_Ijmp, O_Av, O_NONE, O_NONE, O_NONE, P_oso }, + /* 0765 */ { UD_Ijmp, O_Jb, O_NONE, O_NONE, O_NONE, P_def64 }, + /* 0766 */ { UD_Ilahf, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0767 */ { UD_Ilar, O_Gv, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0768 */ { UD_Ildmxcsr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0769 */ { UD_Ilds, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso }, + /* 0770 */ { UD_Ilea, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0771 */ { UD_Iles, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso }, + /* 0772 */ { UD_Ilfs, O_Gz, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0773 */ { UD_Ilgs, O_Gz, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0774 */ { UD_Ilidt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0775 */ { UD_Ilss, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0776 */ { UD_Ileave, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0777 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0778 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0779 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0780 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0781 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0782 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0783 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0784 */ { UD_Ilfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0785 */ { UD_Ilgdt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0786 */ { UD_Illdt, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0787 */ { UD_Ilmsw, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0788 */ { UD_Ilmsw, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0789 */ { UD_Ilock, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0790 */ { UD_Ilodsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0791 */ { UD_Ilodsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0792 */ { UD_Ilodsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0793 */ { UD_Ilodsq, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0794 */ { UD_Iloopne, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0795 */ { UD_Iloope, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0796 */ { UD_Iloop, O_Jb, O_NONE, O_NONE, O_NONE, P_none }, + /* 0797 */ { UD_Ilsl, O_Gv, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0798 */ { UD_Iltr, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0799 */ { UD_Imaskmovq, O_P, O_N, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0800 */ { UD_Imaxpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0801 */ { UD_Ivmaxpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0802 */ { UD_Imaxps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0803 */ { UD_Ivmaxps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0804 */ { UD_Imaxsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0805 */ { UD_Ivmaxsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0806 */ { UD_Imaxss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0807 */ { UD_Ivmaxss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0808 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0809 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0810 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0811 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0812 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0813 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0814 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0815 */ { UD_Imfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0816 */ { UD_Iminpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0817 */ { UD_Ivminpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0818 */ { UD_Iminps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0819 */ { UD_Ivminps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0820 */ { UD_Iminsd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0821 */ { UD_Ivminsd, O_Vx, O_Hx, O_MqU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0822 */ { UD_Iminss, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0823 */ { UD_Ivminss, O_Vx, O_Hx, O_MdU, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0824 */ { UD_Imonitor, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0825 */ { UD_Imontmul, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0826 */ { UD_Imov, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0827 */ { UD_Imov, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0828 */ { UD_Imov, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0829 */ { UD_Imov, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0830 */ { UD_Imov, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0831 */ { UD_Imov, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0832 */ { UD_Imov, O_MwRv, O_S, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0833 */ { UD_Imov, O_S, O_MwRv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0834 */ { UD_Imov, O_AL, O_Ob, O_NONE, O_NONE, P_none }, + /* 0835 */ { UD_Imov, O_rAX, O_Ov, O_NONE, O_NONE, P_aso|P_oso|P_rexw }, + /* 0836 */ { UD_Imov, O_Ob, O_AL, O_NONE, O_NONE, P_none }, + /* 0837 */ { UD_Imov, O_Ov, O_rAX, O_NONE, O_NONE, P_aso|P_oso|P_rexw }, + /* 0838 */ { UD_Imov, O_R0b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0839 */ { UD_Imov, O_R1b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0840 */ { UD_Imov, O_R2b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0841 */ { UD_Imov, O_R3b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0842 */ { UD_Imov, O_R4b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0843 */ { UD_Imov, O_R5b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0844 */ { UD_Imov, O_R6b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0845 */ { UD_Imov, O_R7b, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 0846 */ { UD_Imov, O_R0v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0847 */ { UD_Imov, O_R1v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0848 */ { UD_Imov, O_R2v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0849 */ { UD_Imov, O_R3v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0850 */ { UD_Imov, O_R4v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0851 */ { UD_Imov, O_R5v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0852 */ { UD_Imov, O_R6v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0853 */ { UD_Imov, O_R7v, O_Iv, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 0854 */ { UD_Imov, O_R, O_C, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0855 */ { UD_Imov, O_R, O_D, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0856 */ { UD_Imov, O_C, O_R, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0857 */ { UD_Imov, O_D, O_R, O_NONE, O_NONE, P_rexr|P_rexw|P_rexb }, + /* 0858 */ { UD_Imovapd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0859 */ { UD_Ivmovapd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0860 */ { UD_Imovapd, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0861 */ { UD_Ivmovapd, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0862 */ { UD_Imovaps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0863 */ { UD_Ivmovaps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0864 */ { UD_Imovaps, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0865 */ { UD_Ivmovaps, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0866 */ { UD_Imovd, O_P, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0867 */ { UD_Imovd, O_P, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0868 */ { UD_Imovd, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0869 */ { UD_Ivmovd, O_Vx, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0870 */ { UD_Imovd, O_V, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0871 */ { UD_Ivmovd, O_Vx, O_Ey, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0872 */ { UD_Imovd, O_Ey, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0873 */ { UD_Imovd, O_Ey, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0874 */ { UD_Imovd, O_Ey, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0875 */ { UD_Ivmovd, O_Ey, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0876 */ { UD_Imovd, O_Ey, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0877 */ { UD_Ivmovd, O_Ey, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0878 */ { UD_Imovhpd, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0879 */ { UD_Ivmovhpd, O_Vx, O_Hx, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0880 */ { UD_Imovhpd, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0881 */ { UD_Ivmovhpd, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0882 */ { UD_Imovhps, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0883 */ { UD_Ivmovhps, O_Vx, O_Hx, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0884 */ { UD_Imovhps, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0885 */ { UD_Ivmovhps, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0886 */ { UD_Imovlhps, O_V, O_U, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0887 */ { UD_Ivmovlhps, O_Vx, O_Hx, O_Ux, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0888 */ { UD_Imovlpd, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0889 */ { UD_Ivmovlpd, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0890 */ { UD_Imovlpd, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0891 */ { UD_Ivmovlpd, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0892 */ { UD_Imovlps, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0893 */ { UD_Ivmovlps, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0894 */ { UD_Imovlps, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0895 */ { UD_Ivmovlps, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0896 */ { UD_Imovhlps, O_V, O_U, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0897 */ { UD_Ivmovhlps, O_Vx, O_Ux, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0898 */ { UD_Imovmskpd, O_Gd, O_U, O_NONE, O_NONE, P_oso|P_rexr|P_rexb }, + /* 0899 */ { UD_Ivmovmskpd, O_Gd, O_Ux, O_NONE, O_NONE, P_oso|P_rexr|P_rexb|P_vexl }, + /* 0900 */ { UD_Imovmskps, O_Gd, O_U, O_NONE, O_NONE, P_oso|P_rexr|P_rexb }, + /* 0901 */ { UD_Ivmovmskps, O_Gd, O_Ux, O_NONE, O_NONE, P_oso|P_rexr|P_rexb }, + /* 0902 */ { UD_Imovntdq, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0903 */ { UD_Ivmovntdq, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0904 */ { UD_Imovnti, O_M, O_Gy, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0905 */ { UD_Imovntpd, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0906 */ { UD_Ivmovntpd, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0907 */ { UD_Imovntps, O_M, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0908 */ { UD_Ivmovntps, O_M, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0909 */ { UD_Imovntq, O_M, O_P, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0910 */ { UD_Imovq, O_P, O_Eq, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0911 */ { UD_Imovq, O_V, O_Eq, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0912 */ { UD_Ivmovq, O_Vx, O_Eq, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0913 */ { UD_Imovq, O_Eq, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0914 */ { UD_Imovq, O_Eq, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0915 */ { UD_Ivmovq, O_Eq, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0916 */ { UD_Imovq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0917 */ { UD_Ivmovq, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0918 */ { UD_Imovq, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0919 */ { UD_Ivmovq, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0920 */ { UD_Imovq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0921 */ { UD_Imovq, O_Q, O_P, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0922 */ { UD_Imovsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0923 */ { UD_Imovsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0924 */ { UD_Imovsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0925 */ { UD_Imovsd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0926 */ { UD_Imovsd, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0927 */ { UD_Imovsq, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 0928 */ { UD_Imovss, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0929 */ { UD_Imovss, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0930 */ { UD_Imovsx, O_Gv, O_Eb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0931 */ { UD_Imovsx, O_Gy, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0932 */ { UD_Imovupd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0933 */ { UD_Ivmovupd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0934 */ { UD_Imovupd, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0935 */ { UD_Ivmovupd, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0936 */ { UD_Imovups, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0937 */ { UD_Ivmovups, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0938 */ { UD_Imovups, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0939 */ { UD_Ivmovups, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0940 */ { UD_Imovzx, O_Gv, O_Eb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0941 */ { UD_Imovzx, O_Gy, O_Ew, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0942 */ { UD_Imul, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0943 */ { UD_Imul, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0944 */ { UD_Imulpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0945 */ { UD_Ivmulpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0946 */ { UD_Imulps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0947 */ { UD_Ivmulps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0948 */ { UD_Imulsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0949 */ { UD_Ivmulsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0950 */ { UD_Imulss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0951 */ { UD_Ivmulss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0952 */ { UD_Imwait, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 0953 */ { UD_Ineg, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0954 */ { UD_Ineg, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0955 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0956 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0957 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0958 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0959 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0960 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0961 */ { UD_Inop, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0962 */ { UD_Inot, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0963 */ { UD_Inot, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0964 */ { UD_Ior, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0965 */ { UD_Ior, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0966 */ { UD_Ior, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0967 */ { UD_Ior, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0968 */ { UD_Ior, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 0969 */ { UD_Ior, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 0970 */ { UD_Ior, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0971 */ { UD_Ior, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0972 */ { UD_Ior, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0973 */ { UD_Ior, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 0974 */ { UD_Iorpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0975 */ { UD_Ivorpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0976 */ { UD_Iorps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0977 */ { UD_Ivorps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0978 */ { UD_Iout, O_Ib, O_AL, O_NONE, O_NONE, P_none }, + /* 0979 */ { UD_Iout, O_Ib, O_eAX, O_NONE, O_NONE, P_oso }, + /* 0980 */ { UD_Iout, O_DX, O_AL, O_NONE, O_NONE, P_none }, + /* 0981 */ { UD_Iout, O_DX, O_eAX, O_NONE, O_NONE, P_oso }, + /* 0982 */ { UD_Ioutsb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 0983 */ { UD_Ioutsw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0984 */ { UD_Ioutsd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_oso|P_seg }, + /* 0985 */ { UD_Ipacksswb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0986 */ { UD_Ivpacksswb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0987 */ { UD_Ipacksswb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0988 */ { UD_Ipackssdw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0989 */ { UD_Ivpackssdw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0990 */ { UD_Ipackssdw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0991 */ { UD_Ipackuswb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0992 */ { UD_Ivpackuswb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0993 */ { UD_Ipackuswb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0994 */ { UD_Ipaddb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0995 */ { UD_Ivpaddb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 0996 */ { UD_Ipaddb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0997 */ { UD_Ipaddw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0998 */ { UD_Ipaddw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 0999 */ { UD_Ivpaddw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1000 */ { UD_Ipaddd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1001 */ { UD_Ipaddd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1002 */ { UD_Ivpaddd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1003 */ { UD_Ipaddsb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1004 */ { UD_Ipaddsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1005 */ { UD_Ivpaddsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1006 */ { UD_Ipaddsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1007 */ { UD_Ipaddsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1008 */ { UD_Ivpaddsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1009 */ { UD_Ipaddusb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1010 */ { UD_Ipaddusb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1011 */ { UD_Ivpaddusb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1012 */ { UD_Ipaddusw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1013 */ { UD_Ipaddusw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1014 */ { UD_Ivpaddusw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1015 */ { UD_Ipand, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1016 */ { UD_Ivpand, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1017 */ { UD_Ipand, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1018 */ { UD_Ipandn, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1019 */ { UD_Ivpandn, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1020 */ { UD_Ipandn, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1021 */ { UD_Ipavgb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1022 */ { UD_Ivpavgb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1023 */ { UD_Ipavgb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1024 */ { UD_Ipavgw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1025 */ { UD_Ivpavgw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1026 */ { UD_Ipavgw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1027 */ { UD_Ipcmpeqb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1028 */ { UD_Ipcmpeqb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1029 */ { UD_Ivpcmpeqb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1030 */ { UD_Ipcmpeqw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1031 */ { UD_Ipcmpeqw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1032 */ { UD_Ivpcmpeqw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1033 */ { UD_Ipcmpeqd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1034 */ { UD_Ipcmpeqd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1035 */ { UD_Ivpcmpeqd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1036 */ { UD_Ipcmpgtb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1037 */ { UD_Ivpcmpgtb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1038 */ { UD_Ipcmpgtb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1039 */ { UD_Ipcmpgtw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1040 */ { UD_Ivpcmpgtw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1041 */ { UD_Ipcmpgtw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1042 */ { UD_Ipcmpgtd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1043 */ { UD_Ivpcmpgtd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1044 */ { UD_Ipcmpgtd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1045 */ { UD_Ipextrb, O_MbRv, O_V, O_Ib, O_NONE, P_aso|P_rexx|P_rexr|P_rexb|P_def64 }, + /* 1046 */ { UD_Ivpextrb, O_MbRv, O_Vx, O_Ib, O_NONE, P_aso|P_rexx|P_rexr|P_rexb|P_def64 }, + /* 1047 */ { UD_Ipextrd, O_Ed, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1048 */ { UD_Ivpextrd, O_Ed, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1049 */ { UD_Ipextrd, O_Ed, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1050 */ { UD_Ivpextrd, O_Ed, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexw|P_rexb }, + /* 1051 */ { UD_Ipextrq, O_Eq, O_V, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexb|P_def64 }, + /* 1052 */ { UD_Ivpextrq, O_Eq, O_Vx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexb|P_def64 }, + /* 1053 */ { UD_Ipextrw, O_Gd, O_U, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexb }, + /* 1054 */ { UD_Ivpextrw, O_Gd, O_Ux, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexb }, + /* 1055 */ { UD_Ipextrw, O_Gd, O_N, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1056 */ { UD_Ipextrw, O_MwRd, O_V, O_Ib, O_NONE, P_aso|P_rexw|P_rexx|P_rexr|P_rexb }, + /* 1057 */ { UD_Ivpextrw, O_MwRd, O_Vx, O_Ib, O_NONE, P_aso|P_rexw|P_rexx|P_rexr|P_rexb }, + /* 1058 */ { UD_Ipinsrb, O_V, O_MbRd, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1059 */ { UD_Ipinsrw, O_P, O_MwRy, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1060 */ { UD_Ipinsrw, O_V, O_MwRy, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1061 */ { UD_Ivpinsrw, O_Vx, O_MwRy, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1062 */ { UD_Ipinsrd, O_V, O_Ed, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1063 */ { UD_Ipinsrd, O_V, O_Ed, O_Ib, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1064 */ { UD_Ipinsrq, O_V, O_Eq, O_Ib, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1065 */ { UD_Ivpinsrb, O_V, O_H, O_MbRd, O_Ib, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1066 */ { UD_Ivpinsrd, O_V, O_H, O_Ed, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1067 */ { UD_Ivpinsrd, O_V, O_H, O_Ed, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1068 */ { UD_Ivpinsrq, O_V, O_H, O_Eq, O_Ib, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1069 */ { UD_Ipmaddwd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1070 */ { UD_Ipmaddwd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1071 */ { UD_Ivpmaddwd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1072 */ { UD_Ipmaxsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1073 */ { UD_Ivpmaxsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1074 */ { UD_Ipmaxsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1075 */ { UD_Ipmaxub, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1076 */ { UD_Ipmaxub, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1077 */ { UD_Ivpmaxub, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1078 */ { UD_Ipminsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1079 */ { UD_Ivpminsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1080 */ { UD_Ipminsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1081 */ { UD_Ipminub, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1082 */ { UD_Ivpminub, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1083 */ { UD_Ipminub, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1084 */ { UD_Ipmovmskb, O_Gd, O_U, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexb }, + /* 1085 */ { UD_Ivpmovmskb, O_Gd, O_Ux, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexb }, + /* 1086 */ { UD_Ipmovmskb, O_Gd, O_N, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexb }, + /* 1087 */ { UD_Ipmulhuw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1088 */ { UD_Ipmulhuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1089 */ { UD_Ivpmulhuw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1090 */ { UD_Ipmulhw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1091 */ { UD_Ivpmulhw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1092 */ { UD_Ipmulhw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1093 */ { UD_Ipmullw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1094 */ { UD_Ipmullw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1095 */ { UD_Ivpmullw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1096 */ { UD_Ipop, O_ES, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1097 */ { UD_Ipop, O_SS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1098 */ { UD_Ipop, O_DS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1099 */ { UD_Ipop, O_GS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1100 */ { UD_Ipop, O_FS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1101 */ { UD_Ipop, O_R0v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1102 */ { UD_Ipop, O_R1v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1103 */ { UD_Ipop, O_R2v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1104 */ { UD_Ipop, O_R3v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1105 */ { UD_Ipop, O_R4v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1106 */ { UD_Ipop, O_R5v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1107 */ { UD_Ipop, O_R6v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1108 */ { UD_Ipop, O_R7v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1109 */ { UD_Ipop, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1110 */ { UD_Ipopa, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1111 */ { UD_Ipopad, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1112 */ { UD_Ipopfw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1113 */ { UD_Ipopfd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1114 */ { UD_Ipopfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1115 */ { UD_Ipopfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1116 */ { UD_Ipor, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1117 */ { UD_Ivpor, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1118 */ { UD_Ipor, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1119 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1120 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1121 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1122 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1123 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1124 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1125 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1126 */ { UD_Iprefetch, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1127 */ { UD_Iprefetchnta, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1128 */ { UD_Iprefetcht0, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1129 */ { UD_Iprefetcht1, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1130 */ { UD_Iprefetcht2, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1131 */ { UD_Ipsadbw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1132 */ { UD_Ivpsadbw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1133 */ { UD_Ipsadbw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1134 */ { UD_Ipshufw, O_P, O_Q, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1135 */ { UD_Ipsllw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1136 */ { UD_Ipsllw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1137 */ { UD_Ipsllw, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1138 */ { UD_Ipsllw, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1139 */ { UD_Ipslld, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1140 */ { UD_Ipslld, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1141 */ { UD_Ipslld, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1142 */ { UD_Ipslld, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1143 */ { UD_Ipsllq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1144 */ { UD_Ipsllq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1145 */ { UD_Ipsllq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1146 */ { UD_Ipsllq, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1147 */ { UD_Ipsraw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1148 */ { UD_Ipsraw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1149 */ { UD_Ivpsraw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1150 */ { UD_Ipsraw, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1151 */ { UD_Ivpsraw, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1152 */ { UD_Ipsraw, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1153 */ { UD_Ipsrad, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1154 */ { UD_Ipsrad, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1155 */ { UD_Ivpsrad, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1156 */ { UD_Ipsrad, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1157 */ { UD_Ipsrad, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1158 */ { UD_Ivpsrad, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1159 */ { UD_Ipsrlw, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1160 */ { UD_Ipsrlw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1161 */ { UD_Ipsrlw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1162 */ { UD_Ivpsrlw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1163 */ { UD_Ipsrlw, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1164 */ { UD_Ivpsrlw, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1165 */ { UD_Ipsrld, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1166 */ { UD_Ipsrld, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1167 */ { UD_Ipsrld, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1168 */ { UD_Ivpsrld, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1169 */ { UD_Ipsrld, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1170 */ { UD_Ivpsrld, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1171 */ { UD_Ipsrlq, O_N, O_Ib, O_NONE, O_NONE, P_none }, + /* 1172 */ { UD_Ipsrlq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1173 */ { UD_Ipsrlq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1174 */ { UD_Ivpsrlq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1175 */ { UD_Ipsrlq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1176 */ { UD_Ivpsrlq, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1177 */ { UD_Ipsubb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1178 */ { UD_Ivpsubb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1179 */ { UD_Ipsubb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1180 */ { UD_Ipsubw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1181 */ { UD_Ivpsubw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1182 */ { UD_Ipsubw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1183 */ { UD_Ipsubd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1184 */ { UD_Ipsubd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1185 */ { UD_Ivpsubd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1186 */ { UD_Ipsubsb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1187 */ { UD_Ipsubsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1188 */ { UD_Ivpsubsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1189 */ { UD_Ipsubsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1190 */ { UD_Ipsubsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1191 */ { UD_Ivpsubsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1192 */ { UD_Ipsubusb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1193 */ { UD_Ipsubusb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1194 */ { UD_Ivpsubusb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1195 */ { UD_Ipsubusw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1196 */ { UD_Ipsubusw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1197 */ { UD_Ivpsubusw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1198 */ { UD_Ipunpckhbw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1199 */ { UD_Ivpunpckhbw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1200 */ { UD_Ipunpckhbw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1201 */ { UD_Ipunpckhwd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1202 */ { UD_Ivpunpckhwd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1203 */ { UD_Ipunpckhwd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1204 */ { UD_Ipunpckhdq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1205 */ { UD_Ivpunpckhdq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1206 */ { UD_Ipunpckhdq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1207 */ { UD_Ipunpcklbw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1208 */ { UD_Ivpunpcklbw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1209 */ { UD_Ipunpcklbw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1210 */ { UD_Ipunpcklwd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1211 */ { UD_Ivpunpcklwd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1212 */ { UD_Ipunpcklwd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1213 */ { UD_Ipunpckldq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1214 */ { UD_Ivpunpckldq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1215 */ { UD_Ipunpckldq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1216 */ { UD_Ipi2fw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1217 */ { UD_Ipi2fd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1218 */ { UD_Ipf2iw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1219 */ { UD_Ipf2id, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1220 */ { UD_Ipfnacc, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1221 */ { UD_Ipfpnacc, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1222 */ { UD_Ipfcmpge, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1223 */ { UD_Ipfmin, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1224 */ { UD_Ipfrcp, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1225 */ { UD_Ipfrsqrt, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1226 */ { UD_Ipfsub, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1227 */ { UD_Ipfadd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1228 */ { UD_Ipfcmpgt, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1229 */ { UD_Ipfmax, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1230 */ { UD_Ipfrcpit1, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1231 */ { UD_Ipfrsqit1, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1232 */ { UD_Ipfsubr, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1233 */ { UD_Ipfacc, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1234 */ { UD_Ipfcmpeq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1235 */ { UD_Ipfmul, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1236 */ { UD_Ipfrcpit2, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1237 */ { UD_Ipmulhrw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1238 */ { UD_Ipswapd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1239 */ { UD_Ipavgusb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1240 */ { UD_Ipush, O_ES, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1241 */ { UD_Ipush, O_CS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1242 */ { UD_Ipush, O_SS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1243 */ { UD_Ipush, O_DS, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1244 */ { UD_Ipush, O_GS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1245 */ { UD_Ipush, O_FS, O_NONE, O_NONE, O_NONE, P_none }, + /* 1246 */ { UD_Ipush, O_R0v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1247 */ { UD_Ipush, O_R1v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1248 */ { UD_Ipush, O_R2v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1249 */ { UD_Ipush, O_R3v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1250 */ { UD_Ipush, O_R4v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1251 */ { UD_Ipush, O_R5v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1252 */ { UD_Ipush, O_R6v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1253 */ { UD_Ipush, O_R7v, O_NONE, O_NONE, O_NONE, P_oso|P_rexb|P_def64 }, + /* 1254 */ { UD_Ipush, O_sIz, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1255 */ { UD_Ipush, O_Ev, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1256 */ { UD_Ipush, O_sIb, O_NONE, O_NONE, O_NONE, P_oso|P_def64 }, + /* 1257 */ { UD_Ipusha, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1258 */ { UD_Ipushad, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_inv64 }, + /* 1259 */ { UD_Ipushfw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1260 */ { UD_Ipushfw, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_def64 }, + /* 1261 */ { UD_Ipushfd, O_NONE, O_NONE, O_NONE, O_NONE, P_oso }, + /* 1262 */ { UD_Ipushfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_def64 }, + /* 1263 */ { UD_Ipushfq, O_NONE, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_def64 }, + /* 1264 */ { UD_Ipxor, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1265 */ { UD_Ivpxor, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1266 */ { UD_Ipxor, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1267 */ { UD_Ircl, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1268 */ { UD_Ircl, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1269 */ { UD_Ircl, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1270 */ { UD_Ircl, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1271 */ { UD_Ircl, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1272 */ { UD_Ircl, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1273 */ { UD_Ircr, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1274 */ { UD_Ircr, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1275 */ { UD_Ircr, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1276 */ { UD_Ircr, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1277 */ { UD_Ircr, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1278 */ { UD_Ircr, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1279 */ { UD_Irol, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1280 */ { UD_Irol, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1281 */ { UD_Irol, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1282 */ { UD_Irol, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1283 */ { UD_Irol, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1284 */ { UD_Irol, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1285 */ { UD_Iror, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1286 */ { UD_Iror, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1287 */ { UD_Iror, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1288 */ { UD_Iror, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1289 */ { UD_Iror, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1290 */ { UD_Iror, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1291 */ { UD_Ircpps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1292 */ { UD_Ivrcpps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1293 */ { UD_Ircpss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1294 */ { UD_Ivrcpss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1295 */ { UD_Irdmsr, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1296 */ { UD_Irdpmc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1297 */ { UD_Irdtsc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1298 */ { UD_Irdtscp, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1299 */ { UD_Irepne, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1300 */ { UD_Irep, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1301 */ { UD_Iret, O_Iw, O_NONE, O_NONE, O_NONE, P_none }, + /* 1302 */ { UD_Iret, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1303 */ { UD_Iretf, O_Iw, O_NONE, O_NONE, O_NONE, P_none }, + /* 1304 */ { UD_Iretf, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1305 */ { UD_Irsm, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1306 */ { UD_Irsqrtps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1307 */ { UD_Ivrsqrtps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1308 */ { UD_Irsqrtss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1309 */ { UD_Ivrsqrtss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1310 */ { UD_Isahf, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1311 */ { UD_Isalc, O_NONE, O_NONE, O_NONE, O_NONE, P_inv64 }, + /* 1312 */ { UD_Isar, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1313 */ { UD_Isar, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1314 */ { UD_Isar, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1315 */ { UD_Isar, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1316 */ { UD_Isar, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1317 */ { UD_Isar, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1318 */ { UD_Ishl, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1319 */ { UD_Ishl, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1320 */ { UD_Ishl, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1321 */ { UD_Ishl, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1322 */ { UD_Ishl, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1323 */ { UD_Ishl, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1324 */ { UD_Ishl, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1325 */ { UD_Ishl, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1326 */ { UD_Ishl, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1327 */ { UD_Ishl, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1328 */ { UD_Ishl, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1329 */ { UD_Ishl, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1330 */ { UD_Ishr, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1331 */ { UD_Ishr, O_Eb, O_CL, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1332 */ { UD_Ishr, O_Ev, O_I1, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1333 */ { UD_Ishr, O_Eb, O_I1, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1334 */ { UD_Ishr, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1335 */ { UD_Ishr, O_Ev, O_CL, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1336 */ { UD_Isbb, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1337 */ { UD_Isbb, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1338 */ { UD_Isbb, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1339 */ { UD_Isbb, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1340 */ { UD_Isbb, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1341 */ { UD_Isbb, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1342 */ { UD_Isbb, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1343 */ { UD_Isbb, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1344 */ { UD_Isbb, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 1345 */ { UD_Isbb, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1346 */ { UD_Iscasb, O_NONE, O_NONE, O_NONE, O_NONE, P_strz }, + /* 1347 */ { UD_Iscasw, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw }, + /* 1348 */ { UD_Iscasd, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw }, + /* 1349 */ { UD_Iscasq, O_NONE, O_NONE, O_NONE, O_NONE, P_strz|P_oso|P_rexw }, + /* 1350 */ { UD_Iseto, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1351 */ { UD_Isetno, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1352 */ { UD_Isetb, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1353 */ { UD_Isetae, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1354 */ { UD_Isetz, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1355 */ { UD_Isetnz, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1356 */ { UD_Isetbe, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1357 */ { UD_Iseta, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1358 */ { UD_Isets, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1359 */ { UD_Isetns, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1360 */ { UD_Isetp, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1361 */ { UD_Isetnp, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1362 */ { UD_Isetl, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1363 */ { UD_Isetge, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1364 */ { UD_Isetle, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1365 */ { UD_Isetg, O_Eb, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1366 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1367 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1368 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1369 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1370 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1371 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1372 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1373 */ { UD_Isfence, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1374 */ { UD_Isgdt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1375 */ { UD_Ishld, O_Ev, O_Gv, O_Ib, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1376 */ { UD_Ishld, O_Ev, O_Gv, O_CL, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1377 */ { UD_Ishrd, O_Ev, O_Gv, O_Ib, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1378 */ { UD_Ishrd, O_Ev, O_Gv, O_CL, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1379 */ { UD_Ishufpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1380 */ { UD_Ivshufpd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1381 */ { UD_Ishufps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1382 */ { UD_Ivshufps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1383 */ { UD_Isidt, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1384 */ { UD_Isldt, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1385 */ { UD_Ismsw, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1386 */ { UD_Ismsw, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1387 */ { UD_Isqrtps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1388 */ { UD_Ivsqrtps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1389 */ { UD_Isqrtpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1390 */ { UD_Ivsqrtpd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1391 */ { UD_Isqrtsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1392 */ { UD_Ivsqrtsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1393 */ { UD_Isqrtss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1394 */ { UD_Ivsqrtss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1395 */ { UD_Istc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1396 */ { UD_Istd, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1397 */ { UD_Istgi, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1398 */ { UD_Isti, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1399 */ { UD_Iskinit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1400 */ { UD_Istmxcsr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1401 */ { UD_Ivstmxcsr, O_Md, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1402 */ { UD_Istosb, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg }, + /* 1403 */ { UD_Istosw, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 1404 */ { UD_Istosd, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 1405 */ { UD_Istosq, O_NONE, O_NONE, O_NONE, O_NONE, P_str|P_seg|P_oso|P_rexw }, + /* 1406 */ { UD_Istr, O_MwRv, O_NONE, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1407 */ { UD_Isub, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1408 */ { UD_Isub, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1409 */ { UD_Isub, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1410 */ { UD_Isub, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1411 */ { UD_Isub, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1412 */ { UD_Isub, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1413 */ { UD_Isub, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1414 */ { UD_Isub, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1415 */ { UD_Isub, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 1416 */ { UD_Isub, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1417 */ { UD_Isubpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1418 */ { UD_Ivsubpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1419 */ { UD_Isubps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1420 */ { UD_Ivsubps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1421 */ { UD_Isubsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1422 */ { UD_Ivsubsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1423 */ { UD_Isubss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1424 */ { UD_Ivsubss, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1425 */ { UD_Iswapgs, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1426 */ { UD_Isyscall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1427 */ { UD_Isysenter, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1428 */ { UD_Isysenter, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1429 */ { UD_Isysexit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1430 */ { UD_Isysexit, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1431 */ { UD_Isysret, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1432 */ { UD_Itest, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1433 */ { UD_Itest, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1434 */ { UD_Itest, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1435 */ { UD_Itest, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1436 */ { UD_Itest, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1437 */ { UD_Itest, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1438 */ { UD_Itest, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1439 */ { UD_Itest, O_Ev, O_Iz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1440 */ { UD_Iucomisd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1441 */ { UD_Ivucomisd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1442 */ { UD_Iucomiss, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1443 */ { UD_Ivucomiss, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1444 */ { UD_Iud2, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1445 */ { UD_Iunpckhpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1446 */ { UD_Ivunpckhpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1447 */ { UD_Iunpckhps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1448 */ { UD_Ivunpckhps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1449 */ { UD_Iunpcklps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1450 */ { UD_Ivunpcklps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1451 */ { UD_Iunpcklpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1452 */ { UD_Ivunpcklpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1453 */ { UD_Iverr, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1454 */ { UD_Iverw, O_Ew, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1455 */ { UD_Ivmcall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1456 */ { UD_Irdrand, O_R, O_NONE, O_NONE, O_NONE, P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1457 */ { UD_Ivmclear, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1458 */ { UD_Ivmxon, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1459 */ { UD_Ivmptrld, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1460 */ { UD_Ivmptrst, O_Mq, O_NONE, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1461 */ { UD_Ivmlaunch, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1462 */ { UD_Ivmresume, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1463 */ { UD_Ivmxoff, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1464 */ { UD_Ivmread, O_Ey, O_Gy, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1465 */ { UD_Ivmwrite, O_Gy, O_Ey, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_def64 }, + /* 1466 */ { UD_Ivmrun, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1467 */ { UD_Ivmmcall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1468 */ { UD_Ivmload, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1469 */ { UD_Ivmsave, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1470 */ { UD_Iwait, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1471 */ { UD_Iwbinvd, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1472 */ { UD_Iwrmsr, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1473 */ { UD_Ixadd, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexx|P_rexb }, + /* 1474 */ { UD_Ixadd, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1475 */ { UD_Ixchg, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1476 */ { UD_Ixchg, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1477 */ { UD_Ixchg, O_R0v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1478 */ { UD_Ixchg, O_R1v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1479 */ { UD_Ixchg, O_R2v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1480 */ { UD_Ixchg, O_R3v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1481 */ { UD_Ixchg, O_R4v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1482 */ { UD_Ixchg, O_R5v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1483 */ { UD_Ixchg, O_R6v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1484 */ { UD_Ixchg, O_R7v, O_rAX, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1485 */ { UD_Ixgetbv, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1486 */ { UD_Ixlatb, O_NONE, O_NONE, O_NONE, O_NONE, P_rexw|P_seg }, + /* 1487 */ { UD_Ixor, O_Eb, O_Gb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1488 */ { UD_Ixor, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1489 */ { UD_Ixor, O_Gb, O_Eb, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1490 */ { UD_Ixor, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1491 */ { UD_Ixor, O_AL, O_Ib, O_NONE, O_NONE, P_none }, + /* 1492 */ { UD_Ixor, O_rAX, O_sIz, O_NONE, O_NONE, P_oso|P_rexw }, + /* 1493 */ { UD_Ixor, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1494 */ { UD_Ixor, O_Ev, O_sIz, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1495 */ { UD_Ixor, O_Eb, O_Ib, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_inv64 }, + /* 1496 */ { UD_Ixor, O_Ev, O_sIb, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1497 */ { UD_Ixorpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1498 */ { UD_Ivxorpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1499 */ { UD_Ixorps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1500 */ { UD_Ivxorps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1501 */ { UD_Ixcryptecb, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1502 */ { UD_Ixcryptcbc, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1503 */ { UD_Ixcryptctr, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1504 */ { UD_Ixcryptcfb, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1505 */ { UD_Ixcryptofb, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1506 */ { UD_Ixrstor, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1507 */ { UD_Ixsave, O_M, O_NONE, O_NONE, O_NONE, P_aso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1508 */ { UD_Ixsetbv, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1509 */ { UD_Ixsha1, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1510 */ { UD_Ixsha256, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1511 */ { UD_Ixstore, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1512 */ { UD_Ipclmulqdq, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1513 */ { UD_Ivpclmulqdq, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1514 */ { UD_Igetsec, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1515 */ { UD_Imovdqa, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1516 */ { UD_Ivmovdqa, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1517 */ { UD_Imovdqa, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1518 */ { UD_Ivmovdqa, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1519 */ { UD_Imaskmovdqu, O_V, O_U, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1520 */ { UD_Ivmaskmovdqu, O_Vx, O_Ux, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1521 */ { UD_Imovdq2q, O_P, O_U, O_NONE, O_NONE, P_aso|P_rexb }, + /* 1522 */ { UD_Imovdqu, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1523 */ { UD_Ivmovdqu, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1524 */ { UD_Imovdqu, O_W, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1525 */ { UD_Ivmovdqu, O_Wx, O_Vx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1526 */ { UD_Imovq2dq, O_V, O_N, O_NONE, O_NONE, P_aso|P_rexr }, + /* 1527 */ { UD_Ipaddq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1528 */ { UD_Ipaddq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1529 */ { UD_Ivpaddq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1530 */ { UD_Ipsubq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1531 */ { UD_Ivpsubq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1532 */ { UD_Ipsubq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1533 */ { UD_Ipmuludq, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1534 */ { UD_Ipmuludq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1535 */ { UD_Ipshufhw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1536 */ { UD_Ivpshufhw, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1537 */ { UD_Ipshuflw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1538 */ { UD_Ivpshuflw, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1539 */ { UD_Ipshufd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1540 */ { UD_Ivpshufd, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1541 */ { UD_Ipslldq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1542 */ { UD_Ivpslldq, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1543 */ { UD_Ipsrldq, O_U, O_Ib, O_NONE, O_NONE, P_rexb }, + /* 1544 */ { UD_Ivpsrldq, O_Hx, O_Ux, O_Ib, O_NONE, P_rexb }, + /* 1545 */ { UD_Ipunpckhqdq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1546 */ { UD_Ivpunpckhqdq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1547 */ { UD_Ipunpcklqdq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1548 */ { UD_Ivpunpcklqdq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1549 */ { UD_Ihaddpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1550 */ { UD_Ivhaddpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1551 */ { UD_Ihaddps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1552 */ { UD_Ivhaddps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1553 */ { UD_Ihsubpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1554 */ { UD_Ivhsubpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1555 */ { UD_Ihsubps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1556 */ { UD_Ivhsubps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1557 */ { UD_Iinsertps, O_V, O_Md, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1558 */ { UD_Ivinsertps, O_Vx, O_Hx, O_Md, O_Ib, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1559 */ { UD_Ilddqu, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1560 */ { UD_Ivlddqu, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1561 */ { UD_Imovddup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1562 */ { UD_Ivmovddup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1563 */ { UD_Imovddup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1564 */ { UD_Ivmovddup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1565 */ { UD_Imovshdup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1566 */ { UD_Ivmovshdup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1567 */ { UD_Imovshdup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1568 */ { UD_Ivmovshdup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1569 */ { UD_Imovsldup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1570 */ { UD_Ivmovsldup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1571 */ { UD_Imovsldup, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1572 */ { UD_Ivmovsldup, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1573 */ { UD_Ipabsb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1574 */ { UD_Ipabsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1575 */ { UD_Ivpabsb, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1576 */ { UD_Ipabsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1577 */ { UD_Ipabsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1578 */ { UD_Ivpabsw, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1579 */ { UD_Ipabsd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1580 */ { UD_Ipabsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1581 */ { UD_Ivpabsd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1582 */ { UD_Ipshufb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1583 */ { UD_Ipshufb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1584 */ { UD_Ivpshufb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1585 */ { UD_Iphaddw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1586 */ { UD_Iphaddw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1587 */ { UD_Ivphaddw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1588 */ { UD_Iphaddd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1589 */ { UD_Iphaddd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1590 */ { UD_Ivphaddd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1591 */ { UD_Iphaddsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1592 */ { UD_Iphaddsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1593 */ { UD_Ivphaddsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1594 */ { UD_Ipmaddubsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1595 */ { UD_Ipmaddubsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1596 */ { UD_Ivpmaddubsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1597 */ { UD_Iphsubw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1598 */ { UD_Iphsubw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1599 */ { UD_Ivphsubw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1600 */ { UD_Iphsubd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1601 */ { UD_Iphsubd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1602 */ { UD_Ivphsubd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1603 */ { UD_Iphsubsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1604 */ { UD_Iphsubsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1605 */ { UD_Ivphsubsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1606 */ { UD_Ipsignb, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1607 */ { UD_Ipsignb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1608 */ { UD_Ivpsignb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1609 */ { UD_Ipsignd, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1610 */ { UD_Ipsignd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1611 */ { UD_Ivpsignd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1612 */ { UD_Ipsignw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1613 */ { UD_Ipsignw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1614 */ { UD_Ivpsignw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1615 */ { UD_Ipmulhrsw, O_P, O_Q, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1616 */ { UD_Ipmulhrsw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1617 */ { UD_Ivpmulhrsw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1618 */ { UD_Ipalignr, O_P, O_Q, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1619 */ { UD_Ipalignr, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1620 */ { UD_Ivpalignr, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1621 */ { UD_Ipblendvb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1622 */ { UD_Ipmuldq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1623 */ { UD_Ivpmuldq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1624 */ { UD_Ipminsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1625 */ { UD_Ivpminsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1626 */ { UD_Ipminsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1627 */ { UD_Ivpminsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1628 */ { UD_Ipminuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1629 */ { UD_Ivpminuw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1630 */ { UD_Ipminud, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1631 */ { UD_Ivpminud, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1632 */ { UD_Ipmaxsb, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1633 */ { UD_Ivpmaxsb, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1634 */ { UD_Ipmaxsd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1635 */ { UD_Ivpmaxsd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1636 */ { UD_Ipmaxud, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1637 */ { UD_Ivpmaxud, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1638 */ { UD_Ipmaxuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1639 */ { UD_Ivpmaxuw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1640 */ { UD_Ipmulld, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1641 */ { UD_Ivpmulld, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1642 */ { UD_Iphminposuw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1643 */ { UD_Ivphminposuw, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1644 */ { UD_Iroundps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1645 */ { UD_Ivroundps, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1646 */ { UD_Iroundpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1647 */ { UD_Ivroundpd, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1648 */ { UD_Iroundss, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1649 */ { UD_Ivroundss, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1650 */ { UD_Iroundsd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1651 */ { UD_Ivroundsd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1652 */ { UD_Iblendpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1653 */ { UD_Ivblendpd, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1654 */ { UD_Iblendps, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1655 */ { UD_Ivblendps, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1656 */ { UD_Iblendvpd, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1657 */ { UD_Iblendvps, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1658 */ { UD_Ibound, O_Gv, O_M, O_NONE, O_NONE, P_aso|P_oso }, + /* 1659 */ { UD_Ibsf, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1660 */ { UD_Ibsr, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1661 */ { UD_Ibswap, O_R0y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1662 */ { UD_Ibswap, O_R1y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1663 */ { UD_Ibswap, O_R2y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1664 */ { UD_Ibswap, O_R3y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1665 */ { UD_Ibswap, O_R4y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1666 */ { UD_Ibswap, O_R5y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1667 */ { UD_Ibswap, O_R6y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1668 */ { UD_Ibswap, O_R7y, O_NONE, O_NONE, O_NONE, P_oso|P_rexw|P_rexb }, + /* 1669 */ { UD_Ibt, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1670 */ { UD_Ibt, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1671 */ { UD_Ibtc, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1672 */ { UD_Ibtc, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1673 */ { UD_Ibtr, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1674 */ { UD_Ibtr, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1675 */ { UD_Ibts, O_Ev, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1676 */ { UD_Ibts, O_Ev, O_Ib, O_NONE, O_NONE, P_aso|P_oso|P_rexw|P_rexr|P_rexx|P_rexb }, + /* 1677 */ { UD_Ipblendw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1678 */ { UD_Ivpblendw, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1679 */ { UD_Impsadbw, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1680 */ { UD_Ivmpsadbw, O_Vx, O_Hx, O_Wx, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1681 */ { UD_Imovntdqa, O_V, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1682 */ { UD_Ivmovntdqa, O_Vx, O_M, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb|P_vexl }, + /* 1683 */ { UD_Ipackusdw, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1684 */ { UD_Ivpackusdw, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb|P_vexl }, + /* 1685 */ { UD_Ipmovsxbw, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1686 */ { UD_Ivpmovsxbw, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1687 */ { UD_Ipmovsxbd, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1688 */ { UD_Ivpmovsxbd, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1689 */ { UD_Ipmovsxbq, O_V, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1690 */ { UD_Ivpmovsxbq, O_Vx, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1691 */ { UD_Ipmovsxwd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1692 */ { UD_Ivpmovsxwd, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1693 */ { UD_Ipmovsxwq, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1694 */ { UD_Ivpmovsxwq, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1695 */ { UD_Ipmovsxdq, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1696 */ { UD_Ipmovzxbw, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1697 */ { UD_Ivpmovzxbw, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1698 */ { UD_Ipmovzxbd, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1699 */ { UD_Ivpmovzxbd, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1700 */ { UD_Ipmovzxbq, O_V, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1701 */ { UD_Ivpmovzxbq, O_Vx, O_MwU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1702 */ { UD_Ipmovzxwd, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1703 */ { UD_Ivpmovzxwd, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1704 */ { UD_Ipmovzxwq, O_V, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1705 */ { UD_Ivpmovzxwq, O_Vx, O_MdU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1706 */ { UD_Ipmovzxdq, O_V, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1707 */ { UD_Ivpmovzxdq, O_Vx, O_MqU, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1708 */ { UD_Ipcmpeqq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1709 */ { UD_Ivpcmpeqq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1710 */ { UD_Ipopcnt, O_Gv, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1711 */ { UD_Iptest, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1712 */ { UD_Ivptest, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb|P_vexl }, + /* 1713 */ { UD_Ipcmpestri, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1714 */ { UD_Ivpcmpestri, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1715 */ { UD_Ipcmpestrm, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1716 */ { UD_Ivpcmpestrm, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1717 */ { UD_Ipcmpgtq, O_V, O_W, O_NONE, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1718 */ { UD_Ivpcmpgtq, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1719 */ { UD_Ipcmpistri, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1720 */ { UD_Ivpcmpistri, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1721 */ { UD_Ipcmpistrm, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1722 */ { UD_Ivpcmpistrm, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1723 */ { UD_Imovbe, O_Gv, O_Mv, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1724 */ { UD_Imovbe, O_Mv, O_Gv, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1725 */ { UD_Icrc32, O_Gy, O_Eb, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1726 */ { UD_Icrc32, O_Gy, O_Ev, O_NONE, O_NONE, P_aso|P_oso|P_rexr|P_rexw|P_rexx|P_rexb }, + /* 1727 */ { UD_Ivbroadcastss, O_V, O_Md, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1728 */ { UD_Ivbroadcastsd, O_Vqq, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1729 */ { UD_Ivextractf128, O_Wdq, O_Vqq, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1730 */ { UD_Ivinsertf128, O_Vqq, O_Hqq, O_Wdq, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1731 */ { UD_Ivmaskmovps, O_V, O_H, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1732 */ { UD_Ivmaskmovps, O_M, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1733 */ { UD_Ivmaskmovpd, O_V, O_H, O_M, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1734 */ { UD_Ivmaskmovpd, O_M, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1735 */ { UD_Ivpermilpd, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1736 */ { UD_Ivpermilpd, O_V, O_W, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1737 */ { UD_Ivpermilps, O_Vx, O_Hx, O_Wx, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1738 */ { UD_Ivpermilps, O_Vx, O_Wx, O_Ib, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1739 */ { UD_Ivperm2f128, O_Vqq, O_Hqq, O_Wqq, O_Ib, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1740 */ { UD_Ivtestps, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1741 */ { UD_Ivtestpd, O_Vx, O_Wx, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1742 */ { UD_Ivzeroupper, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1743 */ { UD_Ivzeroall, O_NONE, O_NONE, O_NONE, O_NONE, P_none }, + /* 1744 */ { UD_Ivblendvpd, O_Vx, O_Hx, O_Wx, O_Lx, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1745 */ { UD_Ivblendvps, O_Vx, O_Hx, O_Wx, O_Lx, P_aso|P_rexr|P_rexx|P_rexb|P_vexl }, + /* 1746 */ { UD_Ivmovsd, O_V, O_H, O_U, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1747 */ { UD_Ivmovsd, O_V, O_Mq, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1748 */ { UD_Ivmovsd, O_U, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1749 */ { UD_Ivmovsd, O_Mq, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1750 */ { UD_Ivmovss, O_V, O_H, O_U, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1751 */ { UD_Ivmovss, O_V, O_Md, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1752 */ { UD_Ivmovss, O_U, O_H, O_V, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1753 */ { UD_Ivmovss, O_Md, O_V, O_NONE, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1754 */ { UD_Ivpblendvb, O_V, O_H, O_W, O_L, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1755 */ { UD_Ivpsllw, O_V, O_H, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1756 */ { UD_Ivpsllw, O_H, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1757 */ { UD_Ivpslld, O_V, O_H, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1758 */ { UD_Ivpslld, O_H, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1759 */ { UD_Ivpsllq, O_V, O_H, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, + /* 1760 */ { UD_Ivpsllq, O_H, O_V, O_W, O_NONE, P_aso|P_rexr|P_rexx|P_rexb }, +}; + + +const char* ud_mnemonics_str[] = { + "aaa", + "aad", + "aam", + "aas", + "adc", + "add", + "addpd", + "addps", + "addsd", + "addss", + "addsubpd", + "addsubps", + "aesdec", + "aesdeclast", + "aesenc", + "aesenclast", + "aesimc", + "aeskeygenassist", + "and", + "andnpd", + "andnps", + "andpd", + "andps", + "arpl", + "blendpd", + "blendps", + "blendvpd", + "blendvps", + "bound", + "bsf", + "bsr", + "bswap", + "bt", + "btc", + "btr", + "bts", + "call", + "cbw", + "cdq", + "cdqe", + "clc", + "cld", + "clflush", + "clgi", + "cli", + "clts", + "cmc", + "cmova", + "cmovae", + "cmovb", + "cmovbe", + "cmovg", + "cmovge", + "cmovl", + "cmovle", + "cmovno", + "cmovnp", + "cmovns", + "cmovnz", + "cmovo", + "cmovp", + "cmovs", + "cmovz", + "cmp", + "cmppd", + "cmpps", + "cmpsb", + "cmpsd", + "cmpsq", + "cmpss", + "cmpsw", + "cmpxchg", + "cmpxchg16b", + "cmpxchg8b", + "comisd", + "comiss", + "cpuid", + "cqo", + "crc32", + "cvtdq2pd", + "cvtdq2ps", + "cvtpd2dq", + "cvtpd2pi", + "cvtpd2ps", + "cvtpi2pd", + "cvtpi2ps", + "cvtps2dq", + "cvtps2pd", + "cvtps2pi", + "cvtsd2si", + "cvtsd2ss", + "cvtsi2sd", + "cvtsi2ss", + "cvtss2sd", + "cvtss2si", + "cvttpd2dq", + "cvttpd2pi", + "cvttps2dq", + "cvttps2pi", + "cvttsd2si", + "cvttss2si", + "cwd", + "cwde", + "daa", + "das", + "dec", + "div", + "divpd", + "divps", + "divsd", + "divss", + "dppd", + "dpps", + "emms", + "enter", + "extractps", + "f2xm1", + "fabs", + "fadd", + "faddp", + "fbld", + "fbstp", + "fchs", + "fclex", + "fcmovb", + "fcmovbe", + "fcmove", + "fcmovnb", + "fcmovnbe", + "fcmovne", + "fcmovnu", + "fcmovu", + "fcom", + "fcom2", + "fcomi", + "fcomip", + "fcomp", + "fcomp3", + "fcomp5", + "fcompp", + "fcos", + "fdecstp", + "fdiv", + "fdivp", + "fdivr", + "fdivrp", + "femms", + "ffree", + "ffreep", + "fiadd", + "ficom", + "ficomp", + "fidiv", + "fidivr", + "fild", + "fimul", + "fincstp", + "fist", + "fistp", + "fisttp", + "fisub", + "fisubr", + "fld", + "fld1", + "fldcw", + "fldenv", + "fldl2e", + "fldl2t", + "fldlg2", + "fldln2", + "fldpi", + "fldz", + "fmul", + "fmulp", + "fndisi", + "fneni", + "fninit", + "fnop", + "fnsave", + "fnsetpm", + "fnstcw", + "fnstenv", + "fnstsw", + "fpatan", + "fprem", + "fprem1", + "fptan", + "frndint", + "frstor", + "frstpm", + "fscale", + "fsin", + "fsincos", + "fsqrt", + "fst", + "fstp", + "fstp1", + "fstp8", + "fstp9", + "fsub", + "fsubp", + "fsubr", + "fsubrp", + "ftst", + "fucom", + "fucomi", + "fucomip", + "fucomp", + "fucompp", + "fxam", + "fxch", + "fxch4", + "fxch7", + "fxrstor", + "fxsave", + "fxtract", + "fyl2x", + "fyl2xp1", + "getsec", + "haddpd", + "haddps", + "hlt", + "hsubpd", + "hsubps", + "idiv", + "imul", + "in", + "inc", + "insb", + "insd", + "insertps", + "insw", + "int", + "int1", + "int3", + "into", + "invd", + "invept", + "invlpg", + "invlpga", + "invvpid", + "iretd", + "iretq", + "iretw", + "ja", + "jae", + "jb", + "jbe", + "jcxz", + "jecxz", + "jg", + "jge", + "jl", + "jle", + "jmp", + "jno", + "jnp", + "jns", + "jnz", + "jo", + "jp", + "jrcxz", + "js", + "jz", + "lahf", + "lar", + "lddqu", + "ldmxcsr", + "lds", + "lea", + "leave", + "les", + "lfence", + "lfs", + "lgdt", + "lgs", + "lidt", + "lldt", + "lmsw", + "lock", + "lodsb", + "lodsd", + "lodsq", + "lodsw", + "loop", + "loope", + "loopne", + "lsl", + "lss", + "ltr", + "maskmovdqu", + "maskmovq", + "maxpd", + "maxps", + "maxsd", + "maxss", + "mfence", + "minpd", + "minps", + "minsd", + "minss", + "monitor", + "montmul", + "mov", + "movapd", + "movaps", + "movbe", + "movd", + "movddup", + "movdq2q", + "movdqa", + "movdqu", + "movhlps", + "movhpd", + "movhps", + "movlhps", + "movlpd", + "movlps", + "movmskpd", + "movmskps", + "movntdq", + "movntdqa", + "movnti", + "movntpd", + "movntps", + "movntq", + "movq", + "movq2dq", + "movsb", + "movsd", + "movshdup", + "movsldup", + "movsq", + "movss", + "movsw", + "movsx", + "movsxd", + "movupd", + "movups", + "movzx", + "mpsadbw", + "mul", + "mulpd", + "mulps", + "mulsd", + "mulss", + "mwait", + "neg", + "nop", + "not", + "or", + "orpd", + "orps", + "out", + "outsb", + "outsd", + "outsw", + "pabsb", + "pabsd", + "pabsw", + "packssdw", + "packsswb", + "packusdw", + "packuswb", + "paddb", + "paddd", + "paddq", + "paddsb", + "paddsw", + "paddusb", + "paddusw", + "paddw", + "palignr", + "pand", + "pandn", + "pavgb", + "pavgusb", + "pavgw", + "pblendvb", + "pblendw", + "pclmulqdq", + "pcmpeqb", + "pcmpeqd", + "pcmpeqq", + "pcmpeqw", + "pcmpestri", + "pcmpestrm", + "pcmpgtb", + "pcmpgtd", + "pcmpgtq", + "pcmpgtw", + "pcmpistri", + "pcmpistrm", + "pextrb", + "pextrd", + "pextrq", + "pextrw", + "pf2id", + "pf2iw", + "pfacc", + "pfadd", + "pfcmpeq", + "pfcmpge", + "pfcmpgt", + "pfmax", + "pfmin", + "pfmul", + "pfnacc", + "pfpnacc", + "pfrcp", + "pfrcpit1", + "pfrcpit2", + "pfrsqit1", + "pfrsqrt", + "pfsub", + "pfsubr", + "phaddd", + "phaddsw", + "phaddw", + "phminposuw", + "phsubd", + "phsubsw", + "phsubw", + "pi2fd", + "pi2fw", + "pinsrb", + "pinsrd", + "pinsrq", + "pinsrw", + "pmaddubsw", + "pmaddwd", + "pmaxsb", + "pmaxsd", + "pmaxsw", + "pmaxub", + "pmaxud", + "pmaxuw", + "pminsb", + "pminsd", + "pminsw", + "pminub", + "pminud", + "pminuw", + "pmovmskb", + "pmovsxbd", + "pmovsxbq", + "pmovsxbw", + "pmovsxdq", + "pmovsxwd", + "pmovsxwq", + "pmovzxbd", + "pmovzxbq", + "pmovzxbw", + "pmovzxdq", + "pmovzxwd", + "pmovzxwq", + "pmuldq", + "pmulhrsw", + "pmulhrw", + "pmulhuw", + "pmulhw", + "pmulld", + "pmullw", + "pmuludq", + "pop", + "popa", + "popad", + "popcnt", + "popfd", + "popfq", + "popfw", + "por", + "prefetch", + "prefetchnta", + "prefetcht0", + "prefetcht1", + "prefetcht2", + "psadbw", + "pshufb", + "pshufd", + "pshufhw", + "pshuflw", + "pshufw", + "psignb", + "psignd", + "psignw", + "pslld", + "pslldq", + "psllq", + "psllw", + "psrad", + "psraw", + "psrld", + "psrldq", + "psrlq", + "psrlw", + "psubb", + "psubd", + "psubq", + "psubsb", + "psubsw", + "psubusb", + "psubusw", + "psubw", + "pswapd", + "ptest", + "punpckhbw", + "punpckhdq", + "punpckhqdq", + "punpckhwd", + "punpcklbw", + "punpckldq", + "punpcklqdq", + "punpcklwd", + "push", + "pusha", + "pushad", + "pushfd", + "pushfq", + "pushfw", + "pxor", + "rcl", + "rcpps", + "rcpss", + "rcr", + "rdmsr", + "rdpmc", + "rdrand", + "rdtsc", + "rdtscp", + "rep", + "repne", + "ret", + "retf", + "rol", + "ror", + "roundpd", + "roundps", + "roundsd", + "roundss", + "rsm", + "rsqrtps", + "rsqrtss", + "sahf", + "salc", + "sar", + "sbb", + "scasb", + "scasd", + "scasq", + "scasw", + "seta", + "setae", + "setb", + "setbe", + "setg", + "setge", + "setl", + "setle", + "setno", + "setnp", + "setns", + "setnz", + "seto", + "setp", + "sets", + "setz", + "sfence", + "sgdt", + "shl", + "shld", + "shr", + "shrd", + "shufpd", + "shufps", + "sidt", + "skinit", + "sldt", + "smsw", + "sqrtpd", + "sqrtps", + "sqrtsd", + "sqrtss", + "stc", + "std", + "stgi", + "sti", + "stmxcsr", + "stosb", + "stosd", + "stosq", + "stosw", + "str", + "sub", + "subpd", + "subps", + "subsd", + "subss", + "swapgs", + "syscall", + "sysenter", + "sysexit", + "sysret", + "test", + "ucomisd", + "ucomiss", + "ud2", + "unpckhpd", + "unpckhps", + "unpcklpd", + "unpcklps", + "vaddpd", + "vaddps", + "vaddsd", + "vaddss", + "vaddsubpd", + "vaddsubps", + "vaesdec", + "vaesdeclast", + "vaesenc", + "vaesenclast", + "vaesimc", + "vaeskeygenassist", + "vandnpd", + "vandnps", + "vandpd", + "vandps", + "vblendpd", + "vblendps", + "vblendvpd", + "vblendvps", + "vbroadcastsd", + "vbroadcastss", + "vcmppd", + "vcmpps", + "vcmpsd", + "vcmpss", + "vcomisd", + "vcomiss", + "vcvtdq2pd", + "vcvtdq2ps", + "vcvtpd2dq", + "vcvtpd2ps", + "vcvtps2dq", + "vcvtps2pd", + "vcvtsd2si", + "vcvtsd2ss", + "vcvtsi2sd", + "vcvtsi2ss", + "vcvtss2sd", + "vcvtss2si", + "vcvttpd2dq", + "vcvttps2dq", + "vcvttsd2si", + "vcvttss2si", + "vdivpd", + "vdivps", + "vdivsd", + "vdivss", + "vdppd", + "vdpps", + "verr", + "verw", + "vextractf128", + "vextractps", + "vhaddpd", + "vhaddps", + "vhsubpd", + "vhsubps", + "vinsertf128", + "vinsertps", + "vlddqu", + "vmaskmovdqu", + "vmaskmovpd", + "vmaskmovps", + "vmaxpd", + "vmaxps", + "vmaxsd", + "vmaxss", + "vmcall", + "vmclear", + "vminpd", + "vminps", + "vminsd", + "vminss", + "vmlaunch", + "vmload", + "vmmcall", + "vmovapd", + "vmovaps", + "vmovd", + "vmovddup", + "vmovdqa", + "vmovdqu", + "vmovhlps", + "vmovhpd", + "vmovhps", + "vmovlhps", + "vmovlpd", + "vmovlps", + "vmovmskpd", + "vmovmskps", + "vmovntdq", + "vmovntdqa", + "vmovntpd", + "vmovntps", + "vmovq", + "vmovsd", + "vmovshdup", + "vmovsldup", + "vmovss", + "vmovupd", + "vmovups", + "vmpsadbw", + "vmptrld", + "vmptrst", + "vmread", + "vmresume", + "vmrun", + "vmsave", + "vmulpd", + "vmulps", + "vmulsd", + "vmulss", + "vmwrite", + "vmxoff", + "vmxon", + "vorpd", + "vorps", + "vpabsb", + "vpabsd", + "vpabsw", + "vpackssdw", + "vpacksswb", + "vpackusdw", + "vpackuswb", + "vpaddb", + "vpaddd", + "vpaddq", + "vpaddsb", + "vpaddsw", + "vpaddusb", + "vpaddusw", + "vpaddw", + "vpalignr", + "vpand", + "vpandn", + "vpavgb", + "vpavgw", + "vpblendvb", + "vpblendw", + "vpclmulqdq", + "vpcmpeqb", + "vpcmpeqd", + "vpcmpeqq", + "vpcmpeqw", + "vpcmpestri", + "vpcmpestrm", + "vpcmpgtb", + "vpcmpgtd", + "vpcmpgtq", + "vpcmpgtw", + "vpcmpistri", + "vpcmpistrm", + "vperm2f128", + "vpermilpd", + "vpermilps", + "vpextrb", + "vpextrd", + "vpextrq", + "vpextrw", + "vphaddd", + "vphaddsw", + "vphaddw", + "vphminposuw", + "vphsubd", + "vphsubsw", + "vphsubw", + "vpinsrb", + "vpinsrd", + "vpinsrq", + "vpinsrw", + "vpmaddubsw", + "vpmaddwd", + "vpmaxsb", + "vpmaxsd", + "vpmaxsw", + "vpmaxub", + "vpmaxud", + "vpmaxuw", + "vpminsb", + "vpminsd", + "vpminsw", + "vpminub", + "vpminud", + "vpminuw", + "vpmovmskb", + "vpmovsxbd", + "vpmovsxbq", + "vpmovsxbw", + "vpmovsxwd", + "vpmovsxwq", + "vpmovzxbd", + "vpmovzxbq", + "vpmovzxbw", + "vpmovzxdq", + "vpmovzxwd", + "vpmovzxwq", + "vpmuldq", + "vpmulhrsw", + "vpmulhuw", + "vpmulhw", + "vpmulld", + "vpmullw", + "vpor", + "vpsadbw", + "vpshufb", + "vpshufd", + "vpshufhw", + "vpshuflw", + "vpsignb", + "vpsignd", + "vpsignw", + "vpslld", + "vpslldq", + "vpsllq", + "vpsllw", + "vpsrad", + "vpsraw", + "vpsrld", + "vpsrldq", + "vpsrlq", + "vpsrlw", + "vpsubb", + "vpsubd", + "vpsubq", + "vpsubsb", + "vpsubsw", + "vpsubusb", + "vpsubusw", + "vpsubw", + "vptest", + "vpunpckhbw", + "vpunpckhdq", + "vpunpckhqdq", + "vpunpckhwd", + "vpunpcklbw", + "vpunpckldq", + "vpunpcklqdq", + "vpunpcklwd", + "vpxor", + "vrcpps", + "vrcpss", + "vroundpd", + "vroundps", + "vroundsd", + "vroundss", + "vrsqrtps", + "vrsqrtss", + "vshufpd", + "vshufps", + "vsqrtpd", + "vsqrtps", + "vsqrtsd", + "vsqrtss", + "vstmxcsr", + "vsubpd", + "vsubps", + "vsubsd", + "vsubss", + "vtestpd", + "vtestps", + "vucomisd", + "vucomiss", + "vunpckhpd", + "vunpckhps", + "vunpcklpd", + "vunpcklps", + "vxorpd", + "vxorps", + "vzeroall", + "vzeroupper", + "wait", + "wbinvd", + "wrmsr", + "xadd", + "xchg", + "xcryptcbc", + "xcryptcfb", + "xcryptctr", + "xcryptecb", + "xcryptofb", + "xgetbv", + "xlatb", + "xor", + "xorpd", + "xorps", + "xrstor", + "xsave", + "xsetbv", + "xsha1", + "xsha256", + "xstore", + "invalid", + "3dnow", + "none", + "db", + "pause" +}; diff --git a/deps/extra/udis86/libudis86/itab.h b/deps/extra/udis86/libudis86/itab.h new file mode 100644 index 0000000..3d54c43 --- /dev/null +++ b/deps/extra/udis86/libudis86/itab.h @@ -0,0 +1,939 @@ +#ifndef UD_ITAB_H +#define UD_ITAB_H + +/* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */ + +/* ud_table_type -- lookup table types (see decode.c) */ +enum ud_table_type { + UD_TAB__OPC_VEX, + UD_TAB__OPC_TABLE, + UD_TAB__OPC_X87, + UD_TAB__OPC_MOD, + UD_TAB__OPC_RM, + UD_TAB__OPC_OSIZE, + UD_TAB__OPC_MODE, + UD_TAB__OPC_VEX_L, + UD_TAB__OPC_3DNOW, + UD_TAB__OPC_REG, + UD_TAB__OPC_ASIZE, + UD_TAB__OPC_VEX_W, + UD_TAB__OPC_SSE, + UD_TAB__OPC_VENDOR +}; + +/* ud_mnemonic -- mnemonic constants */ +enum ud_mnemonic_code { + UD_Iaaa, + UD_Iaad, + UD_Iaam, + UD_Iaas, + UD_Iadc, + UD_Iadd, + UD_Iaddpd, + UD_Iaddps, + UD_Iaddsd, + UD_Iaddss, + UD_Iaddsubpd, + UD_Iaddsubps, + UD_Iaesdec, + UD_Iaesdeclast, + UD_Iaesenc, + UD_Iaesenclast, + UD_Iaesimc, + UD_Iaeskeygenassist, + UD_Iand, + UD_Iandnpd, + UD_Iandnps, + UD_Iandpd, + UD_Iandps, + UD_Iarpl, + UD_Iblendpd, + UD_Iblendps, + UD_Iblendvpd, + UD_Iblendvps, + UD_Ibound, + UD_Ibsf, + UD_Ibsr, + UD_Ibswap, + UD_Ibt, + UD_Ibtc, + UD_Ibtr, + UD_Ibts, + UD_Icall, + UD_Icbw, + UD_Icdq, + UD_Icdqe, + UD_Iclc, + UD_Icld, + UD_Iclflush, + UD_Iclgi, + UD_Icli, + UD_Iclts, + UD_Icmc, + UD_Icmova, + UD_Icmovae, + UD_Icmovb, + UD_Icmovbe, + UD_Icmovg, + UD_Icmovge, + UD_Icmovl, + UD_Icmovle, + UD_Icmovno, + UD_Icmovnp, + UD_Icmovns, + UD_Icmovnz, + UD_Icmovo, + UD_Icmovp, + UD_Icmovs, + UD_Icmovz, + UD_Icmp, + UD_Icmppd, + UD_Icmpps, + UD_Icmpsb, + UD_Icmpsd, + UD_Icmpsq, + UD_Icmpss, + UD_Icmpsw, + UD_Icmpxchg, + UD_Icmpxchg16b, + UD_Icmpxchg8b, + UD_Icomisd, + UD_Icomiss, + UD_Icpuid, + UD_Icqo, + UD_Icrc32, + UD_Icvtdq2pd, + UD_Icvtdq2ps, + UD_Icvtpd2dq, + UD_Icvtpd2pi, + UD_Icvtpd2ps, + UD_Icvtpi2pd, + UD_Icvtpi2ps, + UD_Icvtps2dq, + UD_Icvtps2pd, + UD_Icvtps2pi, + UD_Icvtsd2si, + UD_Icvtsd2ss, + UD_Icvtsi2sd, + UD_Icvtsi2ss, + UD_Icvtss2sd, + UD_Icvtss2si, + UD_Icvttpd2dq, + UD_Icvttpd2pi, + UD_Icvttps2dq, + UD_Icvttps2pi, + UD_Icvttsd2si, + UD_Icvttss2si, + UD_Icwd, + UD_Icwde, + UD_Idaa, + UD_Idas, + UD_Idec, + UD_Idiv, + UD_Idivpd, + UD_Idivps, + UD_Idivsd, + UD_Idivss, + UD_Idppd, + UD_Idpps, + UD_Iemms, + UD_Ienter, + UD_Iextractps, + UD_If2xm1, + UD_Ifabs, + UD_Ifadd, + UD_Ifaddp, + UD_Ifbld, + UD_Ifbstp, + UD_Ifchs, + UD_Ifclex, + UD_Ifcmovb, + UD_Ifcmovbe, + UD_Ifcmove, + UD_Ifcmovnb, + UD_Ifcmovnbe, + UD_Ifcmovne, + UD_Ifcmovnu, + UD_Ifcmovu, + UD_Ifcom, + UD_Ifcom2, + UD_Ifcomi, + UD_Ifcomip, + UD_Ifcomp, + UD_Ifcomp3, + UD_Ifcomp5, + UD_Ifcompp, + UD_Ifcos, + UD_Ifdecstp, + UD_Ifdiv, + UD_Ifdivp, + UD_Ifdivr, + UD_Ifdivrp, + UD_Ifemms, + UD_Iffree, + UD_Iffreep, + UD_Ifiadd, + UD_Ificom, + UD_Ificomp, + UD_Ifidiv, + UD_Ifidivr, + UD_Ifild, + UD_Ifimul, + UD_Ifincstp, + UD_Ifist, + UD_Ifistp, + UD_Ifisttp, + UD_Ifisub, + UD_Ifisubr, + UD_Ifld, + UD_Ifld1, + UD_Ifldcw, + UD_Ifldenv, + UD_Ifldl2e, + UD_Ifldl2t, + UD_Ifldlg2, + UD_Ifldln2, + UD_Ifldpi, + UD_Ifldz, + UD_Ifmul, + UD_Ifmulp, + UD_Ifndisi, + UD_Ifneni, + UD_Ifninit, + UD_Ifnop, + UD_Ifnsave, + UD_Ifnsetpm, + UD_Ifnstcw, + UD_Ifnstenv, + UD_Ifnstsw, + UD_Ifpatan, + UD_Ifprem, + UD_Ifprem1, + UD_Ifptan, + UD_Ifrndint, + UD_Ifrstor, + UD_Ifrstpm, + UD_Ifscale, + UD_Ifsin, + UD_Ifsincos, + UD_Ifsqrt, + UD_Ifst, + UD_Ifstp, + UD_Ifstp1, + UD_Ifstp8, + UD_Ifstp9, + UD_Ifsub, + UD_Ifsubp, + UD_Ifsubr, + UD_Ifsubrp, + UD_Iftst, + UD_Ifucom, + UD_Ifucomi, + UD_Ifucomip, + UD_Ifucomp, + UD_Ifucompp, + UD_Ifxam, + UD_Ifxch, + UD_Ifxch4, + UD_Ifxch7, + UD_Ifxrstor, + UD_Ifxsave, + UD_Ifxtract, + UD_Ifyl2x, + UD_Ifyl2xp1, + UD_Igetsec, + UD_Ihaddpd, + UD_Ihaddps, + UD_Ihlt, + UD_Ihsubpd, + UD_Ihsubps, + UD_Iidiv, + UD_Iimul, + UD_Iin, + UD_Iinc, + UD_Iinsb, + UD_Iinsd, + UD_Iinsertps, + UD_Iinsw, + UD_Iint, + UD_Iint1, + UD_Iint3, + UD_Iinto, + UD_Iinvd, + UD_Iinvept, + UD_Iinvlpg, + UD_Iinvlpga, + UD_Iinvvpid, + UD_Iiretd, + UD_Iiretq, + UD_Iiretw, + UD_Ija, + UD_Ijae, + UD_Ijb, + UD_Ijbe, + UD_Ijcxz, + UD_Ijecxz, + UD_Ijg, + UD_Ijge, + UD_Ijl, + UD_Ijle, + UD_Ijmp, + UD_Ijno, + UD_Ijnp, + UD_Ijns, + UD_Ijnz, + UD_Ijo, + UD_Ijp, + UD_Ijrcxz, + UD_Ijs, + UD_Ijz, + UD_Ilahf, + UD_Ilar, + UD_Ilddqu, + UD_Ildmxcsr, + UD_Ilds, + UD_Ilea, + UD_Ileave, + UD_Iles, + UD_Ilfence, + UD_Ilfs, + UD_Ilgdt, + UD_Ilgs, + UD_Ilidt, + UD_Illdt, + UD_Ilmsw, + UD_Ilock, + UD_Ilodsb, + UD_Ilodsd, + UD_Ilodsq, + UD_Ilodsw, + UD_Iloop, + UD_Iloope, + UD_Iloopne, + UD_Ilsl, + UD_Ilss, + UD_Iltr, + UD_Imaskmovdqu, + UD_Imaskmovq, + UD_Imaxpd, + UD_Imaxps, + UD_Imaxsd, + UD_Imaxss, + UD_Imfence, + UD_Iminpd, + UD_Iminps, + UD_Iminsd, + UD_Iminss, + UD_Imonitor, + UD_Imontmul, + UD_Imov, + UD_Imovapd, + UD_Imovaps, + UD_Imovbe, + UD_Imovd, + UD_Imovddup, + UD_Imovdq2q, + UD_Imovdqa, + UD_Imovdqu, + UD_Imovhlps, + UD_Imovhpd, + UD_Imovhps, + UD_Imovlhps, + UD_Imovlpd, + UD_Imovlps, + UD_Imovmskpd, + UD_Imovmskps, + UD_Imovntdq, + UD_Imovntdqa, + UD_Imovnti, + UD_Imovntpd, + UD_Imovntps, + UD_Imovntq, + UD_Imovq, + UD_Imovq2dq, + UD_Imovsb, + UD_Imovsd, + UD_Imovshdup, + UD_Imovsldup, + UD_Imovsq, + UD_Imovss, + UD_Imovsw, + UD_Imovsx, + UD_Imovsxd, + UD_Imovupd, + UD_Imovups, + UD_Imovzx, + UD_Impsadbw, + UD_Imul, + UD_Imulpd, + UD_Imulps, + UD_Imulsd, + UD_Imulss, + UD_Imwait, + UD_Ineg, + UD_Inop, + UD_Inot, + UD_Ior, + UD_Iorpd, + UD_Iorps, + UD_Iout, + UD_Ioutsb, + UD_Ioutsd, + UD_Ioutsw, + UD_Ipabsb, + UD_Ipabsd, + UD_Ipabsw, + UD_Ipackssdw, + UD_Ipacksswb, + UD_Ipackusdw, + UD_Ipackuswb, + UD_Ipaddb, + UD_Ipaddd, + UD_Ipaddq, + UD_Ipaddsb, + UD_Ipaddsw, + UD_Ipaddusb, + UD_Ipaddusw, + UD_Ipaddw, + UD_Ipalignr, + UD_Ipand, + UD_Ipandn, + UD_Ipavgb, + UD_Ipavgusb, + UD_Ipavgw, + UD_Ipblendvb, + UD_Ipblendw, + UD_Ipclmulqdq, + UD_Ipcmpeqb, + UD_Ipcmpeqd, + UD_Ipcmpeqq, + UD_Ipcmpeqw, + UD_Ipcmpestri, + UD_Ipcmpestrm, + UD_Ipcmpgtb, + UD_Ipcmpgtd, + UD_Ipcmpgtq, + UD_Ipcmpgtw, + UD_Ipcmpistri, + UD_Ipcmpistrm, + UD_Ipextrb, + UD_Ipextrd, + UD_Ipextrq, + UD_Ipextrw, + UD_Ipf2id, + UD_Ipf2iw, + UD_Ipfacc, + UD_Ipfadd, + UD_Ipfcmpeq, + UD_Ipfcmpge, + UD_Ipfcmpgt, + UD_Ipfmax, + UD_Ipfmin, + UD_Ipfmul, + UD_Ipfnacc, + UD_Ipfpnacc, + UD_Ipfrcp, + UD_Ipfrcpit1, + UD_Ipfrcpit2, + UD_Ipfrsqit1, + UD_Ipfrsqrt, + UD_Ipfsub, + UD_Ipfsubr, + UD_Iphaddd, + UD_Iphaddsw, + UD_Iphaddw, + UD_Iphminposuw, + UD_Iphsubd, + UD_Iphsubsw, + UD_Iphsubw, + UD_Ipi2fd, + UD_Ipi2fw, + UD_Ipinsrb, + UD_Ipinsrd, + UD_Ipinsrq, + UD_Ipinsrw, + UD_Ipmaddubsw, + UD_Ipmaddwd, + UD_Ipmaxsb, + UD_Ipmaxsd, + UD_Ipmaxsw, + UD_Ipmaxub, + UD_Ipmaxud, + UD_Ipmaxuw, + UD_Ipminsb, + UD_Ipminsd, + UD_Ipminsw, + UD_Ipminub, + UD_Ipminud, + UD_Ipminuw, + UD_Ipmovmskb, + UD_Ipmovsxbd, + UD_Ipmovsxbq, + UD_Ipmovsxbw, + UD_Ipmovsxdq, + UD_Ipmovsxwd, + UD_Ipmovsxwq, + UD_Ipmovzxbd, + UD_Ipmovzxbq, + UD_Ipmovzxbw, + UD_Ipmovzxdq, + UD_Ipmovzxwd, + UD_Ipmovzxwq, + UD_Ipmuldq, + UD_Ipmulhrsw, + UD_Ipmulhrw, + UD_Ipmulhuw, + UD_Ipmulhw, + UD_Ipmulld, + UD_Ipmullw, + UD_Ipmuludq, + UD_Ipop, + UD_Ipopa, + UD_Ipopad, + UD_Ipopcnt, + UD_Ipopfd, + UD_Ipopfq, + UD_Ipopfw, + UD_Ipor, + UD_Iprefetch, + UD_Iprefetchnta, + UD_Iprefetcht0, + UD_Iprefetcht1, + UD_Iprefetcht2, + UD_Ipsadbw, + UD_Ipshufb, + UD_Ipshufd, + UD_Ipshufhw, + UD_Ipshuflw, + UD_Ipshufw, + UD_Ipsignb, + UD_Ipsignd, + UD_Ipsignw, + UD_Ipslld, + UD_Ipslldq, + UD_Ipsllq, + UD_Ipsllw, + UD_Ipsrad, + UD_Ipsraw, + UD_Ipsrld, + UD_Ipsrldq, + UD_Ipsrlq, + UD_Ipsrlw, + UD_Ipsubb, + UD_Ipsubd, + UD_Ipsubq, + UD_Ipsubsb, + UD_Ipsubsw, + UD_Ipsubusb, + UD_Ipsubusw, + UD_Ipsubw, + UD_Ipswapd, + UD_Iptest, + UD_Ipunpckhbw, + UD_Ipunpckhdq, + UD_Ipunpckhqdq, + UD_Ipunpckhwd, + UD_Ipunpcklbw, + UD_Ipunpckldq, + UD_Ipunpcklqdq, + UD_Ipunpcklwd, + UD_Ipush, + UD_Ipusha, + UD_Ipushad, + UD_Ipushfd, + UD_Ipushfq, + UD_Ipushfw, + UD_Ipxor, + UD_Ircl, + UD_Ircpps, + UD_Ircpss, + UD_Ircr, + UD_Irdmsr, + UD_Irdpmc, + UD_Irdrand, + UD_Irdtsc, + UD_Irdtscp, + UD_Irep, + UD_Irepne, + UD_Iret, + UD_Iretf, + UD_Irol, + UD_Iror, + UD_Iroundpd, + UD_Iroundps, + UD_Iroundsd, + UD_Iroundss, + UD_Irsm, + UD_Irsqrtps, + UD_Irsqrtss, + UD_Isahf, + UD_Isalc, + UD_Isar, + UD_Isbb, + UD_Iscasb, + UD_Iscasd, + UD_Iscasq, + UD_Iscasw, + UD_Iseta, + UD_Isetae, + UD_Isetb, + UD_Isetbe, + UD_Isetg, + UD_Isetge, + UD_Isetl, + UD_Isetle, + UD_Isetno, + UD_Isetnp, + UD_Isetns, + UD_Isetnz, + UD_Iseto, + UD_Isetp, + UD_Isets, + UD_Isetz, + UD_Isfence, + UD_Isgdt, + UD_Ishl, + UD_Ishld, + UD_Ishr, + UD_Ishrd, + UD_Ishufpd, + UD_Ishufps, + UD_Isidt, + UD_Iskinit, + UD_Isldt, + UD_Ismsw, + UD_Isqrtpd, + UD_Isqrtps, + UD_Isqrtsd, + UD_Isqrtss, + UD_Istc, + UD_Istd, + UD_Istgi, + UD_Isti, + UD_Istmxcsr, + UD_Istosb, + UD_Istosd, + UD_Istosq, + UD_Istosw, + UD_Istr, + UD_Isub, + UD_Isubpd, + UD_Isubps, + UD_Isubsd, + UD_Isubss, + UD_Iswapgs, + UD_Isyscall, + UD_Isysenter, + UD_Isysexit, + UD_Isysret, + UD_Itest, + UD_Iucomisd, + UD_Iucomiss, + UD_Iud2, + UD_Iunpckhpd, + UD_Iunpckhps, + UD_Iunpcklpd, + UD_Iunpcklps, + UD_Ivaddpd, + UD_Ivaddps, + UD_Ivaddsd, + UD_Ivaddss, + UD_Ivaddsubpd, + UD_Ivaddsubps, + UD_Ivaesdec, + UD_Ivaesdeclast, + UD_Ivaesenc, + UD_Ivaesenclast, + UD_Ivaesimc, + UD_Ivaeskeygenassist, + UD_Ivandnpd, + UD_Ivandnps, + UD_Ivandpd, + UD_Ivandps, + UD_Ivblendpd, + UD_Ivblendps, + UD_Ivblendvpd, + UD_Ivblendvps, + UD_Ivbroadcastsd, + UD_Ivbroadcastss, + UD_Ivcmppd, + UD_Ivcmpps, + UD_Ivcmpsd, + UD_Ivcmpss, + UD_Ivcomisd, + UD_Ivcomiss, + UD_Ivcvtdq2pd, + UD_Ivcvtdq2ps, + UD_Ivcvtpd2dq, + UD_Ivcvtpd2ps, + UD_Ivcvtps2dq, + UD_Ivcvtps2pd, + UD_Ivcvtsd2si, + UD_Ivcvtsd2ss, + UD_Ivcvtsi2sd, + UD_Ivcvtsi2ss, + UD_Ivcvtss2sd, + UD_Ivcvtss2si, + UD_Ivcvttpd2dq, + UD_Ivcvttps2dq, + UD_Ivcvttsd2si, + UD_Ivcvttss2si, + UD_Ivdivpd, + UD_Ivdivps, + UD_Ivdivsd, + UD_Ivdivss, + UD_Ivdppd, + UD_Ivdpps, + UD_Iverr, + UD_Iverw, + UD_Ivextractf128, + UD_Ivextractps, + UD_Ivhaddpd, + UD_Ivhaddps, + UD_Ivhsubpd, + UD_Ivhsubps, + UD_Ivinsertf128, + UD_Ivinsertps, + UD_Ivlddqu, + UD_Ivmaskmovdqu, + UD_Ivmaskmovpd, + UD_Ivmaskmovps, + UD_Ivmaxpd, + UD_Ivmaxps, + UD_Ivmaxsd, + UD_Ivmaxss, + UD_Ivmcall, + UD_Ivmclear, + UD_Ivminpd, + UD_Ivminps, + UD_Ivminsd, + UD_Ivminss, + UD_Ivmlaunch, + UD_Ivmload, + UD_Ivmmcall, + UD_Ivmovapd, + UD_Ivmovaps, + UD_Ivmovd, + UD_Ivmovddup, + UD_Ivmovdqa, + UD_Ivmovdqu, + UD_Ivmovhlps, + UD_Ivmovhpd, + UD_Ivmovhps, + UD_Ivmovlhps, + UD_Ivmovlpd, + UD_Ivmovlps, + UD_Ivmovmskpd, + UD_Ivmovmskps, + UD_Ivmovntdq, + UD_Ivmovntdqa, + UD_Ivmovntpd, + UD_Ivmovntps, + UD_Ivmovq, + UD_Ivmovsd, + UD_Ivmovshdup, + UD_Ivmovsldup, + UD_Ivmovss, + UD_Ivmovupd, + UD_Ivmovups, + UD_Ivmpsadbw, + UD_Ivmptrld, + UD_Ivmptrst, + UD_Ivmread, + UD_Ivmresume, + UD_Ivmrun, + UD_Ivmsave, + UD_Ivmulpd, + UD_Ivmulps, + UD_Ivmulsd, + UD_Ivmulss, + UD_Ivmwrite, + UD_Ivmxoff, + UD_Ivmxon, + UD_Ivorpd, + UD_Ivorps, + UD_Ivpabsb, + UD_Ivpabsd, + UD_Ivpabsw, + UD_Ivpackssdw, + UD_Ivpacksswb, + UD_Ivpackusdw, + UD_Ivpackuswb, + UD_Ivpaddb, + UD_Ivpaddd, + UD_Ivpaddq, + UD_Ivpaddsb, + UD_Ivpaddsw, + UD_Ivpaddusb, + UD_Ivpaddusw, + UD_Ivpaddw, + UD_Ivpalignr, + UD_Ivpand, + UD_Ivpandn, + UD_Ivpavgb, + UD_Ivpavgw, + UD_Ivpblendvb, + UD_Ivpblendw, + UD_Ivpclmulqdq, + UD_Ivpcmpeqb, + UD_Ivpcmpeqd, + UD_Ivpcmpeqq, + UD_Ivpcmpeqw, + UD_Ivpcmpestri, + UD_Ivpcmpestrm, + UD_Ivpcmpgtb, + UD_Ivpcmpgtd, + UD_Ivpcmpgtq, + UD_Ivpcmpgtw, + UD_Ivpcmpistri, + UD_Ivpcmpistrm, + UD_Ivperm2f128, + UD_Ivpermilpd, + UD_Ivpermilps, + UD_Ivpextrb, + UD_Ivpextrd, + UD_Ivpextrq, + UD_Ivpextrw, + UD_Ivphaddd, + UD_Ivphaddsw, + UD_Ivphaddw, + UD_Ivphminposuw, + UD_Ivphsubd, + UD_Ivphsubsw, + UD_Ivphsubw, + UD_Ivpinsrb, + UD_Ivpinsrd, + UD_Ivpinsrq, + UD_Ivpinsrw, + UD_Ivpmaddubsw, + UD_Ivpmaddwd, + UD_Ivpmaxsb, + UD_Ivpmaxsd, + UD_Ivpmaxsw, + UD_Ivpmaxub, + UD_Ivpmaxud, + UD_Ivpmaxuw, + UD_Ivpminsb, + UD_Ivpminsd, + UD_Ivpminsw, + UD_Ivpminub, + UD_Ivpminud, + UD_Ivpminuw, + UD_Ivpmovmskb, + UD_Ivpmovsxbd, + UD_Ivpmovsxbq, + UD_Ivpmovsxbw, + UD_Ivpmovsxwd, + UD_Ivpmovsxwq, + UD_Ivpmovzxbd, + UD_Ivpmovzxbq, + UD_Ivpmovzxbw, + UD_Ivpmovzxdq, + UD_Ivpmovzxwd, + UD_Ivpmovzxwq, + UD_Ivpmuldq, + UD_Ivpmulhrsw, + UD_Ivpmulhuw, + UD_Ivpmulhw, + UD_Ivpmulld, + UD_Ivpmullw, + UD_Ivpor, + UD_Ivpsadbw, + UD_Ivpshufb, + UD_Ivpshufd, + UD_Ivpshufhw, + UD_Ivpshuflw, + UD_Ivpsignb, + UD_Ivpsignd, + UD_Ivpsignw, + UD_Ivpslld, + UD_Ivpslldq, + UD_Ivpsllq, + UD_Ivpsllw, + UD_Ivpsrad, + UD_Ivpsraw, + UD_Ivpsrld, + UD_Ivpsrldq, + UD_Ivpsrlq, + UD_Ivpsrlw, + UD_Ivpsubb, + UD_Ivpsubd, + UD_Ivpsubq, + UD_Ivpsubsb, + UD_Ivpsubsw, + UD_Ivpsubusb, + UD_Ivpsubusw, + UD_Ivpsubw, + UD_Ivptest, + UD_Ivpunpckhbw, + UD_Ivpunpckhdq, + UD_Ivpunpckhqdq, + UD_Ivpunpckhwd, + UD_Ivpunpcklbw, + UD_Ivpunpckldq, + UD_Ivpunpcklqdq, + UD_Ivpunpcklwd, + UD_Ivpxor, + UD_Ivrcpps, + UD_Ivrcpss, + UD_Ivroundpd, + UD_Ivroundps, + UD_Ivroundsd, + UD_Ivroundss, + UD_Ivrsqrtps, + UD_Ivrsqrtss, + UD_Ivshufpd, + UD_Ivshufps, + UD_Ivsqrtpd, + UD_Ivsqrtps, + UD_Ivsqrtsd, + UD_Ivsqrtss, + UD_Ivstmxcsr, + UD_Ivsubpd, + UD_Ivsubps, + UD_Ivsubsd, + UD_Ivsubss, + UD_Ivtestpd, + UD_Ivtestps, + UD_Ivucomisd, + UD_Ivucomiss, + UD_Ivunpckhpd, + UD_Ivunpckhps, + UD_Ivunpcklpd, + UD_Ivunpcklps, + UD_Ivxorpd, + UD_Ivxorps, + UD_Ivzeroall, + UD_Ivzeroupper, + UD_Iwait, + UD_Iwbinvd, + UD_Iwrmsr, + UD_Ixadd, + UD_Ixchg, + UD_Ixcryptcbc, + UD_Ixcryptcfb, + UD_Ixcryptctr, + UD_Ixcryptecb, + UD_Ixcryptofb, + UD_Ixgetbv, + UD_Ixlatb, + UD_Ixor, + UD_Ixorpd, + UD_Ixorps, + UD_Ixrstor, + UD_Ixsave, + UD_Ixsetbv, + UD_Ixsha1, + UD_Ixsha256, + UD_Ixstore, + UD_Iinvalid, + UD_I3dnow, + UD_Inone, + UD_Idb, + UD_Ipause, + UD_MAX_MNEMONIC_CODE +}; + +extern const char * ud_mnemonics_str[]; + +#endif /* UD_ITAB_H */ diff --git a/deps/libtomcrypt b/deps/libtomcrypt new file mode 160000 index 0000000..fae62af --- /dev/null +++ b/deps/libtomcrypt @@ -0,0 +1 @@ +Subproject commit fae62af0ab16f469c2512ec04575dd60ca018657 diff --git a/deps/libtommath b/deps/libtommath new file mode 160000 index 0000000..0df542c --- /dev/null +++ b/deps/libtommath @@ -0,0 +1 @@ +Subproject commit 0df542cb70f621bbeec207be1949832fb1442479 diff --git a/deps/minhook b/deps/minhook new file mode 160000 index 0000000..0f25a24 --- /dev/null +++ b/deps/minhook @@ -0,0 +1 @@ +Subproject commit 0f25a2449b3cf878bcbdbf91b693c38149ecf029 diff --git a/deps/premake/discord-rpc.lua b/deps/premake/discord-rpc.lua new file mode 100644 index 0000000..ef28bcb --- /dev/null +++ b/deps/premake/discord-rpc.lua @@ -0,0 +1,39 @@ +discordrpc = { + source = path.join(dependencies.basePath, "discord-rpc"), +} + +function discordrpc.import() + links { "discord-rpc" } + discordrpc.includes() +end + +function discordrpc.includes() + includedirs { + path.join(discordrpc.source, "include"), + } +end + +function discordrpc.project() + project "discord-rpc" + language "C++" + + discordrpc.includes() + rapidjson.import(); + + files { + path.join(discordrpc.source, "src/*.h"), + path.join(discordrpc.source, "src/*.cpp"), + } + + removefiles { + path.join(discordrpc.source, "src/dllmain.cpp"), + path.join(discordrpc.source, "src/*_linux.cpp"), + path.join(discordrpc.source, "src/*_unix.cpp"), + path.join(discordrpc.source, "src/*_osx.cpp"), + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, discordrpc) diff --git a/deps/premake/gsl.lua b/deps/premake/gsl.lua new file mode 100644 index 0000000..7c0b1e0 --- /dev/null +++ b/deps/premake/gsl.lua @@ -0,0 +1,19 @@ +gsl = { + source = path.join(dependencies.basePath, "GSL") +} + +function gsl.import() + gsl.includes() +end + +function gsl.includes() + includedirs { + path.join(gsl.source, "include") + } +end + +function gsl.project() + +end + +table.insert(dependencies, gsl) diff --git a/deps/premake/libtomcrypt.lua b/deps/premake/libtomcrypt.lua new file mode 100644 index 0000000..7ca3570 --- /dev/null +++ b/deps/premake/libtomcrypt.lua @@ -0,0 +1,64 @@ +libtomcrypt = { + source = path.join(dependencies.basePath, "libtomcrypt"), +} + +function libtomcrypt.import() + links { + "libtomcrypt" + } + + libtomcrypt.includes() +end + +function libtomcrypt.includes() + includedirs { + path.join(libtomcrypt.source, "src/headers") + } + + defines { + "LTC_NO_FAST", + "LTC_NO_PROTOTYPES", + "LTC_NO_RSA_BLINDING", + "LTC_NO_FILE", + "ARGTYPE=4", + } +end + +function libtomcrypt.project() + project "libtomcrypt" + language "C" + + libtomcrypt.includes() + libtommath.import() + + files { + path.join(libtomcrypt.source, "src/**.c"), + } + + removefiles { + path.join(libtomcrypt.source, "src/**/*_test.c"), + path.join(libtomcrypt.source, "src/**/*tab.c"), + path.join(libtomcrypt.source, "src/encauth/ocb3/**.c"), + } + + defines { + "_CRT_SECURE_NO_WARNINGS", + "LTC_SOURCE", + "_LIB", + "USE_LTM" + } + + removedefines { + "_DLL", + "_USRDLL" + } + + linkoptions { + "-IGNORE:4221" + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, libtomcrypt) diff --git a/deps/premake/libtommath.lua b/deps/premake/libtommath.lua new file mode 100644 index 0000000..ab4cdde --- /dev/null +++ b/deps/premake/libtommath.lua @@ -0,0 +1,52 @@ +libtommath = { + source = path.join(dependencies.basePath, "libtommath"), +} + +function libtommath.import() + links { + "libtommath" + } + + libtommath.includes() +end + +function libtommath.includes() + includedirs { + libtommath.source + } + + defines { + "LTM_DESC", + "__STDC_IEC_559__", + "MP_NO_DEV_URANDOM", + } +end + +function libtommath.project() + project "libtommath" + language "C" + + libtommath.includes() + + files { + path.join(libtommath.source, "*.c"), + } + + defines { + "_LIB" + } + + removedefines { + "_DLL", + "_USRDLL" + } + + linkoptions { + "-IGNORE:4221" + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, libtommath) diff --git a/deps/premake/minhook.lua b/deps/premake/minhook.lua new file mode 100644 index 0000000..396d4d3 --- /dev/null +++ b/deps/premake/minhook.lua @@ -0,0 +1,31 @@ +minhook = { + source = path.join(dependencies.basePath, "minhook"), +} + +function minhook.import() + links { "minhook" } + minhook.includes() +end + +function minhook.includes() + includedirs { + path.join(minhook.source, "include") + } +end + +function minhook.project() + project "minhook" + language "C" + + minhook.includes() + + files { + path.join(minhook.source, "src/**.h"), + path.join(minhook.source, "src/**.c"), + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, minhook) diff --git a/deps/premake/minizip.lua b/deps/premake/minizip.lua new file mode 100644 index 0000000..4a5754b --- /dev/null +++ b/deps/premake/minizip.lua @@ -0,0 +1,43 @@ +minizip = { + source = path.join(dependencies.basePath, "zlib/contrib/minizip"), +} + +function minizip.import() + links { "minizip" } + zlib.import() + minizip.includes() +end + +function minizip.includes() + includedirs { + minizip.source + } + + zlib.includes() +end + +function minizip.project() + project "minizip" + language "C" + + minizip.includes() + + files { + path.join(minizip.source, "*.h"), + path.join(minizip.source, "*.c"), + } + + removefiles { + path.join(minizip.source, "miniunz.c"), + path.join(minizip.source, "minizip.c"), + } + + defines { + "_CRT_SECURE_NO_DEPRECATE", + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, minizip) diff --git a/deps/premake/rapidjson.lua b/deps/premake/rapidjson.lua new file mode 100644 index 0000000..d108512 --- /dev/null +++ b/deps/premake/rapidjson.lua @@ -0,0 +1,19 @@ +rapidjson = { + source = path.join(dependencies.basePath, "rapidjson"), +} + +function rapidjson.import() + rapidjson.includes() +end + +function rapidjson.includes() + includedirs { + path.join(rapidjson.source, "include"), + } +end + +function rapidjson.project() + +end + +table.insert(dependencies, rapidjson) diff --git a/deps/premake/udis86.lua b/deps/premake/udis86.lua new file mode 100644 index 0000000..896ec8b --- /dev/null +++ b/deps/premake/udis86.lua @@ -0,0 +1,37 @@ +udis86 = { + source = path.join(dependencies.basePath, "udis86"), +} + +function udis86.import() + links { + "udis86" + } + + udis86.includes() +end + +function udis86.includes() + includedirs { + udis86.source, + path.join(udis86.source, "libudis86"), + path.join(dependencies.basePath, "extra/udis86"), + path.join(dependencies.basePath, "extra/udis86/libudis86"), + } +end + +function udis86.project() + project "udis86" + language "C" + + udis86.includes() + + files { + path.join(udis86.source, "libudis86/*.c"), + path.join(dependencies.basePath, "extra/udis86/libudis86/*.c"), + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, udis86) diff --git a/deps/premake/zlib.lua b/deps/premake/zlib.lua new file mode 100644 index 0000000..566a707 --- /dev/null +++ b/deps/premake/zlib.lua @@ -0,0 +1,39 @@ +zlib = { + source = path.join(dependencies.basePath, "zlib"), +} + +function zlib.import() + links { "zlib" } + zlib.includes() +end + +function zlib.includes() + includedirs { + zlib.source + } + + defines { + "ZLIB_CONST", + } +end + +function zlib.project() + project "zlib" + language "C" + + zlib.includes() + + files { + path.join(zlib.source, "*.h"), + path.join(zlib.source, "*.c"), + } + + defines { + "_CRT_SECURE_NO_DEPRECATE", + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, zlib) diff --git a/deps/rapidjson b/deps/rapidjson new file mode 160000 index 0000000..973dc9c --- /dev/null +++ b/deps/rapidjson @@ -0,0 +1 @@ +Subproject commit 973dc9c06dcd3d035ebd039cfb9ea457721ec213 diff --git a/deps/udis86 b/deps/udis86 new file mode 160000 index 0000000..56ff6c8 --- /dev/null +++ b/deps/udis86 @@ -0,0 +1 @@ +Subproject commit 56ff6c87c11de0ffa725b14339004820556e343d diff --git a/deps/zlib b/deps/zlib new file mode 160000 index 0000000..04f42ce --- /dev/null +++ b/deps/zlib @@ -0,0 +1 @@ +Subproject commit 04f42ceca40f73e2978b50e93806c2a18c1281fc diff --git a/generate.bat b/generate.bat new file mode 100644 index 0000000..2bad27b --- /dev/null +++ b/generate.bat @@ -0,0 +1,4 @@ +@echo off +echo Updating submodules... +call git submodule update --init --recursive +call tools\premake5 %* vs2022 diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 0000000..7212366 --- /dev/null +++ b/premake5.lua @@ -0,0 +1,331 @@ +gitVersioningCommand = "git describe --tags --dirty --always" +gitCurrentBranchCommand = "git symbolic-ref -q --short HEAD" + +-- Quote the given string input as a C string +function cstrquote(value) + if value == nil then + return "\"\"" + end + result = value:gsub("\\", "\\\\") + result = result:gsub("\"", "\\\"") + result = result:gsub("\n", "\\n") + result = result:gsub("\t", "\\t") + result = result:gsub("\r", "\\r") + result = result:gsub("\a", "\\a") + result = result:gsub("\b", "\\b") + result = "\"" .. result .. "\"" + return result +end + +-- Converts tags in "vX.X.X" format and given revision number Y to an array of numbers {X,X,X,Y}. +-- In the case where the format does not work fall back to padding with zeroes and just ending with the revision number. +-- partscount can be either 3 or 4. +function vertonumarr(value, vernumber, partscount) + vernum = {} + for num in string.gmatch(value or "", "%d+") do + if #vernum < 3 then + table.insert(vernum, tonumber(num)) + end + end + while #vernum < 3 do + table.insert(vernum, 0) + end + if #vernum < partscount then + table.insert(vernum, tonumber(vernumber)) + end + return vernum +end + +dependencies = { + basePath = "./deps" +} + +function dependencies.load() + dir = path.join(dependencies.basePath, "premake/*.lua") + deps = os.matchfiles(dir) + + for i, dep in pairs(deps) do + dep = dep:gsub(".lua", "") + require(dep) + end +end + +function dependencies.imports() + for i, proj in pairs(dependencies) do + if type(i) == 'number' then + proj.import() + end + end +end + +function dependencies.projects() + for i, proj in pairs(dependencies) do + if type(i) == 'number' then + proj.project() + end + end +end + +newoption { + trigger = "copy-to", + description = "Optional, copy the exe to a custom folder after build, define the path here if wanted.", + value = "PATH" +} + +newaction { + trigger = "version", + description = "Returns the version string for the current commit of the source code.", + onWorkspace = function(wks) + -- get current version via git + local proc = assert(io.popen(gitVersioningCommand, "r")) + local gitDescribeOutput = assert(proc:read('*a')):gsub("%s+", "") + proc:close() + local version = gitDescribeOutput + + proc = assert(io.popen(gitCurrentBranchCommand, "r")) + local gitCurrentBranchOutput = assert(proc:read('*a')):gsub("%s+", "") + local gitCurrentBranchSuccess = proc:close() + if gitCurrentBranchSuccess then + -- We got a branch name, check if it is a feature branch + if gitCurrentBranchOutput ~= "develop" and gitCurrentBranchOutput ~= "master" then + version = version .. "-" .. gitCurrentBranchOutput + end + end + + print(version) + os.exit(0) + end +} + +newaction { + trigger = "generate-buildinfo", + description = "Sets up build information file like version.h.", + onWorkspace = function(wks) + -- get old version number from version.hpp if any + local oldVersion = "(none)" + local oldVersionHeader = io.open(wks.location .. "/src/version.h", "r") + if oldVersionHeader ~= nil then + local oldVersionHeaderContent = assert(oldVersionHeader:read('*l')) + while oldVersionHeaderContent do + m = string.match(oldVersionHeaderContent, "#define GIT_DESCRIBE (.+)%s*$") + if m ~= nil then + oldVersion = m + end + + oldVersionHeaderContent = oldVersionHeader:read('*l') + end + end + + -- get current version via git + local proc = assert(io.popen(gitVersioningCommand, "r")) + local gitDescribeOutput = assert(proc:read('*a')):gsub("%s+", "") + proc:close() + + -- generate version.hpp with a revision number if not equal + gitDescribeOutputQuoted = cstrquote(gitDescribeOutput) + if oldVersion ~= gitDescribeOutputQuoted then + -- get current git hash and write to version.txt (used by the preliminary updater) + -- TODO - remove once proper updater and release versioning exists + local proc = assert(io.popen("git rev-parse HEAD", "r")) + local gitCommitHash = assert(proc:read('*a')):gsub("%s+", "") + proc:close() + + -- get whether this is a clean revision (no uncommitted changes) + proc = assert(io.popen("git status --porcelain", "r")) + local revDirty = (assert(proc:read('*a')) ~= "") + if revDirty then revDirty = 1 else revDirty = 0 end + proc:close() + + -- get current tag name + proc = assert(io.popen("git describe --tags --abbrev=0")) + local tagName = proc:read('*l') + + -- get current branch name + proc = assert(io.popen("git branch --show-current")) + local branchName = proc:read('*l') + + -- branch for ci + if branchName == nil or branchName == '' then + proc = assert(io.popen("git show -s --pretty=%d HEAD")) + local branchInfo = proc:read('*l') + m = string.match(branchInfo, ".+,.+, ([^)]+)") + if m ~= nil then + branchName = m + end + end + + if branchName == nil then + branchName = "develop" + end + + print("Detected branch: " .. branchName) + + -- get revision number via git + local proc = assert(io.popen("git rev-list --count HEAD", "r")) + local revNumber = assert(proc:read('*a')):gsub("%s+", "") + + print ("Update " .. oldVersion .. " -> " .. gitDescribeOutputQuoted) + + -- write to version.txt for preliminary updater + -- NOTE - remove this once we have a proper updater and proper release versioning + local versionFile = assert(io.open(wks.location .. "/version.txt", "w")) + versionFile:write(gitCommitHash) + versionFile:close() + + -- write version header + local versionHeader = assert(io.open(wks.location .. "/src/version.h", "w")) + versionHeader:write("/*\n") + versionHeader:write(" * Automatically generated by premake5.\n") + versionHeader:write(" * Do not touch!\n") + versionHeader:write(" */\n") + versionHeader:write("\n") + versionHeader:write("#define GIT_DESCRIBE " .. gitDescribeOutputQuoted .. "\n") + versionHeader:write("#define GIT_DIRTY " .. revDirty .. "\n") + versionHeader:write("#define GIT_HASH " .. cstrquote(gitCommitHash) .. "\n") + versionHeader:write("#define GIT_TAG " .. cstrquote(tagName) .. "\n") + versionHeader:write("#define GIT_BRANCH " .. cstrquote(branchName) .. "\n") + versionHeader:write("\n") + versionHeader:write("// Version transformed for RC files\n") + versionHeader:write("#define VERSION_PRODUCT_RC " .. table.concat(vertonumarr(tagName, revNumber, 3), ",") .. "\n") + versionHeader:write("#define VERSION_PRODUCT " .. cstrquote(table.concat(vertonumarr(tagName, revNumber, 3), ".")) .. "\n") + versionHeader:write("#define VERSION_FILE_RC " .. table.concat(vertonumarr(tagName, revNumber, 4), ",") .. "\n") + versionHeader:write("#define VERSION_FILE " .. cstrquote(table.concat(vertonumarr(tagName, revNumber, 4), ".")) .. "\n") + versionHeader:write("\n") + versionHeader:write("// Alias definitions\n") + versionHeader:write("#define VERSION GIT_DESCRIBE\n") + versionHeader:write("#define SHORTVERSION VERSION_PRODUCT\n") + versionHeader:close() + local versionHeader = assert(io.open(wks.location .. "/src/version.hpp", "w")) + versionHeader:write("/*\n") + versionHeader:write(" * Automatically generated by premake5.\n") + versionHeader:write(" * Do not touch!\n") + versionHeader:write(" *\n") + versionHeader:write(" * This file exists for reasons of complying with our coding standards.\n") + versionHeader:write(" *\n") + versionHeader:write(" * The Resource Compiler will ignore any content from C++ header files if they're not from STDInclude.hpp.\n") + versionHeader:write(" * That's the reason why we now place all version info in version.h instead.\n") + versionHeader:write(" */\n") + versionHeader:write("\n") + versionHeader:write("#include \".\\version.h\"\n") + versionHeader:close() + end + end +} + +dependencies.load() + +workspace "iw4-sp" +startproject "client" +location "./build" +objdir "%{wks.location}/obj" +targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}" + +configurations {"Debug", "Release"} + +language "C++" +cppdialect "C++20" + +architecture "x86" +platforms "Win32" + +systemversion "latest" +symbols "On" +staticruntime "On" +editandcontinue "Off" +warnings "Extra" +characterset "ASCII" + +if os.getenv("CI") then + defines {"CI"} +end + +flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"} + +filter "platforms:Win*" + defines {"_WINDOWS", "WIN32"} +filter {} + +filter "configurations:Release" + optimize "Size" + buildoptions {"/GL"} + linkoptions {"/IGNORE:4702", "/LTCG"} + defines {"NDEBUG"} + flags {"FatalCompileWarnings"} +filter {} + +filter "configurations:Debug" + optimize "Debug" + defines {"DEBUG", "_DEBUG"} +filter {} + +project "common" +kind "StaticLib" +language "C++" + +files {"./src/common/**.hpp", "./src/common/**.cpp"} + +includedirs {"./src/common", "%{prj.location}/src"} + +resincludedirs {"$(ProjectDir)src"} + +dependencies.imports() + +project "runner" +kind "WindowedApp" +language "C++" + +files {"./src/runner/**.rc", "./src/runner/**.hpp", "./src/runner/**.cpp", "./src/runner/resources/**.*"} + +includedirs {"./src/runner", "./src/common", "%{prj.location}/src"} + +resincludedirs {"$(ProjectDir)src"} + +links {"common"} + +dependencies.imports() + +project "client" +kind "WindowedApp" +language "C++" + +targetname "iw4-sp" + +pchheader "std_include.hpp" +pchsource "src/client/std_include.cpp" + +linkoptions {"/IGNORE:4254", "/DYNAMICBASE:NO", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/LAST:.main", "/PDBCompress"} + +files {"./src/client/**.rc", "./src/client/**.hpp", "./src/client/**.cpp", "./src/resources/**.*"} + +includedirs {"./src/client", "./src/common", "%{prj.location}/src"} + +resincludedirs {"$(ProjectDir)src"} + +links {"common"} + +prebuildcommands {"pushd %{_MAIN_SCRIPT_DIR}", "tools\\premake5 generate-buildinfo", "popd"} + +if _OPTIONS["copy-to"] then + postbuildcommands { + "copy /y \"$(TargetDir)*.exe\" \"" .. _OPTIONS["copy-to"] .. "\"" + } +end + +dependencies.imports() + +project "tlsdll" +kind "SharedLib" +language "C++" + +files {"./src/tlsdll/**.rc", "./src/tlsdll/**.hpp", "./src/tlsdll/**.cpp", "./src/tlsdll/resources/**.*"} + +includedirs {"./src/tlsdll", "%{prj.location}/src"} + +links {"common"} + +resincludedirs {"$(ProjectDir)src"} + +dependencies.imports() + +group "Dependencies" +dependencies.projects() diff --git a/src/client/component/asset_restrict.cpp b/src/client/component/asset_restrict.cpp new file mode 100644 index 0000000..476de55 --- /dev/null +++ b/src/client/component/asset_restrict.cpp @@ -0,0 +1,49 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include + +namespace asset_restrict { +namespace { +game::XAssetEntry entry_pool[789312]; + +game::XAssetHeader reallocate_asset_pool(game::XAssetType type, + const int size) { + const auto entry_size = + reinterpret_cast(game::DB_GetXAssetSizeHandlers[type])(); + const game::XAssetHeader pool_entry = { + .data = utils::memory::allocate(entry_size * size)}; + game::DB_XAssetPool[type] = pool_entry.data; + game::g_poolSize[type] = size; + + return pool_entry; +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + patch_entry_pool_sp(); + reallocate_asset_pool(game::ASSET_TYPE_GAMEWORLD_MP, 1); + } + + static void patch_entry_pool_sp() { + // Apply new size + utils::hook::set(0x581740, sizeof(entry_pool) / + sizeof(game::XAssetEntry)); + utils::hook::set(0x581721, entry_pool + 1); + utils::hook::set(0x581732, entry_pool + 1); + + utils::hook::signature signature(0x411000, 0x200000); + + signature.add({"\x60\xB3\xB2\x00", "xxxx", [](char* address) { + utils::hook::set(address, entry_pool); + }}); + + signature.process(); + } +}; +} // namespace asset_restrict + +REGISTER_COMPONENT(asset_restrict::component) diff --git a/src/client/component/assets/assets.cpp b/src/client/component/assets/assets.cpp new file mode 100644 index 0000000..d7073e3 --- /dev/null +++ b/src/client/component/assets/assets.cpp @@ -0,0 +1,60 @@ +#include +#include "loader/component_loader.hpp" + +#include "localize_entry.hpp" +#include "map_ents.hpp" +#include "raw_file.hpp" + +#include + +namespace assets { +namespace { +void load_asset(game::XAssetType type, game::XAssetHeader* header) { + if (header) { + switch (type) { + case game::ASSET_TYPE_LOCALIZE_ENTRY: + process_localize_entry(*header); + break; + case game::ASSET_TYPE_MAP_ENTS: + process_map_ents(*header); + break; + case game::ASSET_TYPE_RAWFILE: + process_raw_file(*header); + break; + default: + break; + } + } +} + +void __declspec(naked) db_add_x_asset_stub() { + __asm { + pushad; + + push [esp + 0x20 + 0x8]; + push [esp + 0x20 + 0x8]; + call load_asset; + add esp, 0x8; + + popad; + + sub esp, 0x14; + mov eax, dword ptr [esp + 0x1C]; + + push 0x581EE7; + ret; + } +} +} // namespace + +class asset final : public component_interface { +public: + void post_load() override { + // We may modify assets to some extents here or just dump them + utils::hook(0x581EE0, db_add_x_asset_stub, HOOK_JUMP).install()->quick(); + utils::hook::nop(0x581EE5, 2); + } +}; +} // namespace assets + +REGISTER_COMPONENT(assets::asset) diff --git a/src/client/component/assets/localize_entry.cpp b/src/client/component/assets/localize_entry.cpp new file mode 100644 index 0000000..a8f9d5d --- /dev/null +++ b/src/client/component/assets/localize_entry.cpp @@ -0,0 +1,26 @@ +#include + +#include "localize_entry.hpp" + +#include +#include +#include + +namespace assets { +namespace { +bool is_enabled() { IS_FLAG_ENABLED(dump_localize_entry); } +} // namespace + +void process_localize_entry(game::XAssetHeader header) { + if (!is_enabled()) { + return; + } + + auto* localize = header.localize; + const auto filename = + utils::string::va("raw/localizedstrings/{0}", localize->name); + + // Simple format, should be fine for now + utils::io::write_file(filename, localize->value); +} +} // namespace assets diff --git a/src/client/component/assets/localize_entry.hpp b/src/client/component/assets/localize_entry.hpp new file mode 100644 index 0000000..171a8f5 --- /dev/null +++ b/src/client/component/assets/localize_entry.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace assets { +void process_localize_entry(game::XAssetHeader header); +} diff --git a/src/client/component/assets/map_ents.cpp b/src/client/component/assets/map_ents.cpp new file mode 100644 index 0000000..9df841d --- /dev/null +++ b/src/client/component/assets/map_ents.cpp @@ -0,0 +1,30 @@ +#include + +#include "component/filesystem.hpp" + +#include "map_ents.hpp" + +#include + +namespace assets { +namespace { +std::string map_entities; + +void load_map_entities(game::MapEnts* entry) { + const auto file_name = utils::string::va("{0}.ents", entry->name); + const filesystem::file ent_file(file_name, game::FS_THREAD_DATABASE); + + // Load ent file from raw if it exists + if (ent_file.exists()) { + map_entities = ent_file.get_buffer(); + entry->entityString = map_entities.data(); + entry->numEntityChars = static_cast(map_entities.size()) + 1; + } +} +} // namespace + +void process_map_ents(game::XAssetHeader header) { + auto* map_ents = header.mapEnts; + load_map_entities(map_ents); +} +} // namespace assets diff --git a/src/client/component/assets/map_ents.hpp b/src/client/component/assets/map_ents.hpp new file mode 100644 index 0000000..ccfa5a6 --- /dev/null +++ b/src/client/component/assets/map_ents.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace assets { +void process_map_ents(game::XAssetHeader header); +} diff --git a/src/client/component/assets/raw_file.cpp b/src/client/component/assets/raw_file.cpp new file mode 100644 index 0000000..3586b5f --- /dev/null +++ b/src/client/component/assets/raw_file.cpp @@ -0,0 +1,181 @@ +#include +#include "loader/component_loader.hpp" + +#include "raw_file.hpp" + +#include +#include +#include +#include + +#include + +namespace assets { +namespace { +utils::hook::detour db_read_raw_file_hook; +utils::hook::detour com_load_info_string_hook; + +char* db_read_raw_file_stub(const char* filename, char* buf, int size) { + auto file_handle = 0; + const auto file_size = game::FS_FOpenFileRead(filename, &file_handle); + + if (file_handle != 0) { + if ((file_size + 1) <= size) { + game::FS_Read(buf, file_size, file_handle); + buf[file_size] = '\0'; + game::FS_FCloseFile(file_handle); + return buf; + } + + game::FS_FCloseFile(file_handle); + game::Com_PrintError( + game::CON_CHANNEL_ERROR, + "Ignoring raw file '%s' as it exceeds buffer size %i > %i\n", filename, + file_size, size); + } + + auto* rawfile = + game::DB_FindXAssetHeader(game::ASSET_TYPE_RAWFILE, filename).rawfile; + if (game::DB_IsXAssetDefault(game::ASSET_TYPE_RAWFILE, filename)) { + return nullptr; + } + + game::DB_GetRawBuffer(rawfile, buf, size); + return buf; +} + +const char* com_load_info_string_fast_file(const char* file_name, + const char* file_desc, + const char* ident, + char* load_buffer) { + const static DWORD Com_LoadInfoString_FastFile_t = 0x602FA0; + const char* result{}; + + __asm { + pushad; + + mov ebx, load_buffer; + mov edi, file_name; + push ident; + push file_desc; + call Com_LoadInfoString_FastFile_t; + add esp, 0x8; + mov result, eax; + + popad; + } + + return result; +} + +const char* com_load_info_string_load_obj(const char* file_name, + const char* file_desc, + const char* ident, + char* load_buffer) { + int file_handle; + + const auto file_len = + game::FS_FOpenFileByMode(file_name, &file_handle, game::FS_READ); + if (file_len < 0) { + game::Com_DPrintf(game::CON_CHANNEL_SYSTEM, + "Could not load %s [%s] as rawfile", file_desc, + file_name); + return nullptr; + } + + const auto ident_len = static_cast(std::strlen(ident)); + game::FS_Read(load_buffer, ident_len, file_handle); + load_buffer[ident_len] = '\0'; + + if (std::strncmp(load_buffer, ident, ident_len) != 0) { + game::Com_Error(game::ERR_DROP, + "\x15" + "File [%s] is not a %s\n", + file_name, file_desc); + return nullptr; + } + + if ((file_len - ident_len) >= 0x4000) { + game::Com_Error(game::ERR_DROP, + "\x15" + "File [%s] is too long of a %s to parse\n", + file_name, file_desc); + return nullptr; + } + + game::FS_Read(load_buffer, file_len - ident_len, file_handle); + load_buffer[file_len - ident_len] = '\0'; + game::FS_FCloseFile(file_handle); + + return load_buffer; +} + +const char* com_load_info_string_stub(const char* file_name, + const char* file_desc, const char* ident, + char* load_buffer) { + const auto* buffer = + com_load_info_string_load_obj(file_name, file_desc, ident, load_buffer); + if (!buffer) { + buffer = com_load_info_string_fast_file(file_name, file_desc, ident, + load_buffer); + } + + if (!game::Info_Validate(buffer)) { + game::Com_Error(game::ERR_DROP, + "\x15" + "File [%s] is not a valid %s\n", + file_name, file_desc); + return nullptr; + } + + return buffer; +} + +bool is_enabled() { IS_FLAG_ENABLED(dump_raw_file); } +} // namespace + +void process_raw_file(game::XAssetHeader header) { + if (!is_enabled()) { + return; + } + + const auto* raw_file = header.rawfile; + const auto filename = utils::string::va("raw/{0}", raw_file->name); + + if (raw_file->compressedLen > 0) { + std::vector uncompressed; + uncompressed.resize(raw_file->len); + + if (uncompress(uncompressed.data(), (uLongf*)&raw_file->len, + (const Bytef*)raw_file->buffer, + raw_file->compressedLen) == Z_OK) { + std::string data; + data.assign(uncompressed.begin(), uncompressed.end()); + + utils::io::write_file(filename, data); + } + + return; + } + + // If uncompressed just dump it + utils::io::write_file(filename, raw_file->buffer); +} + +class raw_file final : public component_interface { +public: + void post_load() override { + // Remove fs_game check for moddable raw files + // allows non-fs_game to modify raw files + utils::hook::nop(0x612932, 2); + + db_read_raw_file_hook.create(0x46DA60, &db_read_raw_file_stub); + + com_load_info_string_hook.create(0x42DB20, &com_load_info_string_stub); + } + + void pre_destroy() override { db_read_raw_file_hook.clear(); } +}; +} // namespace assets + +REGISTER_COMPONENT(assets::raw_file) diff --git a/src/client/component/assets/raw_file.hpp b/src/client/component/assets/raw_file.hpp new file mode 100644 index 0000000..0d634f1 --- /dev/null +++ b/src/client/component/assets/raw_file.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace assets { +void process_raw_file(game::XAssetHeader header); +} diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp new file mode 100644 index 0000000..02de7e7 --- /dev/null +++ b/src/client/component/auth.cpp @@ -0,0 +1,84 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include +#include +#include + +#include "auth.hpp" + +namespace auth { +namespace { +std::string get_hw_profile_guid() { + HW_PROFILE_INFO info; + if (!GetCurrentHwProfileA(&info)) { + return {}; + } + + return std::string{info.szHwProfileGuid, sizeof(info.szHwProfileGuid)}; +} + +std::string get_protected_data() { + std::string input = "Alter-Ware-IW4-SP-Auth"; + + DATA_BLOB data_in{}, data_out{}; + data_in.pbData = reinterpret_cast(input.data()); + data_in.cbData = static_cast(input.size()); + if (CryptProtectData(&data_in, nullptr, nullptr, nullptr, nullptr, + CRYPTPROTECT_LOCAL_MACHINE, &data_out) != TRUE) { + return {}; + } + + const auto size = std::min(data_out.cbData, 52); + std::string result(reinterpret_cast(data_out.pbData), size); + LocalFree(data_out.pbData); + + return result; +} + +std::string get_hdd_serial() { + DWORD serial{}; + if (!GetVolumeInformationA("C:\\", nullptr, 0, &serial, nullptr, nullptr, + nullptr, 0)) { + return {}; + } + + return utils::string::va("{0:08X}", serial); +} + +std::string get_key_entropy() { + std::string entropy{}; + entropy.append(utils::smbios::get_uuid()); + entropy.append(get_hw_profile_guid()); + entropy.append(get_protected_data()); + entropy.append(get_hdd_serial()); + + if (entropy.empty()) { + entropy.resize(32); + utils::cryptography::random::get_data(entropy.data(), entropy.size()); + } + + return entropy; +} + +utils::cryptography::ecc::key& get_key() { + static auto key = + utils::cryptography::ecc::generate_key(512, get_key_entropy()); + return key; +} + +} // namespace + +std::uint64_t get_guid() { return get_key().get_hash(); } + +class component final : public component_interface { +public: + void post_load() override { + // Patch Steam_GetClientIDAsXUID + utils::hook::set(0x4911B0, 0xC301B0); + } +}; +} // namespace auth + +REGISTER_COMPONENT(auth::component) diff --git a/src/client/component/auth.hpp b/src/client/component/auth.hpp new file mode 100644 index 0000000..56d5ba1 --- /dev/null +++ b/src/client/component/auth.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace auth { +std::uint64_t get_guid(); +} diff --git a/src/client/component/botlib/l_precomp.cpp b/src/client/component/botlib/l_precomp.cpp new file mode 100644 index 0000000..a9f798e --- /dev/null +++ b/src/client/component/botlib/l_precomp.cpp @@ -0,0 +1,254 @@ +#include + +#include "l_precomp.hpp" +#include "l_script.hpp" + +namespace pc { +constexpr auto DEFINEHASHSIZE = 1024; + +constexpr auto MAX_SOURCEFILES = 64; + +game::define_s* globaldefines; + +void free_token(game::token_s* token) { + game::FreeMemory(token); + --*game::numtokens; +} + +game::define_s* define_from_string(const char* string) { + game::source_s src; + + auto* script = load_script_memory( + string, static_cast(std::strlen(string)), "*extern"); + // create a new source + std::memset(&src, 0, sizeof(game::source_s)); + strncpy_s(src.filename, "*extern", _TRUNCATE); + + src.scriptstack = script; + src.definehash = static_cast( + game::GetClearedMemory(DEFINEHASHSIZE * sizeof(game::define_s*))); + + // create a define from the source + auto res = game::PC_Directive_define(&src); + + // free any tokens if left + for (auto* t = src.tokens; t; t = src.tokens) { + src.tokens = src.tokens->next; + free_token(t); + } + + game::define_s* def = nullptr; + for (auto i = 0; i < DEFINEHASHSIZE; ++i) { + if (src.definehash[i]) { + def = src.definehash[i]; + break; + } + } + + game::FreeMemory(src.definehash); + free_script(script); + + // if the define was created successfully + if (res > 0) { + return def; + } + + // free the define is created + if (src.defines) { + game::PC_FreeDefine(def); + } + + return nullptr; +} + +int name_hash(char* name) { + auto hash = 0; + for (auto i = 0; name[i] != '\0'; ++i) { + hash += name[i] * (119 + i); + } + + hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (DEFINEHASHSIZE - 1); + return hash; +} + +void add_define_to_hash(game::define_s* define, game::define_s** definehash) { + auto hash = name_hash(define->name); + define->hashnext = definehash[hash]; + definehash[hash] = define; +} + +int add_define(game::source_s* source, const char* string) { + + auto* define = define_from_string(string); + if (!define) { + return 0; + } + + add_define_to_hash(define, source->definehash); + + return true; +} + +game::define_s* copy_define([[maybe_unused]] game::source_s* source, + game::define_s* define) { + game::token_s *token, *newtoken, *lasttoken; + + auto* newdefine = static_cast( + game::GetMemory(sizeof(game::define_s) + strlen(define->name) + 1)); + + // copy the define name + newdefine->name = (char*)newdefine + sizeof(game::define_s); + std::memcpy(newdefine->name, define->name, std::strlen(define->name) + 1); + + newdefine->flags = define->flags; + newdefine->builtin = define->builtin; + newdefine->numparms = define->numparms; + + // the define is not linked + newdefine->next = nullptr; + newdefine->hashnext = nullptr; + + // copy the define tokens + newdefine->tokens = nullptr; + for (lasttoken = nullptr, token = define->tokens; token; + token = token->next) { + newtoken = game::PC_CopyToken(token); + newtoken->next = nullptr; + if (lasttoken) { + lasttoken->next = newtoken; + } else { + newdefine->tokens = newtoken; + } + + lasttoken = newtoken; + } + + // copy the define parameters + newdefine->parms = nullptr; + for (lasttoken = nullptr, token = define->parms; token; token = token->next) { + newtoken = game::PC_CopyToken(token); + newtoken->next = nullptr; + if (lasttoken) { + lasttoken->next = newtoken; + } else { + newdefine->parms = newtoken; + } + + lasttoken = newtoken; + } + + return newdefine; +} + +void add_global_defines_to_source(game::source_s* source) { + for (auto* define = globaldefines; define; define = define->next) { + auto* newdefine = copy_define(source, define); + + add_define_to_hash(newdefine, source->definehash); + } +} + +game::source_s* load_source_file(const char* filename) { + auto* script = load_script_file(filename); + if (!script) { + return nullptr; + } + + script->next = nullptr; + + auto* source = + static_cast(game::GetMemory(sizeof(game::source_s))); + std::memset(source, 0, sizeof(game::source_s)); + + strncpy_s(source->filename, filename, _TRUNCATE); + source->scriptstack = script; + source->tokens = nullptr; + source->defines = nullptr; + source->indentstack = nullptr; + source->skip = 0; + + source->definehash = static_cast( + game::GetClearedMemory(DEFINEHASHSIZE * sizeof(game::define_s*))); + + add_global_defines_to_source(source); + return source; +} + +int load_source_handle(const char* filename, const char** builtin_defines) { + int i; + + for (i = 1; i < MAX_SOURCEFILES; ++i) { + if (!game::sourceFiles[i]) { + break; + } + } + + if (i >= MAX_SOURCEFILES) { + return 0; + } + + auto* source = load_source_file(filename); + if (!source) { + return 0; + } + + if (builtin_defines) { + for (auto define_iter = 0; builtin_defines[define_iter]; ++define_iter) { + add_define(source, builtin_defines[define_iter]); + } + } + + game::sourceFiles[i] = source; + return i; +} + +void free_source(game::source_s* source) { + // free all the scripts + while (source->scriptstack) { + auto* script = source->scriptstack; + source->scriptstack = source->scriptstack->next; + free_script(script); + } + + // free all the tokens + while (source->tokens) { + auto* token = source->tokens; + source->tokens = source->tokens->next; + free_token(token); + } + + for (auto i = 0; i < DEFINEHASHSIZE; ++i) { + while (source->definehash[i]) { + auto* define = source->definehash[i]; + source->definehash[i] = source->definehash[i]->hashnext; + game::PC_FreeDefine(define); + } + } + + // free all indents + while (source->indentstack) { + auto* indent = source->indentstack; + source->indentstack = source->indentstack->next; + game::FreeMemory(indent); + } + + if (source->definehash) { + game::FreeMemory(source->definehash); + } + + // free the source itself + game::FreeMemory(source); +} + +int free_source_handle(int handle) { + if (handle < 1 || handle >= MAX_SOURCEFILES) + return 0; + + if (!game::sourceFiles[handle]) + return 0; + + free_source(game::sourceFiles[handle]); + game::sourceFiles[handle] = nullptr; + return 1; +} +} // namespace pc diff --git a/src/client/component/botlib/l_precomp.hpp b/src/client/component/botlib/l_precomp.hpp new file mode 100644 index 0000000..7ceecf2 --- /dev/null +++ b/src/client/component/botlib/l_precomp.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace pc { +int load_source_handle(const char* filename, const char** builtin_defines); +int free_source_handle(int handle); +} // namespace pc diff --git a/src/client/component/botlib/l_script.cpp b/src/client/component/botlib/l_script.cpp new file mode 100644 index 0000000..93df92f --- /dev/null +++ b/src/client/component/botlib/l_script.cpp @@ -0,0 +1,204 @@ +#include +#include "l_script.hpp" + +namespace pc { +// clang-format off +game::punctuation_s default_punctuations[] = +{ + { ">>=", P_RSHIFT_ASSIGN, nullptr }, + { "<<=", P_LSHIFT_ASSIGN, nullptr }, + + { "...", P_PARMS, nullptr }, + // define merge operator + { "##", P_PRECOMPMERGE, nullptr }, + // logic operators + { "&&", P_LOGIC_AND, nullptr }, + { "||", P_LOGIC_OR, nullptr }, + { ">=", P_LOGIC_GEQ, nullptr }, + { "<=", P_LOGIC_LEQ, nullptr }, + { "==", P_LOGIC_EQ, nullptr }, + { "!=", P_LOGIC_UNEQ, nullptr }, + // arithmatic operators + { "*=", P_MUL_ASSIGN, nullptr }, + { "/=",P_DIV_ASSIGN, nullptr }, + { "%=", P_MOD_ASSIGN, nullptr }, + { "+=", P_ADD_ASSIGN, nullptr }, + { "-=", P_SUB_ASSIGN,nullptr }, + { "++", P_INC, nullptr }, + { "--", P_DEC, nullptr }, + // binary operators + { "&=", P_BIN_AND_ASSIGN, nullptr }, + { "|=", P_BIN_OR_ASSIGN, nullptr }, + { "^=", P_BIN_XOR_ASSIGN, nullptr }, + { ">>", P_RSHIFT, nullptr }, + { "<<", P_LSHIFT, nullptr }, + // reference operators + { "->", P_POINTERREF, nullptr }, + // C++ + { "::", P_CPP1, nullptr }, + { ".*", P_CPP2, nullptr }, + // arithmatic operators + { "*", P_MUL, nullptr }, + { "/", P_DIV,nullptr }, + { "%", P_MOD, nullptr }, + { "+", P_ADD, nullptr }, + { "-", P_SUB, nullptr }, + { "=", P_ASSIGN, nullptr }, + // binary operators + { "&", P_BIN_AND, nullptr }, + { "|", P_BIN_OR, nullptr }, + { "^", P_BIN_XOR, nullptr }, + { "~", P_BIN_NOT, nullptr }, + // logic operators + { "!", P_LOGIC_NOT, nullptr }, + { ">", P_LOGIC_GREATER, nullptr }, + { "<", P_LOGIC_LESS, nullptr }, + // reference operator + { ".", P_REF, nullptr }, + // seperators + { ",", P_COMMA, nullptr }, + { ";", P_SEMICOLON, nullptr }, + // label indication + { ":", P_COLON, nullptr }, + // if statement + { "?", P_QUESTIONMARK, nullptr }, + // embracements + { "(", P_PARENTHESESOPEN, nullptr }, + { ")", P_PARENTHESESCLOSE, nullptr }, + { "{", P_BRACEOPEN, nullptr }, + { "}", P_BRACECLOSE, nullptr }, + { "[", P_SQBRACKETOPEN, nullptr }, + { "]", P_SQBRACKETCLOSE, nullptr }, + // + { "\\", P_BACKSLASH, nullptr }, + // precompiler operator + { "#", P_PRECOMP, nullptr }, + { "$", P_DOLLAR, nullptr }, + { nullptr, 0, nullptr }, +}; +// clang-format on + +void create_punctuation_table(game::script_s* script, + game::punctuation_s* punctuations) { + game::punctuation_s* p; + + // get memory for the table + if (!script->punctuationtable) { + script->punctuationtable = static_cast( + game::GetMemory(256 * sizeof(game::punctuation_s*))); + } + + std::memset(script->punctuationtable, 0, 256 * sizeof(game::punctuation_s*)); + + // add the punctuations in the list to the punctuation table + for (auto i = 0; punctuations[i].p; ++i) { + auto* newp = &punctuations[i]; + game::punctuation_s* lastp = nullptr; + + // sort the punctuations in this table entry on length (longer punctuations + // first) + for (p = script->punctuationtable[(unsigned int)newp->p[0]]; p; + p = p->next) { + if (std::strlen(p->p) < std::strlen(newp->p)) { + newp->next = p; + if (lastp) { + lastp->next = newp; + } else { + script->punctuationtable[(unsigned int)newp->p[0]] = newp; + } + + break; + } + + lastp = p; + } + + if (!p) { + newp->next = nullptr; + if (lastp) { + lastp->next = newp; + } else { + script->punctuationtable[(unsigned int)newp->p[0]] = newp; + } + } + } +} + +void set_script_punctuations(game::script_s* script) { + create_punctuation_table(script, default_punctuations); + script->punctuations = default_punctuations; +} + +game::script_s* load_script_file(const char* filename) { + int fp; + char pathname[game::MAX_QPATH]; + + sprintf_s(pathname, "%s", filename); + const auto length = game::FS_FOpenFileRead(pathname, &fp); + if (!fp) { + return nullptr; + } + + auto* buffer = game::GetClearedMemory(sizeof(game::script_s) + length + 1); + auto* script = static_cast(buffer); + strncpy_s(script->filename, filename, _TRUNCATE); + + script->buffer = static_cast(buffer) + sizeof(game::script_s); + script->buffer[length] = '\0'; + script->length = length; + // pointer in script buffer + script->script_p = script->buffer; + // pointer in script buffer before reading token + script->lastscript_p = script->buffer; + // pointer to end of script buffer + script->end_p = &script->buffer[length]; + // set if there's a token available in script->token + script->tokenavailable = 0; + + script->line = 1; + script->lastline = 1; + + set_script_punctuations(script); + + game::FS_Read(script->buffer, length, fp); + game::FS_FCloseFile(fp); + + script->length = game::Com_Compress(script->buffer); + return script; +} + +game::script_s* load_script_memory(const char* ptr, int length, + const char* name) { + auto* buffer = game::GetClearedMemory(sizeof(game::script_s) + length + 1); + auto* script = static_cast(buffer); + + strncpy_s(script->filename, name, _TRUNCATE); + script->buffer = static_cast(buffer) + sizeof(game::script_s); + script->buffer[length] = '\0'; + script->length = length; + // pointer in script buffer + script->script_p = script->buffer; + // pointer in script buffer before reading token + script->lastscript_p = script->buffer; + // pointer to end of script buffer + script->end_p = &script->buffer[length]; + // set if there's a token available in script->token + script->tokenavailable = 0; + + script->line = 1; + script->lastline = 1; + + set_script_punctuations(script); + + std::memcpy(script->buffer, ptr, length); + + return script; +} + +void free_script(game::script_s* script) { + if (script->punctuationtable) + game::FreeMemory(script->punctuationtable); + + game::FreeMemory(script); +} +} // namespace pc diff --git a/src/client/component/botlib/l_script.hpp b/src/client/component/botlib/l_script.hpp new file mode 100644 index 0000000..3e8ca65 --- /dev/null +++ b/src/client/component/botlib/l_script.hpp @@ -0,0 +1,70 @@ +#pragma once + +#define P_RSHIFT_ASSIGN 1 +#define P_LSHIFT_ASSIGN 2 +#define P_PARMS 3 +#define P_PRECOMPMERGE 4 + +#define P_LOGIC_AND 5 +#define P_LOGIC_OR 6 +#define P_LOGIC_GEQ 7 +#define P_LOGIC_LEQ 8 +#define P_LOGIC_EQ 9 +#define P_LOGIC_UNEQ 10 + +#define P_MUL_ASSIGN 11 +#define P_DIV_ASSIGN 12 +#define P_MOD_ASSIGN 13 +#define P_ADD_ASSIGN 14 +#define P_SUB_ASSIGN 15 +#define P_INC 16 +#define P_DEC 17 + +#define P_BIN_AND_ASSIGN 18 +#define P_BIN_OR_ASSIGN 19 +#define P_BIN_XOR_ASSIGN 20 +#define P_RSHIFT 21 +#define P_LSHIFT 22 + +#define P_POINTERREF 23 +#define P_CPP1 24 +#define P_CPP2 25 +#define P_MUL 26 +#define P_DIV 27 +#define P_MOD 28 +#define P_ADD 29 +#define P_SUB 30 +#define P_ASSIGN 31 + +#define P_BIN_AND 32 +#define P_BIN_OR 33 +#define P_BIN_XOR 34 +#define P_BIN_NOT 35 + +#define P_LOGIC_NOT 36 +#define P_LOGIC_GREATER 37 +#define P_LOGIC_LESS 38 + +#define P_REF 39 +#define P_COMMA 40 +#define P_SEMICOLON 41 +#define P_COLON 42 +#define P_QUESTIONMARK 43 + +#define P_PARENTHESESOPEN 44 +#define P_PARENTHESESCLOSE 45 +#define P_BRACEOPEN 46 +#define P_BRACECLOSE 47 +#define P_SQBRACKETOPEN 48 +#define P_SQBRACKETCLOSE 49 +#define P_BACKSLASH 50 + +#define P_PRECOMP 51 +#define P_DOLLAR 52 + +namespace pc { +game::script_s* load_script_file(const char* filename); +game::script_s* load_script_memory(const char* ptr, int length, + const char* name); +void free_script(game::script_s* script); +} // namespace pc diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp new file mode 100644 index 0000000..bd87001 --- /dev/null +++ b/src/client/component/branding.cpp @@ -0,0 +1,123 @@ +#include +#include "loader/component_loader.hpp" +#include "game/dvars.hpp" + +#include +#include + +#include + +namespace branding { +namespace { +#ifdef _DEBUG +constexpr auto* BUILD_TYPE = "IW4_DEV SP"; +#else +constexpr auto* BUILD_TYPE = "IW4 SP"; +#endif + +constexpr const char* get_build_number() { + return SHORTVERSION " latest " __DATE__ " " __TIME__; +} + +const char* get_version_string() { + const auto* result = utils::string::va( + "{} {} build {} {}", BUILD_TYPE, "(Alpha)", get_build_number(), + reinterpret_cast(0x6A1574)); + + return result; +} + +void dvar_set_version_string(const game::dvar_t* dvar, const char* /*value*/) { + const auto* result = get_version_string(); + utils::hook::invoke(0x480E70, dvar, result); +} + +void cg_draw_version() { + assert(game::ScrPlace_IsFullScreenActive()); + + // Default values + constexpr auto font_scale = 0.25f; + constexpr auto max_chars = std::numeric_limits::max(); + // Default colours + constexpr float shadow_color[] = {0.0f, 0.0f, 0.0f, 0.69f}; + constexpr float color[] = {0.4f, 0.69f, 1.0f, 0.69f}; + + auto* const placement = game::ScrPlace_GetUnsafeFullPlacement(); + auto* const font = game::UI_GetFontHandle(placement, 0, 0.583f); + + const auto width = game::UI_TextWidth((*dvars::version)->current.string, 0, + font, font_scale); + const auto height = game::UI_TextHeight(font, font_scale); + + // clang-format off + game::UI_DrawText(placement, (*dvars::version)->current.string, max_chars, + font, + 1.0f - (dvars::cg_drawVersionX->current.value + + static_cast(width)), + 1.0f - (dvars::cg_drawVersionY->current.value + + static_cast(height)), + 3, 3, font_scale, shadow_color, 0); + game::UI_DrawText(placement, (*dvars::version)->current.string, max_chars, + font, + (0.0f - static_cast(width)) - + dvars::cg_drawVersionX->current.value, + (0.0f - static_cast(height)) - + dvars::cg_drawVersionY->current.value, + 3, 3, font_scale, color, 0); + // clang-format on +} + +void cg_draw_full_screen_debug_overlays_stub(int local_client_num) { + assert(game::ScrPlace_IsFullScreenActive()); + + if (dvars::cg_drawVersion->current.enabled) { + cg_draw_version(); + } + + utils::hook::invoke(0x44BD00, local_client_num); +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + utils::hook(0x46F570, get_build_number, HOOK_JUMP).install()->quick(); + utils::hook(0x60429A, dvar_set_version_string, HOOK_CALL) + .install() + ->quick(); + + utils::hook::set(0x446A48, "iw4-sp: Console"); + utils::hook::set(0x50C110, "iw4-sp: Game"); + + utils::hook::set(0x579364, "iw4-sp: " SHORTVERSION "> "); + + // Com_Init_Try_Block_Function + utils::hook::set(0x604004, BUILD_TYPE); + utils::hook::set(0x603FFF, SHORTVERSION); + utils::hook::set(0x603FF5, __DATE__); + + register_branding_dvars(); + utils::hook(0x57DAFF, cg_draw_full_screen_debug_overlays_stub, HOOK_CALL) + .install() + ->quick(); + } + + static void register_branding_dvars() { +#ifdef _DEBUG + constexpr auto value = true; +#else + constexpr auto value = false; +#endif + dvars::cg_drawVersion = game::Dvar_RegisterBool( + "cg_drawVersion", value, game::DVAR_NONE, "Draw the game version"); + dvars::cg_drawVersionX = game::Dvar_RegisterFloat( + "cg_drawVersionX", 50.0f, 0.0f, 512.0f, game::DVAR_NONE, + "X offset for the version string"); + dvars::cg_drawVersionY = game::Dvar_RegisterFloat( + "cg_drawVersionY", 18.0f, 0.0f, 512.0f, game::DVAR_NONE, + "Y offset for the version string"); + } +}; +} // namespace branding + +REGISTER_COMPONENT(branding::component) diff --git a/src/client/component/ceg.cpp b/src/client/component/ceg.cpp new file mode 100644 index 0000000..6a85c33 --- /dev/null +++ b/src/client/component/ceg.cpp @@ -0,0 +1,38 @@ +#include +#include "loader/component_loader.hpp" + +#include + +namespace ceg { +class component final : public component_interface { +public: + void post_load() override { + // Some unnecessary CEG functions. + // Important functions are patched in the exe already + + utils::hook::set(0x44AD80, 0xC301B0); + utils::hook::set(0x476A20, 0xC301B0); + utils::hook::set(0x4E3B90, 0xC301B0); + utils::hook::set(0x4E3B90, 0xC301B0); + utils::hook::set(0x411160, 0xC301B0); + utils::hook::set(0x41E390, 0xC301B0); + utils::hook::set(0x47C2E0, 0xC301B0); + utils::hook::set(0x4EEA90, 0xC301B0); + utils::hook::set(0x40E380, 0xC301B0); + + // Killer caller + utils::hook::set(0x43F320, 0xC3); + utils::hook::set(0x458ED0, 0xC3); + utils::hook::set(0x47A140, 0xC3); + + utils::hook::nop(0x411166, 9); + + // Remove 'Steam Start' check + utils::hook::nop(0x43FAD5, 12); + // Shutdown + utils::hook::set(0x4619B0, 0xC3); + } +}; +} // namespace ceg + +REGISTER_COMPONENT(ceg::component) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp new file mode 100644 index 0000000..9c56ec1 --- /dev/null +++ b/src/client/component/command.cpp @@ -0,0 +1,152 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include +#include + +#include "command.hpp" + +namespace command { +namespace { +utils::hook::detour client_command_hook; + +std::unordered_map> handlers; +std::unordered_map> + handlers_sv; + +void main_handler() { + params params; + + const auto command = utils::string::to_lower(params[0]); + if (handlers.contains(command)) { + handlers[command](params); + } +} + +void client_command_stub(int client_num, const char* s) { + + auto* entity = &game::g_entities[client_num]; + + params_sv params; + + const auto command = utils::string::to_lower(params[0]); + const auto got = handlers_sv.find(command); + + if (got != handlers_sv.end()) { + got->second(entity, params); + return; + } + + client_command_hook.invoke(client_num, s); +} +} // namespace + +params::params() : nesting_(game::cmd_args->nesting) { + assert(game::cmd_args->nesting < game::CMD_MAX_NESTING); +} + +int params::size() const { return game::cmd_args->argc[this->nesting_]; } + +const char* params::get(const int index) const { + if (index >= this->size()) { + return ""; + } + + return game::cmd_args->argv[this->nesting_][index]; +} + +std::string params::join(const int index) const { + std::string result; + + for (auto i = index; i < this->size(); i++) { + if (i > index) + result.append(" "); + result.append(this->get(i)); + } + + return result; +} + +params_sv::params_sv() : nesting_(game::sv_cmd_args->nesting) { + assert(game::sv_cmd_args->nesting < game::CMD_MAX_NESTING); +} + +int params_sv::size() const { return game::sv_cmd_args->argc[this->nesting_]; } + +const char* params_sv::get(const int index) const { + if (index >= this->size()) { + return ""; + } + + return game::sv_cmd_args->argv[this->nesting_][index]; +} + +std::string params_sv::join(const int index) const { + std::string result; + + for (auto i = index; i < this->size(); i++) { + if (i > index) + result.append(" "); + result.append(this->get(i)); + } + + return result; +} + +void add_raw(const char* name, void (*callback)(), const int is_key) { + assert(is_key == 0 || is_key == 1); + + game::Cmd_AddCommand( + name, callback, + utils::memory::get_allocator()->allocate(), is_key); +} + +void add(const char* name, const std::function& callback) { + const auto command = utils::string::to_lower(name); + + if (!handlers.contains(command)) { + add_raw(name, main_handler); + } + + handlers[command] = callback; +} + +void add(const char* name, const std::function& callback) { + add(name, [callback](const params&) { callback(); }); +} + +void add_sv(const char* name, + std::function callback) { + const auto command = utils::string::to_lower(name); + + if (!handlers_sv.contains(command)) { + handlers_sv[command] = callback; + } +} + +void execute(std::string command, const bool sync) { + command += "\n"; + + if (sync) { + game::Cmd_ExecuteSingleCommand(0, 0, command.data()); + } else { + game::Cbuf_AddText(0, command.data()); + } +} + +class component final : public component_interface { +public: + static_assert(sizeof(game::cmd_function_s) == 0x18); + static_assert(offsetof(game::gentity_s, client) == 0x108); + + void post_load() override { + client_command_hook.create(0x4DF4B0, client_command_stub); + } + + void pre_destroy() override { client_command_hook.clear(); } +}; +} // namespace command + +REGISTER_COMPONENT(command::component) diff --git a/src/client/component/command.hpp b/src/client/component/command.hpp new file mode 100644 index 0000000..f34a625 --- /dev/null +++ b/src/client/component/command.hpp @@ -0,0 +1,40 @@ +#pragma once + +namespace command { +class params { +public: + params(); + + [[nodiscard]] int size() const; + [[nodiscard]] const char* get(int index) const; + [[nodiscard]] std::string join(int index) const; + + const char* operator[](const int index) const { return this->get(index); } + +private: + int nesting_; +}; + +class params_sv { +public: + params_sv(); + + [[nodiscard]] int size() const; + [[nodiscard]] const char* get(int index) const; + [[nodiscard]] std::string join(int index) const; + + const char* operator[](const int index) const { return this->get(index); } + +private: + int nesting_; +}; + +void add_raw(const char* name, void (*callback)(), int is_key = 0); +void add(const char* name, const std::function& callback); +void add(const char* name, const std::function& callback); + +void add_sv(const char* name, + std::function callback); + +void execute(std::string command, bool sync = false); +} // namespace command diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp new file mode 100644 index 0000000..fc6c6fb --- /dev/null +++ b/src/client/component/console.cpp @@ -0,0 +1,71 @@ +#include +#include "loader/component_loader.hpp" + +#include + +#include "dvar.hpp" + +namespace console { +namespace { +bool is_command; + +void con_toggle_console() { + game::Field_Clear(game::g_consoleField); + + if (game::conDrawInputGlob->matchIndex >= 0 && + game::conDrawInputGlob->autoCompleteChoice[0] != '\0') { + game::conDrawInputGlob->matchIndex = -1; + game::conDrawInputGlob->autoCompleteChoice[0] = '\0'; + } + + game::g_consoleField->widthInPixels = *game::g_console_field_width; + game::g_consoleField->charHeight = *game::g_console_char_height; + game::g_consoleField->fixedSize = 1; + game::con->outputVisible = false; + + // clientUIActives[0].keyCatchers + utils::hook::set(0x929140, + *reinterpret_cast(0x929140) ^ + game::KEYCATCH_CONSOLE); +} + +bool con_is_dvar_command_stub(const char* cmd) { + is_command = game::Con_IsDvarCommand(cmd); + return is_command; +} + +void cmd_for_each_stub(void (*callback)(const char* str)) { + if (!is_command) { + utils::hook::invoke(0x4B7000, callback); + } +} +} // namespace + +class component final : public component_interface { +public: + static_assert(sizeof(game::field_t) == 0x118); + static_assert(sizeof(game::ConDrawInputGlob) == 0x64); + + void post_start() override { + // Prevents console from opening + dvar::override::register_bool("monkeytoy", false, game::DVAR_NONE); + } + + void post_load() override { + utils::hook(0x44317E, con_toggle_console, HOOK_CALL) + .install() + ->quick(); // CL_KeyEvent + utils::hook(0x442E8E, con_toggle_console, HOOK_JUMP) + .install() + ->quick(); // CL_KeyEvent + + // Con_DrawInput + utils::hook(0x57946D, con_is_dvar_command_stub, HOOK_CALL) + .install() + ->quick(); + utils::hook(0x57951C, cmd_for_each_stub, HOOK_CALL).install()->quick(); + } +}; +} // namespace console + +REGISTER_COMPONENT(console::component) diff --git a/src/client/component/debug.cpp b/src/client/component/debug.cpp new file mode 100644 index 0000000..e3de982 --- /dev/null +++ b/src/client/component/debug.cpp @@ -0,0 +1,129 @@ +#include +#include "loader/component_loader.hpp" +#include "game/dvars.hpp" +#include "game/engine/scoped_critical_section.hpp" +#include "game/engine/large_local.hpp" + +#include + +#include "command.hpp" +#include "scheduler.hpp" + +namespace debug { +namespace { +void com_assert_f() { assert("a" && false); } + +void com_bug_f(const command::params& params) { + char new_file_name[0x105]{}; + char to_ospath[MAX_PATH]{}; + char from_ospath[MAX_PATH]{}; + const char* bug; + + if (!*game::logfile) { + game::Com_PrintError(game::CON_CHANNEL_ERROR, + "CopyFile failed: logfile wasn't opened\n"); + } + + if (params.size() == 2) { + bug = params.get(1); + } else { + assert(dvars::bug_name); + bug = dvars::bug_name->current.string; + } + + sprintf_s(new_file_name, "%s_%s.log", bug, game::Live_GetLocalClientName(0)); + + game::engine::scoped_critical_section _(game::CRITSECT_CONSOLE, + game::SCOPED_CRITSECT_NORMAL); + + if (*game::logfile) { + game::FS_FCloseFile(*game::logfile); + *game::logfile = 0; + } + + game::FS_BuildOSPath(std::filesystem::current_path().string().data(), "", + "console.log", from_ospath); + game::FS_BuildOSPath(std::filesystem::current_path().string().data(), "", + new_file_name, to_ospath); + const auto result = CopyFileA(from_ospath, to_ospath, 0); + game::Com_OpenLogFile(); + + if (!result) { + game::Com_PrintError(game::CON_CHANNEL_ERROR, "CopyFile failed(%d) %s %s\n", + GetLastError(), "console.log", new_file_name); + } +} + +void com_bug_name_inc_f() { + char buf[260]{}; + + if (std::strlen(dvars::bug_name->current.string) < 4) { + game::Dvar_SetString(dvars::bug_name, "bug0"); + return; + } + + if (std::strncmp(dvars::bug_name->current.string, "bug", 3) != 0) { + game::Dvar_SetString(dvars::bug_name, "bug0"); + return; + } + + const auto n = std::strtol(dvars::bug_name->current.string + 3, nullptr, 10); + sprintf_s(buf, "bug%d", n + 1); + game::Dvar_SetString(dvars::bug_name, buf); +} + +void g_print_fast_file_errors(const char* fastfile) { + assert(fastfile); + + game::engine::large_local rawfile_buf_large_local(0x18000); + auto* rawfile_buf = static_cast(rawfile_buf_large_local.get_buf()); + + auto* text = game::DB_ReadRawFile(fastfile, rawfile_buf, 0x18000); + + assert(text); + + if (*text) { + game::Com_PrintError(game::CON_CHANNEL_ERROR, + "There were errors when building fast file '%s'\n", + fastfile); + game::Com_PrintError(game::CON_CHANNEL_ERROR, "%s", text); + } +} + +void g_init_game_stub() { + utils::hook::invoke(0x4D6410); + + g_print_fast_file_errors("code_post_gfx"); + g_print_fast_file_errors("common"); + g_print_fast_file_errors((*dvars::sv_mapname)->current.string); +} +} // namespace + +class component final : public component_interface { +public: + static_assert(sizeof(RTL_CRITICAL_SECTION) == 0x18); + + void post_load() override { + utils::hook::set(0x604203, com_assert_f); + + scheduler::once( + [] { + dvars::bug_name = game::Dvar_RegisterString( + "bug_name", "bug0", game::DVAR_CHEAT | game::DVAR_CODINFO, + "Name appended to the copied console log"); + }, + scheduler::pipeline::main); + + command::add("bug", com_bug_f); + command::add("bug_name_inc", com_bug_name_inc_f); + +#ifdef _DEBUG + utils::hook(0x4C79DF, g_init_game_stub, HOOK_CALL) + .install() + ->quick(); // Scr_FreeEntityList +#endif + } +}; +} // namespace debug + +REGISTER_COMPONENT(debug::component) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp new file mode 100644 index 0000000..1c90a26 --- /dev/null +++ b/src/client/component/discord.cpp @@ -0,0 +1,77 @@ +#include +#include "loader/component_loader.hpp" + +#include + +#include "scheduler.hpp" + +using namespace std::literals; + +namespace discord { +namespace { +DiscordRichPresence discord_presence; + +void update_discord() { + Discord_RunCallbacks(); + + if (!discord_presence.startTimestamp) { + discord_presence.startTimestamp = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + } + + Discord_UpdatePresence(&discord_presence); +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + DiscordEventHandlers handlers; + ZeroMemory(&handlers, sizeof(handlers)); + handlers.ready = ready; + handlers.errored = errored; + handlers.disconnected = errored; + handlers.joinGame = nullptr; + handlers.spectateGame = nullptr; + handlers.joinRequest = nullptr; + + Discord_Initialize("978049907585863710", &handlers, 1, nullptr); + + scheduler::once( + [] { + scheduler::once(update_discord, scheduler::pipeline::async); + scheduler::loop(update_discord, scheduler::pipeline::async, 15s); + }, + scheduler::pipeline::main); + + initialized_ = true; + } + + void pre_destroy() override { + if (initialized_) { + Discord_Shutdown(); + } + } + +private: + bool initialized_ = false; + + static void ready(const DiscordUser* request) { + ZeroMemory(&discord_presence, sizeof(discord_presence)); + + discord_presence.state = "Singleplayer"; + discord_presence.instance = 1; + discord_presence.startTimestamp = 0; + printf("Discord: Ready\n"); + Discord_UpdatePresence(&discord_presence); + } + + static void errored(const int error_code, const char* message) { + printf("Discord: (%i) %s", error_code, message); + } +}; +} // namespace discord + +REGISTER_COMPONENT(discord::component) diff --git a/src/client/component/dvar.cpp b/src/client/component/dvar.cpp new file mode 100644 index 0000000..e83e4ea --- /dev/null +++ b/src/client/component/dvar.cpp @@ -0,0 +1,172 @@ + +#include +#include "loader/component_loader.hpp" + +#include + +#include "dvar.hpp" + +namespace dvar { +struct dvar_base { + std::uint16_t flags{}; +}; + +struct dvar_bool : dvar_base { + bool value{}; +}; + +struct dvar_float : dvar_base { + float value{}; + float min{}; + float max{}; +}; + +struct dvar_int : dvar_base { + int value{}; + int min{}; + int max{}; +}; + +struct dvar_string : dvar_base { + std::string value{}; +}; + +namespace { +template +T* find_dvar(std::unordered_map& map, const std::string& name) { + auto i = map.find(name); + if (i != map.end()) { + return &i->second; + } + + return nullptr; +} +} // namespace + +namespace override { +static std::unordered_map register_bool_overrides; +static std::unordered_map register_float_overrides; +static std::unordered_map register_int_overrides; +static std::unordered_map register_string_overrides; + +void register_bool(const std::string& name, const bool value, + const std::uint16_t flags) { + dvar_bool values; + values.value = value; + values.flags = flags; + register_bool_overrides[name] = values; +} + +void register_float(const std::string& name, const float value, const float min, + const float max, const std::uint16_t flags) { + dvar_float values; + values.value = value; + values.min = min; + values.max = max; + values.flags = flags; + register_float_overrides[name] = values; +} + +void register_int(const std::string& name, const int value, const int min, + const int max, const std::uint16_t flags) { + dvar_int values; + values.value = value; + values.min = min; + values.max = max; + values.flags = flags; + register_int_overrides[name] = values; +} + +void register_string(const std::string& name, const std::string& value, + const std::uint16_t flags) { + dvar_string values; + values.value = value; + values.flags = flags; + register_string_overrides[name] = values; +} +} // namespace override + +namespace { +utils::hook::detour dvar_register_bool_hook; +utils::hook::detour dvar_register_float_hook; +utils::hook::detour dvar_register_int_hook; +utils::hook::detour dvar_register_string_hook; + +const game::dvar_t* dvar_register_bool_stub(const char* name, bool value, + std::uint16_t flags, + const char* description) { + auto* var = find_dvar(override::register_bool_overrides, name); + if (var) { + value = var->value; + flags = var->flags; + } + + return dvar_register_bool_hook.invoke(name, value, flags, + description); +} + +const game::dvar_t* dvar_register_float_stub(const char* name, float value, + float min, float max, + std::uint16_t flags, + const char* description) { + auto* var = find_dvar(override::register_float_overrides, name); + if (var) { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_float_hook.invoke( + name, value, min, max, flags, description); +} + +const game::dvar_t* dvar_register_int_stub(const char* name, int value, int min, + int max, std::uint16_t flags, + const char* description) { + auto* var = find_dvar(override::register_int_overrides, name); + if (var) { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_int_hook.invoke( + name, value, min, max, flags, description); +} + +const game::dvar_t* dvar_register_string_stub(const char* name, + const char* value, + std::uint16_t flags, + const char* description) { + auto* var = find_dvar(override::register_string_overrides, name); + if (var) { + value = var->value.data(); + flags = var->flags; + } + + return dvar_register_string_hook.invoke( + name, value, flags, description); +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + dvar_register_bool_hook.create(0x429390, &dvar_register_bool_stub); + dvar_register_float_hook.create(0x4051D0, &dvar_register_float_stub); + dvar_register_int_hook.create(0x4E9490, &dvar_register_int_stub); + dvar_register_string_hook.create(0x49E0B0, &dvar_register_string_stub); + } + + void pre_destroy() override { + dvar_register_bool_hook.clear(); + dvar_register_float_hook.clear(); + dvar_register_int_hook.clear(); + dvar_register_string_hook.clear(); + } +}; +} // namespace dvar + +REGISTER_COMPONENT(dvar::component) diff --git a/src/client/component/dvar.hpp b/src/client/component/dvar.hpp new file mode 100644 index 0000000..66901ae --- /dev/null +++ b/src/client/component/dvar.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace dvar { +namespace override { +void register_bool(const std::string& name, bool value, std::uint16_t flags); +void register_float(const std::string& name, float value, float min, float max, + std::uint16_t flags); +void register_int(const std::string& name, int value, int min, int max, + std::uint16_t flags); +void register_string(const std::string& name, const std::string& value, + std::uint16_t flags); +} // namespace override +} // namespace dvar diff --git a/src/client/component/dvar_patches.cpp b/src/client/component/dvar_patches.cpp new file mode 100644 index 0000000..f709941 --- /dev/null +++ b/src/client/component/dvar_patches.cpp @@ -0,0 +1,68 @@ +#include +#include "loader/component_loader.hpp" + +#include + +#include "scheduler.hpp" +#include "dvar.hpp" + +namespace dvar_patches { +namespace { +const game::dvar_t* dvar_register_name(const char* dvar_name, const char* value, + unsigned __int16 flags, + const char* description) { + return game::Dvar_RegisterString( + dvar_name, value, game::DVAR_ARCHIVE | game::DVAR_USERINFO, description); +} +} // namespace + +class component final : public component_interface { +public: + void post_start() override { + dvar::override::register_bool("intro", true, game::DVAR_NONE); + dvar::override::register_float("cg_fov", 65.0f, 65.0f, 160.0f, + game::DVAR_ARCHIVE); + dvar::override::register_string("fs_basegame", BASEGAME, game::DVAR_INIT); + +#ifdef _DEBUG + dvar::override::register_bool("sv_cheats", true, game::DVAR_NONE); +#endif + } + + void post_load() override { + utils::hook(0x475156, dvar_register_name, HOOK_CALL).install()->quick(); + patch_sp(); + } + +private: + static void patch_sp() { + utils::hook::set(0x635841, 0xEB); // Read only + utils::hook::set(0x635913, 0xEB); // Cheat protected + utils::hook::set(0x6358A5, 0xEB); // Write protected + utils::hook::set(0x635974, 0xEB); // Latched + +#ifdef _DEBUG + // Nop Dvar_RegisterVariant for sv_cheats in Dvar_Init + utils::hook::nop(0x471522, 5); +#endif + + // Skip dvar output + utils::hook::set(0x4CD2B7, 0xEB); + + // Ignore server dvar change for clients + utils::hook::set(0x63580B, 0xEB); + + scheduler::once( + [] { + game::Dvar_RegisterBool("scr_damageFeedback", true, game::DVAR_NONE, + "Show marker when hitting enemies"); + game::Dvar_RegisterString("connect_ip", "127.0.0.1:28960", + game::DVAR_NONE, + "Temporary dvar used to connect"); + }, + scheduler::pipeline::main); + } +}; +} // namespace dvar_patches + +REGISTER_COMPONENT(dvar_patches::component) diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp new file mode 100644 index 0000000..d945013 --- /dev/null +++ b/src/client/component/filesystem.cpp @@ -0,0 +1,82 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include + +#include "game_module.hpp" +#include "filesystem.hpp" + +namespace filesystem { +namespace { +const char* sys_default_install_path_stub() { + static auto current_path = std::filesystem::current_path().string(); + return current_path.data(); +} +} // namespace + +std::vector vectored_file_list(const std::string& path, + const std::string& extension) { + std::vector file_list; + + auto num_files = 0; + const auto** files = game::FS_ListFiles(path.data(), extension.data(), + game::FS_LIST_ALL, &num_files, 10); + + if (files) { + for (auto i = 0; i < num_files; ++i) { + if (files[i]) { + file_list.emplace_back(files[i]); + } + } + + game::FS_FreeFileList(files, 10); + } + + return file_list; +} + +std::string get_binary_directory() { + const auto dir = game_module::get_host_module().get_folder(); + return utils::string::replace(dir, "/", "\\"); +} + +file::file(std::string name, game::FsThread thread) : name_(std::move(name)) { + assert(!this->name_.empty()); + + auto handle = 0; + const auto len = + game::FS_FOpenFileReadForThread(name_.data(), &handle, thread); + + if (!handle) { + this->valid_ = false; + return; + } + + auto* buf = static_cast(game::Hunk_AllocateTempMemory(len + 1)); + game::FS_Read(buf, len, handle); + buf[len] = '\0'; + + game::FS_FCloseFile(handle); + + this->valid_ = true; + this->buffer_.append(buf, len); +} + +bool file::exists() const { return this->valid_; } + +const std::string& file::get_buffer() const { return this->buffer_; } + +const std::string& file::get_name() const { return this->name_; } + +class component final : public component_interface { +public: + void post_load() override { + utils::hook(0x465B90, sys_default_install_path_stub, HOOK_CALL) + .install() + ->quick(); // Sys_CreateFile + } +}; +} // namespace filesystem + +REGISTER_COMPONENT(filesystem::component) diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp new file mode 100644 index 0000000..177e3ca --- /dev/null +++ b/src/client/component/filesystem.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace filesystem { +std::vector vectored_file_list(const std::string& path, + const std::string& extension); +std::string get_binary_directory(); + +class file { +public: + file(std::string name, game::FsThread thread); + + [[nodiscard]] bool exists() const; + [[nodiscard]] const std::string& get_buffer() const; + [[nodiscard]] const std::string& get_name() const; + +private: + bool valid_ = false; + std::string name_; + std::string buffer_; +}; +} // namespace filesystem diff --git a/src/client/component/game_log.cpp b/src/client/component/game_log.cpp new file mode 100644 index 0000000..ac34055 --- /dev/null +++ b/src/client/component/game_log.cpp @@ -0,0 +1,115 @@ +#include +#include "loader/component_loader.hpp" +#include "game/dvars.hpp" + +#include + +#include "gsc/extension.hpp" + +#include "game_log.hpp" +#include "scheduler.hpp" + +namespace game_log { +namespace { +int log_file = 0; + +void g_scr_log_print() { + char string[1024]{}; + std::size_t i_string_len = 0; + + const auto i_num_parms = game::Scr_GetNumParam(); + for (std::size_t i = 0; i < i_num_parms; ++i) { + const auto* psz_token = game::Scr_GetString(i); + const auto i_token_len = std::strlen(psz_token); + + i_string_len += i_token_len; + if (i_string_len >= sizeof(string)) { + // Do not overflow the buffer + break; + } + + strncat_s(string, psz_token, _TRUNCATE); + } + + log_printf("%s", string); +} + +void g_init_game_stub() { + game::Com_Printf(game::CON_CHANNEL_SERVER, + "------- Game Initialization -------\n"); + game::Com_Printf(game::CON_CHANNEL_SERVER, "gamename: iw4-sp\n"); + game::Com_Printf(game::CON_CHANNEL_SERVER, "gamedate: %s\n", __DATE__); + + if (*dvars::g_log->current.string == '\0') { + game::Com_Printf(game::CON_CHANNEL_SERVER, "Not logging to disk.\n"); + } else { + game::FS_FOpenFileByMode(dvars::g_log->current.string, &log_file, + game::FS_APPEND_SYNC); + + if (!log_file) { + game::Com_PrintWarning(game::CON_CHANNEL_SERVER, + "WARNING: Couldn't open logfile: %s\n"); + } else { + log_printf( + "------------------------------------------------------------\n"); + log_printf("InitGame\n"); + } + } + + utils::hook::invoke(0x4FA880); // Vehicle_ClearServerDefs +} + +void g_shutdown_game_stub() { + if (log_file) { + log_printf("ShutdownGame:\n"); + log_printf( + "------------------------------------------------------------\n"); + + game::FS_FCloseFile(log_file); + log_file = 0; + } + + utils::hook::invoke(0x455F90); // Actor_ClearThreatBiasGroups +} +} // namespace + +void log_printf(const char* fmt, ...) { + char string[1024]{}; + char string2[1024]{}; + va_list ap; + + if (!log_file) { + return; + } + + va_start(ap, fmt); + vsnprintf_s(string2, _TRUNCATE, fmt, ap); + va_end(ap); + + const auto time = game::level->time / 1000; + const auto len = sprintf_s(string, "%3i:%i%i %s", time / 60, time % 60 / 10, + time % 60 % 10, string2); + game::FS_Write(string, len, log_file); +} + +class component final : public component_interface { +public: + static_assert(offsetof(game::level_locals_t, time) == 0x34); + + void post_load() override { + utils::hook(0x4C75E0, g_init_game_stub, HOOK_CALL).install()->quick(); + utils::hook(0x418B5A, g_shutdown_game_stub, HOOK_CALL).install()->quick(); + + scheduler::once( + [] { + dvars::g_log = game::Dvar_RegisterString( + "g_log", "games_sp.log", game::DVAR_NONE, "Log file name"); + }, + scheduler::pipeline::main); + + gsc::add_function("logprint", g_scr_log_print); + } +}; +} // namespace game_log + +REGISTER_COMPONENT(game_log::component) diff --git a/src/client/component/game_log.hpp b/src/client/component/game_log.hpp new file mode 100644 index 0000000..7e39c34 --- /dev/null +++ b/src/client/component/game_log.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace game_log { +void log_printf(const char* fmt, ...); +} diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp new file mode 100644 index 0000000..40ff3ad --- /dev/null +++ b/src/client/component/game_module.cpp @@ -0,0 +1,110 @@ +#include +#include "loader/component_loader.hpp" + +#ifdef INJECT_HOST_AS_LIB +#include +#endif + +#include + +#include "game_module.hpp" + +namespace game_module { +#ifdef INJECT_HOST_AS_LIB +namespace { +utils::hook::detour handle_a_hook; +utils::hook::detour handle_w_hook; +utils::hook::detour handle_ex_a_hook; +utils::hook::detour handle_ex_w_hook; +utils::hook::detour file_name_a_hook; +utils::hook::detour file_name_w_hook; + +HMODULE WINAPI get_module_handle_a(const LPCSTR module_name) { + if (!module_name) { + return get_game_module(); + } + + return handle_a_hook.invoke(module_name); +} + +HMODULE WINAPI get_module_handle_w(const LPWSTR module_name) { + if (!module_name) { + return get_game_module(); + } + + return handle_w_hook.invoke(module_name); +} + +BOOL WINAPI get_module_handle_ex_a(const DWORD flags, const LPCSTR module_name, + HMODULE* hmodule) { + if (!module_name) { + *hmodule = get_game_module(); + return TRUE; + } + + return handle_ex_a_hook.invoke(flags, module_name, hmodule); +} + +BOOL WINAPI get_module_handle_ex_w(const DWORD flags, const LPCWSTR module_name, + HMODULE* hmodule) { + if (!module_name) { + *hmodule = get_game_module(); + return TRUE; + } + + return handle_ex_w_hook.invoke(flags, module_name, hmodule); +} + +DWORD WINAPI get_module_file_name_a(HMODULE hmodule, const LPSTR filename, + const DWORD size) { + if (!hmodule) { + hmodule = get_game_module(); + } + + return file_name_a_hook.invoke(hmodule, filename, size); +} + +DWORD WINAPI get_module_file_name_w(HMODULE hmodule, const LPWSTR filename, + const DWORD size) { + if (!hmodule || utils::nt::library(hmodule) == get_game_module()) { + hmodule = get_host_module(); + } + + return file_name_w_hook.invoke(hmodule, filename, size); +} + +void hook_module_resolving() { + handle_a_hook.create(&GetModuleHandleA, &get_module_handle_a); + handle_w_hook.create(&GetModuleHandleW, &get_module_handle_w); + handle_ex_w_hook.create(&GetModuleHandleExA, &get_module_handle_ex_a); + handle_ex_w_hook.create(&GetModuleHandleExW, &get_module_handle_ex_w); + file_name_a_hook.create(&GetModuleFileNameA, &get_module_file_name_a); + file_name_w_hook.create(&GetModuleFileNameW, &get_module_file_name_w); +} +} // namespace +#endif + +utils::nt::library get_game_module() { + static utils::nt::library game{reinterpret_cast(0x400000)}; + return game; +} + +utils::nt::library get_host_module() { + static utils::nt::library host{}; + return host; +} +class component final : public component_interface { +public: + void post_start() override { get_host_module(); } + + void post_load() override { +#ifdef INJECT_HOST_AS_LIB + hook_module_resolving(); +#else + assert(get_host_module() == get_game_module()); +#endif + } +}; +} // namespace game_module + +REGISTER_COMPONENT(game_module::component) diff --git a/src/client/component/game_module.hpp b/src/client/component/game_module.hpp new file mode 100644 index 0000000..e43f6de --- /dev/null +++ b/src/client/component/game_module.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace game_module { +utils::nt::library get_game_module(); +utils::nt::library get_host_module(); +} // namespace game_module diff --git a/src/client/component/gsc/extension.cpp b/src/client/component/gsc/extension.cpp new file mode 100644 index 0000000..ea7c200 --- /dev/null +++ b/src/client/component/gsc/extension.cpp @@ -0,0 +1,126 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include + +#include "extension.hpp" + +namespace gsc { +#define GSC_DEBUG_FUNCTIONS + +namespace { +struct script_function_def { + game::BuiltinFunction actionFunc; + bool type; +}; + +struct script_method_def { + game::BuiltinMethod actionFunc; + bool type; +}; + +std::unordered_map custom_scr_funcs; +std::unordered_map custom_scr_meths; + +game::BuiltinFunction built_in_get_function_stub(const char** p_name, + int* type) { + if (p_name) { + const auto itr = custom_scr_funcs.find(utils::string::to_lower(*p_name)); + if (itr != custom_scr_funcs.end()) { + *type = itr->second.type; + return itr->second.actionFunc; + } + } else { + for (const auto& [name, func] : custom_scr_funcs) { + game::Scr_RegisterFunction(reinterpret_cast(func.actionFunc), + name.data()); + } + } + + // If no function was found let's call BuiltIn_GetFunction + return utils::hook::invoke(0x4DD160, p_name, type); +} + +game::BuiltinMethod built_in_get_method_stub(const char** p_name, int* type) { + if (p_name) { + const auto itr = custom_scr_meths.find(utils::string::to_lower(*p_name)); + if (itr != custom_scr_meths.end()) { + *type = itr->second.type; + return itr->second.actionFunc; + } + } else { + for (const auto& [name, meth] : custom_scr_meths) { + game::Scr_RegisterFunction(reinterpret_cast(meth.actionFunc), + name.data()); + } + } + + // If no method was found let's call BuiltIn_GetMethod + return utils::hook::invoke(0x5DB850, p_name, type); +} +} // namespace + +void add_function(const char* name, game::BuiltinFunction func, bool type) { + script_function_def def; + def.actionFunc = func; + def.type = type; + + custom_scr_funcs.emplace(utils::string::to_lower(name), def); +} + +void add_method(const char* name, game::BuiltinMethod func, bool type) { + script_method_def def; + def.actionFunc = func; + def.type = type; + + custom_scr_meths.emplace(utils::string::to_lower(name), def); +} + +class extension final : public component_interface { +public: + void post_load() override { + // Fetch custom functions + utils::hook(0x4ADF9C, built_in_get_function_stub, HOOK_CALL) + .install() + ->quick(); // Scr_GetFunction + + utils::hook(0x444827, built_in_get_method_stub, HOOK_CALL) + .install() + ->quick(); // Scr_GetMethod + + add_functions(); +#ifdef GSC_DEBUG_FUNCTIONS + add_debug_functions(); +#endif + } + + static void add_functions() { + add_function("Float", [] { + switch (game::Scr_GetType(0)) { + case game::VAR_STRING: + game::Scr_AddFloat( + static_cast(std::atof(game::Scr_GetString(0)))); + break; + case game::VAR_FLOAT: + game::Scr_AddFloat(game::Scr_GetFloat(0)); + break; + case game::VAR_INTEGER: + game::Scr_AddFloat(static_cast(game::Scr_GetInt(0))); + break; + default: + game::Scr_ParamError(0, utils::string::va("cannot cast {0} to float", + game::Scr_GetTypeName(0))); + break; + } + }); + } + + static void add_debug_functions() { + add_function("AddDebugCommand", + [] { game::Cbuf_AddText(0, game::Scr_GetString(0)); }); + } +}; +} // namespace gsc + +REGISTER_COMPONENT(gsc::extension) diff --git a/src/client/component/gsc/extension.hpp b/src/client/component/gsc/extension.hpp new file mode 100644 index 0000000..6fa2ce1 --- /dev/null +++ b/src/client/component/gsc/extension.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace gsc { +void add_function(const char* name, game::BuiltinFunction func, + bool type = false); +void add_method(const char* name, game::BuiltinMethod func, bool type = false); +} // namespace gsc diff --git a/src/client/component/gsc/loading.cpp b/src/client/component/gsc/loading.cpp new file mode 100644 index 0000000..a393c71 --- /dev/null +++ b/src/client/component/gsc/loading.cpp @@ -0,0 +1,88 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include + +namespace gsc { +namespace { +std::vector main_handles; +std::vector init_handles; + +// Do not use C++ objects because Scr_LoadScript may longjmp +void g_scr_load_scripts_stub() { + // Clear handles (from previous GSC loading session) + main_handles.clear(); + init_handles.clear(); + + char path[MAX_PATH]{}; + + auto num_files = 0; + const auto** files = + game::FS_ListFiles("scripts/", "gsc", game::FS_LIST_ALL, &num_files, 10); + + for (auto i = 0; i < num_files; ++i) { + const auto* script_file = files[i]; + game::Com_Printf(game::CON_CHANNEL_SERVER, "Loading script %s...\n", + script_file); + + const auto len = sprintf_s(path, "%s/%s", "scripts", script_file); + if (len == -1) { + continue; + } + + // Scr_LoadScriptInternal will add the '.gsc' suffix so we remove it + path[len - 4] = '\0'; + + if (!game::Scr_LoadScript(path)) { + game::Com_Printf(game::CON_CHANNEL_SERVER, + "Script %s encountered an error while loading\n", path); + continue; + } + + game::Com_Printf(game::CON_CHANNEL_SERVER, + "Script %s.gsc loaded successfully\n", path); + + const auto main_handle = game::Scr_GetFunctionHandle(path, "main"); + if (main_handle) { + main_handles.push_back(main_handle); + } + + const auto init_handle = game::Scr_GetFunctionHandle(path, "init"); + if (init_handle) { + init_handles.push_back(init_handle); + } + // Allow scripts with no handles + } + + game::FS_FreeFileList(files, 10); +} + +void scr_load_level_stub() { + for (const auto& handle : main_handles) { + const auto id = game::Scr_ExecThread(handle, 0); + game::Scr_FreeThread(static_cast(id)); + } + + utils::hook::invoke(0x470860); // Scr_LoadLevel + + for (const auto& handle : init_handles) { + const auto id = game::Scr_ExecThread(handle, 0); + game::Scr_FreeThread(static_cast(id)); + } +} +} // namespace + +class loading final : public component_interface { +public: + void post_load() override { + utils::hook(0x4054C2, g_scr_load_scripts_stub, HOOK_JUMP) + .install() + ->quick(); + + utils::hook(0x4C1E34, scr_load_level_stub, HOOK_CALL).install()->quick(); + } +}; +} // namespace gsc + +REGISTER_COMPONENT(gsc::loading) diff --git a/src/client/component/gsc/string.cpp b/src/client/component/gsc/string.cpp new file mode 100644 index 0000000..adac45f --- /dev/null +++ b/src/client/component/gsc/string.cpp @@ -0,0 +1,83 @@ +#include +#include "loader/component_loader.hpp" + +#include "extension.hpp" + +namespace gsc { +namespace { +void scr_str_i_cmp() { + const auto* string1 = game::SL_ConvertToString(game::Scr_GetConstString(0)); + const auto* string2 = game::SL_ConvertToString(game::Scr_GetConstString(1)); + + game::Scr_AddInt(game::I_stricmp(string1, string2)); +} + +void scr_is_end_str() { + const auto* str = game::Scr_GetString(0); + const auto* suffix = game::Scr_GetString(1); + + const auto str_len = std::strlen(str); + const auto suffix_len = std::strlen(suffix); + + if (suffix_len > str_len) { + game::Scr_AddInt(0); + return; + } + + game::Scr_AddInt( + std::memcmp(str + str_len - suffix_len, suffix, suffix_len) == 0); +} + +void scr_to_upper() { + const auto script_value = game::Scr_GetConstString(0); + const auto* string = game::SL_ConvertToString(script_value); + + char out[1024]{}; + bool changed = false; + + std::size_t i = 0; + while (i < sizeof(out)) { + const auto value = *string; + const auto result = + static_cast(std::toupper(static_cast(value))); + + out[i] = result; + + if (value != result) { + changed = true; + } + + if (result == '\0') { + break; + } + + ++string; + ++i; + } + + if (i >= sizeof(out)) { + game::Scr_Error("string too long"); + return; + } + + if (changed) { + game::Scr_AddString(out); + } else { + game::SL_AddRefToString(script_value); + game::Scr_AddConstString(script_value); + game::SL_RemoveRefToString(script_value); + } +} +} // namespace + +class string final : public component_interface { +public: + void post_load() override { + add_function("StrICmp", scr_str_i_cmp); + add_function("IsEndStr", scr_is_end_str); + add_function("ToUpper", scr_to_upper); + } +}; +} // namespace gsc + +REGISTER_COMPONENT(gsc::string) diff --git a/src/client/component/images.cpp b/src/client/component/images.cpp new file mode 100644 index 0000000..c6d962d --- /dev/null +++ b/src/client/component/images.cpp @@ -0,0 +1,16 @@ +#include +#include "loader/component_loader.hpp" + +#include + +namespace images { +class component final : public component_interface { +public: + void post_load() override { + // Skip version check + utils::hook::set(0x544746, 0xEB); + } +}; +} // namespace images + +REGISTER_COMPONENT(images::component) diff --git a/src/client/component/lean.cpp b/src/client/component/lean.cpp new file mode 100644 index 0000000..3825118 --- /dev/null +++ b/src/client/component/lean.cpp @@ -0,0 +1,73 @@ +#include +#include "loader/component_loader.hpp" + +#include + +#include "command.hpp" + +namespace lean { +namespace { +game::kbutton_t in_lean_left; +game::kbutton_t in_lean_right; + +void in_lean_left_down() { game::IN_KeyDown(&in_lean_left); } + +void in_lean_left_up() { game::IN_KeyUp(&in_lean_left); } + +void in_lean_right_down() { game::IN_KeyDown(&in_lean_right); } + +void in_lean_right_up() { game::IN_KeyUp(&in_lean_right); } + +void set_lean_flags(game::usercmd_s* cmd) { + if (in_lean_left.active || in_lean_left.wasPressed) { + cmd->buttons |= game::CMD_BUTTON_LEAN_LEFT; + } + + if (in_lean_right.active || in_lean_right.wasPressed) { + cmd->buttons |= game::CMD_BUTTON_LEAN_RIGHT; + } + + in_lean_left.wasPressed = false; + in_lean_right.wasPressed = false; +} + +void __declspec(naked) cl_cmd_buttons_stub() { + __asm { + pushad; + + push esi; + call set_lean_flags; + add esp, 0x4; + + popad; + + // code skipped by our hook + mov eax, ecx; + imul eax, eax, 0x21C; + + // CL_CmdButton + push 0x57B2B8; + ret; + } +} +} // namespace + +class component final : public component_interface { +public: + static_assert(sizeof(game::kbutton_t) == 0x14); + static_assert(sizeof(game::usercmd_s) == 0x40); + + void post_load() override { + command::add_raw("+leanleft", in_lean_left_down, TRUE); + command::add_raw("-leanleft", in_lean_left_up, TRUE); + + command::add_raw("+leanright", in_lean_right_down, TRUE); + command::add_raw("-leanright", in_lean_right_up, TRUE); + + utils::hook(0x57B2B0, cl_cmd_buttons_stub, HOOK_JUMP).install()->quick(); + utils::hook::nop(0x57B2B0 + 5, 3); + } +}; +} // namespace lean + +REGISTER_COMPONENT(lean::component) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp new file mode 100644 index 0000000..11ae9d1 --- /dev/null +++ b/src/client/component/network.cpp @@ -0,0 +1,83 @@ +#include +#include "loader/component_loader.hpp" + +#include "command.hpp" +#include "network.hpp" + +#include +#include + +namespace network { +namespace { +void cl_co_op_connect(const command::params& params) { + // Valid format is IP Port + if (params.size() < 3) { + return; + } + + const auto input = std::strtol(params.get(2), nullptr, 10); + const auto port = ::htons(static_cast(input)); + + command::execute( + utils::string::va("connect_coop {0} {1}", params.get(1), port)); +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { patch_sp(); } + +private: + static void patch_sp() { + // Ignore protocol mismatch + utils::hook::set(0x65D0C2, 0xEB); + utils::hook::set(0x65D0ED, 0xEB); + + // Disable matchmaking stuff + utils::hook::set(0x43BAE0, 0xEB); + + // Ignore 'MAX_PACKET_USERCMDS' + utils::hook::set(0x4B1436, 0xEB); + + // Disable IWNet stuff + utils::hook::set(0x44E824, 0xEB); + utils::hook::set(0x44E808, 0xEB); + + // Disable MP packet handler + utils::hook::set(0x65E717, 0xEB); + + // Disable LSP packet handler + utils::hook::set(0x65E3A4, 0xEB); + + // Avoid spam + utils::hook(0x65E786, game::Com_DPrintf, HOOK_CALL).install()->quick(); + utils::hook(0x65D659, game::Com_DPrintf, HOOK_CALL).install()->quick(); + + // Disable BigShort in NET_AdrToString + utils::hook(0x4BF4D1, game::ShortNoSwap, HOOK_CALL).install()->quick(); + utils::hook(0x4BF50C, game::ShortNoSwap, HOOK_CALL).install()->quick(); + + // Fix NET_StringToAdr (Only known workaround that actually works) + utils::hook::set(0x475417, "connect_coop"); + command::add("connect", cl_co_op_connect); + + // Disable BigShort in GetLocalAddressForEncryptedConnection + utils::hook(0x4CF42D, game::ShortNoSwap, HOOK_CALL).install()->quick(); + + // Parse port as unsigned short in Net_AddrToString + utils::hook::set(0x4BF4F3, "%u.%u.%u.%u:%hu"); + + // Force Win socket initialization + utils::hook::nop(0x42B649, 2); + + // Kill LSP + utils::hook::set(0x4553F0, 0xC3); // Hello + utils::hook::set(0x428D00, 0xC3); // LSP_SendLogRequest + utils::hook::set(0x4D13C0, 0xC3); // LSP_ParsePacket + utils::hook::set(0x66D440, 0xC3); // LSP_AddKeepAlive + utils::hook::nop(0x494E68, 5); // Don't create LSP socket + } +}; +} // namespace network + +REGISTER_COMPONENT(network::component) diff --git a/src/client/component/network.hpp b/src/client/component/network.hpp new file mode 100644 index 0000000..3a91e39 --- /dev/null +++ b/src/client/component/network.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace network { +using callback = std::function; +} diff --git a/src/client/component/no_border.cpp b/src/client/component/no_border.cpp new file mode 100644 index 0000000..a58423b --- /dev/null +++ b/src/client/component/no_border.cpp @@ -0,0 +1,43 @@ +#include +#include "loader/component_loader.hpp" +#include "game/dvars.hpp" + +#include + +namespace no_border { +namespace { +void __declspec(naked) window_style_stub() { + __asm { + push eax; + mov eax, dvars::r_noBorder; + cmp byte ptr [eax + 0x10], 1; + pop eax; + + je remove_border; + + mov ebp, WS_VISIBLE | WS_SYSMENU | WS_CAPTION; + jmp safe_return; + + remove_border: + mov ebp, WS_VISIBLE | WS_POPUP; + + safe_return: + push 0x50C0B8; + ret; + } +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + utils::hook(0x50C0B3, window_style_stub, HOOK_JUMP).install()->quick(); + + dvars::r_noBorder = + game::Dvar_RegisterBool("r_noBorder", false, game::DVAR_ARCHIVE, + "Do not use a border in windowed mode"); + } +}; +} // namespace no_border + +REGISTER_COMPONENT(no_border::component) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp new file mode 100644 index 0000000..000bbff --- /dev/null +++ b/src/client/component/patches.cpp @@ -0,0 +1,103 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include + +#include "command.hpp" +#include "filesystem.hpp" + +namespace patches { +namespace { +void sys_init_stub() { + game::Cmd_SetAutoComplete("exec", "", "cfg"); + utils::hook::invoke(0x4EEB20); +} + +void cl_play_unskippable_cinematic_f() { + // CL_PlayCinematic_f + utils::hook::invoke(0x4CC950); + *game::cin_skippable = true; +} + +void cl_start_multiplayer_f() { + utils::nt::update_dll_search_path(filesystem::get_binary_directory()); + utils::nt::launch_process("iw4mp.exe", "-multiplayer"); + command::execute("quit", false); +} + +const char* live_get_local_client_name_stub() { + return game::Dvar_FindVar("name")->current.string; +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + utils::hook(0x6042A2, sys_init_stub, HOOK_CALL).install()->quick(); + + utils::hook(0x492EF0, live_get_local_client_name_stub, HOOK_JUMP) + .install() + ->quick(); + + patch_sp(); + } + +private: + static void patch_sp() { + // Force external console + utils::hook::nop(0x604071, 21); + + // Remove limit on IWD file loading + utils::hook::set(0x630FF3, 0xEB); + + // Ignore XUID match + utils::hook::set(0x65D1AF, 0xEB); + + // Remove this particular string from the log file + utils::hook::nop(0x6030A6, 5); + + // Config related + utils::hook::set(0x4D3FD3, 0xEB); + + // Improper quit popup + utils::hook::nop(0x4F5B3A, 2); + + // Remove fs_game check + utils::hook::nop(0x612932, 2); + + // Build os path stuff + utils::hook::set(0x6300BF, 0xEB); + + // Show intro (or not) + utils::hook::set(0x6035BD, 0x0); + + // raw -> main + utils::hook::set(0x50A0B2, 0x723390); + + // Disable 'replay' output + utils::hook::nop(0x65F14A, 5); + + // Disable heartbeat output + utils::hook::nop(0x57EF87, 5); + + // Allow intro to be skipped + utils::hook::set(0x47529F, cl_play_unskippable_cinematic_f); + + // Start IW4 MP + utils::hook::set(0x475327, cl_start_multiplayer_f); + + // Enable commandline arguments + utils::hook::set(0x453B24, 0xEB); + + // Rename config + utils::hook::set(0x6040F2, CLIENT_CONFIG); + utils::hook::set(0x602D38, CLIENT_CONFIG); + utils::hook::set(0x6037C9, CLIENT_CONFIG); + utils::hook::set(0x4D3FDB, CLIENT_CONFIG); + utils::hook::set(0x469DB6, CLIENT_CONFIG); + } +}; +} // namespace patches + +REGISTER_COMPONENT(patches::component) diff --git a/src/client/component/player_movement.cpp b/src/client/component/player_movement.cpp new file mode 100644 index 0000000..1a7924f --- /dev/null +++ b/src/client/component/player_movement.cpp @@ -0,0 +1,180 @@ +#include +#include "loader/component_loader.hpp" +#include "game/dvars.hpp" + +#include "gsc/extension.hpp" + +#include + +namespace player_movement { +namespace { +void __declspec(naked) pm_step_slide_move_stub() { + __asm { + push eax; + mov eax, dvars::pm_bounce; + cmp byte ptr [eax + 0x10], 1; + pop eax; + + je bounce; + + cmp dword ptr [esp + 0x24], 0; + jnz no_bounce; + + bounce: + push 0x4E905B; + ret; + + no_bounce: + push 0x4E906F; + ret; + } +} + +void pm_project_velocity_stub(const float* vel_in, const float* normal, + float* vel_out) { + const auto length_squared_2d = vel_in[0] * vel_in[0] + vel_in[1] * vel_in[1]; + + if (std::fabsf(normal[2]) < 0.001f || length_squared_2d == 0.0f) { + vel_out[0] = vel_in[0]; + vel_out[1] = vel_in[1]; + vel_out[2] = vel_in[2]; + return; + } + + auto new_z = vel_in[0] * normal[0] + vel_in[1] * normal[1]; + new_z = -new_z / normal[2]; + + const auto length_scale = + std::sqrtf((vel_in[2] * vel_in[2] + length_squared_2d) / + (new_z * new_z + length_squared_2d)); + + if (dvars::pm_bouncingAllAngles->current.enabled || + (length_scale < 1.f || new_z < 0.f || vel_in[2] > 0.f)) { + vel_out[0] = vel_in[0] * length_scale; + vel_out[1] = vel_in[1] * length_scale; + vel_out[2] = new_z * length_scale; + } +} + +game::gentity_s* weapon_rocket_launcher_fire_stub( + game::gentity_s* ent, unsigned int weapon_index, float spread, + game::weaponParms* wp, const float* gun_vel, + game::lockonFireParms* lock_parms, bool magic_bullet) { + auto* result = utils::hook::invoke( + 0x443F20, ent, weapon_index, spread, wp, gun_vel, lock_parms, + magic_bullet); + + if (ent->client && dvars::pm_rocketJump->current.enabled) { + const auto scale = dvars::pm_rocketJumpScale->current.value; + ent->client->ps.velocity[0] += (0.0f - wp->forward[0]) * scale; + ent->client->ps.velocity[1] += (0.0f - wp->forward[1]) * scale; + ent->client->ps.velocity[2] += (0.0f - wp->forward[2]) * scale; + } + + return result; +} + +void cm_transformed_capsule_trace_stub(game::trace_t* results, + const float* start, const float* end, + const game::Bounds* bounds, + const game::Bounds* capsule, + int contents, const float* origin, + const float* angles) { + if (dvars::pm_playerCollision->current.enabled) { + utils::hook::invoke(0x47C7D0, results, start, end, bounds, capsule, + contents, origin, angles); + } +} + +void pm_trace_stub(game::pmove_t* pm, game::trace_t* results, + const float* start, const float* end, + const game::Bounds* bounds, int pass_entity_num, + int content_mask) { + game::PM_trace(pm, results, start, end, bounds, pass_entity_num, + content_mask); + // Allow the player to stand even when there is no headroom + if (dvars::pm_elevators->current.enabled) { + results->allsolid = false; + } +} + +void pm_player_trace_stub(game::pmove_t* pm, game::trace_t* results, + const float* start, const float* end, + const game::Bounds* bounds, int pass_entity_num, + int content_mask) { + game::PM_playerTrace(pm, results, start, end, bounds, pass_entity_num, + content_mask); + + if (dvars::pm_elevators->current.enabled) { + results->startsolid = false; + } +} +void g_scr_is_sprinting(const game::scr_entref_t entref) { + const auto* client = game::GetEntity(entref)->client; + if (!client) { + game::Scr_Error("IsSprinting can only be called on a player"); + return; + } + + game::Scr_AddInt(game::PM_IsSprinting(&client->ps)); +} +} // namespace + +class component final : public component_interface { +public: + static_assert(sizeof(game::weaponParms) == 0x48); + static_assert(sizeof(game::lockonFireParms) == 0x18); + + void post_load() override { + utils::hook(0x4E9054, pm_step_slide_move_stub, HOOK_JUMP) + .install() + ->quick(); // PM_StepSlideMove + utils::hook(0x4E90BE, pm_project_velocity_stub, HOOK_CALL) + .install() + ->quick(); // PM_StepSlideMove + + utils::hook(0x4FA809, weapon_rocket_launcher_fire_stub, HOOK_CALL) + .install() + ->quick(); // FireWeapon + + utils::hook(0x4B6FC0, cm_transformed_capsule_trace_stub, HOOK_CALL) + .install() + ->quick(); // SV_ClipMoveToEntity + utils::hook(0x57635F, cm_transformed_capsule_trace_stub, HOOK_CALL) + .install() + ->quick(); // CG_ClipMoveToEntity + + utils::hook(0x64F439, pm_trace_stub, HOOK_CALL) + .install() + ->quick(); // PM_CheckDuck + utils::hook(0x651A60, pm_player_trace_stub, HOOK_CALL) + .install() + ->quick(); // PM_CorrectAllSolid + utils::hook(0x651AF2, pm_player_trace_stub, HOOK_CALL) + .install() + ->quick(); // PM_CorrectAllSolid + + gsc::add_method("IsSprinting", g_scr_is_sprinting); + register_dvars(); + } + + static void register_dvars() { + // clang-format off + dvars::pm_bounce = game::Dvar_RegisterBool( + "pm_bounce", false, game::DVAR_NONE, "CoD4 Bounces"); + dvars::pm_bouncingAllAngles = game::Dvar_RegisterBool( + "pm_bouncingAllAngles", false, game::DVAR_NONE, "Enable bouncing from all angles"); + dvars::pm_rocketJump = game::Dvar_RegisterBool( + "pm_rocketJump", true, game::DVAR_NONE, "CoD4 rocket jumps"); + dvars::pm_rocketJumpScale = game::Dvar_RegisterFloat( + "pm_rocketJumpScale", 64.0f, 0.0f, 1024.0f, game::DVAR_NONE, ""); + dvars::pm_playerCollision = game::Dvar_RegisterBool( + "pm_playerCollision", true, game::DVAR_NONE, "Push intersecting players away from each other"); + dvars::pm_elevators = game::Dvar_RegisterBool( + "pm_elevators", false, game::DVAR_NONE, "CoD4 elevators"); + // clang-format on + } +}; +} // namespace player_movement + +REGISTER_COMPONENT(player_movement::component) diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp new file mode 100644 index 0000000..29de32b --- /dev/null +++ b/src/client/component/scheduler.cpp @@ -0,0 +1,163 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include +#include + +#include "scheduler.hpp" + +namespace scheduler { +namespace { +struct task { + std::function handler{}; + std::chrono::milliseconds interval{}; + std::chrono::high_resolution_clock::time_point last_call{}; +}; + +using task_list = std::vector; + +class task_pipeline { +public: + void add(task&& task) { + new_callbacks_.access([&task, this](task_list& tasks) { + tasks.emplace_back(std::move(task)); + }); + } + + void clear() { + callbacks_.access([&](task_list& tasks) { + this->merge_callbacks(); + tasks.clear(); + }); + } + + void execute() { + callbacks_.access([&](task_list& tasks) { + this->merge_callbacks(); + + for (auto i = tasks.begin(); i != tasks.end();) { + const auto now = std::chrono::high_resolution_clock::now(); + const auto diff = now - i->last_call; + + if (diff < i->interval) { + ++i; + continue; + } + + i->last_call = now; + + const auto res = i->handler(); + if (res == cond_end) { + i = tasks.erase(i); + } else { + ++i; + } + } + }); + } + +private: + utils::concurrency::container new_callbacks_; + utils::concurrency::container callbacks_; + + void merge_callbacks() { + callbacks_.access([&](task_list& tasks) { + new_callbacks_.access([&](task_list& new_tasks) { + tasks.insert(tasks.end(), + std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); + new_tasks = {}; + }); + }); + } +}; + +volatile bool kill = false; +std::thread thread; +task_pipeline pipelines[pipeline::count]; + +void execute(const pipeline type) { + assert(type >= 0 && type < pipeline::count); + pipelines[type].execute(); +} + +void g_glass_update_stub() { + utils::hook::invoke(0x43D7E0); + execute(pipeline::server); +} + +void r_end_frame_stub() { + utils::hook::invoke(0x50F540); + execute(pipeline::renderer); +} + +void main_frame_stub() { + utils::hook::invoke(0x4D3FC0); + execute(pipeline::main); +} +} // namespace + +void clear_tasks(const pipeline type) { return pipelines[type].clear(); } + +void schedule(const std::function& callback, const pipeline type, + const std::chrono::milliseconds delay) { + assert(type >= 0 && type < pipeline::count); + + task task; + task.handler = callback; + task.interval = delay; + task.last_call = std::chrono::high_resolution_clock::now(); + + pipelines[type].add(std::move(task)); +} + +void loop(const std::function& callback, const pipeline type, + const std::chrono::milliseconds delay) { + schedule( + [callback]() { + callback(); + return cond_continue; + }, + type, delay); +} + +void once(const std::function& callback, const pipeline type, + const std::chrono::milliseconds delay) { + schedule( + [callback]() { + callback(); + return cond_end; + }, + type, delay); +} + +unsigned int thread_id; + +class component final : public component_interface { +public: + void post_start() override { + thread = utils::thread::create_named_thread("Async Scheduler", [] { + while (!kill) { + execute(pipeline::async); + std::this_thread::sleep_for(10ms); + } + }); + } + + void post_load() override { + utils::hook(0x4EDBDD, g_glass_update_stub, HOOK_CALL).install()->quick(); + utils::hook(0x49C3AF, main_frame_stub, HOOK_CALL).install()->quick(); + utils::hook(0x57DB13, r_end_frame_stub, HOOK_CALL).install()->quick(); + } + + void pre_destroy() override { + kill = true; + if (thread.joinable()) { + thread.join(); + } + } +}; +} // namespace scheduler + +REGISTER_COMPONENT(scheduler::component) diff --git a/src/client/component/scheduler.hpp b/src/client/component/scheduler.hpp new file mode 100644 index 0000000..46348fb --- /dev/null +++ b/src/client/component/scheduler.hpp @@ -0,0 +1,33 @@ +#pragma once + +using namespace std::literals; + +namespace scheduler { +enum pipeline { + // Asynchronuous pipeline, disconnected from the game + async = 0, + + // The game's rendering pipeline + renderer, + + // The game's server thread + server, + + // The game's main thread + main, + + count, +}; + +static constexpr auto cond_continue = false; +static constexpr auto cond_end = true; + +void clear_tasks(pipeline type); + +void schedule(const std::function& callback, pipeline type, + std::chrono::milliseconds delay = 0ms); +void loop(const std::function& callback, pipeline type, + std::chrono::milliseconds delay = 0ms); +void once(const std::function& callback, pipeline type, + std::chrono::milliseconds delay = 0ms); +} // namespace scheduler diff --git a/src/client/component/steam_patches.cpp b/src/client/component/steam_patches.cpp new file mode 100644 index 0000000..a45811c --- /dev/null +++ b/src/client/component/steam_patches.cpp @@ -0,0 +1,47 @@ +#include +#include "loader/component_loader.hpp" + +#include + +namespace steam_patches { +namespace { +void __declspec(naked) steam_init() { + const static DWORD Steam_IsClientSignedInLocally_t = 0x4293F0; + + __asm { + call Steam_IsClientSignedInLocally_t; + test al, al; + jz return_safe; + + push 0x43FAF9; + ret; + + return_safe: + mov al, 1; + ret; + } +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { + patch_sp(); + utils::hook(0x43FAF0, steam_init, HOOK_JUMP).install()->quick(); + } + + static void patch_sp() { + // Prevent stat loading from steam + utils::hook::set(0x43FB33, 0xC3); + + // Steam must be running + utils::hook::nop(0x6040A3, 30); + + // No-Steam + utils::hook::nop(0x4E9458, 7); + utils::hook::nop(0x4E9470, 7); + } +}; +} // namespace steam_patches + +REGISTER_COMPONENT(steam_patches::component) diff --git a/src/client/component/steam_proxy.cpp b/src/client/component/steam_proxy.cpp new file mode 100644 index 0000000..0665afc --- /dev/null +++ b/src/client/component/steam_proxy.cpp @@ -0,0 +1,197 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include +#include +#include + +#include + +#include "steam/steam.hpp" +#include "steam/interface.hpp" + +#include "scheduler.hpp" + +namespace { +enum class ownership_state { + success, + unowned, + nosteam, + error, +}; + +utils::binary_resource runner_file(RUNNER, "iw4sp-runner.exe"); + +bool is_disabled() { + static const auto disabled = utils::flags::has_flag("nosteam"); + return disabled; +} +} // namespace + +class steam_proxy final : public component_interface { +public: + void post_load() override { + if (is_disabled()) { + return; + } + + this->load_client(); + this->clean_up_on_error(); + + try { + this->start_mod("iw4-sp Singleplayer", 10180); + } catch (const std::exception& ex) { + printf("Steam: %s\n", ex.what()); + } + } + + void pre_destroy() override { + if (this->steam_client_module_) { + if (this->steam_pipe_) { + if (this->global_user_) { + this->steam_client_module_.invoke( + "Steam_ReleaseUser", this->steam_pipe_, this->global_user_); + } + + this->steam_client_module_.invoke("Steam_BReleaseSteamPipe", + this->steam_pipe_); + } + } + } + +private: + utils::nt::library steam_client_module_{}; + + steam::interface client_engine_ {}; + steam::interface client_user_ {}; + steam::interface client_utils_ {}; + + void* steam_pipe_ = nullptr; + void* global_user_ = nullptr; + + [[nodiscard]] void* load_client_engine() const { + if (!this->steam_client_module_) + return nullptr; + + for (auto i = 1; i < 1000; ++i) { + const auto* name = + utils::string::va("CLIENTENGINE_INTERFACE_VERSION{0:03}", i); + + auto* const client_engine = this->steam_client_module_.invoke( + "CreateInterface", name, nullptr); + if (client_engine) + return client_engine; + } + + return nullptr; + } + + void load_client() { + const auto steam_path = steam::get_steam_install_directory(); + if (steam_path.empty()) + return; + + utils::nt::library::load(steam_path / "tier0_s.dll"); + utils::nt::library::load(steam_path / "vstdlib_s.dll"); + this->steam_client_module_ = + utils::nt::library::load(steam_path / "steamclient.dll"); + if (!this->steam_client_module_) + return; + + this->client_engine_ = load_client_engine(); + if (!this->client_engine_) + return; + + this->steam_pipe_ = + this->steam_client_module_.invoke("Steam_CreateSteamPipe"); + this->global_user_ = this->steam_client_module_.invoke( + "Steam_ConnectToGlobalUser", this->steam_pipe_); + this->client_user_ = this->client_engine_.invoke( + 8, this->steam_pipe_, this->global_user_); // GetIClientUser + this->client_utils_ = this->client_engine_.invoke( + 14, this->steam_pipe_); // GetIClientUtils + } + + ownership_state start_mod(const std::string& title, + const std::size_t app_id) { + __try { + return this->start_mod_unsafe(title, app_id); + } __except (EXCEPTION_EXECUTE_HANDLER) { + this->do_cleanup(); + return ownership_state::error; + } + } + + ownership_state start_mod_unsafe(const std::string& title, + std::size_t app_id) { + if (!this->client_utils_ || !this->client_user_) + return ownership_state::nosteam; + + if (!this->client_user_.invoke("BIsSubscribedApp", app_id)) { +#ifdef _DEBUG + app_id = 480; // Spacewar +#else + return ownership_state::unowned; +#endif + } + + if (is_disabled()) { + return ownership_state::success; + } + + this->client_utils_.invoke("SetAppIDForCurrentPipe", app_id, false); + + char our_directory[MAX_PATH] = {0}; + GetCurrentDirectoryA(sizeof(our_directory), our_directory); + + const auto path = runner_file.get_extracted_file(); + const auto* cmd_line = + utils::string::va("\"{0}\" -proc {1}", path, GetCurrentProcessId()); + + game_id game_id; + game_id.raw.type = 1; // k_EGameIDTypeGameMod + game_id.raw.app_id = app_id & 0xFFFFFF; + + const auto* mod_id = "IW4"; + game_id.raw.mod_id = + *reinterpret_cast(mod_id) | 0x80000000; + + this->client_user_.invoke("SpawnProcess", path.data(), cmd_line, + our_directory, game_id.bits, title.data(), + app_id, 0, 0, 0); + + return ownership_state::success; + } + + void do_cleanup() { + this->client_engine_ = nullptr; + this->client_user_ = nullptr; + this->client_utils_ = nullptr; + + this->steam_pipe_ = nullptr; + this->global_user_ = nullptr; + + this->steam_client_module_ = utils::nt::library{nullptr}; + } + + void clean_up_on_error() { + scheduler::schedule( + [this] { + if (this->steam_client_module_ && this->steam_pipe_ && + this->global_user_ && + this->steam_client_module_.invoke( + "Steam_BConnected", this->global_user_, this->steam_pipe_) && + this->steam_client_module_.invoke( + "Steam_BLoggedOn", this->global_user_, this->steam_pipe_)) { + return scheduler::cond_continue; + } + + this->do_cleanup(); + return scheduler::cond_end; + }, + scheduler::pipeline::async); + } +}; + +REGISTER_COMPONENT(steam_proxy) diff --git a/src/client/component/ultra_wide.cpp b/src/client/component/ultra_wide.cpp new file mode 100644 index 0000000..83cecb6 --- /dev/null +++ b/src/client/component/ultra_wide.cpp @@ -0,0 +1,74 @@ +#include +#include "loader/component_loader.hpp" + +#include + +namespace ultra_wide { +const game::dvar_t* r_customAspectRatio; + +const game::dvar_t* dvar_register_aspect_ratio(const char* dvar_name, + const char** /*value_list*/, + int default_index, + unsigned __int16 flags, + const char* description) { + static const char* values[] = {"auto", "standard", "wide 16:10", + "wide 16:9", "custom", nullptr}; + + // register enumeration dvar + return game::Dvar_RegisterEnum(dvar_name, values, default_index, flags, + description); +} + +void set_aspect_ratio() { + *reinterpret_cast(0x1C91A78) = r_customAspectRatio->current.value; +} + +__declspec(naked) void set_aspect_ratio_stub() { + __asm { + mov eax, [eax + 0x10]; + cmp eax, 4; + + mov dword ptr ds:0x1C91A68, edx; + mov dword ptr ds:0x1C91A6C, esi; + mov dword ptr ds:0x1C91A74, ecx; + + ja default_case; + je custom_ratio; + + push 0x50AE6C; + ret; + + default_case: + push 0x50AF6C; + ret; + + custom_ratio: + pushad; + call set_aspect_ratio; + popad; + + mov eax, 1; // set widescreen to 1 + + push 0x50AF05; + ret; + } +} + +class component final : public component_interface { +public: + void post_load() override { + utils::hook(0x51E80B, &dvar_register_aspect_ratio, HOOK_CALL) + .install() + ->quick(); + + utils::hook(0x50AE4E, &set_aspect_ratio_stub, HOOK_JUMP).install()->quick(); + utils::hook::nop(0x50AE4E + 5, 1); + + r_customAspectRatio = game::Dvar_RegisterFloat( + "r_customAspectRatio", 16.0f / 9.0f, 4.0f / 3.0f, 63.0f / 9.0f, + game::DVAR_ARCHIVE, "Screen aspect ratio"); + } +}; +} // namespace ultra_wide + +REGISTER_COMPONENT(ultra_wide::component) diff --git a/src/client/component/weapons.cpp b/src/client/component/weapons.cpp new file mode 100644 index 0000000..261ed81 --- /dev/null +++ b/src/client/component/weapons.cpp @@ -0,0 +1,48 @@ +#include +#include "loader/component_loader.hpp" + +#include + +namespace weapons { +namespace { +game::WeaponCompleteDef* +bg_load_weapon_variant_def_fast_file_stub(const char* name) { + if (auto* raw_weapon_file = + game::BG_LoadWeaponVariantDefInternal("sp", name)) { + return raw_weapon_file; + } + + auto* zone_weapon_file = + game::DB_FindXAssetHeader(game::ASSET_TYPE_WEAPON, name).weapon; + return game::DB_IsXAssetDefault(game::ASSET_TYPE_WEAPON, name) + ? nullptr + : zone_weapon_file; +} +} // namespace + +class component final : public component_interface { +public: + void post_load() override { patch_sp(); } + +private: + static void patch_sp() { + // Weapon asset existence check + utils::hook::nop(0x43E1D8, 5); + // Is asset default + utils::hook::nop(0x43E1E0, 5); + // Do not jump + utils::hook::nop(0x43E1EA, 2); + + // Ignore missing default weapon + utils::hook::set(0x659DBE, 0xEB); + + utils::hook(0x659E00, bg_load_weapon_variant_def_fast_file_stub, HOOK_JUMP) + .install() + ->quick(); + // Disable warning if raw weapon file cannot be found + utils::hook::nop(0x659730, 5); + } +}; +} // namespace weapons + +REGISTER_COMPONENT(weapons::component) diff --git a/src/client/component/zone.cpp b/src/client/component/zone.cpp new file mode 100644 index 0000000..71bb387 --- /dev/null +++ b/src/client/component/zone.cpp @@ -0,0 +1,25 @@ +#include +#include "loader/component_loader.hpp" + +#include + +namespace zone { +class component final : public component_interface { +public: + static_assert(sizeof(game::XZoneInfo) == 0xC); + + void post_load() override { patch_sp(); } + +private: + static void patch_sp() { + // Ignore zone version mismatch + utils::hook::set(0x4256D8, 0xEB); + + // Disc read error + utils::hook::nop(0x4B7335, 2); + utils::hook::set(0x4256B9, 0xEB); + } +}; +} // namespace zone + +REGISTER_COMPONENT(zone::component) diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp new file mode 100644 index 0000000..af578f9 --- /dev/null +++ b/src/client/game/dvars.cpp @@ -0,0 +1,30 @@ +#include + +namespace dvars { +const game::dvar_t* r_noBorder = nullptr; + +const game::dvar_t* pm_bounce = nullptr; +const game::dvar_t* pm_bouncingAllAngles = nullptr; +const game::dvar_t* pm_rocketJump = nullptr; +const game::dvar_t* pm_rocketJumpScale = nullptr; +const game::dvar_t* pm_playerCollision = nullptr; +const game::dvar_t* pm_elevators = nullptr; + +const game::dvar_t* cg_drawVersion = nullptr; +const game::dvar_t* cg_drawVersionX = nullptr; +const game::dvar_t* cg_drawVersionY = nullptr; + +const game::dvar_t* bug_name = nullptr; + +const game::dvar_t* g_log = nullptr; + +// Game dvars +const game::dvar_t** g_specialops = + reinterpret_cast(0x1B2E1E8); + +const game::dvar_t** sv_mapname = + reinterpret_cast(0x1B2E1E4); + +const game::dvar_t** version = + reinterpret_cast(0x145D690); +} // namespace dvars diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp new file mode 100644 index 0000000..33c2339 --- /dev/null +++ b/src/client/game/dvars.hpp @@ -0,0 +1,27 @@ +#pragma once + +namespace dvars { +extern const game::dvar_t* r_noBorder; + +extern const game::dvar_t* pm_bounce; +extern const game::dvar_t* pm_bouncingAllAngles; +extern const game::dvar_t* pm_rocketJump; +extern const game::dvar_t* pm_rocketJumpScale; +extern const game::dvar_t* pm_playerCollision; +extern const game::dvar_t* pm_elevators; + +extern const game::dvar_t* cg_drawVersion; +extern const game::dvar_t* cg_drawVersionX; +extern const game::dvar_t* cg_drawVersionY; + +extern const game::dvar_t* bug_name; + +extern const game::dvar_t* g_log; + +// Game dvars +extern const game::dvar_t** g_specialops; + +extern const game::dvar_t** sv_mapname; + +extern const game::dvar_t** version; +} // namespace dvars diff --git a/src/client/game/engine/fast_critical_section.cpp b/src/client/game/engine/fast_critical_section.cpp new file mode 100644 index 0000000..7594088 --- /dev/null +++ b/src/client/game/engine/fast_critical_section.cpp @@ -0,0 +1,34 @@ +#include +#include + +#include "fast_critical_section.hpp" + +namespace game::engine { +fast_critical_section_scope_read::fast_critical_section_scope_read( + FastCriticalSection* cs) + : cs_(cs) { + if (this->cs_) { + Sys_LockRead(this->cs_); + } +} + +fast_critical_section_scope_read::~fast_critical_section_scope_read() { + if (this->cs_) { + Sys_UnlockRead(this->cs_); + } +} + +fast_critical_section_scope_write::fast_critical_section_scope_write( + FastCriticalSection* cs) + : cs_(cs) { + if (this->cs_) { + Sys_LockWrite(this->cs_); + } +} + +fast_critical_section_scope_write::~fast_critical_section_scope_write() { + if (this->cs_) { + Sys_UnlockWrite(this->cs_); + } +} +} // namespace game::engine diff --git a/src/client/game/engine/fast_critical_section.hpp b/src/client/game/engine/fast_critical_section.hpp new file mode 100644 index 0000000..6ddc6ad --- /dev/null +++ b/src/client/game/engine/fast_critical_section.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace game::engine { +class fast_critical_section_scope_read { +public: + fast_critical_section_scope_read(FastCriticalSection* cs); + ~fast_critical_section_scope_read(); + +private: + FastCriticalSection* cs_; +}; + +class fast_critical_section_scope_write { +public: + fast_critical_section_scope_write(FastCriticalSection* cs); + ~fast_critical_section_scope_write(); + +private: + FastCriticalSection* cs_; +}; +} // namespace game::engine diff --git a/src/client/game/engine/large_local.cpp b/src/client/game/engine/large_local.cpp new file mode 100644 index 0000000..b5743dc --- /dev/null +++ b/src/client/game/engine/large_local.cpp @@ -0,0 +1,87 @@ +#include + +#include "large_local.hpp" + +namespace game::engine { +namespace { +constexpr auto PAGE_SIZE = 4096; + +int can_use_server_large_local() { return Sys_IsServerThread(); } + +void large_local_end(int start_pos) { + assert(Sys_IsMainThread()); + assert(g_largeLocalBuf); + + *g_largeLocalPos = start_pos; + + assert(((*g_maxLargeLocalPos + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)) <= + (*g_minLargeLocalRightPos & ~(PAGE_SIZE - 1))); +} + +void large_local_end_right(int start_pos) { + assert(can_use_server_large_local()); + assert(g_largeLocalBuf); + + *g_largeLocalRightPos = start_pos; + + assert(((*g_maxLargeLocalPos + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1)) <= + (*g_minLargeLocalRightPos & ~(PAGE_SIZE - 1))); +} + +void* large_local_get_buf(int start_pos, int size) { + assert(Sys_IsMainThread() || can_use_server_large_local()); + assert(g_largeLocalBuf); + assert(!(size & 127)); + + if (Sys_IsMainThread()) { + return &g_largeLocalBuf[start_pos]; + } + + const auto start_index = start_pos - size; + assert(start_index >= 0); + + return &g_largeLocalBuf[start_index]; +} +} // namespace + +large_local::large_local(int size_param) { + assert(size_param); + assert(Sys_IsMainThread() || can_use_server_large_local()); + + size_param = ((size_param + (128 - 1)) & ~(128 - 1)); + + if (Sys_IsMainThread()) { + this->start_pos_ = LargeLocalBegin(size_param); + } else { + this->start_pos_ = LargeLocalBeginRight(size_param); + } + + this->size_ = size_param; +} + +large_local::~large_local() { + if (this->size_) { + this->pop_buf(); + } +} + +void large_local::pop_buf() { + assert(this->size_); + assert(Sys_IsMainThread() || can_use_server_large_local()); + + if (Sys_IsMainThread()) { + large_local_end(this->start_pos_); + } else { + large_local_end_right(this->start_pos_); + } + + this->size_ = 0; +} + +void* large_local::get_buf() const { + assert(this->size_); + assert(Sys_IsMainThread() || can_use_server_large_local()); + + return large_local_get_buf(this->start_pos_, this->size_); +} +} // namespace game::engine diff --git a/src/client/game/engine/large_local.hpp b/src/client/game/engine/large_local.hpp new file mode 100644 index 0000000..895c714 --- /dev/null +++ b/src/client/game/engine/large_local.hpp @@ -0,0 +1,22 @@ +#pragma once + +namespace game::engine { +class large_local { +public: + explicit large_local(int size_param); + ~large_local(); + + large_local(large_local&&) = delete; + large_local(const large_local&) = delete; + large_local& operator=(large_local&&) = delete; + large_local& operator=(const large_local&) = delete; + + [[nodiscard]] void* get_buf() const; + +private: + void pop_buf(); + + int start_pos_; + int size_; +}; +} // namespace game::engine diff --git a/src/client/game/engine/scoped_critical_section.cpp b/src/client/game/engine/scoped_critical_section.cpp new file mode 100644 index 0000000..7d3ad02 --- /dev/null +++ b/src/client/game/engine/scoped_critical_section.cpp @@ -0,0 +1,63 @@ +#include + +#include "scoped_critical_section.hpp" + +namespace game::engine { +scoped_critical_section::scoped_critical_section( + const CriticalSection s, const ScopedCriticalSectionType type) + : s_(s), is_scoped_release_(false) { + if (type == SCOPED_CRITSECT_NORMAL) { + Sys_EnterCriticalSection(this->s_); + this->has_ownership_ = true; + } else { + if (type == SCOPED_CRITSECT_TRY) { + this->has_ownership_ = Sys_TryEnterCriticalSection(this->s_); + } else { + if (type == SCOPED_CRITSECT_RELEASE) { + Sys_LeaveCriticalSection(this->s_); + this->is_scoped_release_ = true; + } + this->has_ownership_ = false; + } + } +} + +scoped_critical_section::~scoped_critical_section() { + if (!this->has_ownership_ || this->is_scoped_release_) { + if (!this->has_ownership_ && this->is_scoped_release_) + Sys_EnterCriticalSection(this->s_); + } else { + Sys_LeaveCriticalSection(this->s_); + } +} + +void scoped_critical_section::enter_crit_sect() { + assert(!this->has_ownership_); + + this->has_ownership_ = true; + Sys_EnterCriticalSection(this->s_); +} + +void scoped_critical_section::leave_crit_sect() { + assert(this->has_ownership_); + + this->has_ownership_ = false; + Sys_LeaveCriticalSection(this->s_); +} + +bool scoped_critical_section::try_enter_crit_sect() { + assert(!this->has_ownership_); + + const auto result = Sys_TryEnterCriticalSection(this->s_); + this->has_ownership_ = result; + return result; +} + +bool scoped_critical_section::has_ownership() const { + return this->has_ownership_; +} + +bool scoped_critical_section::is_scoped_release() const { + return this->is_scoped_release_; +} +} // namespace game::engine diff --git a/src/client/game/engine/scoped_critical_section.hpp b/src/client/game/engine/scoped_critical_section.hpp new file mode 100644 index 0000000..2b89178 --- /dev/null +++ b/src/client/game/engine/scoped_critical_section.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace game::engine { +class scoped_critical_section { +public: + scoped_critical_section(CriticalSection s, ScopedCriticalSectionType type); + ~scoped_critical_section(); + + void enter_crit_sect(); + void leave_crit_sect(); + bool try_enter_crit_sect(); + + [[nodiscard]] bool has_ownership() const; + [[nodiscard]] bool is_scoped_release() const; + +private: + CriticalSection s_; + bool has_ownership_; + bool is_scoped_release_; +}; +} // namespace game::engine diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp new file mode 100644 index 0000000..e92ad50 --- /dev/null +++ b/src/client/game/game.cpp @@ -0,0 +1,119 @@ +#include + +namespace game { +int FS_FOpenFileReadForThread(const char* filename, int* file, + FsThread thread) { + const static DWORD FS_FOpenFileReadForThread_t = 0x630380; + int result{}; + + __asm { + pushad; + + mov eax, file; + push thread; + push filename; + call FS_FOpenFileReadForThread_t; + add esp, 0x8; + mov result, eax; + + popad; + } + + return result; +} + +void IN_KeyDown(kbutton_t* b) { + const static DWORD IN_KeyDown_t = 0x57A350; + + __asm { + pushad; + + mov esi, b; + call IN_KeyDown_t; + + popad; + } +} + +void IN_KeyUp(kbutton_t* b) { + const static DWORD IN_KeyUp_t = 0x57A3F0; + + __asm { + pushad; + + mov esi, b; + call IN_KeyUp_t; + + popad; + } +} + +bool ScrPlace_IsFullScreenActive() { + return *activeScreenPlacementMode == SCRMODE_FULL; +} + +ScreenPlacement* ScrPlace_GetUnsafeFullPlacement() { + return scrPlaceFullUnsafe; +} + +bool Sys_TryEnterCriticalSection(CriticalSection critSect) { + assert(static_cast(critSect) < + static_cast(CRITSECT_COUNT)); + + return TryEnterCriticalSection(&s_criticalSection[critSect]) != FALSE; +} + +void Sys_LockRead(FastCriticalSection* critSect) { + InterlockedIncrement(&critSect->readCount); + while (critSect->writeCount) { + Sys_Sleep(0); + } +} + +void Sys_UnlockRead(FastCriticalSection* critSect) { + assert(critSect->readCount > 0); + InterlockedDecrement(&critSect->readCount); +} + +void Sys_UnlockWrite(FastCriticalSection* critSect) { + assert(critSect->writeCount > 0); + InterlockedDecrement(&critSect->writeCount); + Sys_TempPriorityEnd(&critSect->tempPriority); +} + +int PC_Int_Parse(int handle, int* i) { + const static DWORD PC_Int_Parse_t = 0x62DF10; + int result{}; + + __asm { + pushad; + + mov eax, handle; + mov esi, i; + call PC_Int_Parse_t; + mov result, eax; + + popad; + } + + return result; +} + +int PC_Float_Parse(int handle, float* f) { + const static DWORD PC_Float_Parse_t = 0x62DE40; + int result{}; + + __asm { + pushad; + + mov eax, handle; + mov esi, f; + call PC_Float_Parse_t; + mov result, eax; + + popad; + } + + return result; +} +} // namespace game diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp new file mode 100644 index 0000000..9876654 --- /dev/null +++ b/src/client/game/game.hpp @@ -0,0 +1,54 @@ +#pragma once + +namespace game { +template struct base_symbol { + base_symbol(const std::size_t address) : address_(address) {} + + [[nodiscard]] T* get() const { return reinterpret_cast(this->address_); } + + operator T*() const { return this->get(); } + + T* operator->() const { return this->get(); } + +private: + std::size_t address_{}; +}; + +template struct symbol : base_symbol { + using base_symbol::base_symbol; +}; + +template +struct symbol : base_symbol { + using func_type = T(Args...); + using base_symbol::base_symbol; +}; + +// Functions that require asm stubs to be called +// or have been inlined + +int FS_FOpenFileReadForThread(const char* filename, int* file, FsThread thread); + +void IN_KeyDown(kbutton_t* b); +void IN_KeyUp(kbutton_t* b); + +bool ScrPlace_IsFullScreenActive(); +ScreenPlacement* ScrPlace_GetUnsafeFullPlacement(); + +bool Sys_TryEnterCriticalSection(CriticalSection critSect); +void Sys_LockRead(FastCriticalSection* critSect); +void Sys_UnlockRead(FastCriticalSection* critSect); +void Sys_UnlockWrite(FastCriticalSection* critSect); + +int PC_Int_Parse(int handle, int* i); +int PC_Float_Parse(int handle, float* f); + +// Global definitions +constexpr auto CMD_MAX_NESTING = 8; + +constexpr std::size_t MAX_LOCAL_CLIENTS = 1; + +constexpr auto MAX_QPATH = 64; +} // namespace game + +#include "symbols.hpp" diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp new file mode 100644 index 0000000..5715a4d --- /dev/null +++ b/src/client/game/structs.hpp @@ -0,0 +1,926 @@ +#pragma once + +#pragma warning(push) +#pragma warning(disable : 4324) + +namespace game { +typedef float vec_t; +typedef vec_t vec2_t[2]; +typedef vec_t vec3_t[3]; +typedef vec_t vec4_t[4]; + +struct scr_entref_t { + unsigned __int16 entnum; + unsigned __int16 classnum; +}; + +typedef void(__cdecl* BuiltinMethod)(scr_entref_t); + +typedef void(__cdecl* BuiltinFunction)(); + +struct BuiltinMethodDef { + const char* actionString; + void(__cdecl* actionFunc)(scr_entref_t); + int type; +}; + +struct BuiltinFunctionDef { + const char* actionString; + void(__cdecl* actionFunc)(); + int type; +}; + +enum { + VAR_STRING = 0x2, + VAR_FLOAT = 0x5, + VAR_INTEGER = 0x6, +}; + +enum { + CON_CHANNEL_DONT_FILTER = 0x0, + CON_CHANNEL_ERROR = 0x1, + CON_CHANNEL_GAMENOTIFY = 0x2, + CON_CHANNEL_BOLDGAME = 0x3, + CON_CHANNEL_SUBTITLE = 0x4, + CON_CHANNEL_OBITUARY = 0x5, + CON_CHANNEL_LOGFILEONLY = 0x6, + CON_CHANNEL_CONSOLEONLY = 0x7, + CON_CHANNEL_GFX = 0x8, + CON_CHANNEL_SOUND = 0x9, + CON_CHANNEL_FILES = 0xA, + CON_CHANNEL_DEVGUI = 0xB, + CON_CHANNEL_PROFILE = 0xC, + CON_CHANNEL_UI = 0xD, + CON_CHANNEL_CLIENT = 0xE, + CON_CHANNEL_SERVER = 0xF, + CON_CHANNEL_SYSTEM = 0x10, + CON_CHANNEL_PLAYERWEAP = 0x11, + CON_CHANNEL_AI = 0x12, + CON_CHANNEL_ANIM = 0x13, + CON_CHANNEL_PHYS = 0x14, + CON_CHANNEL_FX = 0x15, + CON_CHANNEL_LEADERBOARDS = 0x16, + CON_CHANNEL_PARSERSCRIPT = 0x17, + CON_CHANNEL_SCRIPT = 0x18, + CON_CHANNEL_NETWORK = 0x19, + + CON_BUILTIN_CHANNEL_COUNT = 0x1A, +}; + +enum XAssetType { + ASSET_TYPE_PHYSPRESET = 0, + ASSET_TYPE_PHYSCOLLMAP = 1, + ASSET_TYPE_XANIMPARTS = 2, + ASSET_TYPE_XMODEL_SURFS = 3, + ASSET_TYPE_XMODEL = 4, + ASSET_TYPE_MATERIAL = 5, + ASSET_TYPE_PIXELSHADER = 6, + ASSET_TYPE_VERTEXSHADER = 7, + ASSET_TYPE_VERTEXDECL = 8, + ASSET_TYPE_TECHNIQUE_SET = 9, + ASSET_TYPE_IMAGE = 10, + ASSET_TYPE_SOUND = 11, + ASSET_TYPE_SOUND_CURVE = 12, + ASSET_TYPE_LOADED_SOUND = 13, + ASSET_TYPE_CLIPMAP_SP = 14, + ASSET_TYPE_CLIPMAP_MP = 15, + ASSET_TYPE_COMWORLD = 16, + ASSET_TYPE_GAMEWORLD_SP = 17, + ASSET_TYPE_GAMEWORLD_MP = 18, + ASSET_TYPE_MAP_ENTS = 19, + ASSET_TYPE_FXWORLD = 20, + ASSET_TYPE_GFXWORLD = 21, + ASSET_TYPE_LIGHT_DEF = 22, + ASSET_TYPE_UI_MAP = 23, + ASSET_TYPE_FONT = 24, + ASSET_TYPE_MENULIST = 25, + ASSET_TYPE_MENU = 26, + ASSET_TYPE_LOCALIZE_ENTRY = 27, + ASSET_TYPE_WEAPON = 28, + ASSET_TYPE_SNDDRIVER_GLOBALS = 29, + ASSET_TYPE_FX = 30, + ASSET_TYPE_IMPACT_FX = 31, + ASSET_TYPE_AITYPE = 32, + ASSET_TYPE_MPTYPE = 33, + ASSET_TYPE_CHARACTER = 34, + ASSET_TYPE_XMODELALIAS = 35, + ASSET_TYPE_RAWFILE = 36, + ASSET_TYPE_STRINGTABLE = 37, + ASSET_TYPE_LEADERBOARD = 38, + ASSET_TYPE_STRUCTURED_DATA_DEF = 39, + ASSET_TYPE_TRACER = 40, + ASSET_TYPE_VEHICLE = 41, + ASSET_TYPE_ADDON_MAP_ENTS = 42, + + ASSET_TYPE_COUNT = 43, +}; + +enum FsThread { + FS_THREAD_MAIN = 0x0, + FS_THREAD_STREAM = 0x1, + FS_THREAD_DATABASE = 0x2, + FS_THREAD_BACKEND = 0x3, + FS_THREAD_SERVER = 0x4, + FS_THREAD_COUNT = 0x5, + FS_THREAD_INVALID = 0x6, +}; + +enum FsListBehavior_e { + FS_LIST_PURE_ONLY = 0x0, + FS_LIST_ALL = 0x1, +}; + +enum fsMode_t { + FS_READ = 0x0, + FS_WRITE = 0x1, + FS_APPEND = 0x2, + FS_APPEND_SYNC = 0x3, +}; + +struct token_s { + char string[1024]; + int type; + int subtype; + unsigned int intvalue; + long double floatvalue; + char* whitespace_p; + char* endwhitespace_p; + int line; + int linescrossed; + token_s* next; +}; + +static_assert(sizeof(token_s) == 0x430); + +struct define_s { + char* name; + int flags; + int builtin; + int numparms; + token_s* parms; + token_s* tokens; + define_s* next; + define_s* hashnext; +}; + +struct punctuation_s { + const char* p; + int n; + punctuation_s* next; +}; + +struct script_s { + char filename[64]; + char* buffer; + char* script_p; + char* end_p; + char* lastscript_p; + char* whitespace_p; + char* endwhitespace_p; + int length; + int line; + int lastline; + int tokenavailable; + int flags; + punctuation_s* punctuations; + punctuation_s** punctuationtable; + token_s token; + script_s* next; +}; + +enum parseSkip_t { + SKIP_NO = 0x0, + SKIP_YES = 0x1, + SKIP_ALL_ELIFS = 0x2, +}; + +struct indent_s { + int type; + parseSkip_t skip; + script_s* script; + indent_s* next; +}; + +struct source_s { + char filename[64]; + char includepath[64]; + punctuation_s* punctuations; + script_s* scriptstack; + token_s* tokens; + define_s* defines; + define_s** definehash; + indent_s* indentstack; + int skip; + token_s token; +}; + +struct pc_token_s { + int type; + int subtype; + int intvalue; + float floatvalue; + char string[1024]; +}; + +struct cmd_function_s { + cmd_function_s* next; + const char* name; + const char* autoCompleteDir; + const char* autoCompleteExt; + void(__cdecl* function)(); + int flags; +}; + +struct CmdArgs { + int nesting; + int localClientNum[8]; + int controllerIndex[8]; + int argc[8]; + const char** argv[8]; +}; + +struct msg_t { + int overflowed; + int readOnly; + unsigned char* data; + unsigned char* splitData; + int maxsize; + int cursize; + int splitSize; + int readcount; + int bit; + int lastEntityRef; +}; + +static_assert(sizeof(msg_t) == 0x28); + +typedef enum { + ERR_FATAL = 0x0, + ERR_DROP = 0x1, + ERR_SERVERDISCONNECT = 0x2, + ERR_DISCONNECT = 0x3, + ERR_SCRIPT = 0x4, + ERR_SCRIPT_DROP = 0x5, + ERR_LOCALIZATION = 0x6, + ERR_MAPLOADERRORSUMMARY = 0x7, +} errorParm_t; + +enum DvarFlags : std::uint16_t { + DVAR_NONE = 0, + DVAR_ARCHIVE = 1 << 0, + DVAR_LATCH = 1 << 1, + DVAR_CHEAT = 1 << 2, + DVAR_CODINFO = 1 << 3, + DVAR_SCRIPTINFO = 1 << 4, + DVAR_TEMP = 1 << 5, + DVAR_SAVED = 1 << 6, + DVAR_INTERNAL = 1 << 7, + DVAR_EXTERNAL = 1 << 8, + DVAR_USERINFO = 1 << 9, + DVAR_SERVERINFO = 1 << 10, + DVAR_INIT = 1 << 11, + DVAR_SYSTEMINFO = 1 << 12, + DVAR_ROM = 1 << 13, + DVAR_CHANGEABLE_RESET = 1 << 14, + DVAR_AUTOEXEC = 1 << 15, +}; + +enum : std::int8_t { + DVAR_TYPE_BOOL = 0x0, + DVAR_TYPE_FLOAT = 0x1, + DVAR_TYPE_FLOAT_2 = 0x2, + DVAR_TYPE_FLOAT_3 = 0x3, + DVAR_TYPE_FLOAT_4 = 0x4, + DVAR_TYPE_INT = 0x5, + DVAR_TYPE_ENUM = 0x6, + DVAR_TYPE_STRING = 0x7, + DVAR_TYPE_COLOR = 0x8, + DVAR_TYPE_FLOAT_3_COLOR = 0x9, +}; + +enum DvarSetSource { + DVAR_SOURCE_INTERNAL, + DVAR_SOURCE_EXTERNAL, + DVAR_SOURCE_SCRIPT, + DVAR_SOURCE_DEVGUI, +}; + +union DvarValue { + bool enabled; + int integer; + unsigned int unsignedInt; + float value; + float vector[4]; + const char* string; + unsigned char color[4]; +}; + +struct enum_limit { + int stringCount; + const char** strings; +}; + +struct int_limit { + int min; + int max; +}; + +struct float_limit { + float min; + float max; +}; + +union DvarLimits { + enum_limit enumeration; + int_limit integer; + float_limit value; + float_limit vector; +}; + +struct dvar_t { + const char* name; + const char* description; + unsigned int flags; + char type; + bool modified; + DvarValue current; + DvarValue latched; + DvarValue reset; + DvarLimits domain; + bool(__cdecl* domainFunc)(dvar_t*, DvarValue); + dvar_t* hashNext; +}; + +enum netsrc_t { + NS_CLIENT1 = 0x0, + NS_SERVER = 0x1, + NS_MAXCLIENTS = 0x1, + NS_PACKET = 0x2, +}; + +enum netadrtype_t { + NA_BOT = 0x0, + NA_BAD = 0x1, + NA_LOOPBACK = 0x2, + NA_BROADCAST = 0x3, + NA_IP = 0x4, + NA_IPX = 0x5, + NA_BROADCAST_IPX = 0x6, +}; + +struct netadr_t { + netadrtype_t type; + unsigned char ip[4]; + unsigned __int16 port; + char ipx[10]; +}; + +static_assert(sizeof(netadr_t) == 0x14); + +struct Bounds { + float midPoint[3]; + float halfSize[3]; +}; + +struct TriggerModel { + int contents; + unsigned __int16 hullCount; + unsigned __int16 firstHull; +}; + +struct TriggerHull { + Bounds bounds; + int contents; + unsigned __int16 slabCount; + unsigned __int16 firstSlab; +}; + +struct TriggerSlab { + float dir[3]; + float midPoint; + float halfSize; +}; + +struct MapTriggers { + unsigned int count; + TriggerModel* models; + unsigned int hullCount; + TriggerHull* hulls; + unsigned int slabCount; + TriggerSlab* slabs; +}; + +struct Stage { + const char* name; + float origin[3]; + unsigned __int16 triggerIndex; + char sunPrimaryLightIndex; +}; + +struct MapEnts { + const char* name; + char* entityString; + int numEntityChars; + MapTriggers trigger; + Stage* stages; + char stageCount; +}; + +struct WeaponCompleteDef { + const char* szInternalName; +}; // Incomplete + +struct Font_s { + const char* fontName; + int pixelHeight; + int glyphCount; + void* material; + void* glowMaterial; + void* glyphs; +}; + +struct RawFile { + const char* name; + int compressedLen; + int len; + const char* buffer; +}; + +struct G_GlassPiece { + unsigned __int16 damageTaken; + unsigned __int16 collapseTime; + int lastStateChangeTime; + char impactDir; + char impactPos[2]; +}; + +static_assert(sizeof(G_GlassPiece) == 0xC); + +struct G_GlassName { + char* nameStr; + unsigned __int16 name; + unsigned __int16 pieceCount; + unsigned __int16* pieceIndices; +}; + +static_assert(sizeof(G_GlassName) == 0xC); + +struct G_GlassData { + G_GlassPiece* glassPieces; + unsigned int pieceCount; + unsigned __int16 damageToWeaken; + unsigned __int16 damageToDestroy; + unsigned int glassNameCount; + G_GlassName* glassNames; + unsigned __int8 pad[108]; +}; + +static_assert(sizeof(G_GlassData) == 0x80); + +struct GameWorldMp { + const char* name; + G_GlassData* g_glassData; +}; + +struct GameWorldSp { + const char* name; + unsigned char __pad0[0x30]; + G_GlassData* g_glassData; +}; + +static_assert(sizeof(GameWorldSp) == 0x38); + +struct MenuList { + const char* name; + int menuCount; + void** menus; +}; + +struct LocalizeEntry { + const char* value; + const char* name; +}; + +union XAssetHeader { + GameWorldSp* gameWorldSp; + GameWorldMp* gameWorldMp; + MapEnts* mapEnts; + Font_s* font; + MenuList* menuList; + LocalizeEntry* localize; + WeaponCompleteDef* weapon; + RawFile* rawfile; + void* data; +}; + +struct XAsset { + XAssetType type; + XAssetHeader header; +}; + +struct XAssetEntry { + XAsset asset; + unsigned char zoneIndex; + volatile unsigned char inuseMask; + bool printedMissingAsset; + unsigned __int16 nextHash; + unsigned __int16 nextOverride; +}; + +static_assert(sizeof(XAssetEntry) == 0x10); + +struct XZoneInfo { + const char* name; + int allocFlags; + int freeFlags; +}; + +struct playerState_s { + int commandTime; + int pm_type; + int pm_time; + int pm_flags; + int otherFlags; + int linkFlags; + int bobCycle; + float origin[3]; + float velocity[3]; + unsigned char __pad0[0xAC70]; +}; + +static_assert(sizeof(playerState_s) == 0xACA4); + +struct gclient_s { + playerState_s ps; + unsigned char __pad0[0xB0]; + int flags; // 0xAD54 + unsigned char __pad1[0x27C]; +}; + +static_assert(sizeof(gclient_s) == 0xAFD4); + +struct entityState_s { + unsigned char eType; // 0 + unsigned char __pad0[0x7D]; + unsigned __int16 number; // 0x7E + unsigned char __pad1[0x2C]; +}; + +static_assert(sizeof(entityState_s) == 0xAC); + +struct entityShared_t { + unsigned char __pad0[0x5C]; +}; + +static_assert(sizeof(entityShared_t) == 0x5C); + +struct gentity_s { + entityState_s s; + entityShared_t r; + gclient_s* client; + unsigned char __pad0[0x164]; +}; + +static_assert(sizeof(gentity_s) == 0x270); + +struct client_t { + unsigned char __pad0[0x1674]; +}; + +static_assert(sizeof(client_t) == 0x1674); + +struct level_locals_t { + unsigned char __pad0[0x34]; + int time; + unsigned char __pad1[0x4748]; +}; + +static_assert(sizeof(level_locals_t) == 0x4780); + +struct field_t { + int cursor; + int scroll; + int drawWidth; + int widthInPixels; + float charHeight; + int fixedSize; + char buffer[256]; +}; + +struct ConDrawInputGlob { + char autoCompleteChoice[64]; + int matchIndex; + int matchCount; + const char* inputText; + int inputTextLen; + bool hasExactMatch; + bool mayAutoComplete; + float x; + float y; + float leftX; + float fontHeight; +}; + +struct MessageLine { + int messageIndex; + int textBufPos; + int textBufSize; + int typingStartTime; + int lastTypingSoundTime; + int flags; +}; + +struct Message { + int startTime; + int endTime; +}; + +struct MessageWindow { + MessageLine* lines; + Message* messages; + char* circularTextBuffer; + int textBufSize; + int lineCount; + int padding; + int scrollTime; + int fadeIn; + int fadeOut; + int textBufPos; + int firstLineIndex; + int activeLineCount; + int messageIndex; +}; + +struct MessageBuffer { + char gamemsgText[4][2048]; + MessageWindow gamemsgWindows[4]; + MessageLine gamemsgLines[4][12]; + Message gamemsgMessages[4][12]; + char miniconText[4096]; + MessageWindow miniconWindow; + MessageLine miniconLines[100]; + Message miniconMessages[100]; + char errorText[1024]; + MessageWindow errorWindow; + MessageLine errorLines[5]; + Message errorMessages[5]; +}; + +struct Console { + MessageWindow consoleWindow; + MessageLine consoleLines[1024]; + Message consoleMessages[1024]; + char consoleText[65536]; + char textTempLine[512]; + unsigned int lineOffset; + int displayLineOffset; + int prevChannel; + bool outputVisible; + int fontHeight; + int visibleLineCount; + int visiblePixelWidth; + float screenMin[2]; + float screenMax[2]; + MessageBuffer messageBuffer[1]; + float color[4]; +}; + +enum { + KEYCATCH_CONSOLE = 0x1, +}; + +enum ScreenPlacementMode { + SCRMODE_FULL = 0x0, + SCRMODE_DISPLAY = 0x1, + SCRMODE_INVALID = 0x2, + SCRMODE_COUNT = 0x3, +}; + +struct ScreenPlacement { + float scaleVirtualToReal[2]; + float scaleVirtualToFull[2]; + float scaleRealToVirtual[2]; + float realViewportPosition[2]; + float realViewportSize[2]; + float virtualViewableMin[2]; + float virtualViewableMax[2]; + float realViewableMin[2]; + float realViewableMax[2]; + float virtualAdjustableMin[2]; + float virtualAdjustableMax[2]; + float realAdjustableMin[2]; + float realAdjustableMax[2]; + float subScreenLeft; +}; + +enum usercmdButtonBits { + CMD_BUTTON_LEAN_LEFT = 0x40, + CMD_BUTTON_LEAN_RIGHT = 0x80, +}; + +struct kbutton_t { + int down[2]; + unsigned int downtime; + unsigned int msec; + bool active; + bool wasPressed; +}; + +struct usercmd_s { + int serverTime; + int buttons; + int angles[3]; + unsigned __int16 weapon; + unsigned __int16 primaryWeaponForAltMode; + unsigned __int16 offHandIndex; + char forwardmove; + char rightmove; + unsigned char upmove; + unsigned char downmove; + char pitchmove; + char yawmove; + float gunPitch; + float gunYaw; + float gunXOfs; + float gunYOfs; + float gunZOfs; + float meleeChargeYaw; + unsigned char meleeChargeDist; + char selectedLoc[2]; + unsigned char selectedLocAngle; + char remoteControlAngles[2]; +}; + +struct weaponParms { + float forward[3]; + float right[3]; + float up[3]; + float muzzleTrace[3]; + float gunForward[3]; + unsigned int weaponIndex; + const void* weapDef; + const void* weapCompleteDef; +}; + +struct lockonFireParms { + bool lockon; + gentity_s* target; + float targetPosOrOffset[3]; + bool topFire; +}; + +enum TraceHitType { + TRACE_HITTYPE_NONE = 0x0, + TRACE_HITTYPE_ENTITY = 0x1, + TRACE_HITTYPE_DYNENT_MODEL = 0x2, + TRACE_HITTYPE_DYNENT_BRUSH = 0x3, + TRACE_HITTYPE_GLASS = 0x4, +}; + +struct trace_t { + float fraction; + float normal[3]; + int surfaceFlags; + int contents; + const char* material; + TraceHitType hitType; + unsigned __int16 hitId; + unsigned __int16 modelIndex; + unsigned __int16 partName; + unsigned __int16 partGroup; + bool allsolid; + bool startsolid; + bool walkable; +}; + +static_assert(sizeof(trace_t) == 0x2C); + +struct pml_t { + float forward[3]; + float right[3]; + float up[3]; + float frametime; + int msec; + int walking; + int groundPlane; + trace_t groundTrace; + float impactSpeed; + float previous_origin[3]; + float previous_velocity[3]; + unsigned int holdrand; +}; + +static_assert(sizeof(pml_t) == 0x80); + +struct pmove_t { + playerState_s* ps; + usercmd_s cmd; + usercmd_s oldcmd; + int tracemask; + int numtouch; + int touchents[32]; + Bounds bounds; + float xyspeed; + int proneChange; + int viewChangeTime; + float viewChange; + float fTorsoPitch; + float fWaistPitch; + unsigned char handler; +}; + +static_assert(sizeof(pmove_t) == 0x140); + +enum ScopedCriticalSectionType { + SCOPED_CRITSECT_NORMAL = 0x0, + SCOPED_CRITSECT_DISABLED = 0x1, + SCOPED_CRITSECT_RELEASE = 0x2, + SCOPED_CRITSECT_TRY = 0x3, +}; + +enum CriticalSection { + CRITSECT_CONSOLE = 0x0, + CRITSECT_LSP = 0x1A, + CRITSECT_CBUF = 0x21, + CRITSECT_COUNT = 0x28, +}; + +enum { + THREAD_VALUE_PROF_STACK = 0x0, + THREAD_VALUE_VA = 0x1, + THREAD_VALUE_COM_ERROR = 0x2, + THREAD_VALUE_TRACE = 0x3, + THREAD_VALUE_COUNT = 0x4, +}; + +struct TempPriority { + void* threadHandle; + int oldPriority; +}; + +struct FastCriticalSection { + volatile long readCount; + volatile long writeCount; + TempPriority tempPriority; +}; + +struct ProfileAtom { + unsigned int value[1]; +}; + +volatile struct ProfileReadable { + unsigned int hits; + ProfileAtom total; + ProfileAtom self; +}; + +struct ProfileWritable { + int nesting; + unsigned int hits; + ProfileAtom start[3]; + ProfileAtom total; + ProfileAtom child; +}; + +struct profile_t { + ProfileWritable write; + ProfileReadable read; +}; + +struct profile_guard_t { + int id; + profile_t** ppStack; +}; + +struct ProfileStack { + profile_t prof_root; + profile_t* prof_pStack[16384]; + profile_t** prof_ppStack; + profile_t prof_array[443]; + ProfileAtom prof_overhead_internal; + ProfileAtom prof_overhead_external; + profile_guard_t prof_guardstack[32]; + int prof_guardpos; + float prof_timescale; +}; + +struct va_info_t { + char va_string[2][1024]; + int index; +}; + +static_assert(sizeof(va_info_t) == 0x804); + +struct TraceCheckCount { + int global; + int* partitions; +}; + +struct TraceThreadInfo { + TraceCheckCount checkcount; +}; + +static_assert(sizeof(TraceThreadInfo) == 0x8); +} // namespace game + +#pragma warning(pop) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp new file mode 100644 index 0000000..50cad0f --- /dev/null +++ b/src/client/game/symbols.hpp @@ -0,0 +1,259 @@ +#pragma once + +#define WEAK __declspec(selectany) + +namespace game { +// Com +WEAK symbol Com_Printf{0x41BD20}; +WEAK symbol Com_PrintWarning{0x406320}; +WEAK symbol Com_PrintError{0x4C6980}; +WEAK symbol Com_DPrintf{0x42B1F0}; +WEAK symbol Com_Error{0x43DD90}; +WEAK symbol Com_OpenLogFile{0x603030}; +WEAK symbol Com_Compress{0x4316A0}; +WEAK symbol Com_EventLoop{0x4987C0}; +WEAK symbol Com_ServerPacketEvent{0x47FD30}; + +WEAK symbol va{0x4869F0}; + +// Con +WEAK symbol Con_IsDvarCommand{0x4B6610}; + +// Sys +WEAK symbol Sys_QuitAndStartProcess{0x4D69A0}; +WEAK symbol Sys_EnterCriticalSection{0x4A4CD0}; +WEAK symbol Sys_LeaveCriticalSection{0x4F78E0}; +WEAK symbol Sys_TempPriorityEnd{0x4FB800}; +WEAK symbol Sys_LockWrite{0x43C1D0}; +WEAK symbol Sys_Milliseconds{0x44E130}; +WEAK symbol Sys_IsMainThread{0x42FA00}; +WEAK symbol Sys_IsServerThread{0x4590E0}; +WEAK symbol Sys_IsDatabaseThread{0x4C9380}; +WEAK symbol Sys_SetValue{0x483310}; +WEAK symbol Sys_Sleep{0x4CFBE0}; + +WEAK symbol BigShort{0x40E7E0}; +WEAK symbol ShortNoSwap{0x4261A0}; + +WEAK symbol LargeLocalBegin{0x43fA50}; +WEAK symbol LargeLocalBeginRight{0x6317D0}; + +// CL +WEAK symbol CL_IsCgameInitialized{0x4EEA50}; +WEAK symbol CL_CoOpConnect{0x57D240}; + +// BG +WEAK symbol + BG_LoadWeaponVariantDefInternal{0x4F5AF0}; + +// Game +WEAK symbol G_GetTime{0x4E94E0}; + +WEAK symbol Cbuf_AddText{0x4A1090}; +WEAK symbol + Cmd_ExecuteSingleCommand{0x46AFD0}; +WEAK symbol + Cmd_AddCommand{0x4478A0}; +WEAK symbol + Cmd_SetAutoComplete{0x48A880}; + +// Dvars +WEAK symbol Dvar_FindVar{0x4B29D0}; +WEAK symbol + Dvar_RegisterString{0x49E0B0}; +WEAK symbol + Dvar_RegisterBool{0x429390}; +WEAK symbol + Dvar_RegisterEnum{0x4CB7C0}; +WEAK symbol + Dvar_RegisterFloat{0x4051D0}; +WEAK symbol + Dvar_RegisterInt{0x4E9490}; + +WEAK symbol Dvar_SetFloatByName{ + 0x497250}; +WEAK symbol Dvar_SetStringByName{ + 0x440C60}; +WEAK symbol Dvar_SetInt{0x4FA540}; +WEAK symbol Dvar_SetBool{0x4E57E0}; +WEAK symbol Dvar_SetString{ + 0x480E70}; +WEAK symbol Dvar_GetString{0x411F50}; +WEAK symbol Dvar_GetBool{0x481010}; + +// Script +WEAK symbol Scr_Error{0x4E9C50}; +WEAK symbol Scr_ObjectError{0x470600}; +WEAK symbol Scr_ParamError{ + 0x42C880}; +WEAK symbol GetEntity{0x4678C0}; + +WEAK symbol Scr_GetNumParam{0x4443F0}; +WEAK symbol Scr_ClearOutParams{0x4A3A00}; +WEAK symbol Scr_GetTypeName{0x4CE240}; +WEAK symbol Scr_GetString{0x4D39C0}; +WEAK symbol Scr_AddString{0x4CD670}; +WEAK symbol Scr_GetConstString{0x4AF1B0}; +WEAK symbol Scr_AddConstString{0x404CF0}; +WEAK symbol Scr_GetInt{0x454520}; +WEAK symbol Scr_AddInt{0x4865B0}; +WEAK symbol Scr_GetFloat{0x4AE590}; +WEAK symbol Scr_AddFloat{0x4986E0}; +WEAK symbol Scr_GetType{0x464EE0}; +WEAK symbol Scr_RegisterFunction{0x4F59C0}; +WEAK symbol Scr_GetFunc{0x438E10}; + +WEAK symbol + Scr_AddSourceBuffer{0x4173C0}; +WEAK symbol Scr_LoadScript{0x46CD90}; +WEAK symbol Scr_GetFunctionHandle{ + 0x462750}; +WEAK symbol Scr_ExecThread{0x41A2C0}; +WEAK symbol Scr_FreeThread{0x4C44A0}; + +// SL +WEAK symbol SL_ConvertToString{0x40E990}; +WEAK symbol SL_AddRefToString{0x4C4BD0}; +WEAK symbol SL_RemoveRefToString{0x4698E0}; + +WEAK symbol NET_AdrToString{0x4BF490}; +WEAK symbol NET_ErrorString{0x430390}; + +// Memory +WEAK symbol Hunk_AllocateTempMemory{0x492DF0}; +WEAK symbol Hunk_AllocAlignInternal{0x486C40}; + +// Zone +WEAK symbol Z_VirtualAllocInternal{0x4D9CF0}; +WEAK symbol Z_TryVirtualAllocInternal{ + 0x4D9590}; +WEAK symbol Z_VirtualFreeInternal{0x4FE260}; + +// DB +WEAK symbol + DB_FindXAssetHeader{0x40B200}; +WEAK symbol DB_IsXAssetDefault{ + 0x41AB70}; +WEAK symbol DB_GetRawBuffer{ + 0x4345E0}; +WEAK symbol + DB_LoadXAssets{0x4CFC90}; +WEAK symbol DB_ReadRawFile{ + 0x46DA60}; + +// FS +WEAK symbol _FS_ReadFile{0x4A5480}; +WEAK symbol FS_Read{0x42EDC0}; +WEAK symbol FS_Write{0x449FA0}; +WEAK symbol FS_FCloseFile{0x44E0A0}; +WEAK symbol FS_FOpenFileByMode{ + 0x41DF70}; +WEAK symbol FS_FOpenFileRead{0x48DD10}; +WEAK symbol + FS_ListFiles{0x4448F0}; +WEAK symbol FS_FreeFileList{ + 0x41C7A0}; +WEAK symbol + FS_BuildOSPath{0x4E48F0}; +WEAK symbol FS_Startup{0x47AF20}; + +// UI +WEAK symbol + UI_GetFontHandle{0x4C2600}; +WEAK symbol + UI_TextWidth{0x4F5070}; +WEAK symbol UI_TextHeight{0x407710}; +WEAK symbol + UI_DrawText{0x40FC70}; + +// PC +WEAK symbol PC_Directive_define{0x4F8CF0}; +WEAK symbol PC_FreeDefine{0x464F40}; +WEAK symbol PC_CopyToken{0x4D3670}; +WEAK symbol PC_ReadTokenHandle{0x46C3B0}; +WEAK symbol PC_SourceError{0x43A6D0}; + +WEAK symbol GetMemory{0x441880}; +WEAK symbol GetClearedMemory{0x41BCD0}; +WEAK symbol FreeMemory{0x4A7D20}; + +// PM +WEAK symbol + PM_trace{0x4B7A20}; +WEAK symbol + PM_playerTrace{0x447B90}; +WEAK symbol PM_IsSprinting{0x47CF70}; + +// Live +WEAK symbol Live_GetLocalClientName{0x492EF0}; + +// Info +WEAK symbol Info_Validate{0x425530}; + +// IW functions, could use Microsoft specific functions but who cares +WEAK symbol I_stricmp{0x409B80}; +WEAK symbol I_strnicmp{0x491E60}; + +WEAK symbol Field_Clear{0x45C350}; + +// Variables +WEAK symbol cmd_args{0x144FED0}; +WEAK symbol sv_cmd_args{0x145ABA0}; +WEAK symbol g_entities{0xEAAC38}; +WEAK symbol g_clients{0x10911E8}; + +WEAK symbol com_frameTime{0x145EC7C}; + +WEAK symbol cin_skippable{0x73264C}; + +WEAK symbol g_consoleField{0x88C700}; +WEAK symbol conDrawInputGlob{0x86E788}; +WEAK symbol con{0x86ED88}; +WEAK symbol g_console_char_height{0x732658}; +WEAK symbol g_console_field_width{0x732654}; +WEAK symbol activeScreenPlacementMode{0x93AAF4}; +WEAK symbol scrPlaceFullUnsafe{0x93AB70}; + +WEAK symbol logfile{0x145EC6C}; + +WEAK symbol level{0x10A7190}; + +WEAK symbol s_criticalSection{0x19FBA28}; +WEAK symbol ip_socket{0x1A040C8}; + +WEAK symbol sourceFiles{0x7440E8}; +WEAK symbol numtokens{0x7441F0}; + +WEAK symbol DB_GetXAssetSizeHandlers{0x733408}; +WEAK symbol DB_XAssetPool{0x7337F8}; +WEAK symbol g_poolSize{0x733510}; + +WEAK symbol g_largeLocalBuf{0x195AAF8}; + +WEAK symbol g_largeLocalPos{0x1963998}; +WEAK symbol g_maxLargeLocalPos{0x195AAFC}; + +WEAK symbol g_largeLocalRightPos{0x195AAE8}; +WEAK symbol g_minLargeLocalRightPos{0x195AB00}; + +WEAK symbol g_dwTlsIndex{0x1BFC750}; +} // namespace game diff --git a/src/client/loader/binary_loader.cpp b/src/client/loader/binary_loader.cpp new file mode 100644 index 0000000..c344141 --- /dev/null +++ b/src/client/loader/binary_loader.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include "binary_loader.hpp" + +#define SP_HASH \ + "39E9C4FACEA4B19017BB8C2FC64E4149708927AC40C7C3DEACC25BDD25E93D32" + +namespace binary_loader { +std::string load_base() { + std::string data; + if (!utils::io::read_file("iw4sp.exe", &data)) { + throw std::runtime_error("Failed to read game binary (iw4sp.exe)!"); + } + + const auto hash = utils::cryptography::sha256::compute(data, true); + if (hash != SP_HASH) { + throw std::runtime_error( + "Your iw4sp.exe is incompatible with this client."); + } + + return data; +} + +std::string load() { return load_base(); } +} // namespace binary_loader diff --git a/src/client/loader/binary_loader.hpp b/src/client/loader/binary_loader.hpp new file mode 100644 index 0000000..7e8a1ea --- /dev/null +++ b/src/client/loader/binary_loader.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace binary_loader { +std::string load(); +} diff --git a/src/client/loader/component_interface.hpp b/src/client/loader/component_interface.hpp new file mode 100644 index 0000000..e51ba51 --- /dev/null +++ b/src/client/loader/component_interface.hpp @@ -0,0 +1,19 @@ +#pragma once + +class component_interface { +public: + virtual ~component_interface() = default; + + virtual void post_start() {} + + virtual void post_load() {} + + virtual void pre_destroy() {} + + virtual void* load_import([[maybe_unused]] const std::string& library, + [[maybe_unused]] const std::string& function) { + return nullptr; + } + + virtual bool is_supported() { return true; } +}; diff --git a/src/client/loader/component_loader.cpp b/src/client/loader/component_loader.cpp new file mode 100644 index 0000000..3aa56db --- /dev/null +++ b/src/client/loader/component_loader.cpp @@ -0,0 +1,100 @@ +#include +#include "component_loader.hpp" + +void component_loader::register_component( + std::unique_ptr&& component_) { + get_components().push_back(std::move(component_)); +} + +bool component_loader::post_start() { + static auto handled = false; + if (handled) + return true; + handled = true; + + try { + for (const auto& component_ : get_components()) { + component_->post_start(); + } + } catch (premature_shutdown_trigger&) { + return false; + } + + return true; +} + +bool component_loader::post_load() { + static auto handled = false; + if (handled) + return true; + handled = true; + + clean(); + + try { + for (const auto& component_ : get_components()) { + component_->post_load(); + } + } catch (premature_shutdown_trigger&) { + return false; + } + + return true; +} + +void component_loader::pre_destroy() { + static auto handled = false; + if (handled) + return; + handled = true; + + for (const auto& component_ : get_components()) { + component_->pre_destroy(); + } +} + +void component_loader::clean() { + auto& components = get_components(); + for (auto i = components.begin(); i != components.end();) { + if (!(*i)->is_supported()) { + (*i)->pre_destroy(); + i = components.erase(i); + } else { + ++i; + } + } +} + +void* component_loader::load_import(const std::string& library, + const std::string& function) { + void* function_ptr = nullptr; + + for (const auto& component_ : get_components()) { + auto* const component_function_ptr = + component_->load_import(library, function); + if (component_function_ptr) { + function_ptr = component_function_ptr; + } + } + + return function_ptr; +} + +void component_loader::trigger_premature_shutdown() { + throw premature_shutdown_trigger(); +} + +std::vector>& +component_loader::get_components() { + using component_vector = std::vector>; + using component_vector_container = + std::unique_ptr>; + + static component_vector_container components( + new component_vector, [](component_vector* component_vector) { + pre_destroy(); + delete component_vector; + }); + + return *components; +} diff --git a/src/client/loader/component_loader.hpp b/src/client/loader/component_loader.hpp new file mode 100644 index 0000000..cae9910 --- /dev/null +++ b/src/client/loader/component_loader.hpp @@ -0,0 +1,50 @@ +#pragma once +#include "component_interface.hpp" + +class component_loader final { +public: + class premature_shutdown_trigger final : public std::exception { + [[nodiscard]] const char* what() const noexcept override { + return "Premature shutdown requested"; + } + }; + + template class installer final { + static_assert(std::is_base_of::value, + "component has invalid base class"); + + public: + installer() { register_component(std::make_unique()); } + }; + + template static T* get() { + for (const auto& component_ : get_components()) { + if (typeid(*component_.get()) == typeid(T)) { + return reinterpret_cast(component_.get()); + } + } + + return nullptr; + } + + static void + register_component(std::unique_ptr&& component); + + static bool post_start(); + static bool post_load(); + static void pre_destroy(); + static void clean(); + + static void* load_import(const std::string& library, + const std::string& function); + + static void trigger_premature_shutdown(); + +private: + static std::vector>& get_components(); +}; + +#define REGISTER_COMPONENT(name) \ + namespace { \ + static component_loader::installer __component; \ + } diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp new file mode 100644 index 0000000..1ce576c --- /dev/null +++ b/src/client/loader/loader.cpp @@ -0,0 +1,190 @@ +#include + +#include +#include + +#include "loader.hpp" +#include "tls.hpp" + +FARPROC loader::load(const utils::nt::library& library, + const std::string& buffer) const { + + if (buffer.empty()) + return nullptr; + + const utils::nt::library source(HMODULE(buffer.data())); + if (!source) + return nullptr; + + this->load_sections(library, source); + this->load_imports(library, source); + this->load_tls(library, source); + + DWORD oldProtect; + VirtualProtect(library.get_nt_headers(), 0x1000, PAGE_EXECUTE_READWRITE, + &oldProtect); + + library.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] = + source.get_optional_header()->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + std::memmove(library.get_nt_headers(), source.get_nt_headers(), + sizeof(IMAGE_NT_HEADERS) + + source.get_nt_headers()->FileHeader.NumberOfSections * + sizeof(IMAGE_SECTION_HEADER)); + + return FARPROC(library.get_ptr() + source.get_relative_entry_point()); +} + +FARPROC loader::load_library(const std::string& filename) const { + const auto target = utils::nt::library::load(filename); + if (!target) { + throw std::runtime_error{"Failed to map binary!"}; + } + + const auto base = size_t(target.get_ptr()); + if (base != 0x400000) { + throw std::runtime_error{ + utils::string::va("Binary was mapped at {0:#x} (instead of {1:#x}). " + "Something is severely broken :(", + base, 0x400000)}; + } + + this->load_imports(target, target); + this->load_tls(target, target); + + return FARPROC(target.get_ptr() + target.get_relative_entry_point()); +} + +void loader::set_import_resolver( + const std::function& + resolver) { + this->import_resolver_ = resolver; +} + +void loader::load_section(const utils::nt::library& target, + const utils::nt::library& source, + IMAGE_SECTION_HEADER* section) { + void* target_ptr = target.get_ptr() + section->VirtualAddress; + const void* source_ptr = source.get_ptr() + section->PointerToRawData; + + if (PBYTE(target_ptr) >= (target.get_ptr() + BINARY_PAYLOAD_SIZE)) { + throw std::runtime_error( + "Section exceeds the binary payload size, please increase it!"); + } + + if (section->SizeOfRawData > 0) { + DWORD old_protect; + VirtualProtect(target_ptr, section->Misc.VirtualSize, + PAGE_EXECUTE_READWRITE, &old_protect); + + std::memmove(target_ptr, source_ptr, section->SizeOfRawData); + } +} + +void loader::load_sections(const utils::nt::library& target, + const utils::nt::library& source) const { + for (auto& section : source.get_section_headers()) { + this->load_section(target, source, section); + } +} + +void loader::load_imports(const utils::nt::library& target, + const utils::nt::library& source) const { + const auto import_directory = + &source.get_optional_header() + ->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + + auto descriptor = PIMAGE_IMPORT_DESCRIPTOR(target.get_ptr() + + import_directory->VirtualAddress); + + while (descriptor->Name) { + std::string name = LPSTR(target.get_ptr() + descriptor->Name); + + auto name_table_entry = reinterpret_cast( + target.get_ptr() + descriptor->OriginalFirstThunk); + auto address_table_entry = + reinterpret_cast(target.get_ptr() + descriptor->FirstThunk); + + if (!descriptor->OriginalFirstThunk) { + name_table_entry = reinterpret_cast(target.get_ptr() + + descriptor->FirstThunk); + } + + while (*name_table_entry) { + FARPROC function = nullptr; + std::string function_name; + const char* function_procname; + + if (IMAGE_SNAP_BY_ORDINAL(*name_table_entry)) { + function_name = "#" + std::to_string(IMAGE_ORDINAL(*name_table_entry)); + function_procname = MAKEINTRESOURCEA(IMAGE_ORDINAL(*name_table_entry)); + } else { + auto* import = + PIMAGE_IMPORT_BY_NAME(target.get_ptr() + *name_table_entry); + function_name = import->Name; + function_procname = function_name.data(); + } + + if (this->import_resolver_) + function = FARPROC(this->import_resolver_(name, function_name)); + + if (!function) { + auto library = utils::nt::library::load(name); + if (library) { + function = GetProcAddress(library, function_procname); + } + } + + if (!function) { + throw std::runtime_error( + utils::string::va("Unable to load import '{0}' from library {1}'", + function_name, name)); + } + + utils::hook::set(address_table_entry, + reinterpret_cast(function)); + + name_table_entry++; + address_table_entry++; + } + + descriptor++; + } +} + +void loader::load_tls(const utils::nt::library& target, + const utils::nt::library& source) const { + if (!target.get_optional_header() + ->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] + .Size) { + return; + } + + auto* target_tls = tls::allocate_tls_index(); + const auto* const source_tls = reinterpret_cast( + target.get_ptr() + target.get_optional_header() + ->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] + .VirtualAddress); + + auto* target_tls_start = PVOID(target_tls->StartAddressOfRawData); + auto* tls_start = PVOID(source_tls->StartAddressOfRawData); + const auto tls_size = + source_tls->EndAddressOfRawData - source_tls->StartAddressOfRawData; + const auto tls_index = *reinterpret_cast(target_tls->AddressOfIndex); + + utils::hook::set(source_tls->AddressOfIndex, tls_index); + + if (target_tls->AddressOfCallBacks) { + utils::hook::set(target_tls->AddressOfCallBacks, nullptr); + } + + DWORD old_protect; + VirtualProtect(target_tls_start, tls_size, PAGE_READWRITE, &old_protect); + + auto* const tls_base = + *reinterpret_cast(__readfsdword(0x2C) + 4 * tls_index); + std::memmove(tls_base, tls_start, tls_size); + std::memmove(target_tls_start, tls_start, tls_size); + + VirtualProtect(target_tls, sizeof(*target_tls), PAGE_READWRITE, &old_protect); + *target_tls = *source_tls; +} diff --git a/src/client/loader/loader.hpp b/src/client/loader/loader.hpp new file mode 100644 index 0000000..575695e --- /dev/null +++ b/src/client/loader/loader.hpp @@ -0,0 +1,25 @@ +#pragma once + +class loader final { +public: + FARPROC load(const utils::nt::library& library, + const std::string& buffer) const; + FARPROC load_library(const std::string& filename) const; + + void set_import_resolver( + const std::function& + resolver); + +private: + std::function import_resolver_; + + static void load_section(const utils::nt::library& target, + const utils::nt::library& source, + IMAGE_SECTION_HEADER* section); + void load_sections(const utils::nt::library& target, + const utils::nt::library& source) const; + void load_imports(const utils::nt::library& target, + const utils::nt::library& source) const; + void load_tls(const utils::nt::library& target, + const utils::nt::library& source) const; +}; diff --git a/src/client/loader/tls.cpp b/src/client/loader/tls.cpp new file mode 100644 index 0000000..feb4bc1 --- /dev/null +++ b/src/client/loader/tls.cpp @@ -0,0 +1,34 @@ +#include +#include "tls.hpp" + +#include +#include + +#include + +namespace tls { +namespace { +utils::binary_resource tls_dll_file(TLS_DLL, "iw4sp-tlsdll.dll"); +} + +PIMAGE_TLS_DIRECTORY allocate_tls_index() { + static auto already_allocated = false; + if (already_allocated) { + throw std::runtime_error( + "Currently only a single allocation is supported!"); + } + + already_allocated = true; + + const auto dll_path = tls_dll_file.get_extracted_file(); + const auto tls_dll = utils::nt::library::load(dll_path); + if (!tls_dll) { + throw std::runtime_error("Failed to load TLS DLL"); + } + + return reinterpret_cast( + tls_dll.get_ptr() + tls_dll.get_optional_header() + ->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS] + .VirtualAddress); +} +} // namespace tls diff --git a/src/client/loader/tls.hpp b/src/client/loader/tls.hpp new file mode 100644 index 0000000..056eb60 --- /dev/null +++ b/src/client/loader/tls.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace tls { +PIMAGE_TLS_DIRECTORY allocate_tls_index(); +} diff --git a/src/client/main.cpp b/src/client/main.cpp new file mode 100644 index 0000000..aebb973 --- /dev/null +++ b/src/client/main.cpp @@ -0,0 +1,150 @@ +#include "std_include.hpp" +#include +#include +#include + +#include "loader/binary_loader.hpp" +#include "loader/component_loader.hpp" +#include "loader/loader.hpp" + +#include + +#include +#include + +LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception_info) { + if (exception_info->ExceptionRecord->ExceptionCode == 0x406D1388) { + return EXCEPTION_CONTINUE_EXECUTION; + } + + if (exception_info->ExceptionRecord->ExceptionCode < 0x80000000 || + exception_info->ExceptionRecord->ExceptionCode == 0xE06D7363) { + return EXCEPTION_CONTINUE_SEARCH; + } + + MINIDUMP_EXCEPTION_INFORMATION exception_information = { + GetCurrentThreadId(), exception_info, FALSE}; + const auto type = MiniDumpIgnoreInaccessibleMemory // + | MiniDumpWithHandleData // + | MiniDumpScanMemory // + | MiniDumpWithProcessThreadData // + | MiniDumpWithFullMemoryInfo // + | MiniDumpWithThreadInfo; + + CreateDirectoryA("minidumps", nullptr); + const auto* file_name = + utils::string::va("minidumps\\iw4-sp_{0}.dmp", SHORTVERSION); + constexpr auto file_share = FILE_SHARE_READ | FILE_SHARE_WRITE; + const auto file_handle = + CreateFileA(file_name, GENERIC_WRITE | GENERIC_READ, file_share, nullptr, + CREATE_ALWAYS, NULL, nullptr); + + if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), + file_handle, static_cast(type), + &exception_information, nullptr, nullptr)) { + char buf[4096]{}; + sprintf_s(buf, "An exception 0x%08X occurred at location 0x%p\n", + exception_info->ExceptionRecord->ExceptionCode, + exception_info->ExceptionRecord->ExceptionAddress); + MessageBoxA(nullptr, buf, "Fatal Error", MB_ICONERROR); + } + + CloseHandle(file_handle); + TerminateProcess(GetCurrentProcess(), + exception_info->ExceptionRecord->ExceptionCode); + + return EXCEPTION_CONTINUE_SEARCH; +} + +DECLSPEC_NORETURN void WINAPI exit_hook(const int code) { + component_loader::pre_destroy(); + std::exit(code); +} + +FARPROC load_binary() { + loader loader; + utils::nt::library self; + + loader.set_import_resolver( + [self](const std::string& library, const std::string& function) -> void* { + if (library == "steam_api.dll") { + return self.get_proc(function); + } + if (function == "ExitProcess") { + return exit_hook; + } + + return component_loader::load_import(library, function); + }); + + const auto buffer = binary_loader::load(); + return loader.load(self, buffer); +} + +void enable_dpi_awareness() { + const utils::nt::library user32{"user32.dll"}; + const auto set_dpi = + user32 ? user32.get_proc( + "SetProcessDpiAwarenessContext") + : nullptr; + if (set_dpi) { + set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } +} + +void apply_environment() { + char* buffer{}; + std::size_t size{}; + if (_dupenv_s(&buffer, &size, "MW2_INSTALL") != 0 || buffer == nullptr) { + return; + } + + const auto _ = gsl::finally([&] { std::free(buffer); }); + + SetCurrentDirectoryA(buffer); + SetDllDirectoryA(buffer); +} + +int main() { + AddVectoredExceptionHandler(0, exception_handler); + SetProcessDEPPolicy(PROCESS_DEP_ENABLE); + + FARPROC entry_point; + enable_dpi_awareness(); + + std::srand(std::uint32_t(time(nullptr)) ^ + ~(GetTickCount() * GetCurrentProcessId())); + + { + auto premature_shutdown = true; + const auto _0 = gsl::finally([&premature_shutdown] { + if (premature_shutdown) { + component_loader::pre_destroy(); + } + }); + + try { + apply_environment(); + + if (!component_loader::post_start()) + return 0; + + entry_point = load_binary(); + if (!entry_point) { + throw std::runtime_error("Unable to load binary into memory"); + } + + if (!component_loader::post_load()) + return 0; + + premature_shutdown = false; + } catch (const std::exception& ex) { + MessageBoxA(nullptr, ex.what(), "ERROR", MB_ICONERROR); + return 1; + } + } + + return entry_point(); +} + +int APIENTRY WinMain(HINSTANCE, HINSTANCE, PSTR, int) { return main(); } diff --git a/src/client/resource.hpp b/src/client/resource.hpp new file mode 100644 index 0000000..b567072 --- /dev/null +++ b/src/client/resource.hpp @@ -0,0 +1,8 @@ +#pragma once + +#define ID_ICON 102 + +#define TLS_DLL 301 +#define RUNNER 302 + +#define ICON_IMAGE 303 diff --git a/src/client/resource.rc b/src/client/resource.rc new file mode 100644 index 0000000..aff544d --- /dev/null +++ b/src/client/resource.rc @@ -0,0 +1,117 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" +#include "version.h" +#include "resource.hpp" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "AlterWare" + VALUE "FileDescription", "IW4 SP client modification" + VALUE "FileVersion", VERSION_FILE + VALUE "InternalName", "iw4-sp" + VALUE "LegalCopyright", "Copyright (C) 2023 AlterWare. All rights reserved." + VALUE "Licence", "GPLv3" + VALUE "Info", "https://alterware.dev" + VALUE "OriginalFilename", "iw4-sp.exe" + VALUE "ProductName", "iw4-sp" + VALUE "ProductVersion", VERSION_PRODUCT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +///////////////////////////////////////////////////////////////////////////// +// +// Binary Data +// + +ID_ICON ICON "resources/icon.ico" + +#ifdef _DEBUG +TLS_DLL RCDATA "../../build/bin/Win32/Debug/tlsdll.dll" +#else +TLS_DLL RCDATA "../../build/bin/Win32/Release/tlsdll.dll" +#endif + +#ifdef _DEBUG +RUNNER RCDATA "../../build/bin/Win32/Debug/runner.exe" +#else +RUNNER RCDATA "../../build/bin/Win32/Release/runner.exe" +#endif + +ICON_IMAGE RCDATA "resources/icon.png" + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/src/client/resources/icon.ico b/src/client/resources/icon.ico new file mode 100644 index 0000000..255503b Binary files /dev/null and b/src/client/resources/icon.ico differ diff --git a/src/client/resources/icon.png b/src/client/resources/icon.png new file mode 100644 index 0000000..100578d Binary files /dev/null and b/src/client/resources/icon.png differ diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp new file mode 100644 index 0000000..b99bb2b --- /dev/null +++ b/src/client/std_include.cpp @@ -0,0 +1,27 @@ +#include "std_include.hpp" + +#pragma comment(linker, "/merge:.data=.cld") +#pragma comment(linker, "/merge:.rdata=.clr") +#pragma comment(linker, "/merge:.cl=.main") +#pragma comment(linker, "/merge:.text=.main") +#pragma comment(linker, "/base:0x400000") + +#pragma bss_seg(".payload") +char payload_data[BINARY_PAYLOAD_SIZE]; + +extern "C" { +__declspec(dllexport) DWORD NvOptimusEnablement = 1; +__declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1; +} + +extern "C" { +char* get_payload_data() { return payload_data; } +} + +extern "C" { +int s_read_arc4random(void*, std::size_t) { return -1; } + +int s_read_getrandom(void*, std::size_t) { return -1; } + +int s_read_urandom(void*, std::size_t) { return -1; } +} diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp new file mode 100644 index 0000000..ae151cb --- /dev/null +++ b/src/client/std_include.hpp @@ -0,0 +1,47 @@ +#pragma once + +#define BINARY_PAYLOAD_SIZE 0x0A000000 + +#define DLL_EXPORT extern "C" __declspec(dllexport) + +#define WIN32_LEAN_AND_MEAN + +#define BASEGAME "spdata" +#define CLIENT_CONFIG "iw4_sp_config.cfg" + +#include +#include +#include + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma comment(lib, "ntdll.lib") +#pragma comment(lib, "Crypt32.lib") +#pragma comment(lib, "Ws2_32.lib") +#pragma comment(lib, "dbghelp.lib") + +#pragma warning(disable : 4100) +#pragma warning(disable : 4244) + +// I have witnessed clang re-ordering my included even when +// it was set not to do it. :( +// clang-format off +#include "game/structs.hpp" +#include "game/game.hpp" +// clang-format on diff --git a/src/client/steam/interface.cpp b/src/client/steam/interface.cpp new file mode 100644 index 0000000..2326291 --- /dev/null +++ b/src/client/steam/interface.cpp @@ -0,0 +1,117 @@ +#include +#include "interface.hpp" + +#include +#include + +#include + +namespace steam { +interface::interface() : interface(nullptr) {} + +interface::interface(void* interface_ptr) + : interface_ptr_(static_cast(interface_ptr)) {} + +interface::operator bool() const { return this->interface_ptr_ != nullptr; } + +interface::method interface::find_method(const std::string& name) { + const auto method_entry = this->methods_.find(name); + if (method_entry != this->methods_.end()) { + return method_entry->second; + } + + return this->search_method(name); +} + +interface::method interface::search_method(const std::string& name) { + if (!utils::memory::is_bad_read_ptr(this->interface_ptr_)) { + auto vftbl = *this->interface_ptr_; + + while (!utils::memory::is_bad_read_ptr(vftbl) && + !utils::memory::is_bad_code_ptr(*vftbl)) { + const auto result = this->analyze_method(*vftbl); + if (result.param_size_found && result.name_found) { + const method method_result{*vftbl, result.param_size}; + this->methods_[result.name] = method_result; + + if (result.name == name) { + return method_result; + } + } + + ++vftbl; + } + } + + return {}; +} + +interface::method_result interface::analyze_method(const void* method_ptr) { + method_result result; + if (utils::memory::is_bad_code_ptr(method_ptr)) + return result; + + ud_t ud; + ud_init(&ud); + ud_set_mode(&ud, 32); + ud_set_pc(&ud, reinterpret_cast(method_ptr)); + ud_set_input_buffer(&ud, static_cast(method_ptr), + INT32_MAX); + + while (true) { + ud_disassemble(&ud); + + if (ud_insn_mnemonic(&ud) == UD_Iret && !result.param_size_found) { + const ud_operand* operand = ud_insn_opr(&ud, 0); + if (operand && operand->type == UD_OP_IMM && operand->size == 16) { + result.param_size = operand->lval.uword; + } else { + result.param_size = 0; + } + + result.param_size_found = true; + } + + if (ud_insn_mnemonic(&ud) == UD_Ipush && !result.name_found) { + const auto operand = ud_insn_opr(&ud, 0); + if (operand->type == UD_OP_IMM && operand->size == 32) { + auto* operand_ptr = reinterpret_cast(operand->lval.udword); + if (!utils::memory::is_bad_read_ptr(operand_ptr) && + this->is_rdata(operand_ptr)) { + result.name = operand_ptr; + result.name_found = true; + } + } + } + + if (*reinterpret_cast(ud.pc) == 0xCC) + break; // int 3 + if (result.param_size_found && result.name_found) + break; + } + + return result; +} + +bool interface::is_rdata(void* pointer) { + const auto pointer_lib = utils::nt::library::get_by_address(pointer); + + for (const auto& section : pointer_lib.get_section_headers()) { + const auto size = sizeof(section->Name); + char name[size + 1]; + name[size] = 0; + std::memcpy(name, section->Name, size); + + if (std::strcmp(name, ".rdata") == 0) { + const auto target = reinterpret_cast(pointer); + const size_t source_start = + size_t(pointer_lib.get_ptr()) + section->PointerToRawData; + const size_t source_end = source_start + section->SizeOfRawData; + + return target >= source_start && target <= source_end; + } + } + + return false; +} +} // namespace steam diff --git a/src/client/steam/interface.hpp b/src/client/steam/interface.hpp new file mode 100644 index 0000000..b42df89 --- /dev/null +++ b/src/client/steam/interface.hpp @@ -0,0 +1,82 @@ +#pragma once + +#ifdef interface +#undef interface +#endif + +namespace steam { +template +struct argument_size_calculator final : std::integral_constant { +}; + +template +struct argument_size_calculator final + : std::integral_constant::value + + (sizeof(void*) - 1)) & + ~(sizeof(void*) - 1))> {}; + +class interface final { +public: + class method final { + public: + void* pointer = nullptr; + std::size_t param_size = 0; + }; + + class method_result final { + public: + std::string name; + std::size_t param_size = 0; + bool name_found = false; + bool param_size_found = false; + }; + + interface(); + interface(void* interface_ptr); + + operator bool() const; + + template + T invoke(const std::string& method_name, Args... args) { + if (!this->interface_ptr_) { + throw std::runtime_error("Invalid interface pointer"); + } + + const auto method_result = this->find_method(method_name); + if (!method_result.pointer) { + throw std::runtime_error("Unable to find desired method"); + } + + constexpr std::size_t passed_argc = + argument_size_calculator::value; + if (passed_argc != method_result.param_size) { + throw std::runtime_error("Invalid argument count"); + } + + return static_cast(method_result.pointer)( + this->interface_ptr_, args...); + } + + template + T invoke(const std::size_t table_entry, Args... args) { + if (!this->interface_ptr_) { + throw std::runtime_error("Invalid interface pointer"); + } + + return static_cast( + (*this->interface_ptr_)[table_entry])(this->interface_ptr_, args...); + } + +private: + void*** interface_ptr_; + std::unordered_map methods_; + + method find_method(const std::string& name); + method search_method(const std::string& name); + + method_result analyze_method(const void* method_ptr); + + bool is_rdata(void* pointer); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/apps.cpp b/src/client/steam/interfaces/apps.cpp new file mode 100644 index 0000000..ba788e1 --- /dev/null +++ b/src/client/steam/interfaces/apps.cpp @@ -0,0 +1,37 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +bool apps::BIsSubscribed() { return true; } + +bool apps::BIsLowViolence() { return false; } + +bool apps::BIsCybercafe() { return false; } + +bool apps::BIsVACBanned() { return false; } + +const char* apps::GetCurrentGameLanguage() { return "english"; } + +const char* apps::GetAvailableGameLanguages() { return "english"; } + +bool apps::BIsSubscribedApp(unsigned int appID) { return true; } + +bool apps::BIsDlcInstalled(unsigned int appID) { return true; } + +unsigned int apps::GetEarliestPurchaseUnixTime(unsigned int nAppID) { + return 0; +} + +bool apps::BIsSubscribedFromFreeWeekend() { return false; } + +int apps::GetDLCCount() { return 0; } + +bool apps::BGetDLCDataByIndex(int iDLC, unsigned int* pAppID, bool* pbAvailable, + char* pchName, int cchNameBufferSize) { + return false; +} + +void apps::InstallDLC(unsigned int nAppID) {} + +void apps::UninstallDLC(unsigned int nAppID) {} +} // namespace steam diff --git a/src/client/steam/interfaces/apps.hpp b/src/client/steam/interfaces/apps.hpp new file mode 100644 index 0000000..e5c91e4 --- /dev/null +++ b/src/client/steam/interfaces/apps.hpp @@ -0,0 +1,26 @@ +#pragma once + +namespace steam { +class apps { +protected: + ~apps() = default; + +public: + virtual bool BIsSubscribed(); + virtual bool BIsLowViolence(); + virtual bool BIsCybercafe(); + virtual bool BIsVACBanned(); + virtual const char* GetCurrentGameLanguage(); + virtual const char* GetAvailableGameLanguages(); + virtual bool BIsSubscribedApp(unsigned int appID); + virtual bool BIsDlcInstalled(unsigned int appID); + virtual unsigned int GetEarliestPurchaseUnixTime(unsigned int nAppID); + virtual bool BIsSubscribedFromFreeWeekend(); + virtual int GetDLCCount(); + virtual bool BGetDLCDataByIndex(int iDLC, unsigned int* pAppID, + bool* pbAvailable, char* pchName, + int cchNameBufferSize); + virtual void InstallDLC(unsigned int nAppID); + virtual void UninstallDLC(unsigned int nAppID); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/friends.cpp b/src/client/steam/interfaces/friends.cpp new file mode 100644 index 0000000..c05647f --- /dev/null +++ b/src/client/steam/interfaces/friends.cpp @@ -0,0 +1,130 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +const char* friends::GetPersonaName() { return "GlaDos"; } + +void friends::SetPersonaName(const char* pchPersonaName) {} + +int friends::GetPersonaState() { return 1; } + +int friends::GetFriendCount(int eFriendFlags) { return 0; } + +steam_id friends::GetFriendByIndex(int iFriend, int iFriendFlags) { + return steam_id(); +} + +int friends::GetFriendRelationship(steam_id steamIDFriend) { return 0; } + +int friends::GetFriendPersonaState(steam_id steamIDFriend) { return 0; } + +const char* friends::GetFriendPersonaName(steam_id steamIDFriend) { return ""; } + +bool friends::GetFriendGamePlayed(steam_id steamIDFriend, + void* pFriendGameInfo) { + return false; +} + +const char* friends::GetFriendPersonaNameHistory(steam_id steamIDFriend, + int iPersonaName) { + return ""; +} + +bool friends::HasFriend(steam_id steamIDFriend, int eFriendFlags) { + return false; +} + +int friends::GetClanCount() { return 0; } + +steam_id friends::GetClanByIndex(int iClan) { return steam_id(); } + +const char* friends::GetClanName(steam_id steamIDClan) { return "3arc"; } + +const char* friends::GetClanTag(steam_id steamIDClan) { + return this->GetClanName(steamIDClan); +} + +int friends::GetFriendCountFromSource(steam_id steamIDSource) { return 0; } + +steam_id friends::GetFriendFromSourceByIndex(steam_id steamIDSource, + int iFriend) { + return steam_id(); +} + +bool friends::IsUserInSource(steam_id steamIDUser, steam_id steamIDSource) { + return false; +} + +void friends::SetInGameVoiceSpeaking(steam_id steamIDUser, bool bSpeaking) {} + +void friends::ActivateGameOverlay(const char* pchDialog) {} + +void friends::ActivateGameOverlayToUser(const char* pchDialog, + steam_id steamID) {} + +void friends::ActivateGameOverlayToWebPage(const char* pchURL) {} + +void friends::ActivateGameOverlayToStore(unsigned int nAppID) { + OutputDebugStringA("Store requested!"); +} + +void friends::SetPlayedWith(steam_id steamIDUserPlayedWith) {} + +void friends::ActivateGameOverlayInviteDialog(steam_id steamIDLobby) {} + +int friends::GetSmallFriendAvatar(steam_id steamIDFriend) { return 0; } + +int friends::GetMediumFriendAvatar(steam_id steamIDFriend) { return 0; } + +int friends::GetLargeFriendAvatar(steam_id steamIDFriend) { return 0; } + +bool friends::RequestUserInformation(steam_id steamIDUser, + bool bRequireNameOnly) { + return false; +} + +unsigned __int64 friends::RequestClanOfficerList(steam_id steamIDClan) { + return 0; +} + +steam_id friends::GetClanOwner(steam_id steamIDClan) { return steam_id(); } + +int friends::GetClanOfficerCount(steam_id steamIDClan) { return 0; } + +steam_id friends::GetClanOfficerByIndex(steam_id steamIDClan, int iOfficer) { + return steam_id(); +} + +int friends::GetUserRestrictions() { return 0; } + +bool friends::SetRichPresence(const char* pchKey, const char* pchValue) { + return true; +} + +void friends::ClearRichPresence() {} + +const char* friends::GetFriendRichPresence(steam_id steamIDFriend, + const char* pchKey) { + return ""; +} + +int friends::GetFriendRichPresenceKeyCount(steam_id steamIDFriend) { return 0; } + +const char* friends::GetFriendRichPresenceKeyByIndex(steam_id steamIDFriend, + int iKey) { + return "a"; +} + +bool friends::InviteUserToGame(steam_id steamIDFriend, + const char* pchConnectString) { + return false; +} + +int friends::GetCoplayFriendCount() { return 0; } + +steam_id friends::GetCoplayFriend(int iCoplayFriend) { return steam_id(); } + +int friends::GetFriendCoplayTime(steam_id steamIDFriend) { return 0; } + +unsigned int friends::GetFriendCoplayGame(steam_id steamIDFriend) { return 0; } +} // namespace steam diff --git a/src/client/steam/interfaces/friends.hpp b/src/client/steam/interfaces/friends.hpp new file mode 100644 index 0000000..9efedf3 --- /dev/null +++ b/src/client/steam/interfaces/friends.hpp @@ -0,0 +1,62 @@ +#pragma once + +namespace steam { +class friends { +protected: + ~friends() = default; + +public: + virtual const char* GetPersonaName(); + virtual void SetPersonaName(const char* pchPersonaName); + virtual int GetPersonaState(); + virtual int GetFriendCount(int eFriendFlags); + virtual steam_id GetFriendByIndex(int iFriend, int iFriendFlags); + virtual int GetFriendRelationship(steam_id steamIDFriend); + virtual int GetFriendPersonaState(steam_id steamIDFriend); + virtual const char* GetFriendPersonaName(steam_id steamIDFriend); + virtual bool GetFriendGamePlayed(steam_id steamIDFriend, + void* pFriendGameInfo); + virtual const char* GetFriendPersonaNameHistory(steam_id steamIDFriend, + int iPersonaName); + virtual bool HasFriend(steam_id steamIDFriend, int eFriendFlags); + virtual int GetClanCount(); + virtual steam_id GetClanByIndex(int iClan); + virtual const char* GetClanName(steam_id steamIDClan); + virtual const char* GetClanTag(steam_id steamIDClan); + virtual int GetFriendCountFromSource(steam_id steamIDSource); + virtual steam_id GetFriendFromSourceByIndex(steam_id steamIDSource, + int iFriend); + virtual bool IsUserInSource(steam_id steamIDUser, steam_id steamIDSource); + virtual void SetInGameVoiceSpeaking(steam_id steamIDUser, bool bSpeaking); + virtual void ActivateGameOverlay(const char* pchDialog); + virtual void ActivateGameOverlayToUser(const char* pchDialog, + steam_id steamID); + virtual void ActivateGameOverlayToWebPage(const char* pchURL); + virtual void ActivateGameOverlayToStore(unsigned int nAppID); + virtual void SetPlayedWith(steam_id steamIDUserPlayedWith); + virtual void ActivateGameOverlayInviteDialog(steam_id steamIDLobby); + virtual int GetSmallFriendAvatar(steam_id steamIDFriend); + virtual int GetMediumFriendAvatar(steam_id steamIDFriend); + virtual int GetLargeFriendAvatar(steam_id steamIDFriend); + virtual bool RequestUserInformation(steam_id steamIDUser, + bool bRequireNameOnly); + virtual unsigned __int64 RequestClanOfficerList(steam_id steamIDClan); + virtual steam_id GetClanOwner(steam_id steamIDClan); + virtual int GetClanOfficerCount(steam_id steamIDClan); + virtual steam_id GetClanOfficerByIndex(steam_id steamIDClan, int iOfficer); + virtual int GetUserRestrictions(); + virtual bool SetRichPresence(const char* pchKey, const char* pchValue); + virtual void ClearRichPresence(); + virtual const char* GetFriendRichPresence(steam_id steamIDFriend, + const char* pchKey); + virtual int GetFriendRichPresenceKeyCount(steam_id steamIDFriend); + virtual const char* GetFriendRichPresenceKeyByIndex(steam_id steamIDFriend, + int iKey); + virtual bool InviteUserToGame(steam_id steamIDFriend, + const char* pchConnectString); + virtual int GetCoplayFriendCount(); + virtual steam_id GetCoplayFriend(int iCoplayFriend); + virtual int GetFriendCoplayTime(steam_id steamIDFriend); + virtual unsigned int GetFriendCoplayGame(steam_id steamIDFriend); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/game_server.cpp b/src/client/steam/interfaces/game_server.cpp new file mode 100644 index 0000000..eebb5ef --- /dev/null +++ b/src/client/steam/interfaces/game_server.cpp @@ -0,0 +1,74 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +void game_server::LogOn() {} + +void game_server::LogOff() {} + +bool game_server::LoggedOn() { return true; } + +bool game_server::Secure() { return false; } + +steam_id game_server::GetSteamID() { return steam_id(); } + +bool game_server::SendUserConnectAndAuthenticate(unsigned int unIPClient, + const void* pvAuthBlob, + unsigned int cubAuthBlobSize, + steam_id* pSteamIDUser) { + return true; +} + +steam_id game_server::CreateUnauthenticatedUserConnection() { + return steam_id(); +} + +void game_server::SendUserDisconnect(steam_id steamIDUser) {} + +bool game_server::UpdateUserData(steam_id steamIDUser, + const char* pchPlayerName, + unsigned int uScore) { + return true; +} + +bool game_server::SetServerType(unsigned int unServerFlags, + unsigned int unGameIP, + unsigned short unGamePort, + unsigned short unSpectatorPort, + unsigned short usQueryPort, + const char* pchGameDir, const char* pchVersion, + bool bLANMode) { + return true; +} + +void game_server::UpdateServerStatus(int cPlayers, int cPlayersMax, + int cBotPlayers, const char* pchServerName, + const char* pSpectatorServerName, + const char* pchMapName) {} + +void game_server::UpdateSpectatorPort(unsigned short unSpectatorPort) {} + +void game_server::SetGameType(const char* pchGameType) {} + +bool game_server::GetUserAchievementStatus(steam_id steamID, + const char* pchAchievementName) { + return false; +} + +void game_server::GetGameplayStats() {} + +unsigned __int64 game_server::GetServerReputation() { return 0; } + +bool game_server::RequestUserGroupStatus(steam_id steamIDUser, + steam_id steamIDGroup) { + return false; +} + +unsigned int game_server::GetPublicIP() { return 0; } + +void game_server::SetGameData(const char* pchGameData) {} + +int game_server::UserHasLicenseForApp(steam_id steamID, unsigned int appID) { + return 0; +} +} // namespace steam diff --git a/src/client/steam/interfaces/game_server.hpp b/src/client/steam/interfaces/game_server.hpp new file mode 100644 index 0000000..8d2854a --- /dev/null +++ b/src/client/steam/interfaces/game_server.hpp @@ -0,0 +1,43 @@ +#pragma once + +namespace steam { +class game_server { +protected: + ~game_server() = default; + +public: + virtual void LogOn(); + virtual void LogOff(); + virtual bool LoggedOn(); + virtual bool Secure(); + virtual steam_id GetSteamID(); + virtual bool SendUserConnectAndAuthenticate(unsigned int unIPClient, + const void* pvAuthBlob, + unsigned int cubAuthBlobSize, + steam_id* pSteamIDUser); + virtual steam_id CreateUnauthenticatedUserConnection(); + virtual void SendUserDisconnect(steam_id steamIDUser); + virtual bool UpdateUserData(steam_id steamIDUser, const char* pchPlayerName, + unsigned int uScore); + virtual bool SetServerType(unsigned int unServerFlags, unsigned int unGameIP, + unsigned short unGamePort, + unsigned short unSpectatorPort, + unsigned short usQueryPort, const char* pchGameDir, + const char* pchVersion, bool bLANMode); + virtual void UpdateServerStatus(int cPlayers, int cPlayersMax, + int cBotPlayers, const char* pchServerName, + const char* pSpectatorServerName, + const char* pchMapName); + virtual void UpdateSpectatorPort(unsigned short unSpectatorPort); + virtual void SetGameType(const char* pchGameType); + virtual bool GetUserAchievementStatus(steam_id steamID, + const char* pchAchievementName); + virtual void GetGameplayStats(); + virtual unsigned __int64 GetServerReputation(); + virtual bool RequestUserGroupStatus(steam_id steamIDUser, + steam_id steamIDGroup); + virtual unsigned int GetPublicIP(); + virtual void SetGameData(const char* pchGameData); + virtual int UserHasLicenseForApp(steam_id steamID, unsigned int appID); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/master_server_updater.cpp b/src/client/steam/interfaces/master_server_updater.cpp new file mode 100644 index 0000000..a76cb29 --- /dev/null +++ b/src/client/steam/interfaces/master_server_updater.cpp @@ -0,0 +1,51 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +void master_server_updater::SetActive(bool bActive) {} + +void master_server_updater::SetHeartbeatInterval(int iHeartbeatInterval) {} + +bool master_server_updater::HandleIncomingPacket(const void* pData, int cbData, + unsigned int srcIP, + unsigned short srcPort) { + return true; +} + +int master_server_updater::GetNextOutgoingPacket(void* pOut, int cbMaxOut, + unsigned int* pNetAdr, + unsigned short* pPort) { + return 0; +} + +void master_server_updater::SetBasicServerData( + unsigned short nProtocolVersion, bool bDedicatedServer, + const char* pRegionName, const char* pProductName, + unsigned short nMaxReportedClients, bool bPasswordProtected, + const char* pGameDescription) {} + +void master_server_updater::ClearAllKeyValues() {} + +void master_server_updater::SetKeyValue(const char* pKey, const char* pValue) {} + +void master_server_updater::NotifyShutdown() {} + +bool master_server_updater::WasRestartRequested() { return false; } + +void master_server_updater::ForceHeartbeat() {} + +bool master_server_updater::AddMasterServer(const char* pServerAddress) { + return true; +} + +bool master_server_updater::RemoveMasterServer(const char* pServerAddress) { + return true; +} + +int master_server_updater::GetNumMasterServers() { return 0; } + +int master_server_updater::GetMasterServerAddress(int iServer, char* pOut, + int outBufferSize) { + return 0; +} +} // namespace steam diff --git a/src/client/steam/interfaces/master_server_updater.hpp b/src/client/steam/interfaces/master_server_updater.hpp new file mode 100644 index 0000000..f401b66 --- /dev/null +++ b/src/client/steam/interfaces/master_server_updater.hpp @@ -0,0 +1,32 @@ +#pragma once + +namespace steam { +class master_server_updater { +protected: + ~master_server_updater() = default; + +public: + virtual void SetActive(bool bActive); + virtual void SetHeartbeatInterval(int iHeartbeatInterval); + virtual bool HandleIncomingPacket(const void* pData, int cbData, + unsigned int srcIP, unsigned short srcPort); + virtual int GetNextOutgoingPacket(void* pOut, int cbMaxOut, + unsigned int* pNetAdr, + unsigned short* pPort); + virtual void + SetBasicServerData(unsigned short nProtocolVersion, bool bDedicatedServer, + const char* pRegionName, const char* pProductName, + unsigned short nMaxReportedClients, + bool bPasswordProtected, const char* pGameDescription); + virtual void ClearAllKeyValues(); + virtual void SetKeyValue(const char* pKey, const char* pValue); + virtual void NotifyShutdown(); + virtual bool WasRestartRequested(); + virtual void ForceHeartbeat(); + virtual bool AddMasterServer(const char* pServerAddress); + virtual bool RemoveMasterServer(const char* pServerAddress); + virtual int GetNumMasterServers(); + virtual int GetMasterServerAddress(int iServer, char* pOut, + int outBufferSize); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/matchmaking.cpp b/src/client/steam/interfaces/matchmaking.cpp new file mode 100644 index 0000000..04d82a5 --- /dev/null +++ b/src/client/steam/interfaces/matchmaking.cpp @@ -0,0 +1,184 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +int matchmaking::GetFavoriteGameCount() { return 0; } + +bool matchmaking::GetFavoriteGame(int iGame, unsigned int* pnAppID, + unsigned int* pnIP, + unsigned short* pnConnPort, + unsigned short* pnQueryPort, + unsigned int* punFlags, + unsigned int* pRTime32LastPlayedOnServer) { + return false; +} + +int matchmaking::AddFavoriteGame(unsigned int nAppID, unsigned int nIP, + unsigned short nConnPort, + unsigned short nQueryPort, + unsigned int unFlags, + unsigned int rTime32LastPlayedOnServer) { + return 0; +} + +bool matchmaking::RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, + unsigned short nConnPort, + unsigned short nQueryPort, + unsigned int unFlags) { + return false; +} + +unsigned __int64 matchmaking::RequestLobbyList() { return 0; } + +void matchmaking::AddRequestLobbyListStringFilter(const char* pchKeyToMatch, + const char* pchValueToMatch, + int eComparisonType) {} + +void matchmaking::AddRequestLobbyListNumericalFilter(const char* pchKeyToMatch, + int nValueToMatch, + int eComparisonType) {} + +void matchmaking::AddRequestLobbyListNearValueFilter(const char* pchKeyToMatch, + int nValueToBeCloseTo) {} + +void matchmaking::AddRequestLobbyListFilterSlotsAvailable(int nSlotsAvailable) { +} + +void matchmaking::AddRequestLobbyListDistanceFilter(int eLobbyDistanceFilter) {} + +void matchmaking::AddRequestLobbyListResultCountFilter(int cMaxResults) {} + +steam_id matchmaking::GetLobbyByIndex(int iLobby) { return steam_id(); } + +unsigned __int64 matchmaking::CreateLobby(int eLobbyType, int cMaxMembers) { + const auto result = callbacks::register_call(); + auto retvals = static_cast(calloc(1, sizeof(lobby_created))); + //::Utils::Memory::AllocateArray(); + steam_id id; + + id.raw.account_id = 1337132; + id.raw.universe = 1; + id.raw.account_type = 8; + id.raw.account_instance = 0x40000; + + retvals->m_e_result = 1; + retvals->m_ul_steam_id_lobby = id; + + callbacks::return_call(retvals, sizeof(lobby_created), + lobby_created::callback_id, result); + + matchmaking::JoinLobby(id); + + return result; +} + +unsigned __int64 matchmaking::JoinLobby(steam_id steamIDLobby) { + const auto result = callbacks::register_call(); + auto* retvals = static_cast(calloc(1, sizeof(lobby_enter))); + //::Utils::Memory::AllocateArray(); + retvals->m_b_locked = false; + retvals->m_e_chat_room_enter_response = 1; + retvals->m_rgf_chat_permissions = 0xFFFFFFFF; + retvals->m_ul_steam_id_lobby = steamIDLobby; + + callbacks::return_call(retvals, sizeof(lobby_enter), lobby_enter::callback_id, + result); + + return result; +} + +void matchmaking::LeaveLobby(steam_id steamIDLobby) { + // Components::Party::RemoveLobby(steamIDLobby); +} + +bool matchmaking::InviteUserToLobby(steam_id steamIDLobby, + steam_id steamIDInvitee) { + return true; +} + +int matchmaking::GetNumLobbyMembers(steam_id steamIDLobby) { return 1; } + +steam_id matchmaking::GetLobbyMemberByIndex(steam_id steamIDLobby, + int iMember) { + return SteamUser()->GetSteamID(); +} + +const char* matchmaking::GetLobbyData(steam_id steamIDLobby, + const char* pchKey) { + return "212"; // Components::Party::GetLobbyInfo(steamIDLobby, pchKey); +} + +bool matchmaking::SetLobbyData(steam_id steamIDLobby, const char* pchKey, + const char* pchValue) { + return true; +} + +int matchmaking::GetLobbyDataCount(steam_id steamIDLobby) { return 0; } + +bool matchmaking::GetLobbyDataByIndex(steam_id steamIDLobby, int iLobbyData, + char* pchKey, int cchKeyBufferSize, + char* pchValue, int cchValueBufferSize) { + return false; +} + +bool matchmaking::DeleteLobbyData(steam_id steamIDLobby, const char* pchKey) { + return false; +} + +const char* matchmaking::GetLobbyMemberData(steam_id steamIDLobby, + steam_id steamIDUser, + const char* pchKey) { + return ""; +} + +void matchmaking::SetLobbyMemberData(steam_id steamIDLobby, const char* pchKey, + const char* pchValue) {} + +bool matchmaking::SendLobbyChatMsg(steam_id steamIDLobby, const void* pvMsgBody, + int cubMsgBody) { + return true; +} + +int matchmaking::GetLobbyChatEntry(steam_id steamIDLobby, int iChatID, + steam_id* pSteamIDUser, void* pvData, + int cubData, int* peChatEntryType) { + return 0; +} + +bool matchmaking::RequestLobbyData(steam_id steamIDLobby) { return false; } + +void matchmaking::SetLobbyGameServer(steam_id steamIDLobby, + unsigned int unGameServerIP, + unsigned short unGameServerPort, + steam_id steamIDGameServer) {} + +bool matchmaking::GetLobbyGameServer(steam_id steamIDLobby, + unsigned int* punGameServerIP, + unsigned short* punGameServerPort, + steam_id* psteamIDGameServer) { + return false; +} + +bool matchmaking::SetLobbyMemberLimit(steam_id steamIDLobby, int cMaxMembers) { + return true; +} + +int matchmaking::GetLobbyMemberLimit(steam_id steamIDLobby) { return 0; } + +bool matchmaking::SetLobbyType(steam_id steamIDLobby, int eLobbyType) { + return true; +} + +bool matchmaking::SetLobbyJoinable(steam_id steamIDLobby, bool bLobbyJoinable) { + return true; +} + +steam_id matchmaking::GetLobbyOwner(steam_id steamIDLobby) { + return SteamUser()->GetSteamID(); +} + +bool matchmaking::SetLobbyOwner(steam_id steamIDLobby, + steam_id steamIDNewOwner) { + return true; +} +} // namespace steam diff --git a/src/client/steam/interfaces/matchmaking.hpp b/src/client/steam/interfaces/matchmaking.hpp new file mode 100644 index 0000000..0076fda --- /dev/null +++ b/src/client/steam/interfaces/matchmaking.hpp @@ -0,0 +1,94 @@ +#pragma once + +namespace steam { +struct lobby_created final { + enum { callback_id = 513 }; + + int m_e_result; + int m_pad; + steam_id m_ul_steam_id_lobby; +}; + +struct lobby_enter final { + enum { callback_id = 504 }; + + steam_id m_ul_steam_id_lobby; + int m_rgf_chat_permissions; + bool m_b_locked; + int m_e_chat_room_enter_response; +}; + +class matchmaking { +protected: + ~matchmaking() = default; + +public: + virtual int GetFavoriteGameCount(); + virtual bool GetFavoriteGame(int iGame, unsigned int* pnAppID, + unsigned int* pnIP, unsigned short* pnConnPort, + unsigned short* pnQueryPort, + unsigned int* punFlags, + unsigned int* pRTime32LastPlayedOnServer); + virtual int AddFavoriteGame(unsigned int nAppID, unsigned int nIP, + unsigned short nConnPort, + unsigned short nQueryPort, unsigned int unFlags, + unsigned int rTime32LastPlayedOnServer); + virtual bool RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, + unsigned short nConnPort, + unsigned short nQueryPort, + unsigned int unFlags); + virtual unsigned __int64 RequestLobbyList(); + virtual void AddRequestLobbyListStringFilter(const char* pchKeyToMatch, + const char* pchValueToMatch, + int eComparisonType); + virtual void AddRequestLobbyListNumericalFilter(const char* pchKeyToMatch, + int nValueToMatch, + int eComparisonType); + virtual void AddRequestLobbyListNearValueFilter(const char* pchKeyToMatch, + int nValueToBeCloseTo); + virtual void AddRequestLobbyListFilterSlotsAvailable(int nSlotsAvailable); + virtual void AddRequestLobbyListDistanceFilter(int eLobbyDistanceFilter); + virtual void AddRequestLobbyListResultCountFilter(int cMaxResults); + virtual steam_id GetLobbyByIndex(int iLobby); + virtual unsigned __int64 CreateLobby(int eLobbyType, int cMaxMembers); + virtual unsigned __int64 JoinLobby(steam_id steamIDLobby); + virtual void LeaveLobby(steam_id steamIDLobby); + virtual bool InviteUserToLobby(steam_id steamIDLobby, + steam_id steamIDInvitee); + virtual int GetNumLobbyMembers(steam_id steamIDLobby); + virtual steam_id GetLobbyMemberByIndex(steam_id steamIDLobby, int iMember); + virtual const char* GetLobbyData(steam_id steamIDLobby, const char* pchKey); + virtual bool SetLobbyData(steam_id steamIDLobby, const char* pchKey, + const char* pchValue); + virtual int GetLobbyDataCount(steam_id steamIDLobby); + virtual bool GetLobbyDataByIndex(steam_id steamIDLobby, int iLobbyData, + char* pchKey, int cchKeyBufferSize, + char* pchValue, int cchValueBufferSize); + virtual bool DeleteLobbyData(steam_id steamIDLobby, const char* pchKey); + virtual const char* GetLobbyMemberData(steam_id steamIDLobby, + steam_id steamIDUser, + const char* pchKey); + virtual void SetLobbyMemberData(steam_id steamIDLobby, const char* pchKey, + const char* pchValue); + virtual bool SendLobbyChatMsg(steam_id steamIDLobby, const void* pvMsgBody, + int cubMsgBody); + virtual int GetLobbyChatEntry(steam_id steamIDLobby, int iChatID, + steam_id* pSteamIDUser, void* pvData, + int cubData, int* peChatEntryType); + virtual bool RequestLobbyData(steam_id steamIDLobby); + virtual void SetLobbyGameServer(steam_id steamIDLobby, + unsigned int unGameServerIP, + unsigned short unGameServerPort, + steam_id steamIDGameServer); + virtual bool GetLobbyGameServer(steam_id steamIDLobby, + unsigned int* punGameServerIP, + unsigned short* punGameServerPort, + steam_id* psteamIDGameServer); + virtual bool SetLobbyMemberLimit(steam_id steamIDLobby, int cMaxMembers); + virtual int GetLobbyMemberLimit(steam_id steamIDLobby); + virtual bool SetLobbyType(steam_id steamIDLobby, int eLobbyType); + virtual bool SetLobbyJoinable(steam_id steamIDLobby, bool bLobbyJoinable); + virtual steam_id GetLobbyOwner(steam_id steamIDLobby); + virtual bool SetLobbyOwner(steam_id steamIDLobby, steam_id steamIDNewOwner); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/matchmaking_servers.cpp b/src/client/steam/interfaces/matchmaking_servers.cpp new file mode 100644 index 0000000..cf589bc --- /dev/null +++ b/src/client/steam/interfaces/matchmaking_servers.cpp @@ -0,0 +1,72 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +void* matchmaking_servers::RequestInternetServerList( + unsigned int iApp, void** ppchFilters, unsigned int nFilters, + void* pRequestServersResponse) { + return nullptr; +} + +void* matchmaking_servers::RequestLANServerList(unsigned int iApp, + void* pRequestServersResponse) { + return nullptr; +} + +void* matchmaking_servers::RequestFriendsServerList( + unsigned int iApp, void** ppchFilters, unsigned int nFilters, + void* pRequestServersResponse) { + return nullptr; +} + +void* matchmaking_servers::RequestFavoritesServerList( + unsigned int iApp, void** ppchFilters, unsigned int nFilters, + void* pRequestServersResponse) { + return nullptr; +} + +void* matchmaking_servers::RequestHistoryServerList( + unsigned int iApp, void** ppchFilters, unsigned int nFilters, + void* pRequestServersResponse) { + return nullptr; +} + +void* matchmaking_servers::RequestSpectatorServerList( + unsigned int iApp, void** ppchFilters, unsigned int nFilters, + void* pRequestServersResponse) { + return nullptr; +} + +void matchmaking_servers::ReleaseRequest(void* hServerListRequest) {} + +void* matchmaking_servers::GetServerDetails(void* hRequest, int iServer) { + return nullptr; +} + +void matchmaking_servers::CancelQuery(void* hRequest) {} + +void matchmaking_servers::RefreshQuery(void* hRequest) {} + +bool matchmaking_servers::IsRefreshing(void* hRequest) { return false; } + +int matchmaking_servers::GetServerCount(void* hRequest) { return 0; } + +void matchmaking_servers::RefreshServer(void* hRequest, int iServer) {} + +int matchmaking_servers::PingServer(unsigned int unIP, unsigned short usPort, + void* pRequestServersResponse) { + return 0; +} + +int matchmaking_servers::PlayerDetails(unsigned int unIP, unsigned short usPort, + void* pRequestServersResponse) { + return 0; +} + +int matchmaking_servers::ServerRules(unsigned int unIP, unsigned short usPort, + void* pRequestServersResponse) { + return 0; +} + +void matchmaking_servers::CancelServerQuery(int hServerQuery) {} +} // namespace steam diff --git a/src/client/steam/interfaces/matchmaking_servers.hpp b/src/client/steam/interfaces/matchmaking_servers.hpp new file mode 100644 index 0000000..c72a2b6 --- /dev/null +++ b/src/client/steam/interfaces/matchmaking_servers.hpp @@ -0,0 +1,43 @@ +#pragma once + +namespace steam { +class matchmaking_servers { +protected: + ~matchmaking_servers() = default; + +public: + virtual void* RequestInternetServerList(unsigned int iApp, void** ppchFilters, + unsigned int nFilters, + void* pRequestServersResponse); + virtual void* RequestLANServerList(unsigned int iApp, + void* pRequestServersResponse); + virtual void* RequestFriendsServerList(unsigned int iApp, void** ppchFilters, + unsigned int nFilters, + void* pRequestServersResponse); + virtual void* RequestFavoritesServerList(unsigned int iApp, + void** ppchFilters, + unsigned int nFilters, + void* pRequestServersResponse); + virtual void* RequestHistoryServerList(unsigned int iApp, void** ppchFilters, + unsigned int nFilters, + void* pRequestServersResponse); + virtual void* RequestSpectatorServerList(unsigned int iApp, + void** ppchFilters, + unsigned int nFilters, + void* pRequestServersResponse); + virtual void ReleaseRequest(void* hServerListRequest); + virtual void* GetServerDetails(void* hRequest, int iServer); + virtual void CancelQuery(void* hRequest); + virtual void RefreshQuery(void* hRequest); + virtual bool IsRefreshing(void* hRequest); + virtual int GetServerCount(void* hRequest); + virtual void RefreshServer(void* hRequest, int iServer); + virtual int PingServer(unsigned int unIP, unsigned short usPort, + void* pRequestServersResponse); + virtual int PlayerDetails(unsigned int unIP, unsigned short usPort, + void* pRequestServersResponse); + virtual int ServerRules(unsigned int unIP, unsigned short usPort, + void* pRequestServersResponse); + virtual void CancelServerQuery(int hServerQuery); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/networking.cpp b/src/client/steam/interfaces/networking.cpp new file mode 100644 index 0000000..9237dd8 --- /dev/null +++ b/src/client/steam/interfaces/networking.cpp @@ -0,0 +1,112 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +bool networking::SendP2PPacket(steam_id steamIDRemote, const void* pubData, + unsigned int cubData, int eP2PSendType) { + return false; +} + +bool networking::IsP2PPacketAvailable(unsigned int* pcubMsgSize, int idk) { + return false; +} + +bool networking::ReadP2PPacket(void* pubDest, unsigned int cubDest, + unsigned int* pcubMsgSize, + steam_id* psteamIDRemote) { + return false; +} + +bool networking::AcceptP2PSessionWithUser(steam_id steamIDRemote) { + return false; +} + +bool networking::CloseP2PSessionWithUser(steam_id steamIDRemote) { + return false; +} + +bool networking::CloseP2PChannelWithUser(steam_id steamIDRemote, + int iVirtualPort) { + return false; +} + +bool networking::GetP2PSessionState(steam_id steamIDRemote, + void* pConnectionState) { + return false; +} + +bool networking::AllowP2PPacketRelay(bool bAllow) { return false; } + +unsigned int networking::CreateListenSocket(int nVirtualP2PPort, + unsigned int nIP, + unsigned short nPort, + bool bAllowUseOfPacketRelay) { + return NULL; +} + +unsigned int +networking::CreateP2PConnectionSocket(steam_id steamIDTarget, int nVirtualPort, + int nTimeoutSec, + bool bAllowUseOfPacketRelay) { + return NULL; +} + +unsigned int networking::CreateConnectionSocket(unsigned int nIP, + unsigned short nPort, + int nTimeoutSec) { + return NULL; +} + +bool networking::DestroySocket(unsigned int hSocket, bool bNotifyRemoteEnd) { + return false; +} + +bool networking::DestroyListenSocket(unsigned int hSocket, + bool bNotifyRemoteEnd) { + return false; +} + +bool networking::SendDataOnSocket(unsigned int hSocket, void* pubData, + unsigned int cubData, bool bReliable) { + return false; +} + +bool networking::IsDataAvailableOnSocket(unsigned int hSocket, + unsigned int* pcubMsgSize) { + return false; +} + +bool networking::RetrieveDataFromSocket(unsigned int hSocket, void* pubDest, + unsigned int cubDest, + unsigned int* pcubMsgSize) { + return false; +} + +bool networking::IsDataAvailable(unsigned int hListenSocket, + unsigned int* pcubMsgSize, + unsigned int* phSocket) { + return false; +} + +bool networking::RetrieveData(unsigned int hListenSocket, void* pubDest, + unsigned int cubDest, unsigned int* pcubMsgSize, + unsigned int* phSocket) { + return false; +} + +bool networking::GetSocketInfo(unsigned int hSocket, steam_id* pSteamIDRemote, + int* peSocketStatus, unsigned int* punIPRemote, + unsigned short* punPortRemote) { + return false; +} + +bool networking::GetListenSocketInfo(unsigned int hListenSocket, + unsigned int* pnIP, + unsigned short* pnPort) { + return false; +} + +int networking::GetSocketConnectionType(unsigned int hSocket) { return 0; } + +int networking::GetMaxPacketSize(unsigned int hSocket) { return 0; } +} // namespace steam diff --git a/src/client/steam/interfaces/networking.hpp b/src/client/steam/interfaces/networking.hpp new file mode 100644 index 0000000..b6a1f57 --- /dev/null +++ b/src/client/steam/interfaces/networking.hpp @@ -0,0 +1,55 @@ +#pragma once + +namespace steam { +class networking { +protected: + ~networking() = default; + +public: + virtual bool SendP2PPacket(steam_id steamIDRemote, const void* pubData, + unsigned int cubData, int eP2PSendType); + virtual bool IsP2PPacketAvailable(unsigned int* pcubMsgSize, int idk); + virtual bool ReadP2PPacket(void* pubDest, unsigned int cubDest, + unsigned int* pcubMsgSize, + steam_id* psteamIDRemote); + virtual bool AcceptP2PSessionWithUser(steam_id steamIDRemote); + virtual bool CloseP2PSessionWithUser(steam_id steamIDRemote); + virtual bool CloseP2PChannelWithUser(steam_id steamIDRemote, + int iVirtualPort); + virtual bool GetP2PSessionState(steam_id steamIDRemote, + void* pConnectionState); + virtual bool AllowP2PPacketRelay(bool bAllow); + virtual unsigned int CreateListenSocket(int nVirtualP2PPort, unsigned int nIP, + unsigned short nPort, + bool bAllowUseOfPacketRelay); + virtual unsigned int CreateP2PConnectionSocket(steam_id steamIDTarget, + int nVirtualPort, + int nTimeoutSec, + bool bAllowUseOfPacketRelay); + virtual unsigned int CreateConnectionSocket(unsigned int nIP, + unsigned short nPort, + int nTimeoutSec); + virtual bool DestroySocket(unsigned int hSocket, bool bNotifyRemoteEnd); + virtual bool DestroyListenSocket(unsigned int hSocket, bool bNotifyRemoteEnd); + virtual bool SendDataOnSocket(unsigned int hSocket, void* pubData, + unsigned int cubData, bool bReliable); + virtual bool IsDataAvailableOnSocket(unsigned int hSocket, + unsigned int* pcubMsgSize); + virtual bool RetrieveDataFromSocket(unsigned int hSocket, void* pubDest, + unsigned int cubDest, + unsigned int* pcubMsgSize); + virtual bool IsDataAvailable(unsigned int hListenSocket, + unsigned int* pcubMsgSize, + unsigned int* phSocket); + virtual bool RetrieveData(unsigned int hListenSocket, void* pubDest, + unsigned int cubDest, unsigned int* pcubMsgSize, + unsigned int* phSocket); + virtual bool GetSocketInfo(unsigned int hSocket, steam_id* pSteamIDRemote, + int* peSocketStatus, unsigned int* punIPRemote, + unsigned short* punPortRemote); + virtual bool GetListenSocketInfo(unsigned int hListenSocket, + unsigned int* pnIP, unsigned short* pnPort); + virtual int GetSocketConnectionType(unsigned int hSocket); + virtual int GetMaxPacketSize(unsigned int hSocket); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/remote_storage.cpp b/src/client/steam/interfaces/remote_storage.cpp new file mode 100644 index 0000000..33b3a69 --- /dev/null +++ b/src/client/steam/interfaces/remote_storage.cpp @@ -0,0 +1,33 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +bool remote_storage::FileWrite(const char* pchFile, const void* pvData, + int cubData) { + return true; +} + +int remote_storage::GetFileSize(const char* pchFile) { return 0; } + +int remote_storage::FileRead(const char* pchFile, void* pvData, + int cubDataToRead) { + OutputDebugStringA(pchFile); + return 0; +} + +bool remote_storage::FileExists(const char* pchFile) { return false; } + +int remote_storage::GetFileCount() { return 0; } + +const char* remote_storage::GetFileNameAndSize(int iFile, + int* pnFileSizeInBytes) { + *pnFileSizeInBytes = 0; + return ""; +} + +bool remote_storage::GetQuota(int* pnTotalBytes, int* puAvailableBytes) { + *pnTotalBytes = 0x10000000; + *puAvailableBytes = 0x10000000; + return false; +} +} // namespace steam diff --git a/src/client/steam/interfaces/remote_storage.hpp b/src/client/steam/interfaces/remote_storage.hpp new file mode 100644 index 0000000..d63ea69 --- /dev/null +++ b/src/client/steam/interfaces/remote_storage.hpp @@ -0,0 +1,17 @@ +#pragma once + +namespace steam { +class remote_storage { +protected: + ~remote_storage() = default; + +public: + virtual bool FileWrite(const char* pchFile, const void* pvData, int cubData); + virtual int GetFileSize(const char* pchFile); + virtual int FileRead(const char* pchFile, void* pvData, int cubDataToRead); + virtual bool FileExists(const char* pchFile); + virtual int GetFileCount(); + virtual const char* GetFileNameAndSize(int iFile, int* pnFileSizeInBytes); + virtual bool GetQuota(int* pnTotalBytes, int* puAvailableBytes); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/user.cpp b/src/client/steam/interfaces/user.cpp new file mode 100644 index 0000000..fe2c63b --- /dev/null +++ b/src/client/steam/interfaces/user.cpp @@ -0,0 +1,126 @@ +#include +#include "steam/steam.hpp" + +#include "component/auth.hpp" + +namespace steam { +namespace { +std::string auth_ticket; +} // namespace + +int user::GetHSteamUser() { return NULL; } + +bool user::LoggedOn() { return true; } + +steam_id user::GetSteamID() { + static std::uint64_t seed = 0; + if (!seed) { + seed = auth::get_guid(); + } + + steam_id id; + id.bits = seed; + return id; +} + +int user::InitiateGameConnection(void* pAuthBlob, int cbMaxAuthBlob, + steam_id steamIDGameServer, + unsigned int unIPServer, + unsigned short usPortServer, bool bSecure) { + return 0; +} + +void user::TerminateGameConnection(unsigned int unIPServer, + unsigned short usPortServer) {} + +void user::TrackAppUsageEvent(steam_id gameID, int eAppUsageEvent, + const char* pchExtraInfo) {} + +bool user::GetUserDataFolder(char* pchBuffer, int cubBuffer) { return false; } + +void user::StartVoiceRecording() {} + +void user::StopVoiceRecording() {} + +int user::GetAvailableVoice(unsigned int* pcbCompressed, + unsigned int* pcbUncompressed, + unsigned int nUncompressedVoiceDesiredSampleRate) { + return 0; +} + +int user::GetVoice(bool bWantCompressed, void* pDestBuffer, + unsigned int cbDestBufferSize, unsigned int* nBytesWritten, + bool bWantUncompressed, void* pUncompressedDestBuffer, + unsigned int cbUncompressedDestBufferSize, + unsigned int* nUncompressBytesWritten, + unsigned int nUncompressedVoiceDesiredSampleRate) { + return 0; +} + +int user::DecompressVoice(void* pCompressed, unsigned int cbCompressed, + void* pDestBuffer, unsigned int cbDestBufferSize, + unsigned int* nBytesWritten) { + return 0; +} + +unsigned int user::GetVoiceOptimalSampleRate() { return 0; } + +unsigned int user::GetAuthSessionTicket(void* pTicket, int cbMaxTicket, + unsigned int* pcbTicket) { + return 0; +} + +int user::BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, + steam_id steamID) { + return 0; +} + +void user::EndAuthSession(steam_id steamID) {} + +void user::CancelAuthTicket(unsigned int hAuthTicket) {} + +unsigned int user::UserHasLicenseForApp(steam_id steamID, unsigned int appID) { + return 0; +} + +bool user::BIsBehindNAT() { return false; } + +void user::AdvertiseGame(steam_id steamIDGameServer, unsigned int unIPServer, + unsigned short usPortServer) {} + +unsigned __int64 user::RequestEncryptedAppTicket(void* pUserData, + int cbUserData) { + // Generate the authentication ticket + const auto id = this->GetSteamID(); + + auth_ticket = "iw4-sp"; + auth_ticket.resize(32); + auth_ticket.append(static_cast(pUserData), cbUserData); + auth_ticket.append(reinterpret_cast(&id.bits), sizeof(id.bits)); + + // Create the call response + const auto result = callbacks::register_call(); + auto retvals = static_cast( + calloc(1, sizeof(encrypted_app_ticket_response))); + retvals->m_e_result = 1; + + // Return the call response + callbacks::return_call(retvals, sizeof(encrypted_app_ticket_response), + encrypted_app_ticket_response::callback_id, result); + + return result; +} + +bool user::GetEncryptedAppTicket(void* pTicket, int cbMaxTicket, + unsigned int* pcbTicket) { + if (cbMaxTicket < 0 || auth_ticket.empty()) + return false; + + const auto size = + std::min(static_cast(cbMaxTicket), auth_ticket.size()); + std::memcpy(pTicket, auth_ticket.data(), size); + *pcbTicket = size; + + return true; +} +} // namespace steam diff --git a/src/client/steam/interfaces/user.hpp b/src/client/steam/interfaces/user.hpp new file mode 100644 index 0000000..8337558 --- /dev/null +++ b/src/client/steam/interfaces/user.hpp @@ -0,0 +1,61 @@ +#pragma once + +namespace steam { +struct encrypted_app_ticket_response final { + enum { callback_id = 154 }; + + int m_e_result; +}; + +class user { +protected: + ~user() = default; + +public: + virtual int GetHSteamUser(); + virtual bool LoggedOn(); + virtual steam_id GetSteamID(); + + virtual int InitiateGameConnection(void* pAuthBlob, int cbMaxAuthBlob, + steam_id steamIDGameServer, + unsigned int unIPServer, + unsigned short usPortServer, bool bSecure); + virtual void TerminateGameConnection(unsigned int unIPServer, + unsigned short usPortServer); + virtual void TrackAppUsageEvent(steam_id gameID, int eAppUsageEvent, + const char* pchExtraInfo = ""); + virtual bool GetUserDataFolder(char* pchBuffer, int cubBuffer); + virtual void StartVoiceRecording(); + virtual void StopVoiceRecording(); + virtual int + GetAvailableVoice(unsigned int* pcbCompressed, unsigned int* pcbUncompressed, + unsigned int nUncompressedVoiceDesiredSampleRate); + virtual int GetVoice(bool bWantCompressed, void* pDestBuffer, + unsigned int cbDestBufferSize, + unsigned int* nBytesWritten, bool bWantUncompressed, + void* pUncompressedDestBuffer, + unsigned int cbUncompressedDestBufferSize, + unsigned int* nUncompressBytesWritten, + unsigned int nUncompressedVoiceDesiredSampleRate); + virtual int DecompressVoice(void* pCompressed, unsigned int cbCompressed, + void* pDestBuffer, unsigned int cbDestBufferSize, + unsigned int* nBytesWritten); + virtual unsigned int GetVoiceOptimalSampleRate(); + virtual unsigned int GetAuthSessionTicket(void* pTicket, int cbMaxTicket, + unsigned int* pcbTicket); + virtual int BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, + steam_id steamID); + virtual void EndAuthSession(steam_id steamID); + virtual void CancelAuthTicket(unsigned int hAuthTicket); + virtual unsigned int UserHasLicenseForApp(steam_id steamID, + unsigned int appID); + virtual bool BIsBehindNAT(); + virtual void AdvertiseGame(steam_id steamIDGameServer, + unsigned int unIPServer, + unsigned short usPortServer); + virtual unsigned __int64 RequestEncryptedAppTicket(void* pUserData, + int cbUserData); + virtual bool GetEncryptedAppTicket(void* pTicket, int cbMaxTicket, + unsigned int* pcbTicket); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/user_stats.cpp b/src/client/steam/interfaces/user_stats.cpp new file mode 100644 index 0000000..8f80122 --- /dev/null +++ b/src/client/steam/interfaces/user_stats.cpp @@ -0,0 +1,178 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +bool user_stats::RequestCurrentStats() { return true; } + +bool user_stats::GetStat(const char* pchName, int* pData) { return false; } + +bool user_stats::GetStat(const char* pchName, float* pData) { return false; } + +bool user_stats::SetStat(const char* pchName, int nData) { return false; } + +bool user_stats::SetStat(const char* pchName, float fData) { return false; } + +bool user_stats::UpdateAvgRateStat(const char* pchName, + float flCountThisSession, + double dSessionLength) { + return false; +} + +bool user_stats::GetAchievement(const char* pchName, bool* pbAchieved) { + return false; +} + +bool user_stats::SetAchievement(const char* pchName) { return false; } + +bool user_stats::ClearAchievement(const char* pchName) { return false; } + +bool user_stats::GetAchievementAndUnlockTime(const char* pchName, + bool* pbAchieved, + unsigned int* punUnlockTime) { + return false; +} + +bool user_stats::StoreStats() { return false; } + +int user_stats::GetAchievementIcon(const char* pchName) { return 0; } + +const char* user_stats::GetAchievementDisplayAttribute(const char* pchName, + const char* pchKey) { + return ""; +} + +bool user_stats::IndicateAchievementProgress(const char* pchName, + unsigned int nCurProgress, + unsigned int nMaxProgress) { + return false; +} + +unsigned __int64 user_stats::RequestUserStats(steam_id steamIDUser) { + return 0; +} + +bool user_stats::GetUserStat(steam_id steamIDUser, const char* pchName, + int* pData) { + return false; +} + +bool user_stats::GetUserStat(steam_id steamIDUser, const char* pchName, + float* pData) { + return false; +} + +bool user_stats::GetUserAchievement(steam_id steamIDUser, const char* pchName, + bool* pbAchieved) { + return false; +} + +bool user_stats::GetUserAchievementAndUnlockTime(steam_id steamIDUser, + const char* pchName, + bool* pbAchieved, + unsigned int* punUnlockTime) { + return false; +} + +bool user_stats::ResetAllStats(bool bAchievementsToo) { return false; } + +unsigned __int64 +user_stats::FindOrCreateLeaderboard(const char* pchLeaderboardName, + int eLeaderboardSortMethod, + int eLeaderboardDisplayType) { + return 0; +} + +unsigned __int64 user_stats::FindLeaderboard(const char* pchLeaderboardName) { + return 0; +} + +const char* user_stats::GetLeaderboardName(unsigned __int64 hSteamLeaderboard) { + return ""; +} + +int user_stats::GetLeaderboardEntryCount(unsigned __int64 hSteamLeaderboard) { + return 0; +} + +int user_stats::GetLeaderboardSortMethod(unsigned __int64 hSteamLeaderboard) { + return 0; +} + +int user_stats::GetLeaderboardDisplayType(unsigned __int64 hSteamLeaderboard) { + return 0; +} + +unsigned __int64 +user_stats::DownloadLeaderboardEntries(unsigned __int64 hSteamLeaderboard, + int eLeaderboardDataRequest, + int nRangeStart, int nRangeEnd) { + return 0; +} + +unsigned __int64 user_stats::DownloadLeaderboardEntriesForUsers( + unsigned __int64 hSteamLeaderboard, steam_id* prgUsers, int cUsers) { + return 0; +} + +bool user_stats::GetDownloadedLeaderboardEntry( + unsigned __int64 hSteamLeaderboardEntries, int index, + int* pLeaderboardEntry, int* pDetails, int cDetailsMax) { + return false; +} + +unsigned __int64 user_stats::UploadLeaderboardScore( + unsigned __int64 hSteamLeaderboard, int eLeaderboardUploadScoreMethod, + int nScore, const int* pScoreDetails, int cScoreDetailsCount) { + return 0; +} + +unsigned __int64 +user_stats::AttachLeaderboardUGC(unsigned __int64 hSteamLeaderboard, + unsigned __int64 hUGC) { + return 0; +} + +unsigned __int64 user_stats::GetNumberOfCurrentPlayers() { return 0; } + +unsigned __int64 user_stats::RequestGlobalAchievementPercentages() { return 0; } + +int user_stats::GetMostAchievedAchievementInfo(char* pchName, + unsigned int unNameBufLen, + float* pflPercent, + bool* pbAchieved) { + return 0; +} + +int user_stats::GetNextMostAchievedAchievementInfo(int iIteratorPrevious, + char* pchName, + unsigned int unNameBufLen, + float* pflPercent, + bool* pbAchieved) { + return 0; +} + +bool user_stats::GetAchievementAchievedPercent(const char* pchName, + float* pflPercent) { + return false; +} + +unsigned __int64 user_stats::RequestGlobalStats(int nHistoryDays) { return 0; } + +bool user_stats::GetGlobalStat(const char* pchStatName, __int64* pData) { + return false; +} + +bool user_stats::GetGlobalStat(const char* pchStatName, double* pData) { + return false; +} + +int user_stats::GetGlobalStatHistory(const char* pchStatName, __int64* pData, + unsigned int cubData) { + return 0; +} + +int user_stats::GetGlobalStatHistory(const char* pchStatName, double* pData, + unsigned int cubData) { + return 0; +} +} // namespace steam diff --git a/src/client/steam/interfaces/user_stats.hpp b/src/client/steam/interfaces/user_stats.hpp new file mode 100644 index 0000000..7987fd9 --- /dev/null +++ b/src/client/steam/interfaces/user_stats.hpp @@ -0,0 +1,89 @@ +#pragma once + +namespace steam { +class user_stats { +protected: + ~user_stats() = default; + +public: + virtual bool RequestCurrentStats(); + virtual bool GetStat(const char* pchName, int* pData); + virtual bool GetStat(const char* pchName, float* pData); + virtual bool SetStat(const char* pchName, int nData); + virtual bool SetStat(const char* pchName, float fData); + virtual bool UpdateAvgRateStat(const char* pchName, float flCountThisSession, + double dSessionLength); + virtual bool GetAchievement(const char* pchName, bool* pbAchieved); + virtual bool SetAchievement(const char* pchName); + virtual bool ClearAchievement(const char* pchName); + virtual bool GetAchievementAndUnlockTime(const char* pchName, + bool* pbAchieved, + unsigned int* punUnlockTime); + virtual bool StoreStats(); + virtual int GetAchievementIcon(const char* pchName); + virtual const char* GetAchievementDisplayAttribute(const char* pchName, + const char* pchKey); + virtual bool IndicateAchievementProgress(const char* pchName, + unsigned int nCurProgress, + unsigned int nMaxProgress); + virtual unsigned __int64 RequestUserStats(steam_id steamIDUser); + virtual bool GetUserStat(steam_id steamIDUser, const char* pchName, + int* pData); + virtual bool GetUserStat(steam_id steamIDUser, const char* pchName, + float* pData); + virtual bool GetUserAchievement(steam_id steamIDUser, const char* pchName, + bool* pbAchieved); + virtual bool GetUserAchievementAndUnlockTime(steam_id steamIDUser, + const char* pchName, + bool* pbAchieved, + unsigned int* punUnlockTime); + virtual bool ResetAllStats(bool bAchievementsToo); + virtual unsigned __int64 + FindOrCreateLeaderboard(const char* pchLeaderboardName, + int eLeaderboardSortMethod, + int eLeaderboardDisplayType); + virtual unsigned __int64 FindLeaderboard(const char* pchLeaderboardName); + virtual const char* GetLeaderboardName(unsigned __int64 hSteamLeaderboard); + virtual int GetLeaderboardEntryCount(unsigned __int64 hSteamLeaderboard); + virtual int GetLeaderboardSortMethod(unsigned __int64 hSteamLeaderboard); + virtual int GetLeaderboardDisplayType(unsigned __int64 hSteamLeaderboard); + virtual unsigned __int64 + DownloadLeaderboardEntries(unsigned __int64 hSteamLeaderboard, + int eLeaderboardDataRequest, int nRangeStart, + int nRangeEnd); + virtual unsigned __int64 + DownloadLeaderboardEntriesForUsers(unsigned __int64 hSteamLeaderboard, + steam_id* prgUsers, int cUsers); + virtual bool + GetDownloadedLeaderboardEntry(unsigned __int64 hSteamLeaderboardEntries, + int index, int* pLeaderboardEntry, + int* pDetails, int cDetailsMax); + virtual unsigned __int64 + UploadLeaderboardScore(unsigned __int64 hSteamLeaderboard, + int eLeaderboardUploadScoreMethod, int nScore, + const int* pScoreDetails, int cScoreDetailsCount); + virtual unsigned __int64 + AttachLeaderboardUGC(unsigned __int64 hSteamLeaderboard, + unsigned __int64 hUGC); + virtual unsigned __int64 GetNumberOfCurrentPlayers(); + virtual unsigned __int64 RequestGlobalAchievementPercentages(); + virtual int GetMostAchievedAchievementInfo(char* pchName, + unsigned int unNameBufLen, + float* pflPercent, + bool* pbAchieved); + virtual int GetNextMostAchievedAchievementInfo(int iIteratorPrevious, + char* pchName, + unsigned int unNameBufLen, + float* pflPercent, + bool* pbAchieved); + virtual bool GetAchievementAchievedPercent(const char* pchName, + float* pflPercent); + virtual unsigned __int64 RequestGlobalStats(int nHistoryDays); + virtual bool GetGlobalStat(const char* pchStatName, __int64* pData); + virtual bool GetGlobalStat(const char* pchStatName, double* pData); + virtual int GetGlobalStatHistory(const char* pchStatName, __int64* pData, + unsigned int cubData); + virtual int GetGlobalStatHistory(const char* pchStatName, double* pData, + unsigned int cubData); +}; +} // namespace steam diff --git a/src/client/steam/interfaces/utils.cpp b/src/client/steam/interfaces/utils.cpp new file mode 100644 index 0000000..307d5ed --- /dev/null +++ b/src/client/steam/interfaces/utils.cpp @@ -0,0 +1,65 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +unsigned int utils::GetSecondsSinceAppActive() { return 0; } + +unsigned int utils::GetSecondsSinceComputerActive() { return 0; } + +int utils::GetConnectedUniverse() { return 1; } + +unsigned int utils::GetServerRealTime() { return 0; } + +const char* utils::GetIPCountry() { return "US"; } + +bool utils::GetImageSize(int iImage, unsigned int* pnWidth, + unsigned int* pnHeight) { + return false; +} + +bool utils::GetImageRGBA(int iImage, unsigned char* pubDest, + int nDestBufferSize) { + return false; +} + +bool utils::GetCSERIPPort(unsigned int* unIP, unsigned short* usPort) { + return false; +} + +unsigned char utils::GetCurrentBatteryPower() { return 255; } + +unsigned int utils::GetAppID() { return 10180; } + +void utils::SetOverlayNotificationPosition(int eNotificationPosition) { + if (overlay) { + overlay.invoke("SetNotificationPosition", eNotificationPosition); + } +} + +bool utils::IsAPICallCompleted(unsigned __int64 hSteamAPICall, bool* pbFailed) { + return false; +} + +int utils::GetAPICallFailureReason(unsigned __int64 hSteamAPICall) { + return -1; +} + +bool utils::GetAPICallResult(unsigned __int64 hSteamAPICall, void* pCallback, + int cubCallback, int iCallbackExpected, + bool* pbFailed) { + return false; +} + +void utils::RunFrame() {} + +unsigned int utils::GetIPCCallCount() { return 0; } + +void utils::SetWarningMessageHook(void (*pFunction)(int hpipe, + const char* message)) {} + +bool utils::IsOverlayEnabled() { return false; } + +bool utils::BOverlayNeedsPresent() { return false; } + +unsigned __int64 utils::CheckFileSignature(const char* szFileName) { return 0; } +} // namespace steam diff --git a/src/client/steam/interfaces/utils.hpp b/src/client/steam/interfaces/utils.hpp new file mode 100644 index 0000000..7a61b0d --- /dev/null +++ b/src/client/steam/interfaces/utils.hpp @@ -0,0 +1,36 @@ +#pragma once + +namespace steam { +class utils { +protected: + ~utils() = default; + +public: + virtual unsigned int GetSecondsSinceAppActive(); + virtual unsigned int GetSecondsSinceComputerActive(); + virtual int GetConnectedUniverse(); + virtual unsigned int GetServerRealTime(); + virtual const char* GetIPCountry(); + virtual bool GetImageSize(int iImage, unsigned int* pnWidth, + unsigned int* pnHeight); + virtual bool GetImageRGBA(int iImage, unsigned char* pubDest, + int nDestBufferSize); + virtual bool GetCSERIPPort(unsigned int* unIP, unsigned short* usPort); + virtual unsigned char GetCurrentBatteryPower(); + virtual unsigned int GetAppID(); + virtual void SetOverlayNotificationPosition(int eNotificationPosition); + virtual bool IsAPICallCompleted(unsigned __int64 hSteamAPICall, + bool* pbFailed); + virtual int GetAPICallFailureReason(unsigned __int64 hSteamAPICall); + virtual bool GetAPICallResult(unsigned __int64 hSteamAPICall, void* pCallback, + int cubCallback, int iCallbackExpected, + bool* pbFailed); + virtual void RunFrame(); + virtual unsigned int GetIPCCallCount(); + virtual void SetWarningMessageHook(void (*pFunction)(int hpipe, + const char* message)); + virtual bool IsOverlayEnabled(); + virtual bool BOverlayNeedsPresent(); + virtual unsigned __int64 CheckFileSignature(const char* szFileName); +}; +} // namespace steam diff --git a/src/client/steam/steam.cpp b/src/client/steam/steam.cpp new file mode 100644 index 0000000..91cf7ff --- /dev/null +++ b/src/client/steam/steam.cpp @@ -0,0 +1,209 @@ +#include +#include "steam/steam.hpp" + +namespace steam { +::utils::nt::library overlay(nullptr); + +std::uint64_t callbacks::call_id_ = 0; +std::recursive_mutex callbacks::mutex_; +std::map callbacks::calls_; +std::map callbacks::result_handlers_; +std::vector callbacks::results_; +std::vector callbacks::callback_list_; + +uint64_t callbacks::register_call() { + std::lock_guard _(mutex_); + calls_[++call_id_] = false; + return call_id_; +} + +void callbacks::register_callback(base* handler, const int callback) { + std::lock_guard _(mutex_); + handler->set_i_callback(callback); + callback_list_.push_back(handler); +} + +void callbacks::unregister_callback(base* handler) { + std::lock_guard _(mutex_); + for (auto i = callback_list_.begin(); i != callback_list_.end();) { + if (*i == handler) { + i = callback_list_.erase(i); + } else { + ++i; + } + } +} + +void callbacks::register_call_result(const uint64_t call, base* result) { + std::lock_guard _(mutex_); + result_handlers_[call] = result; +} + +void callbacks::unregister_call_result(const uint64_t call, + [[maybe_unused]] base* result) { + std::lock_guard _(mutex_); + const auto i = result_handlers_.find(call); + if (i != result_handlers_.end()) { + result_handlers_.erase(i); + } +} + +void callbacks::return_call(void* data, const int size, const int type, + const uint64_t call) { + std::lock_guard _(mutex_); + + result result; + result.call = call; + result.data = data; + result.size = size; + result.type = type; + + calls_[call] = true; + + results_.push_back(result); +} + +void callbacks::run_callbacks() { + std::lock_guard _(mutex_); + + for (const auto& result : results_) { + if (const auto itr = result_handlers_.find(result.call); + itr != result_handlers_.end()) { + itr->second->run(result.data, false, result.call); + } + + for (const auto& callback : callback_list_) { + if (callback && callback->get_i_callback() == result.type) { + callback->run(result.data, false, 0); + } + } + + if (result.data) { + std::free(result.data); + } + } + + results_.clear(); +} + +std::filesystem::path get_steam_install_directory() { + static std::string install_path{}; + if (!install_path.empty()) { + return {install_path}; + } + + HKEY reg_key; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Valve\\Steam", 0, + KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS) { + char path[MAX_PATH] = {0}; + DWORD length = sizeof(path); + RegQueryValueExA(reg_key, "InstallPath", nullptr, nullptr, + reinterpret_cast(path), &length); + RegCloseKey(reg_key); + + install_path = path; + } + + return {install_path}; +} + +extern "C" { +bool SteamAPI_RestartAppIfNecessary() { return false; } + +bool SteamAPI_Init() { + overlay = ::utils::nt::library("gameoverlayrenderer.dll"); + + if (!overlay) { + const auto steam_path = get_steam_install_directory(); + if (!steam_path.empty()) { + overlay = + ::utils::nt::library::load(steam_path / "gameoverlayrenderer.dll"); + } + } + + return true; +} + +void SteamAPI_RegisterCallResult(callbacks::base* result, uint64_t call) { + callbacks::register_call_result(call, result); +} + +void SteamAPI_RegisterCallback(callbacks::base* handler, int callback) { + callbacks::register_callback(handler, callback); +} + +void SteamAPI_RunCallbacks() { callbacks::run_callbacks(); } + +void SteamAPI_Shutdown() {} + +void SteamAPI_UnregisterCallResult(callbacks::base* result, + const std::uint64_t call) { + callbacks::unregister_call_result(call, result); +} + +void SteamAPI_UnregisterCallback(callbacks::base* handler) { + callbacks::unregister_callback(handler); +} + +bool SteamGameServer_Init() { return true; } + +void SteamGameServer_RunCallbacks() {} + +void SteamGameServer_Shutdown() {} + +friends* SteamFriends() { + static friends friends; + return &friends; +} + +matchmaking* SteamMatchmaking() { + static matchmaking matchmaking; + return &matchmaking; +} + +matchmaking_servers* SteamMatchmakingServers() { + static matchmaking_servers matchmaking_servers; + return &matchmaking_servers; +} + +game_server* SteamGameServer() { + static game_server game_server; + return &game_server; +} + +master_server_updater* SteamMasterServerUpdater() { + static master_server_updater master_server_updater; + return &master_server_updater; +} + +networking* SteamNetworking() { + static networking networking; + return &networking; +} + +remote_storage* SteamRemoteStorage() { + static remote_storage remote_storage; + return &remote_storage; +} + +user* SteamUser() { + static user user; + return &user; +} + +utils* SteamUtils() { + static utils utils; + return &utils; +} + +apps* SteamApps() { + static apps apps; + return &apps; +} + +user_stats* SteamUserStats() { + static user_stats user_stats; + return &user_stats; +} +} +} // namespace steam diff --git a/src/client/steam/steam.hpp b/src/client/steam/steam.hpp new file mode 100644 index 0000000..bcfa179 --- /dev/null +++ b/src/client/steam/steam.hpp @@ -0,0 +1,122 @@ +#pragma once + +#define STEAM_EXPORT extern "C" __declspec(dllexport) +#include + +struct raw_steam_id final { + unsigned int account_id : 32; + unsigned int account_instance : 20; + unsigned int account_type : 4; + int universe : 8; +}; + +typedef union { + raw_steam_id raw; + unsigned long long bits; +} steam_id; + +#pragma pack(push, 1) +struct raw_game_id final { + unsigned int app_id : 24; + unsigned int type : 8; + unsigned int mod_id : 32; +}; + +typedef union { + raw_game_id raw; + unsigned long long bits; +} game_id; +#pragma pack(pop) + +#include "interfaces/apps.hpp" +#include "interfaces/user.hpp" +#include "interfaces/utils.hpp" +#include "interfaces/friends.hpp" +#include "interfaces/user_stats.hpp" +#include "interfaces/game_server.hpp" +#include "interfaces/networking.hpp" +#include "interfaces/matchmaking.hpp" +#include "interfaces/remote_storage.hpp" +#include "interfaces/matchmaking_servers.hpp" +#include "interfaces/master_server_updater.hpp" + +namespace steam { +class callbacks { +public: + class base { + public: + base() : flags_(0), callback_(0) {} + + virtual void run(void* pv_param) = 0; + virtual void run(void* pv_param, bool failure, uint64_t handle) = 0; + virtual int get_callback_size_bytes() = 0; + + [[nodiscard]] int get_i_callback() const { return callback_; } + void set_i_callback(const int i_callback) { callback_ = i_callback; } + + protected: + ~base() = default; + + unsigned char flags_; + int callback_; + }; + + struct result final { + void* data; + int size; + int type; + std::uint64_t call; + }; + + static std::uint64_t register_call(); + + static void register_callback(base* handler, int callback); + static void unregister_callback(base* handler); + + static void register_call_result(std::uint64_t call, base* result); + static void unregister_call_result(std::uint64_t call, base* result); + + static void return_call(void* data, int size, int type, std::uint64_t call); + static void run_callbacks(); + +private: + static std::uint64_t call_id_; + static std::recursive_mutex mutex_; + static std::map calls_; + static std::map result_handlers_; + static std::vector results_; + static std::vector callback_list_; +}; + +STEAM_EXPORT bool SteamAPI_RestartAppIfNecessary(); +STEAM_EXPORT bool SteamAPI_Init(); +STEAM_EXPORT void SteamAPI_RegisterCallResult(callbacks::base* result, + uint64_t call); +STEAM_EXPORT void SteamAPI_RegisterCallback(callbacks::base* handler, + int callback); +STEAM_EXPORT void SteamAPI_RunCallbacks(); +STEAM_EXPORT void SteamAPI_Shutdown(); +STEAM_EXPORT void SteamAPI_UnregisterCallResult(callbacks::base* result, + std::uint64_t call); +STEAM_EXPORT void SteamAPI_UnregisterCallback(callbacks::base* handler); + +STEAM_EXPORT bool SteamGameServer_Init(); +STEAM_EXPORT void SteamGameServer_RunCallbacks(); +STEAM_EXPORT void SteamGameServer_Shutdown(); + +STEAM_EXPORT friends* SteamFriends(); +STEAM_EXPORT matchmaking* SteamMatchmaking(); +STEAM_EXPORT matchmaking_servers* SteamMatchmakingServers(); +STEAM_EXPORT game_server* SteamGameServer(); +STEAM_EXPORT master_server_updater* SteamMasterServerUpdater(); +STEAM_EXPORT networking* SteamNetworking(); +STEAM_EXPORT remote_storage* SteamRemoteStorage(); +STEAM_EXPORT user* SteamUser(); +STEAM_EXPORT utils* SteamUtils(); +STEAM_EXPORT apps* SteamApps(); +STEAM_EXPORT user_stats* SteamUserStats(); + +std::filesystem::path get_steam_install_directory(); + +extern ::utils::nt::library overlay; +} // namespace steam diff --git a/src/common/utils/binary_resource.cpp b/src/common/utils/binary_resource.cpp new file mode 100644 index 0000000..3be37ef --- /dev/null +++ b/src/common/utils/binary_resource.cpp @@ -0,0 +1,64 @@ +#include "binary_resource.hpp" + +#include +#include "nt.hpp" +#include "io.hpp" + +namespace utils { +namespace { +std::string get_temp_folder() { + char path[MAX_PATH] = {0}; + if (!GetTempPathA(sizeof(path), path)) { + throw std::runtime_error("Unable to get temp path"); + } + + return path; +} + +std::string write_exitisting_temp_file(const std::string& file, + const std::string& data, + const bool fatal_if_overwrite_fails) { + const auto temp = get_temp_folder(); + auto file_path = temp + file; + + std::string current_data; + if (!io::read_file(file_path, ¤t_data)) { + if (!io::write_file(file_path, data)) { + throw std::runtime_error("Failed to write file: " + file_path); + } + + return file_path; + } + + if (current_data == data || io::write_file(file_path, data) || + !fatal_if_overwrite_fails) { + return file_path; + } + + throw std::runtime_error("Temporary file was already written, but differs. " + "It can't be overwritten as it's still in use: " + + file_path); +} +} // namespace + +binary_resource::binary_resource(const int id, std::string file) + : filename_(std::move(file)) { + this->resource_ = nt::load_resource(id); + + if (this->resource_.empty()) { + throw std::runtime_error("Unable to load resource: " + std::to_string(id)); + } +} + +std::string +binary_resource::get_extracted_file(const bool fatal_if_overwrite_fails) { + if (this->path_.empty()) { + this->path_ = write_exitisting_temp_file(this->filename_, this->resource_, + fatal_if_overwrite_fails); + } + + return this->path_; +} + +const std::string& binary_resource::get_data() const { return this->resource_; } +} // namespace utils diff --git a/src/common/utils/binary_resource.hpp b/src/common/utils/binary_resource.hpp new file mode 100644 index 0000000..0b221dd --- /dev/null +++ b/src/common/utils/binary_resource.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace utils { +class binary_resource { +public: + binary_resource(int id, std::string file); + + std::string get_extracted_file(bool fatal_if_overwrite_fails = false); + const std::string& get_data() const; + +private: + std::string resource_; + std::string filename_; + std::string path_; +}; +} // namespace utils diff --git a/src/common/utils/compression.cpp b/src/common/utils/compression.cpp new file mode 100644 index 0000000..b19335e --- /dev/null +++ b/src/common/utils/compression.cpp @@ -0,0 +1,138 @@ +#include +#include + +#include "memory.hpp" +#include "compression.hpp" + +#include +#include + +#include + +#include "io.hpp" + +namespace utils::compression { +namespace zlib { +namespace { +class zlib_stream { +public: + zlib_stream() { + std::memset(&stream_, 0, sizeof(z_stream)); + valid_ = inflateInit(&stream_) == Z_OK; + } + + ~zlib_stream() { + if (valid_) { + inflateEnd(&stream_); + } + } + + zlib_stream(zlib_stream&&) = delete; + zlib_stream(const zlib_stream&) = delete; + zlib_stream& operator=(zlib_stream&&) = delete; + zlib_stream& operator=(const zlib_stream&) = delete; + + z_stream& get() { return stream_; } + + [[nodiscard]] bool is_valid() const { return valid_; } + +private: + bool valid_{false}; + z_stream stream_{}; +}; +} // namespace + +std::string decompress(const std::string& data) { + std::string buffer; + zlib_stream stream_container; + if (!stream_container.is_valid()) { + return {}; + } + + int ret; + std::size_t offset = 0; + static thread_local std::uint8_t dest[CHUNK] = {0}; + auto& stream = stream_container.get(); + + do { + const auto input_size = std::min(sizeof(dest), data.size() - offset); + stream.avail_in = static_cast(input_size); + stream.next_in = reinterpret_cast(data.data()) + offset; + offset += stream.avail_in; + + do { + stream.avail_out = sizeof(dest); + stream.next_out = dest; + + ret = inflate(&stream, Z_NO_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) { + return {}; + } + + buffer.insert(buffer.end(), dest, dest + sizeof(dest) - stream.avail_out); + } while (stream.avail_out == 0); + } while (ret != Z_STREAM_END); + + return buffer; +} + +std::string compress(const std::string& data) { + std::string result; + auto length = compressBound(static_cast(data.size())); + result.resize(length); + + if (compress2(reinterpret_cast(result.data()), &length, + reinterpret_cast(data.data()), + static_cast(data.size()), Z_BEST_COMPRESSION) != Z_OK) { + return {}; + } + + result.resize(length); + return result; +} +} // namespace zlib + +namespace zip { +namespace { +bool add_file(zipFile& zip_file, const std::string& filename, + const std::string& data) { + if (zipOpenNewFileInZip(zip_file, filename.data(), nullptr, nullptr, 0, + nullptr, 0, nullptr, Z_DEFLATED, + Z_BEST_COMPRESSION) != ZIP_OK) { + return false; + } + + const auto _ = gsl::finally([&zip_file]() { zipCloseFileInZip(zip_file); }); + + return ZIP_OK == zipWriteInFileInZip(zip_file, data.data(), data.size()); +} +} // namespace + +void archive::add(std::string filename, std::string data) { + this->files_[std::move(filename)] = std::move(data); +} + +bool archive::write(const std::string& filename, const std::string& comment) { + // Hack to create the directory :3 + io::write_file(filename, {}); + io::remove_file(filename); + + auto* zip_file = zipOpen(filename.data(), 0); + if (zip_file == nullptr) { + return false; + } + + const auto _ = gsl::finally([&zip_file, &comment]() { + zipClose(zip_file, comment.empty() ? nullptr : comment.data()); + }); + + for (const auto& file : this->files_) { + if (!add_file(zip_file, file.first, file.second)) { + return false; + } + } + + return true; +} +} // namespace zip +} // namespace utils::compression diff --git a/src/common/utils/compression.hpp b/src/common/utils/compression.hpp new file mode 100644 index 0000000..f2798c9 --- /dev/null +++ b/src/common/utils/compression.hpp @@ -0,0 +1,21 @@ +#pragma once + +#define CHUNK 16384u + +namespace utils::compression { +namespace zlib { +std::string compress(const std::string& data); +std::string decompress(const std::string& data); +} // namespace zlib + +namespace zip { +class archive { +public: + void add(std::string filename, std::string data); + bool write(const std::string& filename, const std::string& comment = {}); + +private: + std::unordered_map files_; +}; +} // namespace zip +} // namespace utils::compression diff --git a/src/common/utils/concurrency.hpp b/src/common/utils/concurrency.hpp new file mode 100644 index 0000000..cfcb6cc --- /dev/null +++ b/src/common/utils/concurrency.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +namespace utils::concurrency { +template class container { +public: + template R access(F&& accessor) const { + std::lock_guard _{mutex_}; + return accessor(object_); + } + + template R access(F&& accessor) { + std::lock_guard _{mutex_}; + return accessor(object_); + } + + template + R access_with_lock(F&& accessor) const { + std::unique_lock lock{mutex_}; + return accessor(object_, lock); + } + + template R access_with_lock(F&& accessor) { + std::unique_lock lock{mutex_}; + return accessor(object_, lock); + } + + T& get_raw() { return object_; } + const T& get_raw() const { return object_; } + +private: + mutable MutexType mutex_{}; + T object_{}; +}; +} // namespace utils::concurrency diff --git a/src/common/utils/cryptography.cpp b/src/common/utils/cryptography.cpp new file mode 100644 index 0000000..c81a9b0 --- /dev/null +++ b/src/common/utils/cryptography.cpp @@ -0,0 +1,556 @@ +#include "string.hpp" +#include "cryptography.hpp" +#include "nt.hpp" + +#include + +#undef max +using namespace std::string_literals; + +/// http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-55010/Source/libtomcrypt/doc/libTomCryptDoc.pdf + +namespace utils::cryptography { +namespace { +struct __ { + __() { + ltc_mp = ltm_desc; + + register_cipher(&aes_desc); + register_cipher(&des3_desc); + + register_prng(&sprng_desc); + register_prng(&fortuna_desc); + register_prng(&yarrow_desc); + + register_hash(&sha1_desc); + register_hash(&sha256_desc); + register_hash(&sha512_desc); + } +} ___; + +[[maybe_unused]] const char* cs(const std::uint8_t* data) { + return reinterpret_cast(data); +} + +[[maybe_unused]] char* cs(std::uint8_t* data) { + return reinterpret_cast(data); +} + +[[maybe_unused]] const std::uint8_t* cs(const char* data) { + return reinterpret_cast(data); +} + +[[maybe_unused]] std::uint8_t* cs(char* data) { + return reinterpret_cast(data); +} + +[[maybe_unused]] unsigned long ul(const std::size_t value) { + return static_cast(value); +} + +class prng { +public: + prng(const ltc_prng_descriptor& descriptor, const bool autoseed = true) + : state_(std::make_unique()), descriptor_(descriptor) { + this->id_ = register_prng(&descriptor); + if (this->id_ == -1) { + throw std::runtime_error("PRNG "s + this->descriptor_.name + + " could not be registered!"); + } + + if (autoseed) { + this->auto_seed(); + } else { + this->descriptor_.start(this->state_.get()); + } + } + + ~prng() { this->descriptor_.done(this->state_.get()); } + + [[nodiscard]] prng_state* get_state() const { + this->descriptor_.ready(this->state_.get()); + return this->state_.get(); + } + + [[nodiscard]] int get_id() const { return this->id_; } + + void add_entropy(const void* data, const std::size_t length) const { + this->descriptor_.add_entropy(static_cast(data), + ul(length), this->state_.get()); + } + + void read(void* data, const std::size_t length) const { + this->descriptor_.read(static_cast(data), ul(length), + this->get_state()); + } + +private: + int id_; + std::unique_ptr state_; + const ltc_prng_descriptor& descriptor_; + + void auto_seed() const { + rng_make_prng(128, this->id_, this->state_.get(), nullptr); + + int i[4]; // uninitialized data + auto* i_ptr = &i; + this->add_entropy(reinterpret_cast(&i), sizeof(i)); + this->add_entropy(reinterpret_cast(&i_ptr), sizeof(i_ptr)); + + auto t = time(nullptr); + this->add_entropy(reinterpret_cast(&t), sizeof(t)); + } +}; + +const prng prng_(fortuna_desc); +} // namespace + +ecc::key::key() { ZeroMemory(&this->key_storage_, sizeof(this->key_storage_)); } + +ecc::key::~key() { this->free(); } + +ecc::key::key(key&& obj) noexcept : key() { this->operator=(std::move(obj)); } + +ecc::key::key(const key& obj) : key() { this->operator=(obj); } + +ecc::key& ecc::key::operator=(key&& obj) noexcept { + if (this != &obj) { + std::memmove(&this->key_storage_, &obj.key_storage_, + sizeof(this->key_storage_)); + ZeroMemory(&obj.key_storage_, sizeof(obj.key_storage_)); + } + + return *this; +} + +ecc::key& ecc::key::operator=(const key& obj) { + if (this != &obj && obj.is_valid()) { + this->deserialize(obj.serialize(obj.key_storage_.type)); + } + + return *this; +} + +bool ecc::key::operator==(key& key) const { + return (this->is_valid() && key.is_valid() && + this->serialize(PK_PUBLIC) == key.serialize(PK_PUBLIC)); +} + +bool ecc::key::is_valid() const { + return (!memory::is_set(&this->key_storage_, 0, sizeof(this->key_storage_))); +} + +ecc_key& ecc::key::get() { return this->key_storage_; } + +const ecc_key& ecc::key::get() const { return this->key_storage_; } + +std::string ecc::key::get_public_key() const { + std::uint8_t buffer[512]{}; + unsigned long length = sizeof(buffer); + + if (ecc_ansi_x963_export(&this->key_storage_, buffer, &length) == CRYPT_OK) { + return {cs(buffer), length}; + } + + return {}; +} + +void ecc::key::set(const std::string& pub_key_buffer) { + this->free(); + + if (ecc_ansi_x963_import(cs(pub_key_buffer.data()), ul(pub_key_buffer.size()), + &this->key_storage_) != CRYPT_OK) { + ZeroMemory(&this->key_storage_, sizeof(this->key_storage_)); + } +} + +void ecc::key::deserialize(const std::string& key) { + this->free(); + + if (ecc_import(cs(key.data()), ul(key.size()), &this->key_storage_) != + CRYPT_OK) { + ZeroMemory(&this->key_storage_, sizeof(this->key_storage_)); + } +} + +std::string ecc::key::serialize(const int type) const { + std::uint8_t buffer[4096]{}; + unsigned long length = sizeof(buffer); + + if (ecc_export(buffer, &length, type, &this->key_storage_) == CRYPT_OK) { + return {cs(buffer), length}; + } + + return {}; +} + +void ecc::key::free() { + if (this->is_valid()) { + ecc_free(&this->key_storage_); + } + + ZeroMemory(&this->key_storage_, sizeof(this->key_storage_)); +} + +std::uint64_t ecc::key::get_hash() const { + const auto hash = sha1::compute(this->get_public_key()); + if (hash.size() >= 8) { + return *reinterpret_cast(hash.data()); + } + + return 0; +} + +ecc::key ecc::generate_key(const int bits) { + key key; + ecc_make_key(prng_.get_state(), prng_.get_id(), bits / 8, &key.get()); + + return key; +} + +ecc::key ecc::generate_key(const int bits, const std::string& entropy) { + key key{}; + const prng yarrow(yarrow_desc, false); + yarrow.add_entropy(entropy.data(), entropy.size()); + + ecc_make_key(yarrow.get_state(), yarrow.get_id(), bits / 8, &key.get()); + + return key; +} + +std::string ecc::sign_message(const key& key, const std::string& message) { + if (!key.is_valid()) + return {}; + + std::uint8_t buffer[512]; + unsigned long length = sizeof(buffer); + + ecc_sign_hash(cs(message.data()), ul(message.size()), buffer, &length, + prng_.get_state(), prng_.get_id(), &key.get()); + + return {cs(buffer), length}; +} + +bool ecc::verify_message(const key& key, const std::string& message, + const std::string& signature) { + if (!key.is_valid()) + return false; + + auto result = 0; + return (ecc_verify_hash(cs(signature.data()), ul(signature.size()), + cs(message.data()), ul(message.size()), &result, + &key.get()) == CRYPT_OK && + result != 0); +} + +bool ecc::encrypt(const key& key, std::string& data) { + std::string out_data{}; + out_data.resize(std::max(ul(data.size() * 3), ul(0x100))); + + auto out_len = ul(out_data.size()); + auto crypt = [&]() { + return ecc_encrypt_key(cs(data.data()), ul(data.size()), + cs(out_data.data()), &out_len, prng_.get_state(), + prng_.get_id(), find_hash("sha512"), &key.get()); + }; + + auto res = crypt(); + + if (res == CRYPT_BUFFER_OVERFLOW) { + out_data.resize(out_len); + res = crypt(); + } + + if (res != CRYPT_OK) { + return false; + } + + out_data.resize(out_len); + data = std::move(out_data); + return true; +} + +bool ecc::decrypt(const key& key, std::string& data) { + std::string out_data{}; + out_data.resize(std::max(ul(data.size() * 3), ul(0x100))); + + auto out_len = ul(out_data.size()); + auto crypt = [&]() { + return ecc_decrypt_key(cs(data.data()), ul(data.size()), + cs(out_data.data()), &out_len, &key.get()); + }; + + auto res = crypt(); + + if (res == CRYPT_BUFFER_OVERFLOW) { + out_data.resize(out_len); + res = crypt(); + } + + if (res != CRYPT_OK) { + return false; + } + + out_data.resize(out_len); + data = std::move(out_data); + return true; +} + +std::string rsa::encrypt(const std::string& data, const std::string& hash, + const std::string& key) { + rsa_key new_key; + rsa_import(cs(key.data()), ul(key.size()), &new_key); + const auto _ = gsl::finally([&]() { rsa_free(&new_key); }); + + std::string out_data{}; + out_data.resize(std::max(ul(data.size() * 3), ul(0x100))); + + auto out_len = ul(out_data.size()); + auto crypt = [&]() { + return rsa_encrypt_key(cs(data.data()), ul(data.size()), + cs(out_data.data()), &out_len, cs(hash.data()), + ul(hash.size()), prng_.get_state(), prng_.get_id(), + find_hash("sha512"), &new_key); + }; + + auto res = crypt(); + + if (res == CRYPT_BUFFER_OVERFLOW) { + out_data.resize(out_len); + res = crypt(); + } + + if (res == CRYPT_OK) { + out_data.resize(out_len); + return out_data; + } + + return {}; +} + +std::string des3::encrypt(const std::string& data, const std::string& iv, + const std::string& key) { + std::string enc_data; + enc_data.resize(data.size()); + + symmetric_CBC cbc; + const auto des3 = find_cipher("3des"); + + cbc_start(des3, cs(iv.data()), cs(key.data()), static_cast(key.size()), + 0, &cbc); + cbc_encrypt(cs(data.data()), cs(enc_data.data()), ul(data.size()), &cbc); + cbc_done(&cbc); + + return enc_data; +} + +std::string des3::decrypt(const std::string& data, const std::string& iv, + const std::string& key) { + std::string dec_data; + dec_data.resize(data.size()); + + symmetric_CBC cbc; + const auto des3 = find_cipher("3des"); + + cbc_start(des3, cs(iv.data()), cs(key.data()), static_cast(key.size()), + 0, &cbc); + cbc_decrypt(cs(data.data()), cs(dec_data.data()), ul(data.size()), &cbc); + cbc_done(&cbc); + + return dec_data; +} + +std::string tiger::compute(const std::string& data, const bool hex) { + return compute(cs(data.data()), data.size(), hex); +} + +std::string tiger::compute(const std::uint8_t* data, const std::size_t length, + const bool hex) { + std::uint8_t buffer[24]{}; + + hash_state state; + tiger_init(&state); + tiger_process(&state, data, ul(length)); + tiger_done(&state, buffer); + + std::string hash(cs(buffer), sizeof(buffer)); + if (!hex) + return hash; + + return string::dump_hex(hash, {}); +} + +std::string aes::encrypt(const std::string& data, const std::string& iv, + const std::string& key) { + std::string enc_data; + enc_data.resize(data.size()); + + symmetric_CBC cbc; + const auto aes = find_cipher("aes"); + + cbc_start(aes, cs(iv.data()), cs(key.data()), static_cast(key.size()), 0, + &cbc); + cbc_encrypt(cs(data.data()), cs(enc_data.data()), ul(data.size()), &cbc); + cbc_done(&cbc); + + return enc_data; +} + +std::string aes::decrypt(const std::string& data, const std::string& iv, + const std::string& key) { + std::string dec_data; + dec_data.resize(data.size()); + + symmetric_CBC cbc; + const auto aes = find_cipher("aes"); + + cbc_start(aes, cs(iv.data()), cs(key.data()), static_cast(key.size()), 0, + &cbc); + cbc_decrypt(cs(data.data()), cs(dec_data.data()), ul(data.size()), &cbc); + cbc_done(&cbc); + + return dec_data; +} + +std::string hmac_sha1::compute(const std::string& data, + const std::string& key) { + std::string buffer; + buffer.resize(20); + + hmac_state state; + hmac_init(&state, find_hash("sha1"), cs(key.data()), ul(key.size())); + hmac_process(&state, cs(data.data()), static_cast(data.size())); + + auto out_len = ul(buffer.size()); + hmac_done(&state, cs(buffer.data()), &out_len); + + buffer.resize(out_len); + return buffer; +} + +std::string sha1::compute(const std::string& data, const bool hex) { + return compute(cs(data.data()), data.size(), hex); +} + +std::string sha1::compute(const std::uint8_t* data, const std::size_t length, + const bool hex) { + std::uint8_t buffer[20]{}; + + hash_state state; + sha1_init(&state); + sha1_process(&state, data, ul(length)); + sha1_done(&state, buffer); + + std::string hash(cs(buffer), sizeof(buffer)); + if (!hex) + return hash; + + return string::dump_hex(hash, {}); +} + +std::string sha256::compute(const std::string& data, const bool hex) { + return compute(cs(data.data()), data.size(), hex); +} + +std::string sha256::compute(const std::uint8_t* data, const std::size_t length, + const bool hex) { + std::uint8_t buffer[32]{}; + + hash_state state; + sha256_init(&state); + sha256_process(&state, data, ul(length)); + sha256_done(&state, buffer); + + std::string hash(cs(buffer), sizeof(buffer)); + if (!hex) + return hash; + + return string::dump_hex(hash, {}); +} + +std::string sha512::compute(const std::string& data, const bool hex) { + return compute(cs(data.data()), data.size(), hex); +} + +std::string sha512::compute(const std::uint8_t* data, const std::size_t length, + const bool hex) { + std::uint8_t buffer[64]{}; + + hash_state state; + sha512_init(&state); + sha512_process(&state, data, ul(length)); + sha512_done(&state, buffer); + + std::string hash(cs(buffer), sizeof(buffer)); + if (!hex) + return hash; + + return string::dump_hex(hash, {}); +} + +std::string base64::encode(const std::uint8_t* data, const std::size_t len) { + std::string result; + result.resize((len + 2) * 2); + + auto out_len = ul(result.size()); + if (base64_encode(data, ul(len), result.data(), &out_len) != CRYPT_OK) { + return {}; + } + + result.resize(out_len); + return result; +} + +std::string base64::encode(const std::string& data) { + return encode(cs(data.data()), data.size()); +} + +std::string base64::decode(const std::string& data) { + std::string result; + result.resize((data.size() + 2) * 2); + + auto out_len = ul(result.size()); + if (base64_decode(data.data(), ul(data.size()), cs(result.data()), + &out_len) != CRYPT_OK) { + return {}; + } + + result.resize(out_len); + return result; +} + +unsigned int jenkins_one_at_a_time::compute(const std::string& data) { + return compute(data.data(), data.size()); +} + +unsigned int jenkins_one_at_a_time::compute(const char* key, + const std::size_t len) { + std::uint32_t hash, i; + for (hash = i = 0; i < len; ++i) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +std::uint32_t random::get_integer() { + std::uint32_t result; + get_data(&result, sizeof(result)); + return result; +} + +std::string random::get_challenge() { + std::string result; + result.resize(sizeof(std::uint32_t)); + get_data(result.data(), result.size()); + return string::dump_hex(result, {}); +} + +void random::get_data(void* data, const std::size_t size) { + prng_.read(data, size); +} +} // namespace utils::cryptography diff --git a/src/common/utils/cryptography.hpp b/src/common/utils/cryptography.hpp new file mode 100644 index 0000000..755cef3 --- /dev/null +++ b/src/common/utils/cryptography.hpp @@ -0,0 +1,113 @@ +#pragma once + +#include +#include + +namespace utils::cryptography { +namespace ecc { +class key final { +public: + key(); + ~key(); + + key(key&& obj) noexcept; + key(const key& obj); + key& operator=(key&& obj) noexcept; + key& operator=(const key& obj); + bool operator==(key& key) const; + + [[nodiscard]] bool is_valid() const; + + ecc_key& get(); + [[nodiscard]] const ecc_key& get() const; + + [[nodiscard]] std::string get_public_key() const; + + void set(const std::string& pub_key_buffer); + + void deserialize(const std::string& key); + + [[nodiscard]] std::string serialize(int type = PK_PRIVATE) const; + + void free(); + + [[nodiscard]] std::uint64_t get_hash() const; + +private: + ecc_key key_storage_{}; +}; + +key generate_key(int bits); +key generate_key(int bits, const std::string& entropy); +std::string sign_message(const key& key, const std::string& message); +bool verify_message(const key& key, const std::string& message, + const std::string& signature); + +bool encrypt(const key& key, std::string& data); +bool decrypt(const key& key, std::string& data); +} // namespace ecc + +namespace rsa { +std::string encrypt(const std::string& data, const std::string& hash, + const std::string& key); +} + +namespace des3 { +std::string encrypt(const std::string& data, const std::string& iv, + const std::string& key); +std::string decrypt(const std::string& data, const std::string& iv, + const std::string& key); +} // namespace des3 + +namespace tiger { +std::string compute(const std::string& data, bool hex = false); +std::string compute(const std::uint8_t* data, std::size_t length, + bool hex = false); +} // namespace tiger + +namespace aes { +std::string encrypt(const std::string& data, const std::string& iv, + const std::string& key); +std::string decrypt(const std::string& data, const std::string& iv, + const std::string& key); +} // namespace aes + +namespace hmac_sha1 { +std::string compute(const std::string& data, const std::string& key); +} + +namespace sha1 { +std::string compute(const std::string& data, bool hex = false); +std::string compute(const std::uint8_t* data, std::size_t length, + bool hex = false); +} // namespace sha1 + +namespace sha256 { +std::string compute(const std::string& data, bool hex = false); +std::string compute(const std::uint8_t* data, std::size_t length, + bool hex = false); +} // namespace sha256 + +namespace sha512 { +std::string compute(const std::string& data, bool hex = false); +std::string compute(const std::uint8_t* data, std::size_t length, + bool hex = false); +} // namespace sha512 + +namespace base64 { +std::string encode(const std::uint8_t* data, std::size_t len); +std::string encode(const std::string& data); +std::string decode(const std::string& data); +} // namespace base64 + +namespace jenkins_one_at_a_time { +unsigned int compute(const std::string& data); +unsigned int compute(const char* key, std::size_t len); +}; // namespace jenkins_one_at_a_time + +namespace random { +std::uint32_t get_integer(); +std::string get_challenge(); +void get_data(void* data, std::size_t size); +} // namespace random +} // namespace utils::cryptography diff --git a/src/common/utils/flags.cpp b/src/common/utils/flags.cpp new file mode 100644 index 0000000..ad2fb97 --- /dev/null +++ b/src/common/utils/flags.cpp @@ -0,0 +1,47 @@ +#include + +#include +#include + +#include "flags.hpp" + +#include +#include + +namespace utils::flags { +void parse_flags(std::vector& flags) { + int num_args; + auto* const argv = CommandLineToArgvW(GetCommandLineW(), &num_args); + + assert(flags.empty()); + + if (argv == nullptr) { + return; + } + + for (auto i = 0; i < num_args; ++i) { + std::wstring wide_flag(argv[i]); + if (wide_flag[0] == L'-') { + wide_flag.erase(wide_flag.begin()); + const auto converted_string = string::convert(wide_flag); + flags.emplace_back(string::to_lower(converted_string)); + } + } + + LocalFree(argv); +} + +bool has_flag(const std::string& flag) { + static auto parsed = false; + static std::vector enabled_flags; + + if (!parsed) { + parse_flags(enabled_flags); + parsed = true; + } + + return std::ranges::any_of( + enabled_flags.cbegin(), enabled_flags.cend(), + [flag](const auto& elem) { return elem == string::to_lower(flag); }); +} +} // namespace utils::flags diff --git a/src/common/utils/flags.hpp b/src/common/utils/flags.hpp new file mode 100644 index 0000000..713fbd0 --- /dev/null +++ b/src/common/utils/flags.hpp @@ -0,0 +1,13 @@ +#pragma once +#include + +namespace utils::flags { +bool has_flag(const std::string& flag); +} + +#define IS_FLAG_ENABLED(flag) \ + static std::optional flag; \ + if (!(flag).has_value()) { \ + (flag).emplace(utils::flags::has_flag(#flag)); \ + } \ + return (flag).value(); diff --git a/src/common/utils/hook.cpp b/src/common/utils/hook.cpp new file mode 100644 index 0000000..d674755 --- /dev/null +++ b/src/common/utils/hook.cpp @@ -0,0 +1,218 @@ +#include "hook.hpp" + +#include + +namespace utils { +namespace { +[[maybe_unused]] class _ { +public: + _() { + if (MH_Initialize() != MH_OK) { + throw std::runtime_error("Failed to initialize MinHook"); + } + } + + ~_() { MH_Uninitialize(); } +} __; +} // namespace + +void hook::signature::process() { + if (this->signatures_.empty()) + return; + + const auto start = static_cast(this->start_); + + const unsigned int sig_count = this->signatures_.size(); + const auto containers = this->signatures_.data(); + + for (size_t i = 0; i < this->length_; ++i) { + const auto address = start + i; + + for (unsigned int k = 0; k < sig_count; ++k) { + const auto container = &containers[k]; + + unsigned int j; + for (j = 0; j < strlen(container->mask); ++j) { + if (container->mask[j] != '?' && + container->signature[j] != address[j]) { + break; + } + } + + if (j == strlen(container->mask)) { + container->callback(address); + } + } + } +} + +void hook::signature::add(const container& container) { + signatures_.push_back(container); +} + +hook::detour::detour(const size_t place, void* target) + : detour(reinterpret_cast(place), target) {} + +hook::detour::detour(void* place, void* target) { this->create(place, target); } + +hook::detour::~detour() { this->clear(); } + +void hook::detour::enable() const { MH_EnableHook(this->place_); } + +void hook::detour::disable() const { MH_DisableHook(this->place_); } + +void hook::detour::create(void* place, void* target) { + this->clear(); + this->place_ = place; + + if (MH_CreateHook(this->place_, target, &this->original_) != MH_OK) { + throw std::runtime_error("Unable to create hook"); + } + + this->enable(); +} + +void hook::detour::create(const size_t place, void* target) { + this->create(reinterpret_cast(place), target); +} + +void hook::detour::clear() { + if (this->place_) { + MH_RemoveHook(this->place_); + } + + this->place_ = nullptr; + this->original_ = nullptr; +} + +void* hook::detour::get_original() const { return this->original_; } + +hook::~hook() { + if (this->initialized_) { + this->uninstall(); + } +} + +hook* hook::initialize(const DWORD place, void (*stub)(), const bool use_jump) { + return this->initialize(place, reinterpret_cast(stub), use_jump); +} + +hook* hook::initialize(const DWORD place, void* stub, const bool use_jump) { + return this->initialize(reinterpret_cast(place), stub, use_jump); +} + +hook* hook::initialize(void* place, void* stub, const bool use_jump) { + if (this->initialized_) + return this; + this->initialized_ = true; + + this->use_jump_ = use_jump; + this->place_ = place; + this->stub_ = stub; + + this->original_ = + static_cast(this->place_) + 5 + + *reinterpret_cast((static_cast(this->place_) + 1)); + + return this; +} + +hook* hook::install(const bool unprotect, const bool keep_unprotected) { + std::lock_guard _(this->state_mutex_); + + if (!this->initialized_ || this->installed_) { + return this; + } + + this->installed_ = true; + + if (unprotect) + VirtualProtect(this->place_, sizeof(this->buffer_), PAGE_EXECUTE_READWRITE, + &this->protection_); + std::memcpy(this->buffer_, this->place_, sizeof(this->buffer_)); + + const auto code = static_cast(this->place_); + + *code = static_cast(this->use_jump_ ? 0xE9 : 0xE8); + + *reinterpret_cast(code + 1) = + reinterpret_cast(this->stub_) - + (reinterpret_cast(this->place_) + 5); + + if (unprotect && !keep_unprotected) + VirtualProtect(this->place_, sizeof(this->buffer_), this->protection_, + &this->protection_); + + FlushInstructionCache(GetCurrentProcess(), this->place_, + sizeof(this->buffer_)); + + return this; +} + +void hook::quick() { + if (this->installed_) { + this->installed_ = false; + } +} + +bool hook::iat(const nt::library module, const std::string& target_module, + const std::string& process, void* stub) { + if (!module.is_valid()) + return false; + + auto ptr = module.get_iat_entry(target_module, process); + if (!ptr) + return false; + + DWORD protect; + VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect); + + *ptr = stub; + + VirtualProtect(ptr, sizeof(*ptr), protect, &protect); + return true; +} + +hook* hook::uninstall(const bool unprotect) { + std::lock_guard _(this->state_mutex_); + + if (!this->initialized_ || !this->installed_) { + return this; + } + + this->installed_ = false; + + if (unprotect) + VirtualProtect(this->place_, sizeof(this->buffer_), PAGE_EXECUTE_READWRITE, + &this->protection_); + + std::memcpy(this->place_, this->buffer_, sizeof(this->buffer_)); + + if (unprotect) + VirtualProtect(this->place_, sizeof(this->buffer_), this->protection_, + &this->protection_); + + FlushInstructionCache(GetCurrentProcess(), this->place_, + sizeof(this->buffer_)); + + return this; +} + +void* hook::get_address() const { return this->place_; } + +void* hook::get_original() const { return this->original_; } + +void hook::nop(void* place, const size_t length) { + DWORD old_protect; + VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect); + + memset(place, 0x90, length); + + VirtualProtect(place, length, old_protect, &old_protect); + FlushInstructionCache(GetCurrentProcess(), place, length); +} + +void hook::nop(const DWORD place, const size_t length) { + nop(reinterpret_cast(place), length); +} +} // namespace utils diff --git a/src/common/utils/hook.hpp b/src/common/utils/hook.hpp new file mode 100644 index 0000000..1a5d367 --- /dev/null +++ b/src/common/utils/hook.hpp @@ -0,0 +1,168 @@ +#pragma once +#include +#include "nt.hpp" + +#define HOOK_JUMP true +#define HOOK_CALL false + +namespace utils { +class hook final { +public: + class signature final { + public: + struct container final { + const char* signature; + const char* mask; + std::function callback; + }; + + signature(void* start, const size_t length) + : start_(start), length_(length) {} + + signature(const DWORD start, const size_t length) + : signature(reinterpret_cast(start), length) {} + + signature() : signature(0x400000, 0x800000) {} + + void process(); + void add(const container& container); + + private: + void* start_; + size_t length_; + std::vector signatures_; + }; + + class detour { + public: + detour() = default; + detour(void* place, void* target); + detour(size_t place, void* target); + ~detour(); + + detour(detour&& other) noexcept { this->operator=(std::move(other)); } + + detour& operator=(detour&& other) noexcept { + if (this != &other) { + this->~detour(); + + this->place_ = other.place_; + this->original_ = other.original_; + + other.place_ = nullptr; + other.original_ = nullptr; + } + + return *this; + } + + detour(const detour&) = delete; + detour& operator=(const detour&) = delete; + + void enable() const; + void disable() const; + + void create(void* place, void* target); + void create(size_t place, void* target); + void clear(); + + template T* get() const { + return static_cast(this->get_original()); + } + + template T invoke(Args... args) { + return static_cast(this->get_original())(args...); + } + + [[nodiscard]] void* get_original() const; + + private: + void* place_{}; + void* original_{}; + }; + + hook() + : initialized_(false), installed_(false), place_(nullptr), stub_(nullptr), + original_(nullptr), use_jump_(false), protection_(0) { + ZeroMemory(this->buffer_, sizeof(this->buffer_)); + } + + hook(void* place, void* stub, const bool use_jump = true) : hook() { + this->initialize(place, stub, use_jump); + } + + hook(void* place, void (*stub)(), const bool use_jump = true) + : hook(place, reinterpret_cast(stub), use_jump) {} + + hook(const DWORD place, void* stub, const bool use_jump = true) + : hook(reinterpret_cast(place), stub, use_jump) {} + + hook(const DWORD place, const DWORD stub, const bool use_jump = true) + : hook(reinterpret_cast(place), reinterpret_cast(stub), + use_jump) {} + + hook(const DWORD place, void (*stub)(), const bool use_jump = true) + : hook(reinterpret_cast(place), reinterpret_cast(stub), + use_jump) {} + + hook(const hook&) = delete; + hook(const hook&&) = delete; + + ~hook(); + + hook* initialize(void* place, void* stub, bool use_jump = true); + hook* initialize(DWORD place, void* stub, bool use_jump = true); + hook* initialize(DWORD place, void (*stub)(), + bool use_jump = true); // For lambdas + hook* install(bool unprotect = true, bool keep_unprotected = false); + hook* uninstall(bool unprotect = true); + + void* get_address() const; + void* get_original() const; + void quick(); + + static bool iat(nt::library module, const std::string& target_module, + const std::string& process, void* stub); + + static void nop(void* place, size_t length); + static void nop(DWORD place, size_t length); + + template static void set(void* place, T value) { + DWORD old_protect; + VirtualProtect(place, sizeof(T), PAGE_EXECUTE_READWRITE, &old_protect); + + *static_cast(place) = value; + + VirtualProtect(place, sizeof(T), old_protect, &old_protect); + FlushInstructionCache(GetCurrentProcess(), place, sizeof(T)); + } + + template static void set(const DWORD place, T value) { + return set(reinterpret_cast(place), value); + } + + template + static T invoke(size_t func, Args... args) { + return reinterpret_cast(func)(args...); + } + + template + static T invoke(void* func, Args... args) { + return static_cast(func)(args...); + } + +private: + bool initialized_; + bool installed_; + + void* place_; + void* stub_; + void* original_; + char buffer_[5]{}; + bool use_jump_; + + DWORD protection_; + + std::mutex state_mutex_; +}; +} // namespace utils diff --git a/src/common/utils/info_string.cpp b/src/common/utils/info_string.cpp new file mode 100644 index 0000000..5cc7d36 --- /dev/null +++ b/src/common/utils/info_string.cpp @@ -0,0 +1,52 @@ +#include "info_string.hpp" +#include "string.hpp" + +namespace utils { +info_string::info_string(const std::string& buffer) { this->parse(buffer); } + +info_string::info_string(const std::string_view& buffer) + : info_string(std::string{buffer}) {} + +void info_string::set(const std::string& key, const std::string& value) { + this->key_value_pairs_[key] = value; +} + +std::string info_string::get(const std::string& key) const { + const auto value = this->key_value_pairs_.find(key); + if (value != this->key_value_pairs_.end()) { + return value->second; + } + + return {}; +} + +void info_string::parse(std::string buffer) { + if (buffer[0] == '\\') { + buffer = buffer.substr(1); + } + + const auto key_values = string::split(buffer, '\\'); + for (size_t i = 0; !key_values.empty() && i < (key_values.size() - 1); + i += 2) { + const auto& key = key_values[i]; + const auto& value = key_values[i + 1]; + + if (!this->key_value_pairs_.contains(key)) { + this->key_value_pairs_[key] = value; + } + } +} + +std::string info_string::build() const { + std::string info_string; + for (const auto& [key, val] : this->key_value_pairs_) { + info_string.append("\\"); + + info_string.append(key); + info_string.append("\\"); + info_string.append(val); + } + + return info_string; +} +} // namespace utils diff --git a/src/common/utils/info_string.hpp b/src/common/utils/info_string.hpp new file mode 100644 index 0000000..d722dff --- /dev/null +++ b/src/common/utils/info_string.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +namespace utils { +class info_string { +public: + info_string() = default; + explicit info_string(const std::string& buffer); + explicit info_string(const std::string_view& buffer); + + void set(const std::string& key, const std::string& value); + [[nodiscard]] std::string get(const std::string& key) const; + [[nodiscard]] std::string build() const; + +private: + std::unordered_map key_value_pairs_; + + void parse(std::string buffer); +}; +} // namespace utils diff --git a/src/common/utils/io.cpp b/src/common/utils/io.cpp new file mode 100644 index 0000000..88e2493 --- /dev/null +++ b/src/common/utils/io.cpp @@ -0,0 +1,111 @@ +#include "io.hpp" +#include "nt.hpp" +#include + +namespace utils::io { +bool remove_file(const std::string& file) { + return DeleteFileA(file.data()) == TRUE; +} + +bool move_file(const std::string& src, const std::string& target) { + return MoveFileA(src.data(), target.data()) == TRUE; +} + +bool file_exists(const std::string& file) { + return std::filesystem::exists(file); +} + +bool write_file(const std::string& file, const std::string& data, + const bool append) { + const auto pos = file.find_last_of("/\\"); + if (pos != std::string::npos) { + create_directory(file.substr(0, pos)); + } + + std::ofstream stream(file, std::ios::binary | std::ofstream::out | + (append ? std::ofstream::app : 0)); + + if (stream.is_open()) { + stream.write(data.data(), data.size()); + stream.close(); + return true; + } + + return false; +} + +std::string read_file(const std::string& file) { + std::string data; + read_file(file, &data); + return data; +} + +bool read_file(const std::string& file, std::string* data) { + if (!data) { + return false; + } + + data->clear(); + + if (file_exists(file)) { + std::ifstream stream(file, std::ios::binary); + if (!stream.is_open()) + return false; + + stream.seekg(0, std::ios::end); + const std::streamsize size = stream.tellg(); + stream.seekg(0, std::ios::beg); + + if (size > -1) { + data->resize(static_cast(size)); + stream.read(data->data(), size); + stream.close(); + return true; + } + } + + return false; +} + +size_t file_size(const std::string& file) { + if (file_exists(file)) { + std::ifstream stream(file, std::ios::binary); + + if (stream.good()) { + stream.seekg(0, std::ios::end); + return static_cast(stream.tellg()); + } + } + + return 0; +} + +bool create_directory(const std::string& directory) { + return std::filesystem::create_directories(directory); +} + +bool directory_exists(const std::string& directory) { + return std::filesystem::is_directory(directory); +} + +bool directory_is_empty(const std::string& directory) { + return std::filesystem::is_empty(directory); +} + +std::vector list_files(const std::string& directory) { + std::vector files; + + for (auto& file : std::filesystem::directory_iterator(directory)) { + files.push_back(file.path().generic_string()); + } + + return files; +} + +void copy_folder(const std::filesystem::path& src, + const std::filesystem::path& target) { + std::filesystem::copy(src, target, + std::filesystem::copy_options::overwrite_existing | + std::filesystem::copy_options::recursive); +} +} // namespace utils::io diff --git a/src/common/utils/io.hpp b/src/common/utils/io.hpp new file mode 100644 index 0000000..92da124 --- /dev/null +++ b/src/common/utils/io.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +namespace utils::io { +bool remove_file(const std::string& file); +bool move_file(const std::string& src, const std::string& target); +bool file_exists(const std::string& file); +bool write_file(const std::string& file, const std::string& data, + bool append = false); +bool read_file(const std::string& file, std::string* data); +std::string read_file(const std::string& file); +size_t file_size(const std::string& file); +bool create_directory(const std::string& directory); +bool directory_exists(const std::string& directory); +bool directory_is_empty(const std::string& directory); +std::vector list_files(const std::string& directory); +void copy_folder(const std::filesystem::path& src, + const std::filesystem::path& target); +} // namespace utils::io diff --git a/src/common/utils/memory.cpp b/src/common/utils/memory.cpp new file mode 100644 index 0000000..3edeaa6 --- /dev/null +++ b/src/common/utils/memory.cpp @@ -0,0 +1,132 @@ +#include "memory.hpp" +#include "nt.hpp" + +namespace utils { +memory::allocator memory::mem_allocator_; + +memory::allocator::~allocator() { this->clear(); } + +void memory::allocator::clear() { + std::lock_guard _(this->mutex_); + + for (const auto& data : this->pool_) { + memory::free(data); + } + + this->pool_.clear(); +} + +void memory::allocator::free(void* data) { + std::lock_guard _(this->mutex_); + + const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); + if (j != this->pool_.end()) { + memory::free(data); + this->pool_.erase(j); + } +} + +void memory::allocator::free(const void* data) { + this->free(const_cast(data)); +} + +void* memory::allocator::allocate(const std::size_t length) { + std::lock_guard _(this->mutex_); + + const auto data = memory::allocate(length); + this->pool_.push_back(data); + return data; +} + +bool memory::allocator::empty() const { return this->pool_.empty(); } + +char* memory::allocator::duplicate_string(const std::string& string) { + std::lock_guard _(this->mutex_); + + const auto data = memory::duplicate_string(string); + this->pool_.push_back(data); + return data; +} + +void* memory::allocate(const std::size_t length) { + return std::calloc(length, 1); +} + +char* memory::duplicate_string(const std::string& string) { + const auto new_string = allocate_array(string.size() + 1); + std::memcpy(new_string, string.data(), string.size()); + return new_string; +} + +void memory::free(void* data) { std::free(data); } + +void memory::free(const void* data) { free(const_cast(data)); } + +bool memory::is_set(const void* mem, const char chr, const std::size_t length) { + const auto mem_arr = static_cast(mem); + + for (std::size_t i = 0; i < length; ++i) { + if (mem_arr[i] != chr) { + return false; + } + } + + return true; +} + +bool memory::is_bad_read_ptr(const void* ptr) { + MEMORY_BASIC_INFORMATION mbi = {}; + if (VirtualQuery(ptr, &mbi, sizeof(mbi))) { + const DWORD mask = + (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | + PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); + auto b = !(mbi.Protect & mask); + // check the page is not a guard page + if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) + b = true; + + return b; + } + return true; +} + +bool memory::is_bad_code_ptr(const void* ptr) { + MEMORY_BASIC_INFORMATION mbi = {}; + if (VirtualQuery(ptr, &mbi, sizeof(mbi))) { + const DWORD mask = + (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); + auto b = !(mbi.Protect & mask); + // check the page is not a guard page + if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) + b = true; + + return b; + } + return true; +} + +bool memory::is_rdata_ptr(void* ptr) { + const std::string rdata = ".rdata"; + const auto pointer_lib = utils::nt::library::get_by_address(ptr); + + for (const auto& section : pointer_lib.get_section_headers()) { + constexpr auto size = sizeof(section->Name); + char name[size + 1]; + name[size] = 0; + std::memcpy(name, section->Name, size); + + if (name == rdata) { + const auto target = reinterpret_cast(ptr); + const auto source_start = + size_t(pointer_lib.get_ptr()) + section->PointerToRawData; + const auto source_end = source_start + section->SizeOfRawData; + + return target >= source_start && target <= source_end; + } + } + + return false; +} + +memory::allocator* memory::get_allocator() { return &memory::mem_allocator_; } +} // namespace utils diff --git a/src/common/utils/memory.hpp b/src/common/utils/memory.hpp new file mode 100644 index 0000000..3e335d8 --- /dev/null +++ b/src/common/utils/memory.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include +#include + +namespace utils { +class memory final { +public: + class allocator final { + public: + ~allocator(); + + void clear(); + + void free(void* data); + + void free(const void* data); + + void* allocate(std::size_t length); + + template T* allocate() { return this->allocate_array(1); } + + template T* allocate_array(const std::size_t count = 1) { + return static_cast(this->allocate(count * sizeof(T))); + } + + [[nodiscard]] bool empty() const; + + char* duplicate_string(const std::string& string); + + private: + std::mutex mutex_; + std::vector pool_; + }; + + static void* allocate(std::size_t length); + + template static T* allocate() { return allocate_array(1); } + + template static T* allocate_array(const std::size_t count = 1) { + return static_cast(allocate(count * sizeof(T))); + } + + static char* duplicate_string(const std::string& string); + + static void free(void* data); + static void free(const void* data); + + static bool is_set(const void* mem, char chr, std::size_t length); + + static bool is_bad_read_ptr(const void* ptr); + static bool is_bad_code_ptr(const void* ptr); + static bool is_rdata_ptr(void* ptr); + + static allocator* get_allocator(); + +private: + static allocator mem_allocator_; +}; +} // namespace utils diff --git a/src/common/utils/nt.cpp b/src/common/utils/nt.cpp new file mode 100644 index 0000000..fed6dce --- /dev/null +++ b/src/common/utils/nt.cpp @@ -0,0 +1,260 @@ +#include "nt.hpp" + +namespace utils::nt { +library library::load(const std::string& name) { + return library(LoadLibraryA(name.data())); +} + +library library::load(const std::filesystem::path& path) { + return library::load(path.generic_string()); +} + +library library::get_by_address(void* address) { + HMODULE handle = nullptr; + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + static_cast(address), &handle); + return library(handle); +} + +library::library() { this->module_ = GetModuleHandleA(nullptr); } + +library::library(const std::string& name) { + this->module_ = GetModuleHandleA(name.data()); +} + +library::library(const HMODULE handle) { this->module_ = handle; } + +bool library::operator==(const library& obj) const { + return this->module_ == obj.module_; +} + +library::operator bool() const { return this->is_valid(); } + +library::operator HMODULE() const { return this->get_handle(); } + +PIMAGE_NT_HEADERS library::get_nt_headers() const { + if (!this->is_valid()) + return nullptr; + return reinterpret_cast(this->get_ptr() + + this->get_dos_header()->e_lfanew); +} + +PIMAGE_DOS_HEADER library::get_dos_header() const { + return reinterpret_cast(this->get_ptr()); +} + +PIMAGE_OPTIONAL_HEADER library::get_optional_header() const { + if (!this->is_valid()) + return nullptr; + return &this->get_nt_headers()->OptionalHeader; +} + +std::vector library::get_section_headers() const { + std::vector headers; + + auto nt_headers = this->get_nt_headers(); + auto section = IMAGE_FIRST_SECTION(nt_headers); + + for (uint16_t i = 0; i < nt_headers->FileHeader.NumberOfSections; + ++i, ++section) { + if (section) + headers.push_back(section); + else + OutputDebugStringA("There was an invalid section :O"); + } + + return headers; +} + +std::uint8_t* library::get_ptr() const { + return reinterpret_cast(this->module_); +} + +void library::unprotect() const { + if (!this->is_valid()) + return; + + DWORD protection; + VirtualProtect(this->get_ptr(), this->get_optional_header()->SizeOfImage, + PAGE_EXECUTE_READWRITE, &protection); +} + +size_t library::get_relative_entry_point() const { + if (!this->is_valid()) + return 0; + return this->get_nt_headers()->OptionalHeader.AddressOfEntryPoint; +} + +void* library::get_entry_point() const { + if (!this->is_valid()) + return nullptr; + return this->get_ptr() + this->get_relative_entry_point(); +} + +bool library::is_valid() const { + return this->module_ != nullptr && + this->get_dos_header()->e_magic == IMAGE_DOS_SIGNATURE; +} + +std::string library::get_name() const { + if (!this->is_valid()) + return {}; + + auto path = this->get_path(); + const auto pos = path.find_last_of("/\\"); + if (pos == std::string::npos) + return path; + + return path.substr(pos + 1); +} + +std::string library::get_path() const { + if (!this->is_valid()) + return {}; + + char name[MAX_PATH] = {0}; + GetModuleFileNameA(this->module_, name, sizeof name); + + return name; +} + +std::string library::get_folder() const { + if (!this->is_valid()) + return {}; + + const auto path = std::filesystem::path(this->get_path()); + return path.parent_path().generic_string(); +} + +void library::free() { + if (this->is_valid()) { + FreeLibrary(this->module_); + this->module_ = nullptr; + } +} + +HMODULE library::get_handle() const { return this->module_; } + +void** library::get_iat_entry(const std::string& module_name, + const std::string& proc_name) const { + if (!this->is_valid()) + return nullptr; + + const library other_module(module_name); + if (!other_module.is_valid()) + return nullptr; + + auto* const target_function = other_module.get_proc(proc_name); + if (!target_function) + return nullptr; + + auto* header = this->get_optional_header(); + if (!header) + return nullptr; + + auto* import_descriptor = reinterpret_cast( + this->get_ptr() + + header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + while (import_descriptor->Name) { + if (!_stricmp( + reinterpret_cast(this->get_ptr() + import_descriptor->Name), + module_name.data())) { + auto* original_thunk_data = reinterpret_cast( + import_descriptor->OriginalFirstThunk + this->get_ptr()); + auto* thunk_data = reinterpret_cast( + import_descriptor->FirstThunk + this->get_ptr()); + + while (original_thunk_data->u1.AddressOfData) { + const size_t ordinal_number = + original_thunk_data->u1.AddressOfData & 0xFFFFFFF; + + if (ordinal_number > 0xFFFF) + continue; + + if (GetProcAddress(other_module.module_, + reinterpret_cast(ordinal_number)) == + target_function) { + return reinterpret_cast(&thunk_data->u1.Function); + } + + ++original_thunk_data; + ++thunk_data; + } + } + + ++import_descriptor; + } + + return nullptr; +} + +void library::set_dll_directory(const std::string& directory) { + SetDllDirectoryA(directory.data()); +} + +std::string library::get_dll_directory() { + char directory[MAX_PATH] = {0}; + if (!GetDllDirectoryA(sizeof(directory), directory)) { + return {}; + } + + return directory; +} + +void raise_hard_exception() { + int data = false; + const library ntdll("ntdll.dll"); + ntdll.invoke_pascal("RtlAdjustPrivilege", 19, true, false, &data); + ntdll.invoke_pascal("NtRaiseHardError", 0xC000007B, 0, nullptr, nullptr, + 6, &data); +} + +std::string load_resource(const int id) { + auto* const res = FindResource(library(), MAKEINTRESOURCE(id), RT_RCDATA); + if (!res) + return {}; + + auto* const handle = LoadResource(nullptr, res); + if (!handle) + return {}; + + return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res)); +} + +void launch_process(const std::string& process, + const std::string& command_line) { + STARTUPINFOA startup_info; + PROCESS_INFORMATION process_info; + + ZeroMemory(&startup_info, sizeof(startup_info)); + ZeroMemory(&process_info, sizeof(process_info)); + startup_info.cb = sizeof(startup_info); + + char current_dir[MAX_PATH]; + GetCurrentDirectoryA(sizeof(current_dir), current_dir); + + CreateProcessA(process.data(), const_cast(command_line.data()), + nullptr, nullptr, false, NULL, nullptr, current_dir, + &startup_info, &process_info); + + if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) + CloseHandle(process_info.hThread); + if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) + CloseHandle(process_info.hProcess); +} + +void relaunch_self(const std::string& command_line) { + const library self; + launch_process(self.get_path(), command_line); +} + +void update_dll_search_path(const std::string& directory) { + const library self; + self.set_dll_directory(directory); +} + +void terminate(const uint32_t code) { + TerminateProcess(GetCurrentProcess(), code); +} +} // namespace utils::nt diff --git a/src/common/utils/nt.hpp b/src/common/utils/nt.hpp new file mode 100644 index 0000000..f55fb7e --- /dev/null +++ b/src/common/utils/nt.hpp @@ -0,0 +1,113 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include + +// min and max is required by gdi, therefore NOMINMAX won't work +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +#include +#include +#include + +namespace utils::nt { +class library final { +public: + static library load(const std::string& name); + static library load(const std::filesystem::path& path); + static library get_by_address(void* address); + + library(); + explicit library(const std::string& name); + explicit library(HMODULE handle); + + library(const library& a) : module_(a.module_) {} + + bool operator!=(const library& obj) const { return !(*this == obj); }; + bool operator==(const library& obj) const; + + operator bool() const; + operator HMODULE() const; + + void unprotect() const; + void* get_entry_point() const; + size_t get_relative_entry_point() const; + + bool is_valid() const; + std::string get_name() const; + std::string get_path() const; + std::string get_folder() const; + std::uint8_t* get_ptr() const; + void free(); + + HMODULE get_handle() const; + + template T get_proc(const std::string& process) const { + if (!this->is_valid()) + T{}; + return reinterpret_cast(GetProcAddress(this->module_, process.data())); + } + + template std::function get(const std::string& process) const { + if (!this->is_valid()) + return std::function(); + return static_cast(this->get_proc(process)); + } + + template + T invoke(const std::string& process, Args... args) const { + auto method = this->get(process); + if (method) + return method(args...); + return T(); + } + + template + T invoke_pascal(const std::string& process, Args... args) const { + auto method = this->get(process); + if (method) + return method(args...); + return T(); + } + + template + T invoke_this(const std::string& process, void* this_ptr, + Args... args) const { + auto method = this->get(this_ptr, process); + if (method) + return method(args...); + return T(); + } + + std::vector get_section_headers() const; + + PIMAGE_NT_HEADERS get_nt_headers() const; + PIMAGE_DOS_HEADER get_dos_header() const; + PIMAGE_OPTIONAL_HEADER get_optional_header() const; + + void** get_iat_entry(const std::string& module_name, + const std::string& proc_name) const; + + static void set_dll_directory(const std::string& directory); + static std::string get_dll_directory(); + +private: + HMODULE module_; +}; + +__declspec(noreturn) void raise_hard_exception(); +std::string load_resource(int id); + +void launch_process(const std::string& process, + const std::string& command_line); +void relaunch_self(const std::string& command_line = ""); +void update_dll_search_path(const std::string& directory); + +__declspec(noreturn) void terminate(uint32_t code = 0); +} // namespace utils::nt diff --git a/src/common/utils/signature.cpp b/src/common/utils/signature.cpp new file mode 100644 index 0000000..601a723 --- /dev/null +++ b/src/common/utils/signature.cpp @@ -0,0 +1,191 @@ +#include "signature.hpp" +#include +#include + +#include + +namespace utils::hook { +void signature::load_pattern(const std::string& pattern) { + this->mask_.clear(); + this->pattern_.clear(); + + uint8_t nibble = 0; + auto has_nibble = false; + + for (auto val : pattern) { + if (val == ' ') + continue; + if (val == '?') { + this->mask_.push_back(val); + this->pattern_.push_back(0); + } else { + if ((val < '0' || val > '9') && (val < 'A' || val > 'F') && + (val < 'a' || val > 'f')) { + throw std::runtime_error("Invalid pattern"); + } + + char str[] = {val, 0}; + const auto current_nibble = + static_cast(strtol(str, nullptr, 16)); + + if (!has_nibble) { + has_nibble = true; + nibble = current_nibble; + } else { + has_nibble = false; + const uint8_t byte = current_nibble | (nibble << 4); + + this->mask_.push_back('x'); + this->pattern_.push_back(byte); + } + } + } + + while (!this->mask_.empty() && this->mask_.back() == '?') { + this->mask_.pop_back(); + this->pattern_.pop_back(); + } + + if (this->has_sse_support()) { + while (this->pattern_.size() < 16) { + this->pattern_.push_back(0); + } + } + + if (has_nibble) { + throw std::runtime_error("Invalid pattern"); + } +} + +std::vector signature::process_range(uint8_t* start, + const size_t length) const { + if (this->has_sse_support()) + return this->process_range_vectorized(start, length); + return this->process_range_linear(start, length); +} + +std::vector signature::process_range_linear(uint8_t* start, + const size_t length) const { + std::vector result; + + for (size_t i = 0; i < length; ++i) { + const auto address = start + i; + + size_t j = 0; + for (; j < this->mask_.size(); ++j) { + if (this->mask_[j] != '?' && this->pattern_[j] != address[j]) { + break; + } + } + + if (j == this->mask_.size()) { + result.push_back(size_t(address)); + } + } + + return result; +} + +std::vector +signature::process_range_vectorized(uint8_t* start, const size_t length) const { + std::vector result; + __declspec(align(16)) char desired_mask[16] = {0}; + + for (size_t i = 0; i < this->mask_.size(); i++) { + desired_mask[i / 8] |= (this->mask_[i] == '?' ? 0 : 1) << i % 8; + } + + const auto mask = + _mm_load_si128(reinterpret_cast(desired_mask)); + const auto comparand = + _mm_loadu_si128(reinterpret_cast(this->pattern_.data())); + + for (size_t i = 0; i < length; ++i) { + const auto address = start + i; + const auto value = + _mm_loadu_si128(reinterpret_cast(address)); + const auto comparison = + _mm_cmpestrm(value, 16, comparand, static_cast(this->mask_.size()), + _SIDD_CMP_EQUAL_EACH); + + const auto matches = _mm_and_si128(mask, comparison); + const auto equivalence = _mm_xor_si128(mask, matches); + + if (_mm_test_all_zeros(equivalence, equivalence)) { + result.push_back(size_t(address)); + } + } + + return result; +} + +signature::signature_result signature::process() const { + const auto range = this->length_ - this->mask_.size(); + const auto cores = std::max(1u, std::thread::hardware_concurrency()); + + if (range <= cores * 10ull) + return this->process_serial(); + return this->process_parallel(); +} + +signature::signature_result signature::process_serial() const { + const auto sub = this->has_sse_support() ? 16 : this->mask_.size(); + return {this->process_range(this->start_, this->length_ - sub)}; +} + +signature::signature_result signature::process_parallel() const { + const auto sub = this->has_sse_support() ? 16 : this->mask_.size(); + const auto range = this->length_ - sub; + const auto cores = std::max(1u, std::thread::hardware_concurrency() / 2); + // Only use half of the available cores + const auto grid = range / cores; + + std::mutex mutex; + std::vector result; + std::vector threads; + + for (auto i = 0u; i < cores; ++i) { + const auto start = this->start_ + (grid * i); + const auto length = + (i + 1 == cores) ? (this->start_ + this->length_ - sub) - start : grid; + threads.emplace_back([&, start, length]() { + auto local_result = this->process_range(start, length); + if (local_result.empty()) + return; + + std::lock_guard _(mutex); + for (const auto& address : local_result) { + result.push_back(address); + } + }); + } + + for (auto& t : threads) { + if (t.joinable()) { + t.join(); + } + } + + std::sort(result.begin(), result.end()); + return {std::move(result)}; +} + +bool signature::has_sse_support() const { + if (this->mask_.size() <= 16) { + int cpu_id[4]; + __cpuid(cpu_id, 0); + + if (cpu_id[0] >= 1) { + __cpuidex(cpu_id, 1, 0); + return (cpu_id[2] & (1 << 20)) != 0; + } + } + + return false; +} +} // namespace utils::hook + +utils::hook::signature::signature_result operator"" _sig(const char* str, + const size_t len) { + return utils::hook::signature(std::string(str, len)).process(); +} diff --git a/src/common/utils/signature.hpp b/src/common/utils/signature.hpp new file mode 100644 index 0000000..d5b1531 --- /dev/null +++ b/src/common/utils/signature.hpp @@ -0,0 +1,62 @@ +#pragma once +#include "nt.hpp" +#include + +namespace utils::hook { +class signature final { +public: + class signature_result { + public: + signature_result(std::vector&& matches) + : matches_(std::move(matches)) {} + + [[nodiscard]] uint8_t* get(const size_t index) const { + if (index >= this->count()) { + throw std::runtime_error("Invalid index"); + } + + return reinterpret_cast(this->matches_[index]); + } + + [[nodiscard]] size_t count() const { return this->matches_.size(); } + + private: + std::vector matches_; + }; + + explicit signature(const std::string& pattern, const nt::library library = {}) + : signature(pattern, library.get_ptr(), + library.get_optional_header()->SizeOfImage) {} + + signature(const std::string& pattern, void* start, void* end) + : signature(pattern, start, size_t(end) - size_t(start)) {} + + signature(const std::string& pattern, void* start, const size_t length) + : start_(static_cast(start)), length_(length) { + this->load_pattern(pattern); + } + + signature_result process() const; + +private: + std::string mask_; + std::basic_string pattern_; + + uint8_t* start_; + size_t length_; + + void load_pattern(const std::string& pattern); + + signature_result process_parallel() const; + signature_result process_serial() const; + std::vector process_range(uint8_t* start, size_t length) const; + std::vector process_range_linear(uint8_t* start, size_t length) const; + std::vector process_range_vectorized(uint8_t* start, + size_t length) const; + + bool has_sse_support() const; +}; +} // namespace utils::hook + +utils::hook::signature::signature_result operator"" _sig(const char* str, + size_t len); diff --git a/src/common/utils/smbios.cpp b/src/common/utils/smbios.cpp new file mode 100644 index 0000000..f9f29e1 --- /dev/null +++ b/src/common/utils/smbios.cpp @@ -0,0 +1,83 @@ +#include "smbios.hpp" +#include "memory.hpp" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +namespace utils::smbios { +namespace { +#pragma warning(push) +#pragma warning(disable : 4200) +struct RawSMBIOSData { + BYTE Used20CallingMethod; + BYTE SMBIOSMajorVersion; + BYTE SMBIOSMinorVersion; + BYTE DmiRevision; + DWORD Length; + BYTE SMBIOSTableData[]; +}; + +typedef struct { + BYTE type; + BYTE length; + WORD handle; +} dmi_header; +#pragma warning(pop) + +std::vector get_smbios_data() { + std::uint32_t size = 0; + std::vector data; + + size = GetSystemFirmwareTable('RSMB', 0, nullptr, size); + data.resize(size); + GetSystemFirmwareTable('RSMB', 0, data.data(), size); + + return data; +} + +std::string parse_uuid(const std::uint8_t* data) { + if (memory::is_set(data, 0, 16) || memory::is_set(data, -1, 16)) { + return {}; + } + + char uuid[16]{}; + *reinterpret_cast(uuid + 0) = + _byteswap_ulong(*reinterpret_cast(data + 0)); + *reinterpret_cast(uuid + 4) = + _byteswap_ushort(*reinterpret_cast(data + 4)); + *reinterpret_cast(uuid + 6) = + _byteswap_ushort(*reinterpret_cast(data + 6)); + memcpy(uuid + 8, data + 8, 8); + + return {uuid, sizeof(uuid)}; +} +} // namespace + +std::string get_uuid() { + auto smbios_data = get_smbios_data(); + auto* raw_data = reinterpret_cast(smbios_data.data()); + + auto* data = raw_data->SMBIOSTableData; + for (DWORD i = 0; i + sizeof(dmi_header) < raw_data->Length;) { + auto* header = reinterpret_cast(data + i); + if (header->length < 4) { + return {}; + } + + if (header->type == 0x01 && header->length >= 0x19) { + return parse_uuid(data + i + 0x8); + } + + i += header->length; + while ((i + 1) < raw_data->Length && + *reinterpret_cast(data + i) != 0) { + ++i; + } + + i += 2; + } + + return {}; +} +} // namespace utils::smbios diff --git a/src/common/utils/smbios.hpp b/src/common/utils/smbios.hpp new file mode 100644 index 0000000..e6c3942 --- /dev/null +++ b/src/common/utils/smbios.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +namespace utils::smbios { +std::string get_uuid(); +} diff --git a/src/common/utils/string.cpp b/src/common/utils/string.cpp new file mode 100644 index 0000000..27c1a31 --- /dev/null +++ b/src/common/utils/string.cpp @@ -0,0 +1,129 @@ +#include "string.hpp" +#include +#include + +#include "nt.hpp" + +namespace utils::string { +std::vector split(const std::string& s, const char delim) { + std::stringstream ss(s); + std::string item; + std::vector elems; + + while (std::getline(ss, item, delim)) { + elems.push_back(item); // elems.push_back(std::move(item)); // if C++11 + // (based on comment from @mchiasson) + } + + return elems; +} + +std::string to_lower(const std::string& text) { + std::string result; + std::ranges::transform(text, std::back_inserter(result), + [](const unsigned char input) { + return static_cast(std::tolower(input)); + }); + + return result; +} + +std::string to_upper(const std::string& text) { + std::string result; + std::ranges::transform(text, std::back_inserter(result), + [](const unsigned char input) { + return static_cast(std::toupper(input)); + }); + + return result; +} + +bool starts_with(const std::string& text, const std::string& substring) { + return text.find(substring) == 0; +} + +bool ends_with(const std::string& text, const std::string& substring) { + if (substring.size() > text.size()) + return false; + return std::equal(substring.rbegin(), substring.rend(), text.rbegin()); +} + +bool compare(const std::string& lhs, const std::string& rhs) { + return std::ranges::equal(lhs, rhs, + [](const unsigned char a, const unsigned char b) { + return std::tolower(a) == std::tolower(b); + }); +} + +std::string dump_hex(const std::string& data, const std::string& separator) { + char buf[64]{}; + std::string result; + + for (unsigned int i = 0; i < data.size(); ++i) { + if (i > 0) { + result.append(separator); + } + + sprintf_s(buf, "%02X", data[i] & 0xFF); + result.append(buf); + } + + return result; +} + +std::string get_clipboard_data() { + if (OpenClipboard(nullptr)) { + std::string data; + + auto* const clipboard_data = GetClipboardData(1u); + if (clipboard_data) { + auto* const cliptext = static_cast(GlobalLock(clipboard_data)); + if (cliptext) { + data.append(cliptext); + GlobalUnlock(clipboard_data); + } + } + CloseClipboard(); + + return data; + } + return {}; +} + +std::string convert(const std::wstring& wstr) { + std::string result; + result.reserve(wstr.size()); + + for (const auto& chr : wstr) { + result.push_back(static_cast(chr)); + } + + return result; +} + +std::wstring convert(const std::string& str) { + std::wstring result; + result.reserve(str.size()); + + for (const auto& chr : str) { + result.push_back(static_cast(chr)); + } + + return result; +} + +std::string replace(std::string str, const std::string& from, + const std::string& to) { + if (from.empty()) { + return str; + } + + std::size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } + + return str; +} +} // namespace utils::string diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp new file mode 100644 index 0000000..5dbcd56 --- /dev/null +++ b/src/common/utils/string.hpp @@ -0,0 +1,48 @@ +#pragma once +#include "memory.hpp" +#include +#include +#include +#include + +namespace utils::string { + +template // This should display a nice "null" instead of a number +static void sanitize_format_args(Arg& arg) { + if constexpr (std::is_same_v || + std::is_same_v) { + if (arg == nullptr) { + arg = const_cast("nullptr"); + } + } +} + +template +static const char* va(std::string_view fmt, Args&&... args) { + static thread_local std::string va_buffer; + + (sanitize_format_args(args), ...); + std::vformat(fmt, std::make_format_args(args...)).swap(va_buffer); + return va_buffer.data(); +} + +std::vector split(const std::string& s, char delim); + +std::string to_lower(const std::string& text); +std::string to_upper(const std::string& text); + +bool starts_with(const std::string& text, const std::string& substring); +bool ends_with(const std::string& text, const std::string& substring); +bool compare(const std::string& lhs, const std::string& rhs); + +std::string dump_hex(const std::string& data, + const std::string& separator = " "); + +std::string get_clipboard_data(); + +std::string convert(const std::wstring& wstr); +std::wstring convert(const std::string& str); + +std::string replace(std::string str, const std::string& from, + const std::string& to); +} // namespace utils::string diff --git a/src/common/utils/thread.cpp b/src/common/utils/thread.cpp new file mode 100644 index 0000000..7d778ed --- /dev/null +++ b/src/common/utils/thread.cpp @@ -0,0 +1,105 @@ +#include +#include "nt.hpp" +#include "string.hpp" + +#include "thread.hpp" + +#include + +#include + +namespace utils::thread { +bool set_name(const HANDLE t, const std::string& name) { + const nt::library kernel32("kernel32.dll"); + if (!kernel32) { + return false; + } + + const auto set_description = + kernel32.get_proc( + "SetThreadDescription"); + if (!set_description) { + return false; + } + + return SUCCEEDED(set_description(t, string::convert(name).data())); +} + +bool set_name(const DWORD id, const std::string& name) { + auto* const t = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, id); + if (!t) + return false; + + const auto _ = gsl::finally([t]() { CloseHandle(t); }); + + return set_name(t, name); +} + +bool set_name(std::thread& t, const std::string& name) { + return set_name(t.native_handle(), name); +} + +bool set_name(const std::string& name) { + return set_name(GetCurrentThread(), name); +} + +std::vector get_thread_ids() { + auto* const h = + CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); + if (h == INVALID_HANDLE_VALUE) { + return {}; + } + + const auto _ = gsl::finally([h]() { CloseHandle(h); }); + + THREADENTRY32 entry{}; + entry.dwSize = sizeof(entry); + if (!Thread32First(h, &entry)) { + return {}; + } + + std::vector ids; + + do { + const auto check_size = + entry.dwSize < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + + sizeof(entry.th32OwnerProcessID); + entry.dwSize = sizeof(entry); + + if (check_size && entry.th32OwnerProcessID == GetCurrentProcessId()) { + ids.emplace_back(entry.th32ThreadID); + } + } while (Thread32Next(h, &entry)); + + return ids; +} + +void for_each_thread(const std::function& callback) { + const auto ids = get_thread_ids(); + + for (const auto& id : ids) { + auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id); + if (thread != nullptr) { + const auto _ = gsl::finally([thread]() { CloseHandle(thread); }); + + callback(thread); + } + } +} + +void suspend_other_threads() { + for_each_thread([](const HANDLE thread) { + if (GetThreadId(thread) != GetCurrentThreadId()) { + SuspendThread(thread); + } + }); +} + +void resume_other_threads() { + for_each_thread([](const HANDLE thread) { + if (GetThreadId(thread) != GetCurrentThreadId()) { + ResumeThread(thread); + } + }); +} +} // namespace utils::thread diff --git a/src/common/utils/thread.hpp b/src/common/utils/thread.hpp new file mode 100644 index 0000000..b9ee875 --- /dev/null +++ b/src/common/utils/thread.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace utils::thread { +bool set_name(HANDLE t, const std::string& name); +bool set_name(DWORD id, const std::string& name); +bool set_name(std::thread& t, const std::string& name); +bool set_name(const std::string& name); + +template +std::thread create_named_thread(const std::string& name, Args&&... args) { + auto t = std::thread(std::forward(args)...); + set_name(t, name); + return t; +} + +std::vector get_thread_ids(); +void for_each_thread(const std::function& callback); + +void suspend_other_threads(); +void resume_other_threads(); +} // namespace utils::thread diff --git a/src/runner/debugger.cpp b/src/runner/debugger.cpp new file mode 100644 index 0000000..6fc87c5 --- /dev/null +++ b/src/runner/debugger.cpp @@ -0,0 +1,82 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include "debugger.hpp" + +namespace { +bool acquire_debug_privilege() { + TOKEN_PRIVILEGES token_privileges; + ZeroMemory(&token_privileges, sizeof(token_privileges)); + token_privileges.PrivilegeCount = 1; + + HANDLE token; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) { + return false; + } + + if (!LookupPrivilegeValue(nullptr, SE_DEBUG_NAME, + &token_privileges.Privileges[0].Luid)) { + CloseHandle(token); + return false; + } + + token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + DWORD size; + if (!AdjustTokenPrivileges(token, FALSE, &token_privileges, 0, nullptr, + &size)) { + CloseHandle(token); + return false; + } + + return CloseHandle(token) != FALSE; +} +} // namespace + +debugger::debugger(const unsigned long process_id, const bool start) { + if (!start) { + return; + } + + this->runner_ = std::thread([this, process_id]() { + this->terminate_ = false; + this->run(process_id); + }); +} + +debugger::~debugger() { + this->terminate_ = true; + if (this->runner_.joinable()) { + this->runner_.join(); + } +} + +void debugger::run(const unsigned long process_id) const { + acquire_debug_privilege(); + if (!DebugActiveProcess(process_id)) { + return; + } + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); + + DEBUG_EVENT event; + while (!this->terminate_ && WaitForDebugEvent(&event, INFINITE)) { + if (event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) { + ContinueDebugEvent(event.dwProcessId, event.dwThreadId, + DBG_EXCEPTION_NOT_HANDLED); + continue; + } + + if (event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) { + ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); + break; + } + +#ifdef _DEBUG + if (event.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) { + OutputDebugStringA("Debugger attached!\n"); + } +#endif + + ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); + } +} diff --git a/src/runner/debugger.hpp b/src/runner/debugger.hpp new file mode 100644 index 0000000..60e960e --- /dev/null +++ b/src/runner/debugger.hpp @@ -0,0 +1,14 @@ +#pragma once +#include + +class debugger { +public: + debugger(unsigned long process_id, bool start); + ~debugger(); + +private: + volatile bool terminate_ = false; + std::thread runner_; + + void run(unsigned long process_id) const; +}; diff --git a/src/runner/resource.rc b/src/runner/resource.rc new file mode 100644 index 0000000..ba86c6f --- /dev/null +++ b/src/runner/resource.rc @@ -0,0 +1,100 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "X Labs" + VALUE "FileDescription", "Steam mod runner" + VALUE "FileVersion", "1.0.0.0" + VALUE "InternalName", "Runner" + VALUE "LegalCopyright", "All rights reserved." + VALUE "OriginalFilename", "runner.exe" + VALUE "ProductName", "runner" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +///////////////////////////////////////////////////////////////////////////// +// +// Binary Data +// + +102 ICON "../client/resources/icon.ico" + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/runner/runner.cpp b/src/runner/runner.cpp new file mode 100644 index 0000000..e37d67b --- /dev/null +++ b/src/runner/runner.cpp @@ -0,0 +1,22 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "debugger.hpp" + +int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int) { + const auto* const command = "-proc "; + const char* parent_proc = std::strstr(GetCommandLineA(), command); + + if (parent_proc) { + const auto pid = DWORD(atoi(parent_proc + std::strlen(command))); + auto* const process_handle = OpenProcess(SYNCHRONIZE, FALSE, pid); + if (process_handle) { + WaitForSingleObject(process_handle, INFINITE); + CloseHandle(process_handle); + return 0; + } + } + + return 1; +} diff --git a/src/tlsdll/dllmain.cpp b/src/tlsdll/dllmain.cpp new file mode 100644 index 0000000..e3ea71a --- /dev/null +++ b/src/tlsdll/dllmain.cpp @@ -0,0 +1,4 @@ +#define TLS_PAYLOAD_SIZE 0x2000 +thread_local char tls_data[TLS_PAYLOAD_SIZE]; + +__declspec(dllexport) void* get_tls_data() { return &tls_data[0]; } diff --git a/src/tlsdll/resource.rc b/src/tlsdll/resource.rc new file mode 100644 index 0000000..bf5ef22 --- /dev/null +++ b/src/tlsdll/resource.rc @@ -0,0 +1,93 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +2 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "X Labs" + VALUE "FileDescription", "TLS index allocation dll" + VALUE "FileVersion", "1.0.0.0" + VALUE "InternalName", "TLS DLL" + VALUE "LegalCopyright", "All rights reserved." + VALUE "OriginalFilename", "tlsdll.dll" + VALUE "ProductName", "tlsdll" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/tools/premake5.exe b/tools/premake5.exe new file mode 100644 index 0000000..1a637aa Binary files /dev/null and b/tools/premake5.exe differ