1 : // Copyright 2012 Google Inc.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/core/disassembler_util.h"
16 :
17 : #include "base/basictypes.h"
18 : #include "base/logging.h"
19 : #include "gtest/gtest.h"
20 :
21 : namespace core {
22 :
23 : namespace {
24 :
25 E : _DInst DecodeBuffer(const uint8* buffer, size_t length) {
26 E : _DInst inst = {};
27 E : EXPECT_TRUE(DecodeOneInstruction(buffer, length, &inst));
28 E : EXPECT_EQ(length, inst.size);
29 E : return inst;
30 E : }
31 :
32 : // One of the AVX instructions that is currently not supported by distorm.
33 : // vxorps ymm0, ymm0, ymm0
34 : const uint8 kVxorps[] = { 0xC5, 0xFC, 0x57, 0xC0 };
35 :
36 : // Nop Instruction byte sequences.
37 : const uint8 kNop2Mov[] = { 0x8B, 0xFF };
38 : const uint8 kNop3Lea[] = { 0x8D, 0x49, 0x00 };
39 : const uint8 kNop1[] = { 0x90 };
40 : const uint8 kNop2[] = { 0x66, 0x90 };
41 : const uint8 kNop3[] = { 0x66, 0x66, 0x90 };
42 : const uint8 kNop4[] = { 0x0F, 0x1F, 0x40, 0x00 };
43 : const uint8 kNop5[] = { 0x0F, 0x1F, 0x44, 0x00, 0x00 };
44 : const uint8 kNop6[] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 };
45 : const uint8 kNop7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 };
46 : const uint8 kNop8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
47 : const uint8 kNop9[] = {
48 : 0x66, // Prefix,
49 : 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 // kNop8.
50 : };
51 : const uint8 kNop10[] = {
52 : 0x66, 0x66, // Prefix.
53 : 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 // kNop8.
54 : };
55 : const uint8 kNop11[] = {
56 : 0x66, 0x66, 0x66, // Prefix.
57 : 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 // kNop8
58 : };
59 :
60 : // Call instruction.
61 : const uint8 kCall[] = { 0xE8, 0xCA, 0xFE, 0xBA, 0xBE };
62 :
63 : // Control Flow byte sequences (note that the JMP is indirect).
64 : const uint8 kJmp[] = { 0xFF, 0x24, 0x8D, 0xCA, 0xFE, 0xBA, 0xBE };
65 : const uint8 kRet[] = { 0xC3 };
66 : const uint8 kRetN[] = { 0xC2, 0x08, 0x00 };
67 : const uint8 kJe[] = { 0x74, 0xCA };
68 : const uint8 kSysEnter[] = { 0x0F, 0x34 };
69 :
70 : // Interrupts.
71 : const uint8 kInt2[] = { 0xCD, 0x02 };
72 : const uint8 kInt3[] = { 0xCC };
73 :
74 : } // namespace
75 :
76 E : TEST(DisassemblerUtilTest, DistormWrapperVxorpsPasses) {
77 E : _DInst inst = {};
78 E : EXPECT_TRUE(DecodeOneInstruction(kVxorps, sizeof(kVxorps), &inst));
79 E : }
80 :
81 E : TEST(DisassemblerUtilTest, IsNop) {
82 E : EXPECT_FALSE(IsNop(DecodeBuffer(kJmp, sizeof(kJmp))));
83 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop1, sizeof(kNop1))));
84 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop2, sizeof(kNop2))));
85 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop3, sizeof(kNop3))));
86 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop4, sizeof(kNop4))));
87 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop5, sizeof(kNop5))));
88 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop6, sizeof(kNop6))));
89 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop7, sizeof(kNop7))));
90 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop8, sizeof(kNop8))));
91 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop9, sizeof(kNop9))));
92 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop10, sizeof(kNop10))));
93 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop11, sizeof(kNop11))));
94 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop2Mov, sizeof(kNop2Mov))));
95 E : EXPECT_TRUE(IsNop(DecodeBuffer(kNop3Lea, sizeof(kNop3Lea))));
96 E : }
97 :
98 E : TEST(DisassemblerUtilTest, IsCall) {
99 E : EXPECT_FALSE(IsCall(DecodeBuffer(kJmp, sizeof(kJmp))));
100 E : EXPECT_FALSE(IsCall(DecodeBuffer(kNop1, sizeof(kNop1))));
101 E : EXPECT_TRUE(IsCall(DecodeBuffer(kCall, sizeof(kCall))));
102 E : }
103 :
104 E : TEST(DisassemblerUtilTest, IsControlFlow) {
105 E : EXPECT_FALSE(IsControlFlow(DecodeBuffer(kNop4, sizeof(kNop4))));
106 E : EXPECT_TRUE(IsControlFlow(DecodeBuffer(kJmp, sizeof(kJmp))));
107 E : EXPECT_TRUE(IsControlFlow(DecodeBuffer(kRet, sizeof(kRet))));
108 E : EXPECT_TRUE(IsControlFlow(DecodeBuffer(kRetN, sizeof(kRetN))));
109 E : EXPECT_TRUE(IsControlFlow(DecodeBuffer(kJe, sizeof(kJe))));
110 E : EXPECT_TRUE(IsControlFlow(DecodeBuffer(kSysEnter, sizeof(kSysEnter))));
111 E : }
112 :
113 E : TEST(DisassemblerUtilTest, IsImplicitControlFlow) {
114 E : EXPECT_FALSE(IsImplicitControlFlow(DecodeBuffer(kJe, sizeof(kJe))));
115 E : EXPECT_TRUE(IsImplicitControlFlow(DecodeBuffer(kRet, sizeof(kRet))));
116 E : EXPECT_TRUE(IsImplicitControlFlow(DecodeBuffer(kRetN, sizeof(kRetN))));
117 E : EXPECT_TRUE(IsImplicitControlFlow(DecodeBuffer(kJmp, sizeof(kJmp))));
118 E : }
119 :
120 E : TEST(DisassemblerUtilTest, IsInterrupt) {
121 E : EXPECT_FALSE(IsInterrupt(DecodeBuffer(kJe, sizeof(kJe))));
122 E : EXPECT_TRUE(IsInterrupt(DecodeBuffer(kInt2, sizeof(kInt2))));
123 E : EXPECT_TRUE(IsInterrupt(DecodeBuffer(kInt3, sizeof(kInt3))));
124 E : }
125 :
126 E : TEST(DisassemblerUtilTest, IsDebugInterrupt) {
127 E : EXPECT_FALSE(IsDebugInterrupt(DecodeBuffer(kJe, sizeof(kJe))));
128 E : EXPECT_FALSE(IsDebugInterrupt(DecodeBuffer(kInt2, sizeof(kInt2))));
129 E : EXPECT_TRUE(IsDebugInterrupt(DecodeBuffer(kInt3, sizeof(kInt3))));
130 E : }
131 :
132 : } // namespace core
|