├── LICENSE ├── Makefile ├── README.md ├── com ├── Dis.java ├── Instruction.java ├── ObjdumpCompare.java ├── PatternGenerator.java ├── Table.java ├── ZygoteInstruction.java ├── ZygoteOperand.java └── gen │ └── TableGen.java ├── diff ├── diff2 ├── diff3 └── x86optable.xml /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: gen 3 | gen: 4 | mkdir -p build 5 | javac -d build `find com/gen -name \*.java` 6 | echo "Manifest-Version: 1.0" > jar.manifest 7 | echo "Name: Ian's Disassembler" >> jar.manifest 8 | echo "Created-By: Ian Preston" >> jar.manifest 9 | echo "Specification-Version: 1" >> jar.manifest 10 | echo "Main-Class: com.gen.TableGen" >> jar.manifest 11 | echo "" >> jar.manifest 12 | 13 | jar -cfm Gen.jar jar.manifest -C build com 14 | rm -f jar.manifest 15 | 16 | .PHONY: dis 17 | dis: 18 | mkdir -p build 19 | javac -g -d build `find com -name \*.java` 20 | echo "Manifest-Version: 1.0" > jar.manifest 21 | echo "Name: Ian's Disassembler" >> jar.manifest 22 | echo "Created-By: Ian Preston" >> jar.manifest 23 | echo "Specification-Version: 1" >> jar.manifest 24 | echo "Main-Class: com.Dis" >> jar.manifest 25 | echo "" >> jar.manifest 26 | 27 | jar -cfm Dis.jar jar.manifest -C build com 28 | rm -f jar.manifest 29 | 30 | .PHONY: pat 31 | pat: 32 | mkdir -p build 33 | javac -g -d build `find com -name \*.java` 34 | echo "Manifest-Version: 1.0" > jar.manifest 35 | echo "Name: Ian's Disassembler" >> jar.manifest 36 | echo "Created-By: Ian Preston" >> jar.manifest 37 | echo "Specification-Version: 1" >> jar.manifest 38 | echo "Main-Class: com.PatternGenerator" >> jar.manifest 39 | echo "" >> jar.manifest 40 | 41 | jar -cfm Pat.jar jar.manifest -C build com 42 | rm -f jar.manifest 43 | 44 | .PHONY: compare 45 | compare: 46 | mkdir -p build 47 | javac -g -d build `find com -name \*.java` 48 | echo "Manifest-Version: 1.0" > jar.manifest 49 | echo "Name: Ian's Disassembler" >> jar.manifest 50 | echo "Created-By: Ian Preston" >> jar.manifest 51 | echo "Specification-Version: 1" >> jar.manifest 52 | echo "Main-Class: com.ObjdumpCompare" >> jar.manifest 53 | echo "" >> jar.manifest 54 | 55 | jar -cfm Compare.jar jar.manifest -C build com 56 | rm -f jar.manifest 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JayD 2 | ==== 3 | 4 | An x86 disassembler written in Java (port of udis86) 5 | 6 | 7 | Usage: 8 | To generate the disassembler from the xml: 9 | * make gen 10 | * java -jar Gen.jar 11 | 12 | To disassemble some bytes: 13 | * make dis 14 | * java -jar Dis.jar 05 01 2c 34 1d 15 | or 16 | * java -jar Dis.jar -rm 05 01 2c -------------------------------------------------------------------------------- /com/Dis.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import java.io.*; 4 | import static com.ZygoteOperand.*; 5 | import static com.Table.*; 6 | 7 | public class Dis 8 | { 9 | 10 | static ZygoteInstruction[][] itab = new Table().itab_list; 11 | public static final int vendor = VENDOR_INTEL; 12 | public static ZygoteInstruction ie_invalid = new ZygoteInstruction("invalid", O_NONE, O_NONE, O_NONE, P_none); 13 | public static ZygoteInstruction ie_pause = new ZygoteInstruction("pause", O_NONE, O_NONE, O_NONE, P_none); 14 | public static ZygoteInstruction ie_nop = new ZygoteInstruction("nop", O_NONE, O_NONE, O_NONE, P_none); 15 | 16 | public static void main(String[] args) throws IOException 17 | { 18 | if (args.length == 0) 19 | { 20 | Instruction d = decode(new ReversibleInputStream(new byte[5]), 32); 21 | System.out.println(d); 22 | return; 23 | } 24 | int size =32; 25 | if (args[0].equals("-rm")) 26 | { 27 | size = 16; 28 | String[] tmp = new String[args.length-1]; 29 | System.arraycopy(args, 1, tmp, 0, tmp.length); 30 | args = tmp; 31 | } 32 | byte[] data = new byte[args.length]; 33 | for (int i=0; i < args.length; i++) 34 | data[i] = (byte)Integer.parseInt(args[i], 16); 35 | System.out.printf("Raw bytes: "); 36 | for (int i=0; i < args.length; i++) 37 | System.out.printf("%2x ", data[i]); 38 | System.out.println(); 39 | Instruction x = decode(new ReversibleInputStream(data), size); 40 | System.out.println(x); 41 | } 42 | 43 | public static Instruction decode(ReversibleInputStream input, int mode) 44 | { 45 | input.resetCounter(); 46 | Instruction in = new Instruction(); 47 | get_prefixes(mode, input, in); 48 | search_table(mode, input, in); 49 | do_mode(mode, input, in); 50 | disasm_operands(mode, input, in); 51 | resolve_operator(mode, input, in); 52 | in.x86Length = input.getCounter(); 53 | return in; 54 | } 55 | 56 | public static class ReversibleInputStream 57 | { 58 | byte[] data; 59 | int index=0; 60 | 61 | public ReversibleInputStream(byte[] data) 62 | { 63 | this.data = data; 64 | } 65 | 66 | public void resetCounter() 67 | { 68 | index = 0; 69 | } 70 | 71 | public int getCounter() 72 | { 73 | return index; 74 | } 75 | 76 | public long read(long bits) 77 | { 78 | if (bits == 8) 79 | return data[index++]; 80 | if (bits == 16) 81 | return read16(); 82 | if (bits == 32) 83 | return read32(); 84 | if (bits == 64) 85 | return read32() | (((long)read32()) << 32); 86 | throw new IllegalStateException("unimplemented read amount " + bits); 87 | } 88 | 89 | public int read32() 90 | { 91 | return (data[index++] &0xFF) | ((data[index++] & 0xFF) << 8) | ((data[index++] & 0xFF) << 16) | ((data[index++] & 0xFF) << 24); 92 | } 93 | 94 | public int read16() 95 | { 96 | return (data[index++] & 0xFF) | (data[index++] << 8); 97 | } 98 | 99 | public int getByte() 100 | { 101 | return data[index] & 0xFF; 102 | } 103 | 104 | public void forward() 105 | { 106 | index++; 107 | } 108 | 109 | public void reverse() 110 | { 111 | index--; 112 | } 113 | } 114 | 115 | private static void get_prefixes(int mode, ReversibleInputStream input, Instruction inst) 116 | { 117 | int curr; 118 | int i=0; 119 | while(true) 120 | { 121 | curr = input.getByte(); 122 | input.forward(); 123 | i++; 124 | 125 | if ((mode == 64) && ((curr & 0xF0) == 0x40)) 126 | inst.pfx.rex = curr; 127 | else 128 | { 129 | if (curr == 0x2E) 130 | { 131 | inst.pfx.seg = "cs"; 132 | inst.pfx.rex = 0; 133 | } 134 | else if (curr == 0x36) 135 | { 136 | inst.pfx.seg = "ss"; 137 | inst.pfx.rex = 0; 138 | } 139 | else if (curr == 0x3E) 140 | { 141 | inst.pfx.seg = "ds"; 142 | inst.pfx.rex = 0; 143 | } 144 | else if (curr == 0x26) 145 | { 146 | inst.pfx.seg = "es"; 147 | inst.pfx.rex = 0; 148 | } 149 | else if (curr == 0x64) 150 | { 151 | inst.pfx.seg = "fs"; 152 | inst.pfx.rex = 0; 153 | } 154 | else if (curr == 0x65) 155 | { 156 | inst.pfx.seg = "gs"; 157 | inst.pfx.rex = 0; 158 | } 159 | else if (curr == 0x67) //adress-size override prefix 160 | { 161 | inst.pfx.adr = 0x67; 162 | inst.pfx.rex = 0; 163 | } 164 | else if (curr == 0xF0) 165 | { 166 | inst.pfx.lock = 0xF0; 167 | inst.pfx.rex = 0; 168 | } 169 | else if (curr == 0x66) 170 | { 171 | // the 0x66 sse prefix is only effective if no other sse prefix 172 | // has already been specified. 173 | if (inst.pfx.insn == 0) 174 | inst.pfx.insn = 0x66; 175 | inst.pfx.opr = 0x66; 176 | inst.pfx.rex = 0; 177 | } 178 | else if (curr == 0xF2) 179 | { 180 | inst.pfx.insn = 0xF2; 181 | inst.pfx.repne = 0xF2; 182 | inst.pfx.rex = 0; 183 | } 184 | else if (curr == 0xF3) 185 | { 186 | inst.pfx.insn = 0xF3; 187 | inst.pfx.rep = 0xF3; 188 | inst.pfx.repe = 0xF3; 189 | inst.pfx.rex = 0; 190 | } 191 | else 192 | //No more prefixes 193 | break; 194 | } 195 | } 196 | if (i >= MAX_INSTRUCTION_LENGTH) 197 | throw new IllegalStateException("Max instruction length exceeded"); 198 | 199 | input.reverse(); 200 | 201 | // speculatively determine the effective operand mode, 202 | // based on the prefixes and the current disassembly 203 | // mode. This may be inaccurate, but useful for mode 204 | // dependent decoding. 205 | if (mode == 64) 206 | { 207 | if (REX_W(inst.pfx.rex) != 0) 208 | inst.opr_mode = 64; 209 | else if (inst.pfx.opr != 0) 210 | inst.opr_mode = 16; 211 | else if (P_DEF64(inst.zygote.prefix) != 0) 212 | inst.opr_mode = 64; 213 | else 214 | inst.opr_mode = 32; 215 | if (inst.pfx.adr != 0) 216 | inst.adr_mode = 32; 217 | else 218 | inst.adr_mode = 64; 219 | } 220 | else if (mode == 32) 221 | { 222 | if (inst.pfx.opr != 0) 223 | inst.opr_mode = 16; 224 | else 225 | inst.opr_mode = 32; 226 | if (inst.pfx.adr != 0) 227 | inst.adr_mode = 16; 228 | else 229 | inst.adr_mode = 32; 230 | } 231 | else if (mode == 16) 232 | { 233 | if (inst.pfx.opr != 0) 234 | inst.opr_mode = 32; 235 | else 236 | inst.opr_mode = 16; 237 | if (inst.pfx.adr != 0) 238 | inst.adr_mode = 32; 239 | else 240 | inst.adr_mode = 16; 241 | } 242 | } 243 | 244 | private static void search_table(int mode, ReversibleInputStream input, Instruction inst) 245 | { 246 | boolean did_peek = false; 247 | int peek; 248 | int curr = input.getByte(); 249 | input.forward(); 250 | 251 | int table=0; 252 | ZygoteInstruction e; 253 | 254 | // resolve xchg, nop, pause crazyness 255 | if (0x90 == curr) 256 | { 257 | if (!((mode == 64) && (REX_B(inst.pfx.rex) != 0))) 258 | { 259 | if (inst.pfx.rep != 0) 260 | { 261 | inst.pfx.rep = 0; 262 | e = ie_pause; 263 | } 264 | else 265 | e = ie_nop; 266 | inst.zygote = e; 267 | inst.operator = inst.zygote.operator; 268 | return; 269 | } 270 | } 271 | else if (curr == 0x0F) 272 | { 273 | table = ITAB__0F; 274 | curr = input.getByte(); 275 | input.forward(); 276 | 277 | // 2byte opcodes can be modified by 0x66, F3, and F2 prefixes 278 | if (0x66 == inst.pfx.insn) 279 | { 280 | if (!itab[ITAB__PFX_SSE66__0F][curr].operator.equals("invalid")) 281 | { 282 | table = ITAB__PFX_SSE66__0F; 283 | //inst.pfx.opr = 0; 284 | } 285 | } 286 | else if (0xF2 == inst.pfx.insn) 287 | { 288 | if (!itab[ITAB__PFX_SSEF2__0F][curr].operator.equals("invalid")) 289 | { 290 | table = ITAB__PFX_SSEF2__0F; 291 | inst.pfx.repne = 0; 292 | } 293 | } 294 | else if (0xF3 == inst.pfx.insn) 295 | { 296 | if (!itab[ITAB__PFX_SSEF3__0F][curr].operator.equals("invalid")) 297 | { 298 | table = ITAB__PFX_SSEF3__0F; 299 | inst.pfx.repe = 0; 300 | inst.pfx.rep = 0; 301 | } 302 | } 303 | } 304 | else 305 | table = ITAB__1BYTE; 306 | 307 | int index = curr; 308 | 309 | while (true) 310 | { 311 | e = itab[table][index]; 312 | // if operator constant is a standard instruction constant 313 | // our search is over. 314 | if (operator.contains(e.operator)) 315 | { 316 | if (e.operator.equals("invalid")) 317 | if (did_peek) 318 | input.forward(); 319 | inst.zygote = e; 320 | inst.operator = e.operator; 321 | return; 322 | } 323 | 324 | table = e.prefix; 325 | 326 | if (e.operator.equals("grp_reg")) 327 | { 328 | peek = input.getByte(); 329 | did_peek = true; 330 | index = MODRM_REG(peek); 331 | } 332 | else if (e.operator.equals("grp_mod")) 333 | { 334 | peek = input.getByte(); 335 | did_peek = true; 336 | index = MODRM_MOD(peek); 337 | if (index == 3) 338 | index = ITAB__MOD_INDX__11; 339 | else 340 | index = ITAB__MOD_INDX__NOT_11; 341 | } 342 | else if (e.operator.equals("grp_rm")) 343 | { 344 | curr = input.getByte(); 345 | input.forward(); 346 | did_peek = false; 347 | index = MODRM_RM(curr); 348 | } 349 | else if (e.operator.equals("grp_x87")) 350 | { 351 | curr = input.getByte(); 352 | input.forward(); 353 | did_peek = false; 354 | index = curr - 0xC0; 355 | } 356 | else if (e.operator.equals("grp_osize")) 357 | { 358 | if (inst.opr_mode == 64) 359 | index = ITAB__MODE_INDX__64; 360 | else if (inst.opr_mode == 32) 361 | index = ITAB__MODE_INDX__32; 362 | else 363 | index = ITAB__MODE_INDX__16; 364 | } 365 | else if (e.operator.equals("grp_asize")) 366 | { 367 | if (inst.adr_mode == 64) 368 | index = ITAB__MODE_INDX__64; 369 | else if (inst.adr_mode == 32) 370 | index = ITAB__MODE_INDX__32; 371 | else 372 | index = ITAB__MODE_INDX__16; 373 | } 374 | else if (e.operator.equals("grp_mode")) 375 | { 376 | if (mode == 64) 377 | index = ITAB__MODE_INDX__64; 378 | else if (mode == 32) 379 | index = ITAB__MODE_INDX__32; 380 | else 381 | index = ITAB__MODE_INDX__16; 382 | } 383 | else if (e.operator.equals("grp_vendor")) 384 | { 385 | if (vendor == VENDOR_INTEL) 386 | index = ITAB__VENDOR_INDX__INTEL; 387 | else if (vendor == VENDOR_AMD) 388 | index = ITAB__VENDOR_INDX__AMD; 389 | else 390 | throw new RuntimeException("unrecognized vendor id"); 391 | } 392 | else if (e.operator.equals("d3vil")) 393 | throw new RuntimeException("invalid instruction operator constant Id3vil"); 394 | else 395 | throw new RuntimeException("invalid instruction operator constant"); 396 | } 397 | //inst.zygote = e; 398 | //inst.operator = e.operator; 399 | //return; 400 | } 401 | 402 | private static void do_mode(int mode, ReversibleInputStream input, Instruction inst) 403 | { 404 | // propagate prefix effects 405 | if (mode == 64) // set 64bit-mode flags 406 | { 407 | // Check validity of instruction m64 408 | if ((P_INV64(inst.zygote.prefix) != 0)) 409 | throw new IllegalStateException("Invalid instruction"); 410 | 411 | // effective rex prefix is the effective mask for the 412 | // instruction hard-coded in the opcode map. 413 | inst.pfx.rex = ((inst.pfx.rex & 0x40) 414 | |(inst.pfx.rex & REX_PFX_MASK(inst.zygote.prefix))); 415 | 416 | // calculate effective operand size 417 | if ((REX_W(inst.pfx.rex) != 0) || (P_DEF64(inst.zygote.prefix) != 0)) 418 | inst.opr_mode = 64; 419 | else if (inst.pfx.opr != 0) 420 | inst.opr_mode = 16; 421 | else 422 | inst.opr_mode = 32; 423 | 424 | // calculate effective address size 425 | if (inst.pfx.adr != 0) 426 | inst.adr_mode = 32; 427 | else 428 | inst.adr_mode = 64; 429 | } 430 | else if (mode == 32) // set 32bit-mode flags 431 | { 432 | if (inst.pfx.opr != 0) 433 | inst.opr_mode = 16; 434 | else 435 | inst.opr_mode = 32; 436 | if (inst.pfx.adr != 0) 437 | inst.adr_mode = 16; 438 | else 439 | inst.adr_mode = 32; 440 | } 441 | else if (mode == 16) // set 16bit-mode flags 442 | { 443 | if (inst.pfx.opr != 0) 444 | inst.opr_mode = 32; 445 | else 446 | inst.opr_mode = 16; 447 | if (inst.pfx.adr != 0) 448 | inst.adr_mode = 32; 449 | else 450 | inst.adr_mode = 16; 451 | } 452 | } 453 | 454 | private static void resolve_operator(int mode, ReversibleInputStream input, Instruction inst) 455 | { 456 | // far/near flags 457 | inst.branch_dist = null; 458 | // readjust operand sizes for call/jmp instrcutions 459 | if (inst.operator.equals("call") || inst.operator.equals("jmp")) 460 | { 461 | if (inst.operand[0].size == SZ_WP) 462 | { 463 | // WP: 16bit pointer 464 | inst.operand[0].size = 16; 465 | inst.branch_dist = "far"; 466 | } 467 | else if (inst.operand[0].size == SZ_DP) 468 | { 469 | // DP: 32bit pointer 470 | inst.operand[0].size = 32; 471 | inst.branch_dist = "far"; 472 | } 473 | else if (inst.operand[0].size == 8) 474 | inst.branch_dist = "near"; 475 | } 476 | else if (inst.operator.equals("3dnow")) 477 | { 478 | // resolve 3dnow weirdness 479 | inst.operator = itab[ITAB__3DNOW][input.getByte()].operator; 480 | } 481 | // SWAPGS is only valid in 64bits mode 482 | if ((inst.operator.equals("swapgs")) && (mode != 64)) 483 | throw new IllegalStateException("SWAPGS only valid in 64 bit mode"); 484 | } 485 | 486 | private static void disasm_operands(int mode, ReversibleInputStream input, Instruction inst) 487 | { 488 | // get type 489 | int[] mopt = new int[inst.zygote.operand.length]; 490 | for (int i=0; i < mopt.length; i++) 491 | mopt[i] = inst.zygote.operand[i].type; 492 | // get size 493 | int[] mops = new int[inst.zygote.operand.length]; 494 | for (int i=0; i < mops.length; i++) 495 | mops[i] = inst.zygote.operand[i].size; 496 | 497 | if (mopt[2] != OP_NONE) 498 | inst.operand = new Instruction.Operand[]{new Instruction.Operand(), new Instruction.Operand(), new Instruction.Operand()}; 499 | else if (mopt[1] != OP_NONE) 500 | inst.operand = new Instruction.Operand[]{new Instruction.Operand(), new Instruction.Operand()}; 501 | else if (mopt[0] != OP_NONE) 502 | inst.operand = new Instruction.Operand[]{new Instruction.Operand()}; 503 | 504 | // These flags determine which operand to apply the operand size 505 | // cast to. 506 | if (inst.operand.length > 0) 507 | inst.operand[0].cast = P_C0(inst.zygote.prefix); 508 | if (inst.operand.length > 1) 509 | inst.operand[1].cast = P_C1(inst.zygote.prefix); 510 | if (inst.operand.length > 2) 511 | inst.operand[2].cast = P_C2(inst.zygote.prefix); 512 | 513 | // iop = instruction operand 514 | //iop = inst.operand 515 | 516 | if (mopt[0] == OP_A) 517 | decode_a(mode, inst, input, inst.operand[0]); 518 | // M[b] ... 519 | // E, G/P/V/I/CL/1/S 520 | else if ((mopt[0] == OP_M) || (mopt[0] == OP_E)) 521 | { 522 | if ((mopt[0] == OP_M) && (MODRM_MOD(input.getByte()) == 3)) 523 | throw new IllegalStateException(""); 524 | if (mopt[1] == OP_G) 525 | { 526 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", inst.operand[1], mops[1], "T_GPR"); 527 | if (mopt[2] == OP_I) 528 | decode_imm(mode, inst, input, mops[2], inst.operand[2]); 529 | else if (mopt[2] == OP_CL) 530 | { 531 | inst.operand[2].type = "OP_REG"; 532 | inst.operand[2].base = "cl"; 533 | inst.operand[2].size = 8; 534 | } 535 | } 536 | else if (mopt[1] == OP_P) 537 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", inst.operand[1], mops[1], "T_MMX"); 538 | else if (mopt[1] == OP_V) 539 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", inst.operand[1], mops[1], "T_XMM"); 540 | else if (mopt[1] == OP_S) 541 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", inst.operand[1], mops[1], "T_SEG"); 542 | else 543 | { 544 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", null, 0, "T_NONE"); 545 | if (mopt[1] == OP_CL) 546 | { 547 | inst.operand[1].type = "OP_REG"; 548 | inst.operand[1].base = "cl"; 549 | inst.operand[1].size = 8; 550 | } 551 | else if (mopt[1] == OP_I1) 552 | { 553 | inst.operand[1].type = "OP_IMM"; 554 | inst.operand[1].lval = 1; 555 | } 556 | else if (mopt[1] == OP_I) 557 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 558 | } 559 | } 560 | // G, E/PR[,I]/VR 561 | else if (mopt[0] == OP_G) 562 | { 563 | if (mopt[1] == OP_M) 564 | { 565 | if (MODRM_MOD(input.getByte()) == 3) 566 | throw new IllegalStateException("invalid"); 567 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_GPR"); 568 | } 569 | else if (mopt[1] == OP_E) 570 | { 571 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_GPR"); 572 | if (mopt[2] == OP_I) 573 | decode_imm(mode, inst, input, mops[2], inst.operand[2]); 574 | } 575 | else if (mopt[1] == OP_PR) 576 | { 577 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_MMX", inst.operand[0], mops[0], "T_GPR"); 578 | if (mopt[2] == OP_I) 579 | decode_imm(mode, inst, input, mops[2], inst.operand[2]); 580 | } 581 | else if (mopt[1] == OP_VR) 582 | { 583 | if (MODRM_MOD(input.getByte()) != 3) 584 | throw new IllegalStateException("Invalid instruction"); 585 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_XMM", inst.operand[0], mops[0], "T_GPR"); 586 | } 587 | else if (mopt[1] == OP_W) 588 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_XMM", inst.operand[0], mops[0], "T_GPR"); 589 | } 590 | // AL..BH, I/O/DX 591 | else if (ops8.contains(mopt[0])) 592 | { 593 | inst.operand[0].type = "OP_REG"; 594 | inst.operand[0].base = GPR.get("8").get(mopt[0] - OP_AL); 595 | inst.operand[0].size = 8; 596 | 597 | if (mopt[1] == OP_I) 598 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 599 | else if (mopt[1] == OP_DX) 600 | { 601 | inst.operand[1].type = "OP_REG"; 602 | inst.operand[1].base = "dx"; 603 | inst.operand[1].size = 16; 604 | } 605 | else if (mopt[1] == OP_O) 606 | decode_o(mode, inst, input, mops[1], inst.operand[1]); 607 | } 608 | // rAX[r8]..rDI[r15], I/rAX..rDI/O 609 | else if (ops2.contains(mopt[0])) 610 | { 611 | inst.operand[0].type = "OP_REG"; 612 | inst.operand[0].base = resolve_gpr64(mode, inst, mopt[0]); 613 | 614 | if (mopt[1] == OP_I) 615 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 616 | else if (ops64.contains(mopt[1])) 617 | { 618 | inst.operand[1].type = "OP_REG"; 619 | inst.operand[1].base = resolve_gpr64(mode, inst, mopt[1]); 620 | } 621 | else if (mopt[1] == OP_O) 622 | { 623 | decode_o(mode, inst, input, mops[1], inst.operand[1]); 624 | inst.operand[0].size = resolve_operand_size(mode, inst, mops[1]); 625 | } 626 | } 627 | else if (ops3.contains(mopt[0])) 628 | { 629 | int gpr = (mopt[0] - OP_ALr8b +(REX_B(inst.pfx.rex) << 3)); 630 | /*if ((gpr in ["ah", "ch", "dh", "bh", 631 | "spl", "bpl", "sil", "dil", 632 | "r8b", "r9b", "r10b", "r11b", 633 | "r12b", "r13b", "r14b", "r15b", 634 | ]) && (inst.pfx.rex != 0)) 635 | gpr = gpr + 4;*/ 636 | inst.operand[0].type = "OP_REG"; 637 | inst.operand[0].base = GPR.get("8").get(gpr); 638 | if (mopt[1] == OP_I) 639 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 640 | } 641 | // eAX..eDX, DX/I 642 | else if (ops32.contains(mopt[0])) 643 | { 644 | inst.operand[0].type = "OP_REG"; 645 | inst.operand[0].base = resolve_gpr32(inst, mopt[0]); 646 | if (mopt[1] == OP_DX) 647 | { 648 | inst.operand[1].type = "OP_REG"; 649 | inst.operand[1].base = "dx"; 650 | inst.operand[1].size = 16; 651 | } 652 | else if (mopt[1] == OP_I) 653 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 654 | } 655 | // ES..GS 656 | else if (ops_segs.contains(mopt[0])) 657 | { 658 | // in 64bits mode, only fs and gs are allowed 659 | if (mode == 64) 660 | if ((mopt[0] != OP_FS) && (mopt[0] != OP_GS)) 661 | throw new IllegalStateException("only fs and gs allowed in 64 bit mode"); 662 | inst.operand[0].type = "OP_REG"; 663 | inst.operand[0].base = GPR.get("T_SEG").get(mopt[0] - OP_ES); 664 | inst.operand[0].size = 16; 665 | } 666 | // J 667 | else if (mopt[0] == OP_J) 668 | { 669 | decode_imm(mode, inst, input, mops[0], inst.operand[0]); 670 | // MK take care of signs 671 | long bound = 1L << (inst.operand[0].size - 1); 672 | if (inst.operand[0].lval > bound) 673 | inst.operand[0].lval = -(((2 * bound) - inst.operand[0].lval) % bound); 674 | inst.operand[0].type = "OP_JIMM"; 675 | } 676 | // PR, I 677 | else if (mopt[0] == OP_PR) 678 | { 679 | if (MODRM_MOD(input.getByte()) != 3) 680 | throw new IllegalStateException("Invalid instruction"); 681 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_MMX", null, 0, "T_NONE"); 682 | if (mopt[1] == OP_I) 683 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 684 | } 685 | // VR, I 686 | else if (mopt[0] == OP_VR) 687 | { 688 | if (MODRM_MOD(input.getByte()) != 3) 689 | throw new IllegalStateException("Invalid instruction"); 690 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_XMM", null, 0, "T_NONE"); 691 | if (mopt[1] == OP_I) 692 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 693 | } 694 | // P, Q[,I]/W/E[,I],VR 695 | else if (mopt[0] == OP_P) 696 | { 697 | if (mopt[1] == OP_Q) 698 | { 699 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_MMX", inst.operand[0], mops[0], "T_MMX"); 700 | if (mopt[2] == OP_I) 701 | decode_imm(mode, inst, input, mops[2], inst.operand[2]); 702 | } 703 | else if (mopt[1] == OP_W) 704 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_XMM", inst.operand[0], mops[0], "T_MMX"); 705 | else if (mopt[1] == OP_VR) 706 | { 707 | if (MODRM_MOD(input.getByte()) != 3) 708 | throw new IllegalStateException("Invalid instruction"); 709 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_XMM", inst.operand[0], mops[0], "T_MMX"); 710 | } 711 | else if (mopt[1] == OP_E) 712 | { 713 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_MMX"); 714 | if (mopt[2] == OP_I) 715 | decode_imm(mode, inst, input, mops[2], inst.operand[2]); 716 | } 717 | } 718 | // R, C/D 719 | else if (mopt[0] == OP_R) 720 | { 721 | if (mopt[1] == OP_C) 722 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", inst.operand[1], mops[1], "T_CRG"); 723 | else if (mopt[1] == OP_D) 724 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_GPR", inst.operand[1], mops[1], "T_DBG"); 725 | } 726 | // C, R 727 | else if (mopt[0] == OP_C) 728 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_CRG"); 729 | // D, R 730 | else if (mopt[0] == OP_D) 731 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_DBG"); 732 | // Q, P 733 | else if (mopt[0] == OP_Q) 734 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_MMX", inst.operand[1], mops[1], "T_MMX"); 735 | // S, E 736 | else if (mopt[0] == OP_S) 737 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_SEG"); 738 | // W, V 739 | else if (mopt[0] == OP_W) 740 | decode_modrm(mode, inst, input, inst.operand[0], mops[0], "T_XMM", inst.operand[1], mops[1], "T_XMM"); 741 | // V, W[,I]/Q/M/E 742 | else if (mopt[0] == OP_V) 743 | { 744 | if (mopt[1] == OP_W) 745 | { 746 | // special cases for movlps and movhps 747 | if (MODRM_MOD(input.getByte()) == 3) 748 | { 749 | if (inst.operator.equals("movlps")) 750 | inst.operator = "movhlps"; 751 | else if (inst.operator.equals("movhps")) 752 | inst.operator = "movlhps"; 753 | } 754 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_XMM", inst.operand[0], mops[0], "T_XMM"); 755 | if (mopt[2] == OP_I) 756 | decode_imm(mode, inst, input, mops[2], inst.operand[2]); 757 | } 758 | else if (mopt[1] == OP_Q) 759 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_MMX", inst.operand[0], mops[0], "T_XMM"); 760 | else if (mopt[1] == OP_M) 761 | { 762 | if (MODRM_MOD(input.getByte()) == 3) 763 | throw new IllegalStateException("Invalid instruction"); 764 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_XMM"); 765 | } 766 | else if (mopt[1] == OP_E) 767 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_GPR", inst.operand[0], mops[0], "T_XMM"); 768 | else if (mopt[1] == OP_PR) 769 | decode_modrm(mode, inst, input, inst.operand[1], mops[1], "T_MMX", inst.operand[0], mops[0], "T_XMM"); 770 | } 771 | // DX, eAX/AL 772 | else if (mopt[0] == OP_DX) 773 | { 774 | inst.operand[0].type = "OP_REG"; 775 | inst.operand[0].base = "dx"; 776 | inst.operand[0].size = 16; 777 | 778 | if (mopt[1] == OP_eAX) 779 | { 780 | inst.operand[1].type = "OP_REG"; 781 | inst.operand[1].base = resolve_gpr32(inst, mopt[1]); 782 | } 783 | else if (mopt[1] == OP_AL) 784 | { 785 | inst.operand[1].type = "OP_REG"; 786 | inst.operand[1].base = "al"; 787 | inst.operand[1].size = 8; 788 | } 789 | } 790 | // I, I/AL/eAX 791 | else if (mopt[0] == OP_I) 792 | { 793 | decode_imm(mode, inst, input, mops[0], inst.operand[0]); 794 | if (mopt[1] == OP_I) 795 | decode_imm(mode, inst, input, mops[1], inst.operand[1]); 796 | else if (mopt[1] == OP_AL) 797 | { 798 | inst.operand[1].type = "OP_REG"; 799 | inst.operand[1].base = "al"; 800 | inst.operand[1].size = 8; 801 | } 802 | else if (mopt[1] == OP_eAX) 803 | { 804 | inst.operand[1].type = "OP_REG"; 805 | inst.operand[1].base = resolve_gpr32(inst, mopt[1]); 806 | } 807 | } 808 | // O, AL/eAX 809 | else if (mopt[0] == OP_O) 810 | { 811 | decode_o(mode, inst, input, mops[0], inst.operand[0]); 812 | inst.operand[1].type = "OP_REG"; 813 | inst.operand[1].size = resolve_operand_size(mode, inst, mops[0]); 814 | if (mopt[1] == OP_AL) 815 | inst.operand[1].base = "al"; 816 | else if (mopt[1] == OP_eAX) 817 | inst.operand[1].base = resolve_gpr32(inst, mopt[1]); 818 | else if (mopt[1] == OP_rAX) 819 | inst.operand[1].base = resolve_gpr64(mode, inst, mopt[1]); 820 | } 821 | // 3 822 | else if (mopt[0] == OP_I3) 823 | { 824 | inst.operand[0].type = "OP_IMM"; 825 | inst.operand[0].lval = 3; 826 | } 827 | // ST(n), ST(n) 828 | else if (ops_st.contains(mopt[0])) 829 | { 830 | inst.operand[0].type = "OP_REG"; 831 | inst.operand[0].base = GPR.get("T_ST").get(mopt[0] - OP_ST0); 832 | inst.operand[0].size = 0; 833 | 834 | if (ops_st.contains(mopt[1])) 835 | { 836 | inst.operand[1].type = "OP_REG"; 837 | inst.operand[1].base = GPR.get("T_ST").get(mopt[1] - OP_ST0); 838 | inst.operand[1].size = 0; 839 | } 840 | } 841 | // AX 842 | else if (mopt[0] == OP_AX) 843 | { 844 | inst.operand[0].type = "OP_REG"; 845 | inst.operand[0].base = "ax"; 846 | inst.operand[0].size = 16; 847 | } 848 | // none 849 | else 850 | for (int i=0; i < inst.operand.length; i++) 851 | inst.operand[i].type = null; 852 | } 853 | 854 | private static void decode_a(int mode, Instruction inst, ReversibleInputStream input, Instruction.Operand op) 855 | { 856 | //Decodes operands of the type seg:offset. 857 | if (inst.opr_mode == 16) 858 | { 859 | // seg16:off16 860 | op.type = "OP_PTR"; 861 | op.size = 32; 862 | op.dis_start = input.getCounter(); 863 | op.ptr = new Instruction.Ptr(input.read16(), input.read16()); 864 | } 865 | else 866 | { 867 | // seg16:off32 868 | op.type = "OP_PTR"; 869 | op.size = 48; 870 | op.dis_start = input.getCounter(); 871 | op.ptr = new Instruction.Ptr(input.read32(), input.read16()); 872 | } 873 | } 874 | 875 | private static void decode_modrm(int mode, Instruction inst, ReversibleInputStream input, Instruction.Operand op, int s, String rm_type, Instruction.Operand opreg, int reg_size, String reg_type) 876 | { 877 | // get mod, r/m and reg fields 878 | int mod = MODRM_MOD(input.getByte()); 879 | int rm = (REX_B(inst.pfx.rex) << 3) | MODRM_RM(input.getByte()); 880 | int reg = (REX_R(inst.pfx.rex) << 3) | MODRM_REG(input.getByte()); 881 | 882 | if (reg_type.equals("T_DBG") || reg_type.equals("T_CRG")) // force these to be reg ops (mod is ignored) 883 | mod = 3; 884 | 885 | op.size = resolve_operand_size(mode, inst, s); 886 | 887 | // if mod is 11b, then the m specifies a gpr/mmx/sse/control/debug 888 | if (mod == 3) 889 | { 890 | op.type = "OP_REG"; 891 | if (rm_type == "T_GPR") 892 | op.base = decode_gpr(mode, inst, op.size, rm); 893 | else 894 | op.base = resolve_reg(rm_type, (REX_B(inst.pfx.rex) << 3) |(rm&7)); 895 | } 896 | // else its memory addressing 897 | else 898 | { 899 | op.type = "OP_MEM"; 900 | op.seg = inst.pfx.seg; 901 | // 64bit addressing 902 | if (inst.adr_mode == 64) 903 | { 904 | op.base = GPR.get("64").get(rm); 905 | 906 | // get offset type 907 | if (mod == 1) 908 | op.offset = 8; 909 | else if (mod == 2) 910 | op.offset = 32; 911 | else if ((mod == 0) &&((rm & 7) == 5)) 912 | { 913 | op.base = "rip"; 914 | op.offset = 32; 915 | } 916 | else 917 | op.offset = 0; 918 | 919 | // Scale-Index-Base(SIB) 920 | if ((rm & 7) == 4) 921 | { 922 | input.forward(); 923 | 924 | op.scale = (1 << SIB_S(input.getByte())) & ~1; 925 | op.index = GPR.get("64").get((SIB_I(input.getByte()) |(REX_X(inst.pfx.rex) << 3))); 926 | op.base = GPR.get("64").get((SIB_B(input.getByte()) |(REX_B(inst.pfx.rex) << 3))); 927 | 928 | // special conditions for base reference 929 | if (op.index.equals("rsp")) 930 | { 931 | op.index = null; 932 | op.scale = 0; 933 | } 934 | 935 | if ((op.base.equals("rbp")) || (op.base.equals("r13"))) 936 | { 937 | if (mod == 0) 938 | op.base = null; 939 | if (mod == 1) 940 | op.offset = 8; 941 | else 942 | op.offset = 32; 943 | } 944 | } 945 | } 946 | // 32-Bit addressing mode 947 | else if (inst.adr_mode == 32) 948 | { 949 | // get base 950 | op.base = GPR.get("32").get(rm); 951 | 952 | // get offset type 953 | if (mod == 1) 954 | op.offset = 8; 955 | else if (mod == 2) 956 | op.offset = 32; 957 | else if ((mod == 0) && (rm == 5)) 958 | { 959 | op.base = null; 960 | op.offset = 32; 961 | } 962 | else 963 | op.offset = 0; 964 | 965 | // Scale-Index-Base(SIB) 966 | if ((rm & 7) == 4) 967 | { 968 | input.forward(); 969 | 970 | op.scale = (1 << SIB_S(input.getByte())) & ~1; 971 | op.index = GPR.get("32").get(SIB_I(input.getByte()) |(REX_X(inst.pfx.rex) << 3)); 972 | op.base = GPR.get("32").get(SIB_B(input.getByte()) |(REX_B(inst.pfx.rex) << 3)); 973 | 974 | if (op.index.equals("esp")) 975 | { 976 | op.index = null; 977 | op.scale = 0; 978 | } 979 | 980 | // special condition for base reference 981 | if (op.base.equals("ebp")) 982 | { 983 | if (mod == 0) 984 | op.base = null; 985 | if (mod == 1) 986 | op.offset = 8; 987 | else 988 | op.offset = 32; 989 | } 990 | } 991 | } 992 | // 16bit addressing mode 993 | else 994 | { 995 | if (rm == 0) 996 | { 997 | op.base = "bx"; 998 | op.index = "si"; 999 | } 1000 | else if (rm == 1) 1001 | { 1002 | op.base = "bx"; 1003 | op.index = "di"; 1004 | } 1005 | else if (rm == 2) 1006 | { 1007 | op.base = "bp"; 1008 | op.index = "si"; 1009 | } 1010 | else if (rm == 3) 1011 | { 1012 | op.base = "bp"; 1013 | op.index = "di"; 1014 | } 1015 | else if (rm == 4) 1016 | op.base = "si"; 1017 | else if (rm == 5) 1018 | op.base = "di"; 1019 | else if (rm == 6) 1020 | op.base = "bp"; 1021 | else if (rm == 7) 1022 | op.base = "bx"; 1023 | 1024 | if ((mod == 0) && (rm == 6)) 1025 | { 1026 | op.offset = 16; 1027 | op.base = null; 1028 | } 1029 | else if (mod == 1) 1030 | op.offset = 8; 1031 | else if (mod == 2) 1032 | op.offset = 16; 1033 | } 1034 | } 1035 | input.forward(); 1036 | // extract offset, if any 1037 | if ((op.offset==8) || (op.offset==16) ||(op.offset==32) || (op.offset==64)) 1038 | { 1039 | op.dis_start = input.getCounter(); 1040 | op.lval = input.read(op.offset); 1041 | long bound = 1L << (op.offset - 1); 1042 | if (op.lval > bound) 1043 | op.lval = -(((2 * bound) - op.lval) % bound); 1044 | } 1045 | 1046 | // resolve register encoded in reg field 1047 | if (opreg != null) 1048 | { 1049 | opreg.type = "OP_REG"; 1050 | opreg.size = resolve_operand_size(mode, inst, reg_size); 1051 | if (reg_type.equals("T_GPR")) 1052 | opreg.base = decode_gpr(mode, inst, opreg.size, reg); 1053 | else 1054 | opreg.base = resolve_reg(reg_type, reg); 1055 | } 1056 | } 1057 | 1058 | private static void decode_imm(int mode, Instruction inst, ReversibleInputStream input, int s, Instruction.Operand op) 1059 | { 1060 | op.size = resolve_operand_size(mode, inst, s); 1061 | op.type = "OP_IMM"; 1062 | op.imm_start = input.getCounter(); 1063 | op.lval = input.read(op.size); 1064 | } 1065 | 1066 | private static void decode_o(int mode, Instruction inst, ReversibleInputStream input, int s, Instruction.Operand op) 1067 | { 1068 | // offset 1069 | op.seg = inst.pfx.seg; 1070 | op.offset = inst.adr_mode; 1071 | op.dis_start = input.getCounter(); 1072 | op.lval = input.read(inst.adr_mode); 1073 | op.type = "OP_MEM"; 1074 | op.size = resolve_operand_size(mode, inst, s); 1075 | } 1076 | 1077 | private static String resolve_gpr32(Instruction inst, int gpr_op) 1078 | { 1079 | int index = gpr_op - OP_eAX; 1080 | if(inst.opr_mode == 16) 1081 | return GPR.get("16").get(index); 1082 | return GPR.get("32").get(index); 1083 | } 1084 | 1085 | private static String resolve_gpr64(int mode, Instruction inst, int gpr_op) 1086 | { 1087 | int index = 0; 1088 | if ((OP_rAXr8 <= gpr_op) && (OP_rDIr15 >= gpr_op)) 1089 | index = (gpr_op - OP_rAXr8) |(REX_B(inst.pfx.rex) << 3); 1090 | else 1091 | index = gpr_op - OP_rAX; 1092 | if (inst.opr_mode == 16) 1093 | return GPR.get("16").get(index); 1094 | else if ((mode == 32) || !((inst.opr_mode == 32) && (REX_W(inst.pfx.rex) == 0))) 1095 | return GPR.get("32").get(index); 1096 | return GPR.get("64").get(index); 1097 | } 1098 | 1099 | private static int resolve_operand_size(int mode, Instruction inst, int s) 1100 | { 1101 | if (s == SZ_V) 1102 | return inst.opr_mode; 1103 | else if (s == SZ_Z) 1104 | if (inst.opr_mode == 16) 1105 | return 16; 1106 | else 1107 | return 32; 1108 | else if (s == SZ_P) 1109 | if (inst.opr_mode == 16) 1110 | return SZ_WP; 1111 | else 1112 | return SZ_DP; 1113 | else if (s == SZ_MDQ) 1114 | if (inst.opr_mode == 16) 1115 | return 32; 1116 | else 1117 | return inst.opr_mode; 1118 | else if (s == SZ_RDQ) 1119 | if (mode == 64) 1120 | return 64; 1121 | else 1122 | return 32; 1123 | else 1124 | return s; 1125 | } 1126 | 1127 | private static String decode_gpr(int mode, Instruction inst, int s, int rm) 1128 | { 1129 | s = resolve_operand_size(mode, inst, s); 1130 | 1131 | if (s == 64) 1132 | return GPR.get("64").get(rm); 1133 | else if ((s == SZ_DP) || (s == 32)) 1134 | return GPR.get("32").get(rm); 1135 | else if ((s == SZ_WP) || (s == 16)) 1136 | return GPR.get("16").get(rm); 1137 | else if (s == 8) 1138 | { 1139 | if ((mode == 64) && (inst.pfx.rex != 0)) 1140 | { 1141 | if (rm >= 4) 1142 | return GPR.get("8").get(rm+4); 1143 | return GPR.get("8").get(rm); 1144 | } 1145 | else 1146 | return GPR.get("8").get(rm); 1147 | } 1148 | else 1149 | return null; 1150 | } 1151 | 1152 | private static String resolve_reg(String regtype, int i) 1153 | { 1154 | return GPR.get(regtype).get(i); 1155 | } 1156 | } -------------------------------------------------------------------------------- /com/Instruction.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import java.util.*; 4 | 5 | public class Instruction 6 | { 7 | private static Set invalid = new HashSet(); 8 | private static Set call = new HashSet(); 9 | private static Set ret = new HashSet(); 10 | private static Set jmp = new HashSet(); 11 | private static Set jcc = new HashSet(); 12 | private static Set hlt = new HashSet(); 13 | 14 | static 15 | { 16 | invalid.add("invalid"); 17 | call.add("call"); 18 | call.add("syscall"); 19 | call.add("vmcall"); 20 | call.add("vmmcall"); 21 | ret.add("ret"); 22 | ret.add("retf"); 23 | ret.add("sysret"); 24 | ret.add("iretw"); 25 | ret.add("iretd"); 26 | ret.add("iretq"); 27 | jmp.add("jmp"); 28 | jcc.add("jo"); 29 | jcc.add("jno"); 30 | jcc.add("jb"); 31 | jcc.add("jbe"); 32 | jcc.add("ja"); 33 | jcc.add("jae"); 34 | jcc.add("je"); 35 | jcc.add("jne"); 36 | jcc.add("js"); 37 | jcc.add("jns"); 38 | jcc.add("jp"); 39 | jcc.add("jnp"); 40 | jcc.add("jl"); 41 | jcc.add("jle"); 42 | jcc.add("jg"); 43 | jcc.add("jge"); 44 | jcc.add("jcxz"); 45 | jcc.add("jecxz"); 46 | jcc.add("jrcxz"); 47 | jcc.add("loop"); 48 | jcc.add("loope"); 49 | jcc.add("loopnz"); 50 | hlt.add("hlt"); 51 | } 52 | 53 | static boolean pattern = false; 54 | /*input; 55 | mode; 56 | add;*/ 57 | int x86Length; 58 | long eip; 59 | ZygoteInstruction zygote; 60 | String operator = "invalid"; 61 | Operand[] operand = new Operand[0]; 62 | Prefix pfx = new Prefix(); 63 | int opr_mode, adr_mode; 64 | String branch_dist; 65 | 66 | public Instruction() 67 | { 68 | } 69 | 70 | public static class Ptr 71 | { 72 | int off, seg; 73 | 74 | public Ptr(int off, int seg) 75 | { 76 | this.off = off; 77 | this.seg = seg; 78 | } 79 | } 80 | 81 | public static class Prefix 82 | { 83 | int rex, opr, adr, lock, rep, repe, repne, insn; 84 | String seg; 85 | public String toString() 86 | { 87 | StringBuffer b = new StringBuffer(); 88 | if (lock != 0) 89 | b.append("lock "); 90 | if (rep != 0) 91 | b.append("rep "); 92 | if (repe != 0) 93 | b.append("repe "); 94 | if (repne != 0) 95 | b.append("repne "); 96 | //if (seg != null) 97 | // b.append(seg+" "); 98 | 99 | return b.toString(); 100 | } 101 | } 102 | 103 | public static class Operand 104 | { 105 | private int x86Length; 106 | Instruction parent; 107 | long eip; 108 | String seg; 109 | String type, base; 110 | int size; 111 | long lval; 112 | Ptr ptr; // should be same as lval somehow 113 | String index; 114 | long offset, scale; 115 | int cast; 116 | //long pc; 117 | //value; 118 | //ref; 119 | // required for patterns 120 | int maxSize; 121 | int imm_start, dis_start; 122 | 123 | public String toString() 124 | { 125 | if (type == null) 126 | return "UNKNOWN - AVX?"; 127 | if (type.equals("OP_REG")) 128 | return base; 129 | boolean first = true; 130 | StringBuffer b = new StringBuffer(); 131 | //if (cast == 1) 132 | // b.append(intel_size(size)); 133 | if (type.equals("OP_MEM")) 134 | { 135 | b.append(intel_size(size)); 136 | 137 | if (seg != null) 138 | b.append(seg + ":"); 139 | else if ((base == null) && (index == null)) 140 | b.append("ds:"); 141 | if ((base != null) || (index != null)) 142 | b.append("["); 143 | 144 | if (base != null) 145 | { 146 | b.append(base); 147 | first = false; 148 | } 149 | if (index != null) 150 | { 151 | if (!first) 152 | b.append("+"); 153 | b.append(index); 154 | first = false; 155 | } 156 | if (scale != 0) 157 | b.append("*"+scale); 158 | if ((offset == 8) || (offset == 16) || (offset == 32) || (offset == 64)) 159 | { 160 | if (!pattern) 161 | { 162 | if ((lval <0) && ((base != null) || (index != null))) 163 | b.append("-"+String.format("0x%x", -lval)); 164 | else 165 | { 166 | if (!first) 167 | b.append("+"+String.format("0x%x", lval & ((1L << offset)-1))); 168 | else 169 | b.append(String.format("0x%x", lval & ((1L << offset)-1))); 170 | } 171 | } 172 | else 173 | { 174 | b.append("$"); 175 | for (int i=0; i < offset/8; i++) 176 | b.append("DD"); 177 | } 178 | } 179 | if ((base != null) || (index != null)) 180 | b.append("]"); 181 | } 182 | else if (type.equals("OP_IMM")) 183 | { 184 | if (!pattern) 185 | { 186 | if (lval <0) 187 | { 188 | if (sign_extends.contains(parent.operator)) // these are sign extended 189 | b.append(String.format("0x%x", lval & ((1L << maxSize)-1))); 190 | else 191 | b.append(String.format("0x%x", lval & ((1L << size)-1))); 192 | } 193 | else 194 | b.append(String.format("0x%x", lval)); 195 | } 196 | else 197 | { 198 | b.append("$"); 199 | for (int i=0; i < size/8; i++) 200 | b.append("II"); 201 | } 202 | } 203 | else if (type.equals("OP_JIMM")) 204 | { 205 | if (!pattern) 206 | { 207 | if (eip+x86Length+lval < 0) 208 | b.append(String.format("0x%x", (eip+x86Length+lval) & ((1L << maxSize)-1))); 209 | else 210 | b.append(String.format("0x%x", eip+x86Length+lval)); 211 | } 212 | else 213 | { 214 | b.append("$"); 215 | for (int i=0; i < size/8; i++) 216 | b.append("II"); 217 | } 218 | } 219 | else if (type.equals("OP_PTR")) 220 | { 221 | if (!pattern) 222 | b.append(String.format("0x%x:0x%x", ptr.seg & 0xFFFF, ptr.off)); 223 | else 224 | b.append("$SSSS:$DDDDDDDD"); 225 | } 226 | return b.toString(); 227 | //return String.format("[%s %s %s %d %x %x %x]", type, base, index, size, lval, offset, scale); 228 | } 229 | } 230 | 231 | private static List sign_extends = Arrays.asList("cmp", "or", "imul", "adc", "sbb", "xor"); 232 | 233 | private static String intel_size(int size) 234 | { 235 | switch (size) 236 | { 237 | case 0: 238 | return "";//XMMWORD PTR "; 239 | case 8: 240 | return "BYTE PTR "; 241 | case 16: 242 | return "WORD PTR "; 243 | case 32: 244 | return "DWORD PTR "; 245 | case 64: 246 | return "QWORD PTR "; 247 | case 80: 248 | return "TBYTE PTR "; 249 | default: 250 | throw new IllegalStateException("Unknown operand size " + size); 251 | } 252 | } 253 | 254 | private static boolean print_size = false; 255 | 256 | public String toString() 257 | { 258 | int maxSize = 0; 259 | for (Operand op: operand) 260 | { 261 | op.parent = this; 262 | if (op.size > maxSize) 263 | maxSize = op.size; 264 | op.eip = eip; 265 | op.x86Length = x86Length; 266 | } 267 | for (Operand op: operand) 268 | op.maxSize = maxSize; 269 | 270 | if (print_size) 271 | { 272 | if (operand.length == 1) 273 | return String.format("(%d bytes) %s%s %s", x86Length, pfx, operator + (branch_dist == null ? "": " "+branch_dist), operand[0]); 274 | else if (operand.length == 2) 275 | return String.format("(%d bytes) %s%s %s, %s", x86Length, pfx, operator + (branch_dist == null ? "": " "+branch_dist), operand[0], operand[1]); 276 | else if (operand.length == 3) 277 | return String.format("(%d bytes) %s%s %s, %s, %s", x86Length, pfx, operator + (branch_dist == null ? "": " "+branch_dist), operand[0], operand[1], operand[2]); 278 | return String.format("(%d bytes) %s%s", x86Length, pfx, operator + (branch_dist == null ? "": " "+branch_dist)); 279 | } 280 | if (operand.length == 1) 281 | return String.format("%s%s %s", pfx, operator + (branch_dist == null ? "": " "+branch_dist), operand[0]); 282 | else if (operand.length == 2) 283 | return String.format("%s%s %s,%s", pfx, operator + (branch_dist == null ? "": " "+branch_dist), operand[0], operand[1]); 284 | else if (operand.length == 3) 285 | return String.format("%s%s %s,%s,%s", pfx, operator + (branch_dist == null ? "": " "+branch_dist), operand[0], operand[1], operand[2]); 286 | return String.format("%s%s", pfx, operator + (branch_dist == null ? "": " "+branch_dist)); 287 | } 288 | } -------------------------------------------------------------------------------- /com/ObjdumpCompare.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | 6 | public class ObjdumpCompare 7 | { 8 | 9 | public static void main(String[] args) throws IOException 10 | { 11 | int mode = 32; 12 | 13 | Map invalid = new HashMap(); 14 | for (String file: args) 15 | { 16 | int lineCount = 0; 17 | BufferedReader br = new BufferedReader(new FileReader(file)); 18 | while (true) 19 | { 20 | String line = br.readLine(); 21 | if (line == null) 22 | break; 23 | lineCount++; 24 | 25 | if (line.indexOf("\t") < 0) 26 | continue; 27 | if (line.length() < 5) 28 | continue; 29 | 30 | String[] parts = line.split("\t"); 31 | String addrString = parts[0].trim(); 32 | if (!addrString.endsWith(":")) 33 | continue; 34 | //throw new IllegalStateException("Invalid address prefix on line "+lineCount + " of " + file); 35 | long address = Long.parseLong(addrString.substring(0, addrString.length()-1), 16); 36 | 37 | String x86Bytes = parts[1].trim(); 38 | String[] byteStrings = parts[1].trim().split(" "); 39 | byte[] rawX86 = new byte[byteStrings.length]; 40 | for (int i=0; i0) 48 | objdump = objdump.substring(0, end).trim(); 49 | if (objdump.contains("?") || objdump.contains("bad") || objdump.contains("fs:gs:") || objdump.contains(".byte") || objdump.contains("addr16") || objdump.contains("data16") || objdump.startsWith("nop") || objdump.equals("lock") || objdump.equals("cs") || objdump.equals("ds") || objdump.equals("es") || objdump.equals("fs") || objdump.equals("gs") || objdump.equals("ss") || objdump.equals("fnop") || objdump.equals("xgetbv")) 50 | continue; 51 | 52 | List excludes = Arrays.asList("insb", "insd", "outsb", "outsw", "outsd", "movsb", "movsw", "movsd", "lodsb", "lodsw", "lodsd", "stosb", "stosw", "stosd", "scasb", "scasw", "scasd", "cmpsb", "cmpsw", "cmpsd", "prefetch", "prefetcht0", "prefetchnta", "ret", "iretd", "fld", "lea", "fxch", "fcom", "fcomp", "pause", "sahf", "mov", "popad", "popfd", "pushfd", "pushad", "xlatb", "frstor", "fnsave", "fldenv", "fnstenv", "rcl", "jle", "je", "jbe", "int1", "push", "wait", "popa", "pshufw", "movq", "movlps", "movlpd", "movhpd", "call", "jmp", "bound", "fsub", "fsubrp", "pop", "arpl", "aam", "dec", "and", "add", "fiadd", "fisttp", "sub", "enter", "sldt", "les", "lds", "lfs", "hlt", "str", "cmpxchg8b"); 53 | 54 | Dis.ReversibleInputStream in = new Dis.ReversibleInputStream(rawX86); 55 | Instruction x; 56 | try 57 | { 58 | x = Dis.decode(in, mode); 59 | x.eip = address; 60 | } catch (Exception e) 61 | { 62 | if (!objdump.startsWith("v")) // AVX 63 | System.out.printf("Disassemble error on : %s (%s)", x86Bytes, objdump); 64 | continue; 65 | //throw e; 66 | //e.printStackTrace(); 67 | } 68 | try 69 | { 70 | if (x.operator.equals("invalid")) 71 | { 72 | String opname = objdump.substring(0, objdump.indexOf(" ")); 73 | if (!invalid.containsKey(opname)) 74 | { 75 | invalid.put(opname, x86Bytes+" " + objdump); 76 | System.out.println(x86Bytes + " -> " + x + " != " + objdump); 77 | } 78 | continue; 79 | } 80 | if ((x.operator != "nop") || (!objdump.contains("xchg"))) 81 | if (!excludes.contains(x.operator)) 82 | if (!x.toString().replace("near ", "").replace("0x", "").replace("DWORD PTR ", "").equals(objdump.replace("0x", ""))) 83 | System.out.println(x86Bytes + " -> " + x + " != " + objdump); 84 | } catch (Exception e) 85 | { 86 | System.out.printf("Print error on : %s (%s)", x86Bytes, objdump); 87 | throw e; 88 | } 89 | } 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /com/PatternGenerator.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import java.io.*; 4 | 5 | public class PatternGenerator 6 | { 7 | 8 | public static void main(String[] args) 9 | { 10 | byte[] data = new byte[15]; 11 | Dis.ReversibleInputStream in = new Dis.ReversibleInputStream(data); 12 | int mode = 32; 13 | 14 | int index=0; 15 | while (true) 16 | { 17 | Instruction x; 18 | try 19 | { 20 | x = Dis.decode(in, mode); 21 | } 22 | catch (IllegalStateException e) 23 | { 24 | index = advance(index, data); 25 | if (index == -1) 26 | break; 27 | continue; 28 | } 29 | catch (ArrayIndexOutOfBoundsException e) 30 | { 31 | index--; 32 | if ((index == 0) && (data[0] == -1)) 33 | break; 34 | data[index]++; 35 | for (int i = index+1; i < data.length; i++) 36 | data[i] = (byte)0; 37 | continue; 38 | } 39 | if (x.operator.equals("invalid")) 40 | { 41 | index = advance(index, data); 42 | if (index == -1) 43 | break; 44 | continue; 45 | } 46 | StringBuffer pat = new StringBuffer(); 47 | for (int c=0; c < x.x86Length; c++) 48 | pat.append(String.format("%02x", data[c]&0xFF)); 49 | // mask out with DD and II 50 | String disam = x.toString(); 51 | for (Instruction.Operand op: x.operand) 52 | { 53 | if (op.type == null) 54 | { 55 | disam = "Unknown"; 56 | } 57 | if (op.type.equals("OP_IMM") || op.type.equals("OP_JIMM")) 58 | { 59 | for (int c=op.imm_start; c < op.imm_start+op.size/8; c++) 60 | { 61 | pat.setCharAt(2*c, 'I'); 62 | pat.setCharAt(2*c+1, 'I'); 63 | } 64 | } 65 | else if (op.type.equals("OP_MEM")) 66 | { 67 | if (op.offset > 0) 68 | { 69 | for (int c=op.dis_start; c < op.dis_start+op.offset/8; c++) 70 | { 71 | pat.setCharAt(2*c, 'D'); 72 | pat.setCharAt(2*c+1, 'D'); 73 | } 74 | } 75 | } 76 | else if (op.type.equals("OP_PTR")) 77 | { 78 | if (op.size == 32) 79 | { 80 | for (int c=op.dis_start; c < op.dis_start+2; c++) 81 | { 82 | pat.setCharAt(2*c, 'D'); 83 | pat.setCharAt(2*c+1, 'D'); 84 | } 85 | for (int c=op.dis_start+2; c < op.dis_start+4; c++) 86 | { 87 | pat.setCharAt(2*c, 'S'); 88 | pat.setCharAt(2*c+1, 'S'); 89 | } 90 | } 91 | else if (op.size == 48) 92 | { 93 | for (int c=op.dis_start; c < op.dis_start+4; c++) 94 | { 95 | pat.setCharAt(2*c, 'D'); 96 | pat.setCharAt(2*c+1, 'D'); 97 | } 98 | for (int c=op.dis_start+4; c < op.dis_start+6; c++) 99 | { 100 | pat.setCharAt(2*c, 'S'); 101 | pat.setCharAt(2*c+1, 'S'); 102 | } 103 | } 104 | } 105 | } 106 | System.out.println(pat + " " + disam); 107 | // find last byte that is not II SS or DD and increment it, zeroing above it 108 | index = lastOpcodeByteBefore(pat.toString(), pat.length()-1); 109 | index = advance(index, data); 110 | if (index == -1) 111 | break; 112 | } 113 | 114 | } 115 | 116 | public static int advance(int index, byte[] data) 117 | { 118 | while ((index > 0) && !((data[index] & 0xFF) < 255)) 119 | index--; 120 | if ((index == 0) && (data[0] == -1)) 121 | return -1; 122 | data[index]++; 123 | for (int i = index+1; i < data.length; i++) 124 | data[i] = (byte)0; 125 | return index; 126 | } 127 | 128 | public static int lastOpcodeByteBefore(String pat, int index) 129 | { 130 | while ((index > 0) && ((pat.charAt(index) == 'I') || (pat.charAt(index) == 'D') || (pat.charAt(index) == 'S'))) 131 | index--; 132 | return index/2; 133 | } 134 | } -------------------------------------------------------------------------------- /com/ZygoteInstruction.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | public class ZygoteInstruction 4 | { 5 | String operator; 6 | ZygoteOperand[] operand; 7 | int prefix; 8 | 9 | public ZygoteInstruction(String mnemonic, ZygoteOperand op1, ZygoteOperand op2, ZygoteOperand op3, int prefix) 10 | { 11 | this.operator = mnemonic; 12 | this.operand = new ZygoteOperand[]{op1, op2, op3}; 13 | this.prefix = prefix; 14 | } 15 | } -------------------------------------------------------------------------------- /com/ZygoteOperand.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import java.util.*; 4 | 5 | public class ZygoteOperand 6 | { 7 | 8 | public static final int VENDOR_INTEL = 0; 9 | public static final int VENDOR_AMD = 1; 10 | public static final int MAX_INSTRUCTION_LENGTH = 15; 11 | 12 | public static final Map> GPR = new HashMap(); 13 | 14 | static 15 | { 16 | GPR.put("T_NONE", null); 17 | GPR.put("8", Arrays.asList(new String[]{ 18 | "al", "cl", "dl", "bl", 19 | "ah", "ch", "dh", "bh", 20 | "spl", "bpl", "sil", "dil", 21 | "r8b", "r9b", "r10b", "r11b", 22 | "r12b", "r13b", "r14b", "r15b"})); 23 | GPR.put("16", Arrays.asList(new String[]{ 24 | "ax", "cx", "dx", "bx", 25 | "sp", "bp", "si", "di", 26 | "r8w", "r9w", "r10w", "r11w", 27 | "r12w", "r13w", "r14w", "r15w"})); 28 | GPR.put("32", Arrays.asList(new String[]{ 29 | "eax", "ecx", "edx", "ebx", 30 | "esp", "ebp", "esi", "edi", 31 | "r8d", "r9d", "r10d", "r11d", 32 | "r12d", "r13d", "r14d", "r15d"})); 33 | GPR.put("64", Arrays.asList(new String[]{ 34 | "rax", "rcx", "rdx", "rbx", 35 | "rsp", "rbp", "rsi", "rdi", 36 | "r8", "r9", "r10", "r11", 37 | "r12", "r13", "r14", "r15"})); 38 | GPR.put("T_SEG", Arrays.asList(new String[]{ 39 | "es", "cs", "ss", "ds", 40 | "fs", "gs"})); 41 | GPR.put("T_CRG", Arrays.asList(new String[]{ 42 | "cr0", "cr1", "cr2", "cr3", 43 | "cr4", "cr5", "cr6", "cr7", 44 | "cr8", "cr9", "cr10", "cr11", 45 | "cr12", "cr13", "cr14", "cr15"})); 46 | GPR.put("T_DBG", Arrays.asList(new String[]{ 47 | "dr0", "dr1", "dr2", "dr3", 48 | "dr4", "dr5", "dr6", "dr7", 49 | "dr8", "dr9", "dr10", "dr11", 50 | "dr12", "dr13", "dr14", "dr15"})); 51 | GPR.put("T_MMX", Arrays.asList(new String[]{ 52 | "mm0", "mm1", "mm2", "mm3", 53 | "mm4", "mm5", "mm6", "mm7"})); 54 | GPR.put("T_ST", Arrays.asList(new String[]{ 55 | "st0", "st1", "st2", "st3", 56 | "st4", "st5", "st6", "st7"})); 57 | GPR.put("T_XMM", Arrays.asList(new String[]{ 58 | "xmm0", "xmm1", "xmm2", "xmm3", 59 | "xmm4", "xmm5", "xmm6", "xmm7", 60 | "xmm8", "xmm9", "xmm10", "xmm11", 61 | "xmm12", "xmm13", "xmm14", "xmm15"})); 62 | GPR.put("IP", Arrays.asList(new String[]{"rip"})); 63 | GPR.put("OP", Arrays.asList(new String[]{ 64 | "OP_REG", "OP_MEM", "OP_PTR", 65 | "OP_IMM", "OP_JIMM", "OP_CONST"})); 66 | } 67 | 68 | public static final int P_none = (0); 69 | public static final int P_c1 = (1 << 0); 70 | public static final int P_rexb = (1 << 1); 71 | public static final int P_depM = (1 << 2); 72 | public static final int P_c3 = (1 << 3); 73 | public static final int P_inv64 = (1 << 4); 74 | public static final int P_rexw = (1 << 5); 75 | public static final int P_c2 = (1 << 6); 76 | public static final int P_def64 = (1 << 7); 77 | public static final int P_rexr = (1 << 8); 78 | public static final int P_oso = (1 << 9); 79 | public static final int P_aso = (1 << 10); 80 | public static final int P_rexx = (1 << 11); 81 | public static final int P_ImpAddr = (1 << 12); 82 | 83 | public static int P_C0(int n) 84 | { 85 | return (n >> 0) & 1; 86 | } 87 | 88 | public static int P_REXB(int n) 89 | { 90 | return (n >> 1) & 1; 91 | } 92 | 93 | public static int P_DEPM(int n) 94 | { 95 | return (n >> 2) & 1; 96 | } 97 | 98 | public static int P_C2(int n) 99 | { 100 | return (n >> 3) & 1; 101 | } 102 | 103 | public static int P_INV64(int n) 104 | { 105 | return (n >> 4) & 1; 106 | } 107 | 108 | public static int P_REXW(int n) 109 | { 110 | return (n >> 5) & 1; 111 | } 112 | 113 | public static int P_C1(int n) 114 | { 115 | return (n >> 6) & 1; 116 | } 117 | 118 | public static int P_DEF64(int n) 119 | { 120 | return (n >> 7) & 1; 121 | } 122 | 123 | public static int P_REXR(int n) 124 | { 125 | return (n >> 8) & 1; 126 | } 127 | 128 | public static int P_OSO(int n) 129 | { 130 | return (n >> 9) & 1; 131 | } 132 | 133 | public static int P_ASO(int n) 134 | { 135 | return (n >> 10) & 1; 136 | } 137 | 138 | public static int P_REXX(int n) 139 | { 140 | return (n >> 11) & 1; 141 | } 142 | 143 | public static int P_IMPADDR(int n) 144 | { 145 | return (n >> 12) & 1; 146 | } 147 | 148 | // rex prefix bits 149 | public static int REX_W(int r) 150 | { 151 | return (0xF & r) >> 3; 152 | } 153 | 154 | public static int REX_R(int r) 155 | { 156 | return (0x7 & r) >> 2; 157 | } 158 | 159 | public static int REX_X(int r) 160 | { 161 | return (0x3 & r) >> 1; 162 | } 163 | 164 | public static int REX_B(int r) 165 | { 166 | return (0x1 & r) >> 0; 167 | } 168 | 169 | public static int REX_PFX_MASK(int n) 170 | { 171 | return ((P_REXW(n) << 3) | 172 | (P_REXR(n) << 2) | 173 | (P_REXX(n) << 1) | 174 | (P_REXB(n) << 0)); 175 | } 176 | 177 | // scable-index-base bits 178 | public static int SIB_S(int b) 179 | { 180 | return b >> 6; 181 | } 182 | 183 | public static int SIB_I(int b) 184 | { 185 | return (b >> 3) & 7; 186 | } 187 | 188 | public static int SIB_B(int b) 189 | { 190 | return b & 7; 191 | } 192 | 193 | // modrm bits 194 | public static int MODRM_REG(int b) 195 | { 196 | return (b >> 3) & 7; 197 | } 198 | 199 | public static int MODRM_NNN(int b) 200 | { 201 | return (b >> 3) & 7; 202 | } 203 | 204 | public static int MODRM_MOD(int b) 205 | { 206 | return (b >> 6) & 3; 207 | } 208 | 209 | public static int MODRM_RM(int b) 210 | { 211 | return b & 7; 212 | } 213 | 214 | // operand types 215 | public static final int OP_NONE = 0; 216 | 217 | public static final int OP_A = 1; 218 | public static final int OP_E = 2; 219 | public static final int OP_M = 3; 220 | public static final int OP_G = 4 ; 221 | public static final int OP_I = 5; 222 | 223 | public static final int OP_AL = 6; 224 | public static final int OP_CL = 7; 225 | public static final int OP_DL = 8; 226 | public static final int OP_BL = 9; 227 | public static final int OP_AH = 10; 228 | public static final int OP_CH = 11; 229 | public static final int OP_DH = 12; 230 | public static final int OP_BH = 13; 231 | 232 | public static final int OP_ALr8b = 14; 233 | public static final int OP_CLr9b = 15; 234 | public static final int OP_DLr10b = 16; 235 | public static final int OP_BLr11b = 17; 236 | public static final int OP_AHr12b = 18; 237 | public static final int OP_CHr13b = 19; 238 | public static final int OP_DHr14b = 20; 239 | public static final int OP_BHr15b = 21; 240 | 241 | public static final int OP_AX = 22; 242 | public static final int OP_CX = 23; 243 | public static final int OP_DX = 24; 244 | public static final int OP_BX = 25; 245 | public static final int OP_SI = 26; 246 | public static final int OP_DI = 27; 247 | public static final int OP_SP = 28; 248 | public static final int OP_BP = 29; 249 | 250 | public static final int OP_rAX = 30; 251 | public static final int OP_rCX = 31; 252 | public static final int OP_rDX = 32; 253 | public static final int OP_rBX = 33; 254 | public static final int OP_rSP = 34; 255 | public static final int OP_rBP = 35; 256 | public static final int OP_rSI = 36; 257 | public static final int OP_rDI = 37; 258 | 259 | public static final int OP_rAXr8 = 38; 260 | public static final int OP_rCXr9 = 39; 261 | public static final int OP_rDXr10 = 40; 262 | public static final int OP_rBXr11 = 41; 263 | public static final int OP_rSPr12 = 42; 264 | public static final int OP_rBPr13 = 43; 265 | public static final int OP_rSIr14 = 44; 266 | public static final int OP_rDIr15 = 45; 267 | 268 | public static final int OP_eAX = 46; 269 | public static final int OP_eCX = 47; 270 | public static final int OP_eDX = 48; 271 | public static final int OP_eBX = 49; 272 | public static final int OP_eSP = 50; 273 | public static final int OP_eBP = 51; 274 | public static final int OP_eSI = 52; 275 | public static final int OP_eDI = 53; 276 | 277 | public static final int OP_ES = 54; 278 | public static final int OP_CS = 55; 279 | public static final int OP_SS = 56; 280 | public static final int OP_DS = 57; 281 | public static final int OP_FS = 58; 282 | public static final int OP_GS = 59; 283 | 284 | public static final int OP_ST0 = 60; 285 | public static final int OP_ST1 = 61; 286 | public static final int OP_ST2 = 62; 287 | public static final int OP_ST3 = 63; 288 | public static final int OP_ST4 = 64; 289 | public static final int OP_ST5 = 65; 290 | public static final int OP_ST6 = 66; 291 | public static final int OP_ST7 = 67; 292 | 293 | public static final int OP_J = 68; 294 | public static final int OP_S = 69; 295 | public static final int OP_O = 70; 296 | public static final int OP_I1 = 71; 297 | public static final int OP_I3 = 72; 298 | public static final int OP_V = 73; 299 | public static final int OP_W = 74; 300 | public static final int OP_Q = 75; 301 | public static final int OP_P = 76; 302 | public static final int OP_R = 77; 303 | public static final int OP_C = 78; 304 | public static final int OP_D = 79; 305 | public static final int OP_VR = 80; 306 | public static final int OP_PR = 81; 307 | 308 | // operand size constants 309 | public static final int SZ_NA = 0; 310 | public static final int SZ_Z = 1; 311 | public static final int SZ_V = 2; 312 | public static final int SZ_P = 3; 313 | public static final int SZ_WP = 4; 314 | public static final int SZ_DP = 5; 315 | public static final int SZ_MDQ = 6; 316 | public static final int SZ_RDQ = 7; 317 | 318 | public static final int SZ_B = 8; 319 | public static final int SZ_W = 16; 320 | public static final int SZ_D = 32; 321 | public static final int SZ_Q = 64; 322 | public static final int SZ_T = 80; 323 | 324 | public static List ops8 = Arrays.asList(OP_AL, OP_CL, OP_DL, OP_BL, OP_AH, OP_CH, OP_DH, OP_BH); 325 | 326 | public static List ops32 = Arrays.asList( 327 | OP_eAX, OP_eCX, OP_eDX, OP_eBX, 328 | OP_eSP, OP_eBP, OP_eSI, OP_eDI); 329 | 330 | public static List ops64 = Arrays.asList( 331 | OP_rAX, OP_rCX, OP_rDX, OP_rBX, 332 | OP_rSP, OP_rBP, OP_rSI, OP_rDI); 333 | 334 | public static List ops2 = Arrays.asList( 335 | OP_rAXr8, OP_rCXr9, OP_rDXr10, OP_rBXr11, 336 | OP_rSPr12, OP_rBPr13, OP_rSIr14, OP_rDIr15, 337 | OP_rAX, OP_rCX, OP_rDX, OP_rBX, 338 | OP_rSP, OP_rBP, OP_rSI, OP_rDI); 339 | 340 | public static List ops3 = Arrays.asList( 341 | OP_ALr8b, OP_CLr9b, OP_DLr10b, OP_BLr11b, 342 | OP_AHr12b, OP_CHr13b, OP_DHr14b, OP_BHr15b); 343 | 344 | public static List ops_st = Arrays.asList( 345 | OP_ST0, OP_ST1, OP_ST2, OP_ST3, 346 | OP_ST4, OP_ST5, OP_ST6, OP_ST7); 347 | 348 | public static List ops_segs = Arrays.asList( 349 | OP_ES, OP_CS, OP_DS, OP_SS, OP_FS, OP_GS); 350 | 351 | final int type, size; 352 | 353 | public ZygoteOperand(int type, int size) 354 | { 355 | this.type = type; 356 | this.size = size; 357 | } 358 | 359 | // operands 360 | public static final ZygoteOperand O_rSPr12 = new ZygoteOperand(OP_rSPr12, SZ_NA); 361 | public static final ZygoteOperand O_BL = new ZygoteOperand(OP_BL, SZ_NA); 362 | public static final ZygoteOperand O_BH = new ZygoteOperand(OP_BH, SZ_NA); 363 | public static final ZygoteOperand O_BP = new ZygoteOperand(OP_BP, SZ_NA); 364 | public static final ZygoteOperand O_AHr12b = new ZygoteOperand(OP_AHr12b, SZ_NA); 365 | public static final ZygoteOperand O_BX = new ZygoteOperand(OP_BX, SZ_NA); 366 | public static final ZygoteOperand O_Jz = new ZygoteOperand(OP_J, SZ_Z); 367 | public static final ZygoteOperand O_Jv = new ZygoteOperand(OP_J, SZ_V); 368 | public static final ZygoteOperand O_Jb = new ZygoteOperand(OP_J, SZ_B); 369 | public static final ZygoteOperand O_rSIr14 = new ZygoteOperand(OP_rSIr14, SZ_NA); 370 | public static final ZygoteOperand O_GS = new ZygoteOperand(OP_GS, SZ_NA); 371 | public static final ZygoteOperand O_D = new ZygoteOperand(OP_D, SZ_NA); 372 | public static final ZygoteOperand O_rBPr13 = new ZygoteOperand(OP_rBPr13, SZ_NA); 373 | public static final ZygoteOperand O_Ob = new ZygoteOperand(OP_O, SZ_B); 374 | public static final ZygoteOperand O_P = new ZygoteOperand(OP_P, SZ_NA); 375 | public static final ZygoteOperand O_Ow = new ZygoteOperand(OP_O, SZ_W); 376 | public static final ZygoteOperand O_Ov = new ZygoteOperand(OP_O, SZ_V); 377 | public static final ZygoteOperand O_Gw = new ZygoteOperand(OP_G, SZ_W); 378 | public static final ZygoteOperand O_Gv = new ZygoteOperand(OP_G, SZ_V); 379 | public static final ZygoteOperand O_rDX = new ZygoteOperand(OP_rDX, SZ_NA); 380 | public static final ZygoteOperand O_Gx = new ZygoteOperand(OP_G, SZ_MDQ); 381 | public static final ZygoteOperand O_Gd = new ZygoteOperand(OP_G, SZ_D); 382 | public static final ZygoteOperand O_Gb = new ZygoteOperand(OP_G, SZ_B); 383 | public static final ZygoteOperand O_rBXr11 = new ZygoteOperand(OP_rBXr11, SZ_NA); 384 | public static final ZygoteOperand O_rDI = new ZygoteOperand(OP_rDI, SZ_NA); 385 | public static final ZygoteOperand O_rSI = new ZygoteOperand(OP_rSI, SZ_NA); 386 | public static final ZygoteOperand O_ALr8b = new ZygoteOperand(OP_ALr8b, SZ_NA); 387 | public static final ZygoteOperand O_eDI = new ZygoteOperand(OP_eDI, SZ_NA); 388 | public static final ZygoteOperand O_Gz = new ZygoteOperand(OP_G, SZ_Z); 389 | public static final ZygoteOperand O_eDX = new ZygoteOperand(OP_eDX, SZ_NA); 390 | public static final ZygoteOperand O_DHr14b = new ZygoteOperand(OP_DHr14b, SZ_NA); 391 | public static final ZygoteOperand O_rSP = new ZygoteOperand(OP_rSP, SZ_NA); 392 | public static final ZygoteOperand O_PR = new ZygoteOperand(OP_PR, SZ_NA); 393 | public static final ZygoteOperand O_NONE = new ZygoteOperand(OP_NONE, SZ_NA); 394 | public static final ZygoteOperand O_rCX = new ZygoteOperand(OP_rCX, SZ_NA); 395 | public static final ZygoteOperand O_jWP = new ZygoteOperand(OP_J, SZ_WP); 396 | public static final ZygoteOperand O_rDXr10 = new ZygoteOperand(OP_rDXr10, SZ_NA); 397 | public static final ZygoteOperand O_Md = new ZygoteOperand(OP_M, SZ_D); 398 | public static final ZygoteOperand O_C = new ZygoteOperand(OP_C, SZ_NA); 399 | public static final ZygoteOperand O_G = new ZygoteOperand(OP_G, SZ_NA); 400 | public static final ZygoteOperand O_Mb = new ZygoteOperand(OP_M, SZ_B); 401 | public static final ZygoteOperand O_Mt = new ZygoteOperand(OP_M, SZ_T); 402 | public static final ZygoteOperand O_S = new ZygoteOperand(OP_S, SZ_NA); 403 | public static final ZygoteOperand O_Mq = new ZygoteOperand(OP_M, SZ_Q); 404 | public static final ZygoteOperand O_W = new ZygoteOperand(OP_W, SZ_NA); 405 | public static final ZygoteOperand O_ES = new ZygoteOperand(OP_ES, SZ_NA); 406 | public static final ZygoteOperand O_rBX = new ZygoteOperand(OP_rBX, SZ_NA); 407 | public static final ZygoteOperand O_Ed = new ZygoteOperand(OP_E, SZ_D); 408 | public static final ZygoteOperand O_DLr10b = new ZygoteOperand(OP_DLr10b, SZ_NA); 409 | public static final ZygoteOperand O_Mw = new ZygoteOperand(OP_M, SZ_W); 410 | public static final ZygoteOperand O_Eb = new ZygoteOperand(OP_E, SZ_B); 411 | public static final ZygoteOperand O_Ex = new ZygoteOperand(OP_E, SZ_MDQ); 412 | public static final ZygoteOperand O_Ez = new ZygoteOperand(OP_E, SZ_Z); 413 | public static final ZygoteOperand O_Ew = new ZygoteOperand(OP_E, SZ_W); 414 | public static final ZygoteOperand O_Ev = new ZygoteOperand(OP_E, SZ_V); 415 | public static final ZygoteOperand O_Ep = new ZygoteOperand(OP_E, SZ_P); 416 | public static final ZygoteOperand O_FS = new ZygoteOperand(OP_FS, SZ_NA); 417 | public static final ZygoteOperand O_Ms = new ZygoteOperand(OP_M, SZ_W); 418 | public static final ZygoteOperand O_rAXr8 = new ZygoteOperand(OP_rAXr8, SZ_NA); 419 | public static final ZygoteOperand O_eBP = new ZygoteOperand(OP_eBP, SZ_NA); 420 | public static final ZygoteOperand O_Isb = new ZygoteOperand(OP_I, SZ_B); 421 | public static final ZygoteOperand O_eBX = new ZygoteOperand(OP_eBX, SZ_NA); 422 | public static final ZygoteOperand O_rCXr9 = new ZygoteOperand(OP_rCXr9, SZ_NA); 423 | public static final ZygoteOperand O_jDP = new ZygoteOperand(OP_J, SZ_DP); 424 | public static final ZygoteOperand O_CH = new ZygoteOperand(OP_CH, SZ_NA); 425 | public static final ZygoteOperand O_CL = new ZygoteOperand(OP_CL, SZ_NA); 426 | public static final ZygoteOperand O_R = new ZygoteOperand(OP_R, SZ_RDQ); 427 | public static final ZygoteOperand O_V = new ZygoteOperand(OP_V, SZ_NA); 428 | public static final ZygoteOperand O_CS = new ZygoteOperand(OP_CS, SZ_NA); 429 | public static final ZygoteOperand O_CHr13b = new ZygoteOperand(OP_CHr13b, SZ_NA); 430 | public static final ZygoteOperand O_eCX = new ZygoteOperand(OP_eCX, SZ_NA); 431 | public static final ZygoteOperand O_eSP = new ZygoteOperand(OP_eSP, SZ_NA); 432 | public static final ZygoteOperand O_SS = new ZygoteOperand(OP_SS, SZ_NA); 433 | public static final ZygoteOperand O_SP = new ZygoteOperand(OP_SP, SZ_NA); 434 | public static final ZygoteOperand O_BLr11b = new ZygoteOperand(OP_BLr11b, SZ_NA); 435 | public static final ZygoteOperand O_SI = new ZygoteOperand(OP_SI, SZ_NA); 436 | public static final ZygoteOperand O_eSI = new ZygoteOperand(OP_eSI, SZ_NA); 437 | public static final ZygoteOperand O_DL = new ZygoteOperand(OP_DL, SZ_NA); 438 | public static final ZygoteOperand O_DH = new ZygoteOperand(OP_DH, SZ_NA); 439 | public static final ZygoteOperand O_DI = new ZygoteOperand(OP_DI, SZ_NA); 440 | public static final ZygoteOperand O_DX = new ZygoteOperand(OP_DX, SZ_NA); 441 | public static final ZygoteOperand O_rBP = new ZygoteOperand(OP_rBP, SZ_NA); 442 | public static final ZygoteOperand O_Gvw = new ZygoteOperand(OP_G, SZ_MDQ); 443 | public static final ZygoteOperand O_I1 = new ZygoteOperand(OP_I1, SZ_NA); 444 | public static final ZygoteOperand O_I3 = new ZygoteOperand(OP_I3, SZ_NA); 445 | public static final ZygoteOperand O_DS = new ZygoteOperand(OP_DS, SZ_NA); 446 | public static final ZygoteOperand O_ST4 = new ZygoteOperand(OP_ST4, SZ_NA); 447 | public static final ZygoteOperand O_ST5 = new ZygoteOperand(OP_ST5, SZ_NA); 448 | public static final ZygoteOperand O_ST6 = new ZygoteOperand(OP_ST6, SZ_NA); 449 | public static final ZygoteOperand O_ST7 = new ZygoteOperand(OP_ST7, SZ_NA); 450 | public static final ZygoteOperand O_ST0 = new ZygoteOperand(OP_ST0, SZ_NA); 451 | public static final ZygoteOperand O_ST1 = new ZygoteOperand(OP_ST1, SZ_NA); 452 | public static final ZygoteOperand O_ST2 = new ZygoteOperand(OP_ST2, SZ_NA); 453 | public static final ZygoteOperand O_ST3 = new ZygoteOperand(OP_ST3, SZ_NA); 454 | public static final ZygoteOperand O_E = new ZygoteOperand(OP_E, SZ_NA); 455 | public static final ZygoteOperand O_AH = new ZygoteOperand(OP_AH, SZ_NA); 456 | public static final ZygoteOperand O_M = new ZygoteOperand(OP_M, SZ_NA); 457 | public static final ZygoteOperand O_AL = new ZygoteOperand(OP_AL, SZ_NA); 458 | public static final ZygoteOperand O_CLr9b = new ZygoteOperand(OP_CLr9b, SZ_NA); 459 | public static final ZygoteOperand O_Q = new ZygoteOperand(OP_Q, SZ_NA); 460 | public static final ZygoteOperand O_eAX = new ZygoteOperand(OP_eAX, SZ_NA); 461 | public static final ZygoteOperand O_VR = new ZygoteOperand(OP_VR, SZ_NA); 462 | public static final ZygoteOperand O_AX = new ZygoteOperand(OP_AX, SZ_NA); 463 | public static final ZygoteOperand O_rAX = new ZygoteOperand(OP_rAX, SZ_NA); 464 | public static final ZygoteOperand O_Iz = new ZygoteOperand(OP_I, SZ_Z); 465 | public static final ZygoteOperand O_rDIr15 = new ZygoteOperand(OP_rDIr15, SZ_NA); 466 | public static final ZygoteOperand O_Iw = new ZygoteOperand(OP_I, SZ_W); 467 | public static final ZygoteOperand O_Iv = new ZygoteOperand(OP_I, SZ_V); 468 | public static final ZygoteOperand O_Ap = new ZygoteOperand(OP_A, SZ_P); 469 | public static final ZygoteOperand O_CX = new ZygoteOperand(OP_CX, SZ_NA); 470 | public static final ZygoteOperand O_Ib = new ZygoteOperand(OP_I, SZ_B); 471 | public static final ZygoteOperand O_BHr15b = new ZygoteOperand(OP_BHr15b, SZ_NA); 472 | 473 | } -------------------------------------------------------------------------------- /com/gen/TableGen.java: -------------------------------------------------------------------------------- 1 | package com.gen; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | import javax.xml.parsers.*; 6 | import org.w3c.dom.*; 7 | import org.xml.sax.*; 8 | 9 | public class TableGen 10 | { 11 | private static Set spl_mnm_types = new HashSet(); 12 | private static Map vend_dict = new HashMap(); 13 | private static Map mode_dict = new HashMap(); 14 | private static Map operand_dict = new HashMap(); 15 | private static Map pfx_dict = new HashMap(); 16 | private static String default_opr = "O_NONE, O_NONE, O_NONE"; 17 | 18 | static 19 | { 20 | spl_mnm_types.add("d3vil"); 21 | spl_mnm_types.add("na"); 22 | spl_mnm_types.add("grp_reg"); 23 | spl_mnm_types.add("grp_rm"); 24 | spl_mnm_types.add("grp_vendor"); 25 | spl_mnm_types.add("grp_x87"); 26 | spl_mnm_types.add("grp_mode"); 27 | spl_mnm_types.add("grp_osize"); 28 | spl_mnm_types.add("grp_asize"); 29 | spl_mnm_types.add("grp_mod"); 30 | spl_mnm_types.add("none"); 31 | vend_dict.put("AMD", "00"); 32 | vend_dict.put("INTEL", "01"); 33 | mode_dict.put("16", "00"); 34 | mode_dict.put("32", "01"); 35 | mode_dict.put("64", "02"); 36 | operand_dict.put("Ap", new String[]{"OP_A", "SZ_P"}); 37 | operand_dict.put("E", new String[]{"OP_E", "SZ_NA"}); 38 | operand_dict.put("Eb", new String[]{"OP_E", "SZ_B"}); 39 | operand_dict.put("Ew", new String[]{"OP_E", "SZ_W"}); 40 | operand_dict.put("Ev", new String[]{"OP_E", "SZ_V"}); 41 | operand_dict.put("Ed", new String[]{"OP_E", "SZ_D"}); 42 | operand_dict.put("Ez", new String[]{"OP_E", "SZ_Z"}); 43 | operand_dict.put("Ex", new String[]{"OP_E", "SZ_MDQ"}); 44 | operand_dict.put("Ep", new String[]{"OP_E", "SZ_P"}); 45 | operand_dict.put("G", new String[]{"OP_G", "SZ_NA"}); 46 | operand_dict.put("Gb", new String[]{"OP_G", "SZ_B"}); 47 | operand_dict.put("Gw", new String[]{"OP_G", "SZ_W"}); 48 | operand_dict.put("Gv", new String[]{"OP_G", "SZ_V"}); 49 | operand_dict.put("Gvw", new String[]{"OP_G", "SZ_MDQ"}); 50 | operand_dict.put("Gd", new String[]{"OP_G", "SZ_D"}); 51 | operand_dict.put("Gx", new String[]{"OP_G", "SZ_MDQ"}); 52 | operand_dict.put("Gz", new String[]{"OP_G", "SZ_Z"}); 53 | operand_dict.put("M", new String[]{"OP_M", "SZ_NA"}); 54 | operand_dict.put("Mb", new String[]{"OP_M", "SZ_B"}); 55 | operand_dict.put("Mw", new String[]{"OP_M", "SZ_W"}); 56 | operand_dict.put("Ms", new String[]{"OP_M", "SZ_W"}); 57 | operand_dict.put("Md", new String[]{"OP_M", "SZ_D"}); 58 | operand_dict.put("Mq", new String[]{"OP_M", "SZ_Q"}); 59 | operand_dict.put("Mt", new String[]{"OP_M", "SZ_T"}); 60 | operand_dict.put("I1", new String[]{"OP_I1", "SZ_NA"}); 61 | operand_dict.put("I3", new String[]{"OP_I3", "SZ_NA"}); 62 | operand_dict.put("Ib", new String[]{"OP_I", "SZ_B"}); 63 | operand_dict.put("Isb", new String[]{"OP_I", "SZ_SB"}); 64 | operand_dict.put("Iw", new String[]{"OP_I", "SZ_W"}); 65 | operand_dict.put("Iv", new String[]{"OP_I", "SZ_V"}); 66 | operand_dict.put("Iz", new String[]{"OP_I", "SZ_Z"}); 67 | operand_dict.put("Jv", new String[]{"OP_J", "SZ_V"}); 68 | operand_dict.put("Jz", new String[]{"OP_J", "SZ_Z"}); 69 | operand_dict.put("Jb", new String[]{"OP_J", "SZ_B"}); 70 | operand_dict.put("R", new String[]{"OP_R", "SZ_RDQ"}); 71 | operand_dict.put( "C", new String[]{"OP_C", "SZ_NA"}); 72 | operand_dict.put("D", new String[]{"OP_D", "SZ_NA"}); 73 | operand_dict.put("S", new String[]{"OP_S", "SZ_NA"}); 74 | operand_dict.put("Ob", new String[]{"OP_O", "SZ_B" }); 75 | operand_dict.put("Ow", new String[]{"OP_O", "SZ_W" }); 76 | operand_dict.put("Ov", new String[]{"OP_O", "SZ_V" }); 77 | operand_dict.put("V", new String[]{"OP_V", "SZ_NA"}); 78 | operand_dict.put("W", new String[]{"OP_W", "SZ_NA"}); 79 | operand_dict.put("P", new String[]{"OP_P", "SZ_NA"}); 80 | operand_dict.put("Q", new String[]{"OP_Q", "SZ_NA"}); 81 | operand_dict.put("VR", new String[]{"OP_VR", "SZ_NA"}); 82 | operand_dict.put("PR", new String[]{"OP_PR", "SZ_NA"}); 83 | operand_dict.put("AL", new String[]{"OP_AL", "SZ_NA"}); 84 | operand_dict.put("CL", new String[]{"OP_CL", "SZ_NA"}); 85 | operand_dict.put("DL", new String[]{"OP_DL", "SZ_NA"}); 86 | operand_dict.put("BL", new String[]{"OP_BL", "SZ_NA"}); 87 | operand_dict.put("AH", new String[]{"OP_AH", "SZ_NA"}); 88 | operand_dict.put("CH", new String[]{"OP_CH", "SZ_NA"}); 89 | operand_dict.put("DH", new String[]{"OP_DH", "SZ_NA"}); 90 | operand_dict.put("BH", new String[]{"OP_BH", "SZ_NA"}); 91 | operand_dict.put("AX", new String[]{"OP_AX", "SZ_NA"}); 92 | operand_dict.put("CX", new String[]{"OP_CX", "SZ_NA"}); 93 | operand_dict.put("DX", new String[]{"OP_DX", "SZ_NA"}); 94 | operand_dict.put("BX", new String[]{"OP_BX", "SZ_NA"}); 95 | operand_dict.put("SI", new String[]{"OP_SI", "SZ_NA"}); 96 | operand_dict.put("DI", new String[]{"OP_DI", "SZ_NA"}); 97 | operand_dict.put("SP", new String[]{"OP_SP", "SZ_NA"}); 98 | operand_dict.put("BP", new String[]{"OP_BP", "SZ_NA"}); 99 | operand_dict.put("eAX", new String[]{"OP_eAX", "SZ_NA"}); 100 | operand_dict.put("eCX", new String[]{"OP_eCX", "SZ_NA"}); 101 | operand_dict.put("eDX", new String[]{"OP_eDX", "SZ_NA"}); 102 | operand_dict.put("eBX", new String[]{"OP_eBX", "SZ_NA"}); 103 | operand_dict.put("eSI", new String[]{"OP_eSI", "SZ_NA"}); 104 | operand_dict.put("eDI", new String[]{"OP_eDI", "SZ_NA"}); 105 | operand_dict.put("eSP", new String[]{"OP_eSP", "SZ_NA"}); 106 | operand_dict.put("eBP", new String[]{"OP_eBP", "SZ_NA"}); 107 | operand_dict.put("rAX", new String[]{"OP_rAX", "SZ_NA"}); 108 | operand_dict.put("rCX", new String[]{"OP_rCX", "SZ_NA"}); 109 | operand_dict.put("rBX", new String[]{"OP_rBX", "SZ_NA"}); 110 | operand_dict.put("rDX", new String[]{"OP_rDX", "SZ_NA"}); 111 | operand_dict.put("rSI", new String[]{"OP_rSI", "SZ_NA"}); 112 | operand_dict.put("rDI", new String[]{"OP_rDI", "SZ_NA"}); 113 | operand_dict.put("rSP", new String[]{"OP_rSP", "SZ_NA"}); 114 | operand_dict.put("rBP", new String[]{"OP_rBP", "SZ_NA"}); 115 | operand_dict.put("ES", new String[]{"OP_ES", "SZ_NA"}); 116 | operand_dict.put("CS", new String[]{"OP_CS", "SZ_NA"}); 117 | operand_dict.put("DS", new String[]{"OP_DS", "SZ_NA"}); 118 | operand_dict.put("SS", new String[]{"OP_SS", "SZ_NA"}); 119 | operand_dict.put("GS", new String[]{"OP_GS", "SZ_NA"}); 120 | operand_dict.put("FS", new String[]{"OP_FS", "SZ_NA"}); 121 | operand_dict.put("ST0", new String[]{"OP_ST0", "SZ_NA"}); 122 | operand_dict.put("ST1", new String[]{"OP_ST1", "SZ_NA"}); 123 | operand_dict.put("ST2", new String[]{"OP_ST2", "SZ_NA"}); 124 | operand_dict.put("ST3", new String[]{"OP_ST3", "SZ_NA"}); 125 | operand_dict.put("ST4", new String[]{"OP_ST4", "SZ_NA"}); 126 | operand_dict.put("ST5", new String[]{"OP_ST5", "SZ_NA"}); 127 | operand_dict.put("ST6", new String[]{"OP_ST6", "SZ_NA"}); 128 | operand_dict.put("ST7", new String[]{"OP_ST7", "SZ_NA"}); 129 | operand_dict.put(null , new String[]{"OP_NONE", "SZ_NA"}); 130 | operand_dict.put("ALr8b" , new String[]{"OP_ALr8b", "SZ_NA"}); 131 | operand_dict.put("CLr9b" , new String[]{"OP_CLr9b", "SZ_NA"}); 132 | operand_dict.put("DLr10b", new String[]{"OP_DLr10b", "SZ_NA"}); 133 | operand_dict.put("BLr11b", new String[]{"OP_BLr11b", "SZ_NA"}); 134 | operand_dict.put("AHr12b", new String[]{"OP_AHr12b", "SZ_NA"}); 135 | operand_dict.put("CHr13b", new String[]{"OP_CHr13b", "SZ_NA"}); 136 | operand_dict.put("DHr14b", new String[]{"OP_DHr14b", "SZ_NA"}); 137 | operand_dict.put("BHr15b", new String[]{"OP_BHr15b", "SZ_NA"}); 138 | operand_dict.put("rAXr8" , new String[]{"OP_rAXr8", "SZ_NA"}); 139 | operand_dict.put("rCXr9" , new String[]{"OP_rCXr9", "SZ_NA"}); 140 | operand_dict.put("rDXr10", new String[]{"OP_rDXr10", "SZ_NA"}); 141 | operand_dict.put("rBXr11", new String[]{"OP_rBXr11", "SZ_NA"}); 142 | operand_dict.put("rSPr12", new String[]{"OP_rSPr12", "SZ_NA"}); 143 | operand_dict.put("rBPr13", new String[]{"OP_rBPr13", "SZ_NA"}); 144 | operand_dict.put("rSIr14", new String[]{"OP_rSIr14", "SZ_NA"}); 145 | operand_dict.put("rDIr15", new String[]{"OP_rDIr15", "SZ_NA"}); 146 | operand_dict.put("jWP", new String[]{"OP_J", "SZ_WP"}); 147 | operand_dict.put("jDP", new String[]{"OP_J", "SZ_DP"}); 148 | pfx_dict.put("aso", "P_aso"); 149 | pfx_dict.put("oso", "P_oso"); 150 | pfx_dict.put("rexw", "P_rexw"); 151 | pfx_dict.put("rexb", "P_rexb"); 152 | pfx_dict.put("rexx", "P_rexx"); 153 | pfx_dict.put("rexr", "P_rexr"); 154 | pfx_dict.put("inv64", "P_inv64"); 155 | pfx_dict.put("def64", "P_def64"); 156 | pfx_dict.put("depM", "P_depM"); 157 | pfx_dict.put("cast1", "P_c1"); 158 | pfx_dict.put("cast2", "P_c2"); 159 | pfx_dict.put("cast3", "P_c3"); 160 | } 161 | 162 | public static List mnm_list = new ArrayList(); 163 | 164 | public static void main(String[] args) throws IOException 165 | { 166 | Document dom = parseXML(); 167 | NodeList list = dom.getElementsByTagName("instruction"); 168 | Map>> tables = new HashMap(); 169 | Map table_sizes = new HashMap(); 170 | for (int i=0; i < list.getLength(); i++) 171 | { 172 | Node n = list.item(i); 173 | String mnemonic = n.getAttributes().getNamedItem("mnemonic").getNodeValue(); 174 | //System.out.println(mnemonic); 175 | if (mnm_list.contains(mnemonic)) 176 | throw new IllegalStateException("Multiple opcode definition for "+mnemonic); 177 | mnm_list.add(mnemonic); 178 | String iclass = ""; 179 | String vendor = ""; 180 | NodeList children = n.getChildNodes(); 181 | for (int j=0; j < children.getLength(); j++) 182 | { 183 | Node c = children.item(j); 184 | if (!(c instanceof Element)) 185 | continue; 186 | if (c.getNodeName().equals("vendor")) 187 | vendor = c.getTextContent().trim(); 188 | if (c.getNodeName().equals("class")) 189 | iclass = c.getTextContent().trim(); 190 | } 191 | 192 | // get each opcode definition 193 | for (int j=0; j < children.getLength(); j++) 194 | { 195 | Node c = children.item(j); 196 | if (!c.getNodeName().equals("opcode")) 197 | continue; 198 | String opcode = c.getTextContent(); 199 | String[] parts = opcode.split(";"); 200 | List flags = new ArrayList(); 201 | String[] opc; 202 | String[] opr = new String[0]; 203 | String[] pfx = new String[0]; 204 | List pfx_c = new ArrayList(); 205 | 206 | Node cast = c.getAttributes().getNamedItem("cast"); 207 | if (null != cast) 208 | pfx_c.add("P_c"+cast.getNodeValue()); 209 | 210 | Node imp = c.getAttributes().getNamedItem("imp_addr"); 211 | if ((null != imp) && (Integer.parseInt(imp.getNodeValue())!=0)) 212 | pfx_c.add("P_ImpAddr"); 213 | 214 | Node mode = c.getAttributes().getNamedItem("mode"); 215 | if (null != mode) 216 | { 217 | String[] modef = mode.getNodeValue().trim().split(" "); 218 | for (int m = 0; m < modef.length; m++) 219 | if (!pfx_dict.containsKey(modef[m])) 220 | System.out.println("Warning: unrecognised mode attribute "+modef[m]); 221 | else 222 | pfx_c.add(pfx_dict.get(modef[m])); 223 | } 224 | 225 | // prefices, opcode bytes, operands 226 | if (parts.length == 1) 227 | opc = parts[0].split(" "); 228 | else if (parts.length == 2) 229 | { 230 | opc = parts[0].split(" "); 231 | opr = parts[1].trim().split(" "); 232 | for (int p=0; p < opc.length; p++) 233 | if (pfx_dict.containsKey(opc[p])) 234 | { 235 | pfx = parts[0].split(" "); 236 | opc = parts[1].split(" "); 237 | break; 238 | } 239 | } 240 | else if (parts.length == 3) 241 | { 242 | pfx = parts[0].trim().split(" "); 243 | opc = parts[1].trim().split(" "); 244 | opr = parts[2].trim().split(" "); 245 | } 246 | else 247 | throw new IllegalStateException("Invalid opcode definition for "+mnemonic); 248 | for (int k=0; k < opc.length; k++) 249 | opc[k] = opc[k].toUpperCase(); 250 | 251 | if (mnemonic.equals("pause") || (mnemonic.equals("nop") && opc[0].equals("90")) || mnemonic.equals("invalid") || mnemonic.equals("db")) 252 | continue; 253 | 254 | // prefix 255 | for (int k=0; k < pfx.length; k++) 256 | { 257 | if ((pfx[k].length()>0) && !pfx_dict.containsKey(pfx[k])) 258 | System.out.println("Error: invalid prefix specification: "+pfx[k]); 259 | if (pfx[k].trim().length() > 0) 260 | pfx_c.add(pfx_dict.get(pfx[k])); 261 | } 262 | if (pfx.length == 0 || ((pfx.length == 1) && pfx[0].trim().length()==0)) 263 | pfx_c.add("P_none"); 264 | pfx = pfx_c.toArray(new String[0]); 265 | 266 | // operands 267 | String[] opr_c = new String[]{"O_NONE", "O_NONE", "O_NONE"}; 268 | for (int k=0; k < opr.length; k++) 269 | { 270 | if ((opr[k].length()>0) && !operand_dict.containsKey(opr[k])) 271 | System.out.println("Error: Invalid operand "+opr[k]); 272 | if (opr[k].trim().length() == 0) 273 | opr[k] = "NONE"; 274 | opr_c[k]= "O_"+opr[k]; 275 | } 276 | opr = new String[]{String.format("%-8s %-8s %s", opr_c[0]+",", opr_c[1]+",", opr_c[2])}; 277 | 278 | String table_sse = ""; 279 | String table_name = "itab__1byte"; 280 | int table_size = 256; 281 | String table_index = ""; 282 | 283 | for (int k=0; k < opc.length; k++) 284 | { 285 | String op = opc[k]; 286 | if (op.startsWith("SSE")) 287 | table_sse = op; 288 | else if (op.equals("0F") && (table_sse.length()>0)) 289 | { 290 | table_name = "itab__pfx_"+table_sse+"__0f"; 291 | table_size = 256; 292 | table_sse = ""; 293 | } 294 | else if (op.equals("0F")) 295 | { 296 | table_name = "itab__0f"; 297 | table_size = 256; 298 | } 299 | else if (op.startsWith("/X87=")) 300 | { 301 | Map tmp = new HashMap(); 302 | tmp.put("type", "grp_x87"); 303 | tmp.put("name", table_name+"__op_"+table_index+"__x87"); 304 | tables.get(table_name).put(table_index, tmp); 305 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 306 | table_index = String.format("%02X", Integer.parseInt(op.substring(5, 7), 16)); 307 | table_size = 64; 308 | } 309 | else if (op.startsWith("/RM=")) 310 | { 311 | Map tmp = new HashMap(); 312 | tmp.put("type", "grp_rm"); 313 | tmp.put("name", table_name+"__op_"+table_index+"__rm"); 314 | tables.get(table_name).put(table_index, tmp); 315 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 316 | table_index = String.format("%02X", Integer.parseInt(op.substring(4, op.length()), 16)); 317 | table_size = 8; 318 | } 319 | else if (op.startsWith("/MOD=")) 320 | { 321 | Map tmp = new HashMap(); 322 | tmp.put("type", "grp_mod"); 323 | tmp.put("name", table_name+"__op_"+table_index+"__mod"); 324 | tables.get(table_name).put(table_index, tmp); 325 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 326 | String v = op.substring(5, 7); 327 | if (op.length() == 8) 328 | v = op.substring(5, 8); 329 | 330 | if (v.equals("!11")) 331 | table_index = "00"; 332 | else if (v.equals("11")) 333 | table_index = "01"; 334 | table_size = 2; 335 | } 336 | else if (op.startsWith("/O")) 337 | { 338 | Map tmp = new HashMap(); 339 | tmp.put("type", "grp_osize"); 340 | tmp.put("name", table_name+"__op_"+table_index+"__osize"); 341 | tables.get(table_name).put(table_index, tmp); 342 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 343 | table_index = mode_dict.get(op.substring(2,4)); 344 | table_size = 3; 345 | } 346 | else if (op.startsWith("/A")) 347 | { 348 | Map tmp = new HashMap(); 349 | tmp.put("type", "grp_asize"); 350 | tmp.put("name", table_name+"__op_"+table_index+"__asize"); 351 | tables.get(table_name).put(table_index, tmp); 352 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 353 | table_index = mode_dict.get(op.substring(2, 4)); 354 | table_size = 3; 355 | } 356 | else if (op.startsWith("/M")) 357 | { 358 | Map tmp = new HashMap(); 359 | tmp.put("type", "grp_mode"); 360 | tmp.put("name", table_name+"__op_"+table_index+"__mode"); 361 | tables.get(table_name).put(table_index, tmp); 362 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 363 | table_index = mode_dict.get(op.substring(2, 4)); 364 | table_size = 3; 365 | } 366 | else if (op.startsWith("/3DNOW")) 367 | { 368 | table_name = "itab__3dnow"; 369 | table_size = 256; 370 | } 371 | else if (op.startsWith("/")) 372 | { 373 | Map tmp = new HashMap(); 374 | tmp.put("type", "grp_reg"); 375 | tmp.put("name", table_name+"__op_"+table_index+"__reg"); 376 | tables.get(table_name).put(table_index, tmp); 377 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 378 | table_index = String.format("%02X", Integer.parseInt(op.substring(1, 2))); 379 | table_size = 8; 380 | } 381 | else 382 | table_index = op; 383 | 384 | if (!tables.containsKey(table_name)) 385 | { 386 | tables.put(table_name, new HashMap()); 387 | table_sizes.put(table_name, table_size); 388 | } 389 | } 390 | if (vendor.length()>0) 391 | { 392 | Map tmp = new HashMap(); 393 | tmp.put("type", "grp_vendor"); 394 | tmp.put("name", table_name+"__op_"+table_index+"__vendor"); 395 | tables.get(table_name).put(table_index, tmp); 396 | table_name = (String) tables.get(table_name).get(table_index).get("name"); 397 | table_index = vend_dict.get(vendor); 398 | table_size = 2; 399 | if (!tables.containsKey(table_name)) 400 | { 401 | tables.put(table_name, new HashMap()); 402 | table_sizes.put(table_name, table_size); 403 | } 404 | } 405 | 406 | Map leaf = new HashMap(); 407 | leaf.put("type", "leaf"); 408 | leaf.put("name", mnemonic); 409 | String pfx_string = ""; 410 | if (pfx.length >0) 411 | { 412 | pfx_string = pfx[0]; 413 | for (int cc = 1; cc < pfx.length; cc++) 414 | pfx_string += "|"+pfx[cc]; 415 | } 416 | leaf.put("pfx", pfx_string); 417 | String opr_string = ""; 418 | if (opr.length >0) 419 | { 420 | opr_string = opr[0]; 421 | for (int cc=1; cc < opr.length; cc++) 422 | opr_string += "|"+opr[cc]; 423 | } 424 | leaf.put("opr", opr_string); 425 | leaf.put("flags", flags); 426 | tables.get(table_name).put(table_index, leaf); 427 | } 428 | } 429 | 430 | // now print to file 431 | BufferedWriter w = new BufferedWriter(new FileWriter("com/Table.java")); 432 | w.write("package com;\n\n"); 433 | w.write("import java.util.*;\n"); 434 | w.write("import static com.ZygoteOperand.*;\n\n"); 435 | w.write("public class Table\n{\n"); 436 | 437 | w.write("\n"); 438 | w.write("public static final int ITAB__VENDOR_INDX__AMD = 0;\n"); 439 | w.write("public static final int ITAB__VENDOR_INDX__INTEL = 1;\n"); 440 | 441 | w.write("\n"); 442 | w.write("public static final int ITAB__MODE_INDX__16 = 0;\n"); 443 | w.write("public static final int ITAB__MODE_INDX__32 = 1;\n"); 444 | w.write("public static final int ITAB__MODE_INDX__64 = 2;\n"); 445 | 446 | w.write("\n"); 447 | w.write("public static final int ITAB__MOD_INDX__NOT_11 = 0;\n"); 448 | w.write("public static final int ITAB__MOD_INDX__11 = 1;\n"); 449 | 450 | // Generate enumeration of the tables 451 | List table_names = new ArrayList(); 452 | table_names.addAll(tables.keySet()); 453 | Collections.sort(table_names); 454 | w.write("\n"); 455 | int h=0; 456 | for (String name: table_names) 457 | { 458 | w.write("public static final int "+name.toUpperCase() + " = "+h+";\n"); 459 | h++; 460 | } 461 | 462 | // Generate operators list 463 | w.write("\npublic static List operator = Arrays.asList(new String[]{\n"); 464 | for (String m: mnm_list) 465 | w.write(" \""+m+"\",\n"); 466 | w.write("});\n\n"); 467 | 468 | w.write("\npublic static List operator_spl = Arrays.asList(new String[]{\n"); 469 | for (String m: spl_mnm_types) 470 | w.write(" \""+m+"\",\n"); 471 | w.write("});\n\n"); 472 | 473 | w.write("\npublic static List operators_str = Arrays.asList(new String[]{\n"); 474 | for (String m: mnm_list) 475 | w.write(" \""+m+"\",\n"); 476 | w.write("});\n\n"); 477 | 478 | // Generate instruction tables 479 | for (String t:table_names) 480 | { 481 | w.write("private ZygoteInstruction[] "+t.toLowerCase()+" = new ZygoteInstruction[]{\n"); 482 | for (int i=0; i < table_sizes.get(t); i++) 483 | { 484 | String index = String.format("%02X", i); 485 | HashMap tmp = new HashMap(); 486 | tmp.put("type", "invalid"); 487 | if (tables.get(t).containsKey(index)) 488 | w.write(centry(index, (Map)tables.get(t).get(index))); 489 | else 490 | w.write(centry(index, tmp)); 491 | } 492 | w.write("};\n"); 493 | } 494 | 495 | w.write("\n// the order of this table matches itab_index "); 496 | w.write("\npublic ZygoteInstruction[][] itab_list = new ZygoteInstruction[][]{\n"); 497 | for (String name: table_names) 498 | w.write(" "+name.toLowerCase()+",\n"); 499 | w.write("};\n"); 500 | w.write("}\n"); 501 | w.flush(); 502 | w.close(); 503 | } 504 | 505 | private static String centry(String i, Map defmap) 506 | { 507 | String opr, mnm, pfx; 508 | if (((String)defmap.get("type")).substring(0, 3).equals("grp")) 509 | { 510 | opr = default_opr; 511 | mnm = "\""+((String)defmap.get("type")).toLowerCase()+"\""; 512 | pfx = ((String)defmap.get("name")).toUpperCase(); 513 | } 514 | else if (((String)defmap.get("type")).equals("leaf")) 515 | { 516 | mnm = "\""+((String)defmap.get("name")).toLowerCase()+"\""; 517 | opr = (String) defmap.get("opr"); 518 | pfx = (String) defmap.get("pfx"); 519 | if (mnm.length() == 0) 520 | mnm = "\'na\'"; 521 | if (opr.length() == 0) 522 | opr = default_opr; 523 | if ((pfx == null) || (pfx.length() == 0)) 524 | pfx = "P_none"; 525 | } 526 | else 527 | { 528 | opr = default_opr; 529 | mnm = "\"invalid\""; 530 | pfx = "P_none"; 531 | } 532 | return String.format(" new ZygoteInstruction( %-16s %-26s %s ),\n", mnm+",", opr+",", pfx); 533 | } 534 | 535 | public static Document parseXML() 536 | { 537 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 538 | try { 539 | DocumentBuilder db = dbf.newDocumentBuilder(); 540 | return db.parse("x86optable.xml"); 541 | }catch(ParserConfigurationException pce) { 542 | pce.printStackTrace(); 543 | }catch(SAXException se) { 544 | se.printStackTrace(); 545 | }catch(IOException ioe) { 546 | ioe.printStackTrace(); 547 | } 548 | return null; 549 | } 550 | } -------------------------------------------------------------------------------- /diff: -------------------------------------------------------------------------------- 1 | 66 0f 3a 0f da 01 -> invalid != palignr xmm3,xmm2,0x1 2 | 66 0f 38 17 c1 -> invalid != ptest xmm0,xmm1 3 | 66 0f 3a 63 ca 1a -> invalid != pcmpistri xmm1,xmm2,0x1a 4 | 66 0f 38 00 c8 -> invalid != pshufb xmm1,xmm0 5 | 66 0f 3a 20 16 00 -> invalid != pinsrb xmm2,BYTE PTR [esi],0x0 6 | c4 11 -> les edx,[ecx] != ledx,FWORD PTR [ecx] 7 | 0f 00 0c d1 -> str DWORD PTR [ecx+edx*8] != str WORD PTR [ecx+edx*8] 8 | 0f 00 84 ce 0f 00 74 ce -> sldt DWORD PTR [esi+ecx*8-0x318bfff1] != sldt WORD PTR [esi+ecx*8-0x318bfff1] 9 | 0f 00 0c ce -> str DWORD PTR [esi+ecx*8] != str WORD PTR [esi+ecx*8] 10 | 0f 00 04 cf -> sldt DWORD PTR [edi+ecx*8] != sldt WORD PTR [edi+ecx*8] 11 | 0f 00 8c 91 0f 00 74 91 -> str DWORD PTR [ecx+edx*4-0x6e8bfff1] != str WORD PTR [ecx+edx*4-0x6e8bfff1] 12 | 0f 00 0c 92 -> str DWORD PTR [edx+edx*4] != str WORD PTR [edx+edx*4] 13 | 0f 00 84 60 0f 00 dc 5f -> sldt DWORD PTR [eax+0x5fdc000f] != sldt WORD PTR [eax+0x5fdc000f] 14 | 0f 00 44 60 0f -> sldt DWORD PTR [eax+0xf] != sldt WORD PTR [eax+0xf] 15 | f3 0f b8 c9 -> rep repe invalid != popcnt ecx,ecx 16 | c4 11 -> les edx,[ecx] != ledx,FWORD PTR [ecx] 17 | 0f 00 0c d1 -> str DWORD PTR [ecx+edx*8] != str WORD PTR [ecx+edx*8] 18 | 0f 00 84 ce 0f 00 74 ce -> sldt DWORD PTR [esi+ecx*8-0x318bfff1] != sldt WORD PTR [esi+ecx*8-0x318bfff1] 19 | 0f 00 0c ce -> str DWORD PTR [esi+ecx*8] != str WORD PTR [esi+ecx*8] 20 | 0f 00 04 cf -> sldt DWORD PTR [edi+ecx*8] != sldt WORD PTR [edi+ecx*8] 21 | 0f 00 8c 91 0f 00 74 91 -> str DWORD PTR [ecx+edx*4-0x6e8bfff1] != str WORD PTR [ecx+edx*4-0x6e8bfff1] 22 | 0f 00 0c 92 -> str DWORD PTR [edx+edx*4] != str WORD PTR [edx+edx*4] 23 | 0f 00 84 60 0f 00 dc 5f -> sldt DWORD PTR [eax+0x5fdc000f] != sldt WORD PTR [eax+0x5fdc000f] 24 | 0f 00 44 60 0f -> sldt DWORD PTR [eax+0xf] != sldt WORD PTR [eax+0xf] 25 | 0f b4 55 ee -> lfs edx,[ebp-0x12] != lfs edx,FWORD PTR [ebp-0x12] 26 | 0f ae 0e -> invalid != fxrstor [esi] 27 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 28 | c4 05 00 00 c6 05 -> les eax,ds:0x5c60000 != leax,FWORD PTR ds:0x5c60000 29 | c4 06 -> les eax,[esi] != leax,FWORD PTR [esi] 30 | c4 07 -> les eax,[edi] != leax,FWORD PTR [edi] 31 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 32 | c5 0f -> lds ecx,[edi] != lds ecx,FWORD PTR [edi] 33 | f2 0f 00 00 -> repne sldt DWORD PTR [eax] != repnz sldt WORD PTR [eax] 34 | 0f 0f 0f 8e -> invalid != pfpnacc mm1,QWORD PTR [edi] 35 | c5 15 35 c5 0a 14 -> lds edx,ds:0x140ac535 != lds edx,FWORD PTR ds:0x140ac535 36 | c4 9f 1b 49 bc 88 -> les ebx,[edi-0x7743b6e5] != lebx,FWORD PTR [edi-0x7743b6e5] 37 | c4 10 -> les edx,[eax] != ledx,FWORD PTR [eax] 38 | c4 10 -> les edx,[eax] != ledx,FWORD PTR [eax] 39 | c4 08 -> les ecx,[eax] != lecx,FWORD PTR [eax] 40 | c4 3c 1d e4 7c 62 80 -> les edi,[ebx-0x7f9d831c] != ledi,FWORD PTR [ebx-0x7f9d831c] 41 | 0f 00 80 96 98 00 00 -> sldt DWORD PTR [eax+0x9896] != sldt WORD PTR [eax+0x9896] 42 | c4 00 -> les eax,[eax] != leax,FWORD PTR [eax] 43 | c4 a7 f7 ff 54 02 -> les esp,[edi+0x254fff7] != lesp,FWORD PTR [edi+0x254fff7] 44 | c4 bf f7 ff 52 00 -> les edi,[edi+0x52fff7] != ledi,FWORD PTR [edi+0x52fff7] 45 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 46 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 47 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 48 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 49 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 50 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 51 | c4 01 -> les eax,[ecx] != leax,FWORD PTR [ecx] 52 | c4 3e -> les edi,[esi] != ledi,FWORD PTR [esi] 53 | c5 0a -> lds ecx,[edx] != lds ecx,FWORD PTR [edx] 54 | c4 17 -> les edx,[edi] != ledx,FWORD PTR [edi] 55 | c4 48 00 -> les ecx,[eax+0x0] != lecx,FWORD PTR [eax+0x0] 56 | c4 01 -> les eax,[ecx] != leax,FWORD PTR [ecx] 57 | c4 55 00 -> les edx,[ebp+0x0] != ledx,FWORD PTR [ebp+0x0] 58 | ff 2a -> jmp far DWORD PTR [edx] != jmp FWORD PTR [edx] 59 | c8 e0 fd ff -> enter 0xfde0,0xffff != enter 0xfde0,0xff 60 | ff 6b 01 -> jmp far DWORD PTR [ebx+0x1] != jmp FWORD PTR [ebx+0x1] 61 | c5 04 00 -> lds eax,[eax+eax] != lds eax,FWORD PTR [eax+eax] 62 | c5 01 -> lds eax,[ecx] != lds eax,FWORD PTR [ecx] 63 | c5 00 -> lds eax,[eax] != lds eax,FWORD PTR [eax] 64 | c5 00 -> lds eax,[eax] != lds eax,FWORD PTR [eax] 65 | c4 15 2c 40 10 21 -> les edx,ds:0x2110402c != ledx,FWORD PTR ds:0x2110402c 66 | c5 00 -> lds eax,[eax] != lds eax,FWORD PTR [eax] 67 | 0f b2 92 d4 08 4a c3 -> lss edx,[edx-0x3cb5f72c] != lss edx,FWORD PTR [edx-0x3cb5f72c] 68 | f3 92 -> rep repe xchg edx,eax != repz xchg edx,eax 69 | c4 95 4b 4a 64 b9 -> les edx,[ebp-0x469bb5b5] != ledx,FWORD PTR [ebp-0x469bb5b5] 70 | c5 1f -> lds ebx,[edi] != lds ebx,FWORD PTR [edi] 71 | c4 b4 ae d9 71 58 1c -> les esi,[esi+ebp*4+0x1c5871d9] != lesi,FWORD PTR [esi+ebp*4+0x1c5871d9] 72 | c5 05 00 00 00 00 -> lds eax,ds:0x0 != lds eax,FWORD PTR ds:0x0 73 | c4 12 -> les edx,[edx] != ledx,FWORD PTR [edx] 74 | 0f 00 4d 1a -> str DWORD PTR [ebp+0x1a] != str WORD PTR [ebp+0x1a] 75 | 0f 00 00 -> sldt DWORD PTR [eax] != sldt WORD PTR [eax] 76 | c4 00 -> les eax,[eax] != leax,FWORD PTR [eax] 77 | c4 06 -> les eax,[esi] != leax,FWORD PTR [esi] 78 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 79 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 80 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 81 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 82 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 83 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 84 | c5 06 -> lds eax,[esi] != lds eax,FWORD PTR [esi] 85 | 0f 01 1b -> lidt [ebx] != lidtd [ebx] 86 | c4 6d 07 -> les ebp,[ebp+0x7] != lebp,FWORD PTR [ebp+0x7] 87 | c5 28 -> lds ebp,[eax] != lds ebp,FWORD PTR [eax] 88 | c4 02 -> les eax,[edx] != leax,FWORD PTR [edx] 89 | c5 0c 04 -> lds ecx,[esp+eax] != lds ecx,FWORD PTR [esp+eax] 90 | c5 0c 04 -> lds ecx,[esp+eax] != lds ecx,FWORD PTR [esp+eax] 91 | c5 04 08 -> lds eax,[eax+ecx] != lds eax,FWORD PTR [eax+ecx] 92 | c5 00 -> lds eax,[eax] != lds eax,FWORD PTR [eax] 93 | c5 00 -> lds eax,[eax] != lds eax,FWORD PTR [eax] 94 | 0f 00 04 eb -> sldt DWORD PTR [ebx+ebp*8] != sldt WORD PTR [ebx+ebp*8] 95 | 0f 00 0f -> str DWORD PTR [edi] != str WORD PTR [edi] 96 | 0f 00 09 -> str DWORD PTR [ecx] != str WORD PTR [ecx] 97 | 0f 00 09 -> str DWORD PTR [ecx] != str WORD PTR [ecx] 98 | 0f 00 8d 74 26 00 80 -> str DWORD PTR [ebp-0x7fffd98c] != str WORD PTR [ebp-0x7fffd98c] 99 | c4 0c 00 -> les ecx,[eax+eax] != lecx,FWORD PTR [eax+eax] 100 | c5 b4 0c 00 c5 b4 0c -> lds esi,[esp+ecx+0xcb4c500] != lds esi,FWORD PTR [esp+ecx+0xcb4c500] 101 | c5 09 -> lds ecx,[ecx] != lds ecx,FWORD PTR [ecx] 102 | c4 09 -> les ecx,[ecx] != lecx,FWORD PTR [ecx] 103 | c4 09 -> les ecx,[ecx] != lecx,FWORD PTR [ecx] 104 | 66 83 fa ff -> cmp dx,0xffff != cmp dx,0xffffffff 105 | ff e9 -> jmp far ecx != jmp 106 | c4 3f -> les edi,[edi] != ledi,FWORD PTR [edi] 107 | -------------------------------------------------------------------------------- /diff2: -------------------------------------------------------------------------------- 1 | 66 0f 3a 0f da 01 -> invalid != palignr xmm3,xmm2,0x1 2 | 66 0f 38 17 c1 -> invalid != ptest xmm0,xmm1 3 | 66 0f 3a 63 ca 1a -> invalid != pcmpistri xmm1,xmm2,0x1a 4 | 66 0f 38 00 c8 -> invalid != pshufb xmm1,xmm0 5 | 66 0f 3a 20 16 00 -> invalid != pinsrb xmm2,BYTE PTR [esi],0x0 6 | f3 0f b8 c9 -> rep repe invalid != popcnt ecx,ecx 7 | 0f ae 0e -> invalid != fxrstor [esi] 8 | 0f 0f 0f 8e -> invalid != pfpnacc mm1,QWORD PTR [edi] 9 | -------------------------------------------------------------------------------- /diff3: -------------------------------------------------------------------------------- 1 | 66 0f 3a 0f da 01 -> invalid != palignr xmm3,xmm2,0x1 2 | 66 0f 38 17 c1 -> invalid != ptest xmm0,xmm1 3 | 66 0f 3a 63 ca 1a -> invalid != pcmpistri xmm1,xmm2,0x1a 4 | 66 0f 38 00 c8 -> invalid != pshufb xmm1,xmm0 5 | 66 0f 3a 20 16 00 -> invalid != pinsrb xmm2,BYTE PTR [esi],0x0 6 | 64 36 12 00 -> adc al,BYTE PTR ss:[eax] != fs adc al,BYTE PTR ss:fs:[eax] 7 | f3 0f b8 c9 -> rep repe invalid != popcnt ecx,ecx 8 | 64 36 12 00 -> adc al,BYTE PTR ss:[eax] != fs adc al,BYTE PTR ss:fs:[eax] 9 | 66 6b c7 d3 -> imul ax,di,0xffd3 != imul ax,di,0xffffffd3 10 | 0f b4 55 ee -> lfs edx,[ebp-0x12] != lfs edx,FWORD PTR [ebp-0x12] 11 | 0f ae 0e -> invalid != fxrstor [esi] 12 | 2e 64 6b 00 2b -> imul eax,DWORD PTR fs:[eax],0x2b != cs imul eax,cs:fs:[eax],0x2b 13 | f2 f3 f4 -> rep repe repne hlt != repnz repz hlt 14 | 0f 0f 0f 8e -> invalid != pfpnacc mm1,QWORD PTR [edi] 15 | 64 64 69 74 69 6f 6e 61 6c 20 -> imul esi,DWORD PTR fs:[ecx+ebp*2+0x6f],0x206c616e != fs imul esi,fs:[ecx+ebp*2+0x6f],0x206c616e 16 | 3e 2e 0a 00 -> or al,BYTE PTR cs:[eax] != ds or al,BYTE PTR cs:ds:[eax] 17 | f3 dc 0c 08 -> rep repe fmul QWORD PTR [eax+ecx] != repz fmul QWORD PTR [eax+ecx] 18 | 0f d8 95 d5 6e 71 b2 -> psubusb mm2,[ebp-0x4d8e912b] != psubusb mm2,QWORD PTR [ebp-0x4d8e912b] 19 | f2 3d d7 d0 89 fa -> repne cmp eax,0xfa89d0d7 != repnz cmp eax,0xfa89d0d7 20 | 0f 69 6e 69 -> punpckhwd mm5,[esi+0x69] != punpckhwd mm5,QWORD PTR [esi+0x69] 21 | f3 33 f8 -> rep repe xor edi,eax != repz xor edi,eax 22 | f3 31 f8 -> rep repe xor eax,edi != repz xor eax,edi 23 | f2 18 f8 -> repne sbb al,bh != repnz sbb al,bh 24 | f3 1a f8 -> rep repe sbb bh,al != repz sbb bh,al 25 | f3 f8 -> rep repe clc != repz clc 26 | f2 9f -> repne lahf != repnz lahf 27 | f2 fd -> repne std != repnz std 28 | 0f b2 92 d4 08 4a c3 -> lss edx,[edx-0x3cb5f72c] != lss edx,FWORD PTR [edx-0x3cb5f72c] 29 | f3 92 -> rep repe xchg edx,eax != repz xchg edx,eax 30 | f2 71 a7 -> repne jno 0x80486f6 != repnz jno 80486f6 31 | 64 3e 0a 20 -> or ah,BYTE PTR ds:[eax] != fs or ah,BYTE PTR ds:fs:[eax] 32 | 65 3e 0a 20 -> or ah,BYTE PTR ds:[eax] != or ah,BYTE PTR ds:gs:[eax] 33 | 0f 01 1b -> lidt [ebx] != lidtd [ebx] 34 | 0f 18 19 -> prefetcht2 [ecx] != prefetcht2 BYTE PTR [ecx] 35 | f3 81 0c 00 94 82 0c 00 -> rep repe or DWORD PTR [eax+eax],0xc8294 != repz or [eax+eax],0xc8294 36 | 66 83 7f 38 ff -> cmp WORD PTR [edi+0x38],0xffff != cmp WORD PTR [edi+0x38],0xffffffff 37 | 66 83 fa ff -> cmp dx,0xffff != cmp dx,0xffffffff 38 | --------------------------------------------------------------------------------