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